Merge V8 at 3.9.24.21
Bug: 5688872
Change-Id: I8c6370d6e881d372b602527bf6c02994e0165515
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index ed1c0be..a80c7d8 100644
--- a/V8_MERGE_REVISION
+++ b/V8_MERGE_REVISION
@@ -1,2 +1,2 @@
-V8 3.9.24.17
-http://v8.googlecode.com/svn/branches/3.9@11450
+V8 3.9.24.21
+http://v8.googlecode.com/svn/branches/3.9@11511
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index 7b2a3c4..699e6aa 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -457,6 +457,8 @@
void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
int frame_index) {
+ Builtins* builtins = isolate_->builtins();
+ Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
@@ -464,7 +466,7 @@
PrintF(" translating construct stub => height=%d\n", height_in_bytes);
}
- unsigned fixed_frame_size = 7 * kPointerSize;
+ unsigned fixed_frame_size = 8 * kPointerSize;
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
@@ -529,6 +531,15 @@
top_address + output_offset, output_offset, value);
}
+ // The output frame reflects a JSConstructStubGeneric frame.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(construct_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
// Number of incoming arguments.
output_offset -= kPointerSize;
value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -559,8 +570,6 @@
ASSERT(0 == output_offset);
- Builtins* builtins = isolate_->builtins();
- Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
uint32_t pc = reinterpret_cast<uint32_t>(
construct_stub->instruction_start() +
isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 852824f..98a3cdc 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -4429,6 +4429,8 @@
// Increment the length of the array.
__ mov(length_reg, Operand(Smi::FromInt(1)));
__ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+ __ ldr(elements_reg,
+ FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
__ jmp(&finish_store);
__ bind(&check_capacity);
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 92d7cc1..6de2c81 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -548,6 +548,8 @@
void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
int frame_index) {
+ Builtins* builtins = isolate_->builtins();
+ Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
@@ -555,7 +557,7 @@
PrintF(" translating construct stub => height=%d\n", height_in_bytes);
}
- unsigned fixed_frame_size = 6 * kPointerSize;
+ unsigned fixed_frame_size = 7 * kPointerSize;
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
@@ -620,6 +622,15 @@
top_address + output_offset, output_offset, value);
}
+ // The output frame reflects a JSConstructStubGeneric frame.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(construct_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
// Number of incoming arguments.
output_offset -= kPointerSize;
value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -641,8 +652,6 @@
ASSERT(0 == output_offset);
- Builtins* builtins = isolate_->builtins();
- Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
uint32_t pc = reinterpret_cast<uint32_t>(
construct_stub->instruction_start() +
isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc
index 51c2e46..62f3155 100644
--- a/src/mips/deoptimizer-mips.cc
+++ b/src/mips/deoptimizer-mips.cc
@@ -447,6 +447,8 @@
void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
int frame_index) {
+ Builtins* builtins = isolate_->builtins();
+ Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
@@ -454,7 +456,7 @@
PrintF(" translating construct stub => height=%d\n", height_in_bytes);
}
- unsigned fixed_frame_size = 7 * kPointerSize;
+ unsigned fixed_frame_size = 8 * kPointerSize;
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
@@ -519,6 +521,15 @@
top_address + output_offset, output_offset, value);
}
+ // The output frame reflects a JSConstructStubGeneric frame.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(construct_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
// Number of incoming arguments.
output_offset -= kPointerSize;
value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -549,8 +560,6 @@
ASSERT(0 == output_offset);
- Builtins* builtins = isolate_->builtins();
- Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
uint32_t pc = reinterpret_cast<uint32_t>(
construct_stub->instruction_start() +
isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index f7b94b9..f1a8c89 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -4494,6 +4494,8 @@
// Increment the length of the array.
__ li(length_reg, Operand(Smi::FromInt(1)));
__ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+ __ lw(elements_reg,
+ FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
__ jmp(&finish_store);
__ bind(&check_capacity);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 6c2c73a..68feda4 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1383,7 +1383,9 @@
void JSObject::initialize_elements() {
- ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
+ ASSERT(map()->has_fast_elements() ||
+ map()->has_fast_smi_only_elements() ||
+ map()->has_fast_double_elements());
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
}
diff --git a/src/spaces.cc b/src/spaces.cc
index 57b223f..929a45f 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -362,13 +362,20 @@
if (base == NULL) return NULL;
if (executable == EXECUTABLE) {
- CommitCodePage(&reservation, base, size);
- } else {
- if (!reservation.Commit(base,
- size,
- executable == EXECUTABLE)) {
- return NULL;
+ if (!CommitCodePage(&reservation, base, size)) {
+ base = NULL;
}
+ } else {
+ if (!reservation.Commit(base, size, false)) {
+ base = NULL;
+ }
+ }
+
+ if (base == NULL) {
+ // Failed to commit the body. Release the mapping and any partially
+ // commited regions inside it.
+ reservation.Release();
+ return NULL;
}
controller->TakeControl(&reservation);
diff --git a/src/spaces.h b/src/spaces.h
index b614c3b..9e74a88 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1040,7 +1040,9 @@
return CodePageAreaEndOffset() - CodePageAreaStartOffset();
}
- static bool CommitCodePage(VirtualMemory* vm, Address start, size_t size);
+ MUST_USE_RESULT static bool CommitCodePage(VirtualMemory* vm,
+ Address start,
+ size_t size);
private:
Isolate* isolate_;
diff --git a/src/version.cc b/src/version.cc
index a5b9279..d024048 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 9
#define BUILD_NUMBER 24
-#define PATCH_LEVEL 17
+#define PATCH_LEVEL 21
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index 2adf587..f55ebfc 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -440,6 +440,8 @@
void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
int frame_index) {
+ Builtins* builtins = isolate_->builtins();
+ Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
unsigned height = iterator->Next();
unsigned height_in_bytes = height * kPointerSize;
@@ -447,7 +449,7 @@
PrintF(" translating construct stub => height=%d\n", height_in_bytes);
}
- unsigned fixed_frame_size = 6 * kPointerSize;
+ unsigned fixed_frame_size = 7 * kPointerSize;
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
@@ -516,6 +518,16 @@
top_address + output_offset, output_offset, value);
}
+ // The output frame reflects a JSConstructStubGeneric frame.
+ output_offset -= kPointerSize;
+ value = reinterpret_cast<intptr_t>(construct_stub);
+ output_frame->SetFrameSlot(output_offset, value);
+ if (FLAG_trace_deopt) {
+ PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+ V8PRIxPTR " ; code object\n",
+ top_address + output_offset, output_offset, value);
+ }
+
// Number of incoming arguments.
output_offset -= kPointerSize;
value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
@@ -539,8 +551,6 @@
ASSERT(0 == output_offset);
- Builtins* builtins = isolate_->builtins();
- Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
intptr_t pc = reinterpret_cast<intptr_t>(
construct_stub->instruction_start() +
isolate_->heap()->construct_stub_deopt_pc_offset()->value());
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index a275f55..7ce4568 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -3767,6 +3767,7 @@
// Increment the length of the array.
__ Move(FieldOperand(rdx, JSArray::kLengthOffset), Smi::FromInt(1));
+ __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset));
__ jmp(&finish_store);
__ bind(&check_capacity);
diff --git a/test/mjsunit/regress/regress-124594.js b/test/mjsunit/regress/regress-124594.js
new file mode 100644
index 0000000..d51e1f6
--- /dev/null
+++ b/test/mjsunit/regress/regress-124594.js
@@ -0,0 +1,50 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+// Test that a GC inside a constructor frame is correctly handled right
+// after we deoptimize from an inlined constructor to a constructor stub
+// stack frame.
+
+function f(deopt) {
+ var x = 1;
+ if (deopt) {
+ x = x + "foo";
+ gc();
+ }
+ this.x = x;
+}
+
+function g(deopt) {
+ return new f(deopt);
+}
+
+assertEquals({x:1}, g(false));
+assertEquals({x:1}, g(false));
+%OptimizeFunctionOnNextCall(g);
+assertEquals({x:"1foo"}, g(true));
diff --git a/test/mjsunit/regress/regress-125515.js b/test/mjsunit/regress/regress-125515.js
new file mode 100644
index 0000000..91650ce
--- /dev/null
+++ b/test/mjsunit/regress/regress-125515.js
@@ -0,0 +1,41 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-gc --debug-code
+
+function test(a) {
+ a[0] = 1.5;
+ assertEquals(0, a.length = 0);
+}
+a = new Array();
+test(a);
+test(a);
+// Make sure that a ends up in old space
+gc();
+gc();
+test(a);
+test(a);