diff options
Diffstat (limited to 'deps/v8/src/mips64/builtins-mips64.cc')
-rw-r--r-- | deps/v8/src/mips64/builtins-mips64.cc | 154 |
1 files changed, 132 insertions, 22 deletions
diff --git a/deps/v8/src/mips64/builtins-mips64.cc b/deps/v8/src/mips64/builtins-mips64.cc index c95ff30785..89fda10b05 100644 --- a/deps/v8/src/mips64/builtins-mips64.cc +++ b/deps/v8/src/mips64/builtins-mips64.cc @@ -137,6 +137,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { // Run the native code for the Array function called as a normal function. // Tail call a stub. + __ mov(a3, a1); __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); ArrayConstructorStub stub(masm->isolate()); __ TailCallStub(&stub); @@ -314,6 +315,36 @@ void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) { } +static void Generate_Runtime_NewObject(MacroAssembler* masm, + bool create_memento, + Register original_constructor, + Label* count_incremented, + Label* allocated) { + if (create_memento) { + // Get the cell or allocation site. + __ ld(a2, MemOperand(sp, 2 * kPointerSize)); + __ push(a2); + } + + __ push(a1); // argument for Runtime_NewObject + __ push(original_constructor); // original constructor + if (create_memento) { + __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); + } else { + __ CallRuntime(Runtime::kNewObject, 2); + } + __ mov(t0, v0); + + // Runtime_NewObjectWithAllocationSite increments allocation count. + // Skip the increment. + if (create_memento) { + __ jmp(count_incremented); + } else { + __ jmp(allocated); + } +} + + static void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, bool create_memento) { @@ -321,6 +352,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // -- a0 : number of arguments // -- a1 : constructor function // -- a2 : allocation site or undefined + // -- a3 : original constructor // -- ra : return address // -- sp[...]: constructor arguments // ----------------------------------- @@ -342,7 +374,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, FrameScope scope(masm, StackFrame::CONSTRUCT); if (create_memento) { - __ AssertUndefinedOrAllocationSite(a2, a3); + __ AssertUndefinedOrAllocationSite(a2, t0); __ push(a2); } @@ -351,7 +383,14 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, __ dsll32(a0, a0, 0); __ MultiPushReversed(a0.bit() | a1.bit()); - Label rt_call, allocated; + Label rt_call, allocated, normal_new, count_incremented; + __ Branch(&normal_new, eq, a1, Operand(a3)); + + // Original constructor and function are different. + Generate_Runtime_NewObject(masm, create_memento, a3, &count_incremented, + &allocated); + __ bind(&normal_new); + // 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. if (FLAG_inline_new) { @@ -597,27 +636,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // Allocate the new receiver object using the runtime call. // a1: constructor function __ bind(&rt_call); - if (create_memento) { - // Get the cell or allocation site. - __ ld(a2, MemOperand(sp, 2 * kPointerSize)); - __ push(a2); - } + Generate_Runtime_NewObject(masm, create_memento, a1, &count_incremented, + &allocated); - __ push(a1); // Argument for Runtime_NewObject. - if (create_memento) { - __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2); - } else { - __ CallRuntime(Runtime::kNewObject, 1); - } - __ mov(t0, v0); - - // If we ended up using the runtime, and we want a memento, then the - // runtime call made it for us, and we shouldn't do create count - // increment. - Label count_incremented; - if (create_memento) { - __ jmp(&count_incremented); - } // Receiver for constructor call allocated. // t0: JSObject @@ -747,6 +768,95 @@ void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { } +void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { + // ----------- S t a t e ------------- + // -- a0 : number of arguments + // -- a1 : constructor function + // -- a2 : allocation site or undefined + // -- a3 : original constructor + // -- ra : return address + // -- sp[...]: constructor arguments + // ----------------------------------- + + // TODO(dslomov): support pretenuring + CHECK(!FLAG_pretenuring_call_new); + + { + FrameScope frame_scope(masm, StackFrame::CONSTRUCT); + + __ mov(a4, a0); + __ SmiTag(a4); + __ push(a4); // Smi-tagged arguments count. + + // Push new.target. + __ push(a3); + + // receiver is the hole. + __ LoadRoot(at, Heap::kTheHoleValueRootIndex); + __ push(at); + + // Set up pointer to last argument. + __ Daddu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); + + // Copy arguments and receiver to the expression stack. + // a0: number of arguments + // a1: constructor function + // a2: address of last argument (caller sp) + // a4: number of arguments (smi-tagged) + // sp[0]: receiver + // sp[1]: new.target + // sp[2]: number of arguments (smi-tagged) + Label loop, entry; + __ SmiUntag(a4); + __ jmp(&entry); + __ bind(&loop); + __ dsll(at, a4, kPointerSizeLog2); + __ Daddu(at, a2, Operand(at)); + __ ld(at, MemOperand(at)); + __ push(at); + __ bind(&entry); + __ Daddu(a4, a4, Operand(-1)); + __ Branch(&loop, ge, a4, Operand(zero_reg)); + + __ Daddu(a0, a0, Operand(1)); + + // Handle step in. + Label skip_step_in; + ExternalReference debug_step_in_fp = + ExternalReference::debug_step_in_fp_address(masm->isolate()); + __ li(a2, Operand(debug_step_in_fp)); + __ ld(a2, MemOperand(a2)); + __ Branch(&skip_step_in, eq, a2, Operand(zero_reg)); + + __ Push(a0, a1, a1); + __ CallRuntime(Runtime::kHandleStepInForDerivedConstructors, 1); + __ Pop(a0, a1); + + __ bind(&skip_step_in); + + + // Call the function. + // a0: number of arguments + // a1: constructor function + ParameterCount actual(a0); + __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); + + // Restore context from the frame. + // v0: result + // sp[0]: number of arguments (smi-tagged) + __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + __ ld(a1, MemOperand(sp, 0)); + + // Leave construct frame. + } + + __ SmiScale(at, a1, kPointerSizeLog2); + __ Daddu(sp, sp, Operand(at)); + __ Daddu(sp, sp, Operand(kPointerSize)); + __ Jump(ra); +} + + static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, bool is_construct) { // Called from JSEntryStub::GenerateBody |