diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc index 3f0177457a..5dfdd2adee 100644 --- a/src/arm/builtins-arm.cc +++ b/src/arm/builtins-arm.cc @@ -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. diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc index 43420564b0..536cda1368 100644 --- a/src/arm64/builtins-arm64.cc +++ b/src/arm64/builtins-arm64.cc @@ -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); diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index c6e6baa942..587fc0946a 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -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(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(Smi::FromInt(height - 1)); diff --git a/src/frames.cc b/src/frames.cc index 5dea8484c9..66bcf3d448 100644 --- a/src/frames.cc +++ b/src/frames.cc @@ -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); } diff --git a/src/frames.h b/src/frames.h index 0d2a2e3aa8..9eee5a136e 100644 --- a/src/frames.h +++ b/src/frames.h @@ -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; }; diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc index 3a85089d47..bd8c5fbb0b 100644 --- a/src/ia32/builtins-ia32.cc +++ b/src/ia32/builtins-ia32.cc @@ -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); diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc index cddb5d1266..d037be2635 100644 --- a/src/mips/builtins-mips.cc +++ b/src/mips/builtins-mips.cc @@ -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. diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc index 31f9e979dd..af2475f41b 100644 --- a/src/mips64/builtins-mips64.cc +++ b/src/mips64/builtins-mips64.cc @@ -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. diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc index 7873aa2a3d..695bd299f7 100644 --- a/src/x64/builtins-x64.cc +++ b/src/x64/builtins-x64.cc @@ -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); diff --git a/test/cctest/test-mementos.cc b/test/cctest/test-mementos.cc index 9aa1e6d30e..a97666384b 100644 --- a/test/cctest/test-mementos.cc +++ b/test/cctest/test-mementos.cc @@ -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();