Fix memento initialization when constructing from new call
authormlippautz <mlippautz@chromium.org>
Fri, 17 Jul 2015 08:51:24 +0000 (01:51 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 17 Jul 2015 08:51:41 +0000 (08:51 +0000)
Additionally, push the allocation site or undefined independently of creating a memento to preserve a fixed size for the construct frames.

BUG=

Review URL: https://codereview.chromium.org/1239593003

Cr-Commit-Position: refs/heads/master@{#29719}

src/arm/builtins-arm.cc
src/arm64/builtins-arm64.cc
src/deoptimizer.cc
src/frames.cc
src/frames.h
src/ia32/builtins-ia32.cc
src/mips/builtins-mips.cc
src/mips64/builtins-mips64.cc
src/x64/builtins-x64.cc
test/cctest/test-mementos.cc

index 3f01774..5dfdd2a 100644 (file)
@@ -332,12 +332,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
   {
     FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
 
-    if (create_memento) {
-      __ AssertUndefinedOrAllocationSite(r2, r4);
-      __ push(r2);
-    }
-
     // Preserve the incoming parameters on the stack.
+    __ AssertUndefinedOrAllocationSite(r2, r4);
+    __ push(r2);
     __ SmiTag(r0);
     __ push(r0);
     __ push(r1);
@@ -476,7 +473,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
         __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
         // Load the AllocationSite
-        __ ldr(r6, MemOperand(sp, 2 * kPointerSize));
+        __ ldr(r6, MemOperand(sp, 3 * kPointerSize));
+        __ AssertUndefinedOrAllocationSite(r6, r0);
         DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
         __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
       } else {
@@ -664,12 +662,12 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
   //  -- sp[...]: constructor arguments
   // -----------------------------------
 
-  // TODO(dslomov): support pretenuring
-  CHECK(!FLAG_pretenuring_call_new);
-
   {
     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
 
+    __ AssertUndefinedOrAllocationSite(r2, r4);
+    __ push(r2);
+
     __ mov(r4, r0);
     __ SmiTag(r4);
     __ push(r4);  // Smi-tagged arguments count.
index 4342056..536cda1 100644 (file)
@@ -324,22 +324,20 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
   {
     FrameScope scope(masm, StackFrame::CONSTRUCT);
 
-    // Preserve the three incoming parameters on the stack.
-    if (create_memento) {
-      __ AssertUndefinedOrAllocationSite(x2, x10);
-      __ Push(x2);
-    }
-
+    // Preserve the four incoming parameters on the stack.
     Register argc = x0;
     Register constructor = x1;
+    Register allocation_site = x2;
     Register original_constructor = x3;
 
     // Preserve the incoming parameters on the stack.
+    __ AssertUndefinedOrAllocationSite(allocation_site, x10);
     __ SmiTag(argc);
-    __ Push(argc, constructor, original_constructor);
+    __ Push(allocation_site, argc, constructor, original_constructor);
     // sp[0]: new.target
     // sp[1]: Constructor function.
     // sp[2]: number of arguments (smi-tagged)
+    // sp[3]: allocation site
 
     // Try to allocate the object without transitioning into C code. If any of
     // the preconditions is not met, the code bails out to the runtime call.
@@ -483,7 +481,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
         __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
         // Load the AllocationSite
-        __ Peek(x14, 2 * kXRegSize);
+        __ Peek(x14, 3 * kXRegSize);
+        __ AssertUndefinedOrAllocationSite(x14, x10);
         DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
         __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
         first_prop = NoReg;
@@ -669,18 +668,18 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
   // -----------------------------------
   ASM_LOCATION("Builtins::Generate_JSConstructStubForDerived");
 
-  // TODO(dslomov): support pretenuring
-  CHECK(!FLAG_pretenuring_call_new);
-
   {
     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
+
+    __ AssertUndefinedOrAllocationSite(x2, x10);
     __ Mov(x4, x0);
     __ SmiTag(x4);
     __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
-    __ Push(x4, x3, x10);
-    // sp[0]: number of arguments
+    __ Push(x2, x4, x3, x10);
+    // sp[0]: receiver (the hole)
     // sp[1]: new.target
-    // sp[2]: receiver (the hole)
+    // sp[2]: number of arguments
+    // sp[3]: allocation site
 
     // Set up pointer to last argument.
     __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset);
index c6e6baa..587fc09 100644 (file)
@@ -1221,6 +1221,12 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
   output_frame->SetFrameSlot(output_offset, value);
   DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
 
+  // The allocation site.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value());
+  output_frame->SetFrameSlot(output_offset, value);
+  DebugPrintOutputSlot(value, frame_index, output_offset, "allocation site\n");
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
index 5dea848..66bcf3d 100644 (file)
@@ -738,8 +738,8 @@ Object* JavaScriptFrame::GetOriginalConstructor() const {
   }
   DCHECK(IsConstructFrame(fp));
   STATIC_ASSERT(ConstructFrameConstants::kOriginalConstructorOffset ==
-                StandardFrameConstants::kExpressionsOffset - 2 * kPointerSize);
-  return GetExpression(fp, 2);
+                StandardFrameConstants::kExpressionsOffset - 3 * kPointerSize);
+  return GetExpression(fp, 3);
 }
 
 
index 0d2a2e3..9eee5a1 100644 (file)
@@ -155,16 +155,18 @@ class ConstructFrameConstants : public AllStatic {
  public:
   // FP-relative.
   static const int kImplicitReceiverOffset =
-      StandardFrameConstants::kExpressionsOffset - 3 * kPointerSize;
+      StandardFrameConstants::kExpressionsOffset - 4 * kPointerSize;
   static const int kOriginalConstructorOffset =
-      StandardFrameConstants::kExpressionsOffset - 2 * kPointerSize;
+      StandardFrameConstants::kExpressionsOffset - 3 * kPointerSize;
   static const int kLengthOffset =
+      StandardFrameConstants::kExpressionsOffset - 2 * kPointerSize;
+  static const int kAllocationSiteOffset =
       StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
   static const int kCodeOffset =
       StandardFrameConstants::kExpressionsOffset - 0 * kPointerSize;
 
   static const int kFrameSize =
-      StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
+      StandardFrameConstants::kFixedFrameSize + 5 * kPointerSize;
 };
 
 
index 3a85089..bd8c5fb 100644 (file)
@@ -117,12 +117,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
   {
     FrameScope scope(masm, StackFrame::CONSTRUCT);
 
-    if (create_memento) {
-      __ AssertUndefinedOrAllocationSite(ebx);
-      __ push(ebx);
-    }
-
     // Preserve the incoming parameters on the stack.
+    __ AssertUndefinedOrAllocationSite(ebx);
+    __ push(ebx);
     __ SmiTag(eax);
     __ push(eax);
     __ push(edi);
@@ -254,7 +251,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ mov(Operand(esi, AllocationMemento::kMapOffset),
                factory->allocation_memento_map());
         // Get the cell or undefined.
-        __ mov(edx, Operand(esp, kPointerSize*2));
+        __ mov(edx, Operand(esp, 3 * kPointerSize));
+        __ AssertUndefinedOrAllocationSite(edx);
         __ mov(Operand(esi, AllocationMemento::kAllocationSiteOffset),
                edx);
       } else {
@@ -422,12 +420,13 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
   //  -- edx: original constructor
   // -----------------------------------
 
-  // TODO(dslomov): support pretenuring
-  CHECK(!FLAG_pretenuring_call_new);
-
   {
     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
 
+    // Preserve allocation site.
+    __ AssertUndefinedOrAllocationSite(ebx);
+    __ push(ebx);
+
     // Preserve actual arguments count.
     __ SmiTag(eax);
     __ push(eax);
index cddb5d1..d037be2 100644 (file)
@@ -337,14 +337,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
   {
     FrameScope scope(masm, StackFrame::CONSTRUCT);
 
-    if (create_memento) {
-      __ AssertUndefinedOrAllocationSite(a2, t0);
-      __ push(a2);
-    }
-
     // Preserve the incoming parameters on the stack.
+    __ AssertUndefinedOrAllocationSite(a2, t0);
     __ SmiTag(a0);
-    __ Push(a0, a1, a3);
+    __ Push(a2, a0, a1, a3);
 
     // Try to allocate the object without transitioning into C code. If any of
     // the preconditions is not met, the code bails out to the runtime call.
@@ -476,7 +472,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ sw(t7, MemOperand(t5));
         __ Addu(t5, t5, kPointerSize);
         // Load the AllocationSite.
-        __ lw(t7, MemOperand(sp, 2 * kPointerSize));
+        __ lw(t7, MemOperand(sp, 3 * kPointerSize));
+        __ AssertUndefinedOrAllocationSite(a2, t0);
         DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
         __ sw(t7, MemOperand(t5));
         __ Addu(t5, t5, kPointerSize);
@@ -659,12 +656,12 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
   //  -- sp[...]: constructor arguments
   // -----------------------------------
 
-  // TODO(dslomov): support pretenuring
-  CHECK(!FLAG_pretenuring_call_new);
-
   {
     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
 
+    __ AssertUndefinedOrAllocationSite(a2, t0);
+    __ push(a2);
+
     __ mov(t0, a0);
     __ SmiTag(t0);
     __ push(t0);  // Smi-tagged arguments count.
index 31f9e97..af2475f 100644 (file)
@@ -336,14 +336,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
   {
     FrameScope scope(masm, StackFrame::CONSTRUCT);
 
-    if (create_memento) {
-      __ AssertUndefinedOrAllocationSite(a2, t0);
-      __ push(a2);
-    }
-
     // Preserve the incoming parameters on the stack.
+    __ AssertUndefinedOrAllocationSite(a2, t0);
     __ SmiTag(a0);
-    __ Push(a0, a1, a3);
+    __ Push(a2, a0, a1, a3);
 
     // Try to allocate the object without transitioning into C code. If any of
     // the preconditions is not met, the code bails out to the runtime call.
@@ -476,7 +472,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ sd(t3, MemOperand(t1));
         __ Daddu(t1, t1, kPointerSize);
         // Load the AllocationSite.
-        __ ld(t3, MemOperand(sp, 2 * kPointerSize));
+        __ ld(t3, MemOperand(sp, 3 * kPointerSize));
+        __ AssertUndefinedOrAllocationSite(t3, a0);
         DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
         __ sd(t3, MemOperand(t1));
         __ Daddu(t1, t1, kPointerSize);
@@ -658,12 +655,12 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
   //  -- sp[...]: constructor arguments
   // -----------------------------------
 
-  // TODO(dslomov): support pretenuring
-  CHECK(!FLAG_pretenuring_call_new);
-
   {
     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
 
+    __ AssertUndefinedOrAllocationSite(a2, t0);
+    __ push(a2);
+
     __ mov(a4, a0);
     __ SmiTag(a4);
     __ push(a4);  // Smi-tagged arguments count.
index 7873aa2..695bd29 100644 (file)
@@ -116,12 +116,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
   {
     FrameScope scope(masm, StackFrame::CONSTRUCT);
 
-    if (create_memento) {
-      __ AssertUndefinedOrAllocationSite(rbx);
-      __ Push(rbx);
-    }
-
     // Preserve the incoming parameters on the stack.
+    __ AssertUndefinedOrAllocationSite(rbx);
+    __ Push(rbx);
     __ Integer32ToSmi(rax, rax);
     __ Push(rax);
     __ Push(rdi);
@@ -254,7 +251,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ Move(Operand(rsi, AllocationMemento::kMapOffset),
                 factory->allocation_memento_map());
         // Get the cell or undefined.
-        __ movp(rdx, Operand(rsp, kPointerSize*2));
+        __ movp(rdx, Operand(rsp, 3 * kPointerSize));
+        __ AssertUndefinedOrAllocationSite(rdx);
         __ movp(Operand(rsi, AllocationMemento::kAllocationSiteOffset), rdx);
       } else {
         __ InitializeFieldsWithFiller(rcx, rdi, rdx);
@@ -420,12 +418,14 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
   //  -- rbx: allocation site or undefined
   //  -- rdx: original constructor
   // -----------------------------------
-  // TODO(dslomov): support pretenuring
-  CHECK(!FLAG_pretenuring_call_new);
 
   {
     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
 
+    // Preserve allocation site.
+    __ AssertUndefinedOrAllocationSite(rbx);
+    __ Push(rbx);
+
     // Store a smi-tagged arguments count on the stack.
     __ Integer32ToSmi(rax, rax);
     __ Push(rax);
index 9aa1e6d..a976663 100644 (file)
@@ -101,6 +101,7 @@ TEST(PretenuringCallNew) {
   CcTest::InitializeVM();
   if (!i::FLAG_allocation_site_pretenuring) return;
   if (!i::FLAG_pretenuring_call_new) return;
+  if (i::FLAG_always_opt) return;
 
   v8::HandleScope scope(CcTest::isolate());
   Isolate* isolate = CcTest::i_isolate();