diff options
author | Michaël Zasso <targos@protonmail.com> | 2021-02-24 14:47:06 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2021-02-25 00:14:47 +0100 |
commit | c5ff019a4e93891106859cb272ded1197a92c7e5 (patch) | |
tree | caf6b7e50b0ceac09878ac4402d9f725b8685dd7 /deps/v8/src/builtins/mips64 | |
parent | 67dc2bf2084b125dec43689874d237d125562cdf (diff) | |
download | node-new-c5ff019a4e93891106859cb272ded1197a92c7e5.tar.gz |
deps: update V8 to 8.9.255.19
PR-URL: https://github.com/nodejs/node/pull/37330
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'deps/v8/src/builtins/mips64')
-rw-r--r-- | deps/v8/src/builtins/mips64/builtins-mips64.cc | 342 |
1 files changed, 195 insertions, 147 deletions
diff --git a/deps/v8/src/builtins/mips64/builtins-mips64.cc b/deps/v8/src/builtins/mips64/builtins-mips64.cc index 1027ec35e5..4c42a2aa0a 100644 --- a/deps/v8/src/builtins/mips64/builtins-mips64.cc +++ b/deps/v8/src/builtins/mips64/builtins-mips64.cc @@ -129,169 +129,167 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { // ----------------------------------- // Enter a construct frame. - { - FrameScope scope(masm, StackFrame::CONSTRUCT); - Label post_instantiation_deopt_entry, not_create_implicit_receiver; - - // Preserve the incoming parameters on the stack. - __ SmiTag(a0); - __ Push(cp, a0, a1); - __ PushRoot(RootIndex::kUndefinedValue); - __ Push(a3); - - // ----------- S t a t e ------------- - // -- sp[0*kPointerSize]: new target - // -- sp[1*kPointerSize]: padding - // -- a1 and sp[2*kPointerSize]: constructor function - // -- sp[3*kPointerSize]: number of arguments (tagged) - // -- sp[4*kPointerSize]: context - // ----------------------------------- - - __ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); - __ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kFlagsOffset)); - __ DecodeField<SharedFunctionInfo::FunctionKindBits>(t2); - __ JumpIfIsInRange(t2, kDefaultDerivedConstructor, kDerivedConstructor, - ¬_create_implicit_receiver); - - // If not derived class constructor: Allocate the new receiver object. - __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1, - t2, t3); - __ Call(BUILTIN_CODE(masm->isolate(), FastNewObject), - RelocInfo::CODE_TARGET); - __ Branch(&post_instantiation_deopt_entry); - - // Else: use TheHoleValue as receiver for constructor call - __ bind(¬_create_implicit_receiver); - __ LoadRoot(v0, RootIndex::kTheHoleValue); + FrameScope scope(masm, StackFrame::MANUAL); + Label post_instantiation_deopt_entry, not_create_implicit_receiver; + __ EnterFrame(StackFrame::CONSTRUCT); - // ----------- S t a t e ------------- - // -- v0: receiver - // -- Slot 4 / sp[0*kPointerSize]: new target - // -- Slot 3 / sp[1*kPointerSize]: padding - // -- Slot 2 / sp[2*kPointerSize]: constructor function - // -- Slot 1 / sp[3*kPointerSize]: number of arguments (tagged) - // -- Slot 0 / sp[4*kPointerSize]: context - // ----------------------------------- - // Deoptimizer enters here. - masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset( - masm->pc_offset()); - __ bind(&post_instantiation_deopt_entry); + // Preserve the incoming parameters on the stack. + __ SmiTag(a0); + __ Push(cp, a0, a1); + __ PushRoot(RootIndex::kUndefinedValue); + __ Push(a3); - // Restore new target. - __ Pop(a3); + // ----------- S t a t e ------------- + // -- sp[0*kPointerSize]: new target + // -- sp[1*kPointerSize]: padding + // -- a1 and sp[2*kPointerSize]: constructor function + // -- sp[3*kPointerSize]: number of arguments (tagged) + // -- sp[4*kPointerSize]: context + // ----------------------------------- - // Push the allocated receiver to the stack. - __ Push(v0); + __ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); + __ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kFlagsOffset)); + __ DecodeField<SharedFunctionInfo::FunctionKindBits>(t2); + __ JumpIfIsInRange(t2, kDefaultDerivedConstructor, kDerivedConstructor, + ¬_create_implicit_receiver); - // We need two copies because we may have to return the original one - // and the calling conventions dictate that the called function pops the - // receiver. The second copy is pushed after the arguments, we saved in a6 - // since v0 will store the return value of callRuntime. - __ mov(a6, v0); + // If not derived class constructor: Allocate the new receiver object. + __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1, + t2, t3); + __ Call(BUILTIN_CODE(masm->isolate(), FastNewObject), + RelocInfo::CODE_TARGET); + __ Branch(&post_instantiation_deopt_entry); - // Set up pointer to last argument. - __ Daddu(t2, fp, Operand(StandardFrameConstants::kCallerSPOffset + - kSystemPointerSize)); + // Else: use TheHoleValue as receiver for constructor call + __ bind(¬_create_implicit_receiver); + __ LoadRoot(v0, RootIndex::kTheHoleValue); - // ----------- S t a t e ------------- - // -- r3: new target - // -- sp[0*kPointerSize]: implicit receiver - // -- sp[1*kPointerSize]: implicit receiver - // -- sp[2*kPointerSize]: padding - // -- sp[3*kPointerSize]: constructor function - // -- sp[4*kPointerSize]: number of arguments (tagged) - // -- sp[5*kPointerSize]: context - // ----------------------------------- + // ----------- S t a t e ------------- + // -- v0: receiver + // -- Slot 4 / sp[0*kPointerSize]: new target + // -- Slot 3 / sp[1*kPointerSize]: padding + // -- Slot 2 / sp[2*kPointerSize]: constructor function + // -- Slot 1 / sp[3*kPointerSize]: number of arguments (tagged) + // -- Slot 0 / sp[4*kPointerSize]: context + // ----------------------------------- + // Deoptimizer enters here. + masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset( + masm->pc_offset()); + __ bind(&post_instantiation_deopt_entry); - // Restore constructor function and argument count. - __ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset)); - __ Ld(a0, MemOperand(fp, ConstructFrameConstants::kLengthOffset)); - __ SmiUntag(a0); + // Restore new target. + __ Pop(a3); - Label enough_stack_space, stack_overflow; - __ StackOverflowCheck(a0, t0, t1, &stack_overflow); - __ Branch(&enough_stack_space); + // Push the allocated receiver to the stack. + __ Push(v0); - __ bind(&stack_overflow); - // Restore the context from the frame. - __ Ld(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); - __ CallRuntime(Runtime::kThrowStackOverflow); - // Unreachable code. - __ break_(0xCC); + // We need two copies because we may have to return the original one + // and the calling conventions dictate that the called function pops the + // receiver. The second copy is pushed after the arguments, we saved in a6 + // since v0 will store the return value of callRuntime. + __ mov(a6, v0); - __ bind(&enough_stack_space); + // Set up pointer to last argument. + __ Daddu(t2, fp, Operand(StandardFrameConstants::kCallerSPOffset + + kSystemPointerSize)); - // TODO(victorgomes): When the arguments adaptor is completely removed, we - // should get the formal parameter count and copy the arguments in its - // correct position (including any undefined), instead of delaying this to - // InvokeFunction. + // ----------- S t a t e ------------- + // -- r3: new target + // -- sp[0*kPointerSize]: implicit receiver + // -- sp[1*kPointerSize]: implicit receiver + // -- sp[2*kPointerSize]: padding + // -- sp[3*kPointerSize]: constructor function + // -- sp[4*kPointerSize]: number of arguments (tagged) + // -- sp[5*kPointerSize]: context + // ----------------------------------- - // Copy arguments and receiver to the expression stack. - __ PushArray(t2, a0, t0, t1); - // We need two copies because we may have to return the original one - // and the calling conventions dictate that the called function pops the - // receiver. The second copy is pushed after the arguments, - __ Push(a6); + // Restore constructor function and argument count. + __ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset)); + __ Ld(a0, MemOperand(fp, ConstructFrameConstants::kLengthOffset)); + __ SmiUntag(a0); - // Call the function. - __ InvokeFunctionWithNewTarget(a1, a3, a0, CALL_FUNCTION); + Label stack_overflow; + __ StackOverflowCheck(a0, t0, t1, &stack_overflow); - // ----------- S t a t e ------------- - // -- v0: constructor result - // -- sp[0*kPointerSize]: implicit receiver - // -- sp[1*kPointerSize]: padding - // -- sp[2*kPointerSize]: constructor function - // -- sp[3*kPointerSize]: number of arguments - // -- sp[4*kPointerSize]: context - // ----------------------------------- + // TODO(victorgomes): When the arguments adaptor is completely removed, we + // should get the formal parameter count and copy the arguments in its + // correct position (including any undefined), instead of delaying this to + // InvokeFunction. - // Store offset of return address for deoptimizer. - masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset( - masm->pc_offset()); + // Copy arguments and receiver to the expression stack. + __ PushArray(t2, a0, t0, t1); + // We need two copies because we may have to return the original one + // and the calling conventions dictate that the called function pops the + // receiver. The second copy is pushed after the arguments, + __ Push(a6); - // Restore the context from the frame. - __ Ld(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); + // Call the function. + __ InvokeFunctionWithNewTarget(a1, a3, a0, CALL_FUNCTION); - // If the result is an object (in the ECMA sense), we should get rid - // of the receiver and use the result; see ECMA-262 section 13.2.2-7 - // on page 74. - Label use_receiver, do_throw, leave_frame; + // ----------- S t a t e ------------- + // -- v0: constructor result + // -- sp[0*kPointerSize]: implicit receiver + // -- sp[1*kPointerSize]: padding + // -- sp[2*kPointerSize]: constructor function + // -- sp[3*kPointerSize]: number of arguments + // -- sp[4*kPointerSize]: context + // ----------------------------------- - // If the result is undefined, we jump out to using the implicit receiver. - __ JumpIfRoot(v0, RootIndex::kUndefinedValue, &use_receiver); + // Store offset of return address for deoptimizer. + masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset( + masm->pc_offset()); - // Otherwise we do a smi check and fall through to check if the return value - // is a valid receiver. + // If the result is an object (in the ECMA sense), we should get rid + // of the receiver and use the result; see ECMA-262 section 13.2.2-7 + // on page 74. + Label use_receiver, do_throw, leave_and_return, check_receiver; - // If the result is a smi, it is *not* an object in the ECMA sense. - __ JumpIfSmi(v0, &use_receiver); + // If the result is undefined, we jump out to using the implicit receiver. + __ JumpIfNotRoot(v0, RootIndex::kUndefinedValue, &check_receiver); - // If the type of the result (stored in its map) is less than - // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense. - __ GetObjectType(v0, t2, t2); - STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); - __ Branch(&leave_frame, greater_equal, t2, Operand(FIRST_JS_RECEIVER_TYPE)); - __ Branch(&use_receiver); + // Otherwise we do a smi check and fall through to check if the return value + // is a valid receiver. - __ bind(&do_throw); - __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject); + // Throw away the result of the constructor invocation and use the + // on-stack receiver as the result. + __ bind(&use_receiver); + __ Ld(v0, MemOperand(sp, 0 * kPointerSize)); + __ JumpIfRoot(v0, RootIndex::kTheHoleValue, &do_throw); - // Throw away the result of the constructor invocation and use the - // on-stack receiver as the result. - __ bind(&use_receiver); - __ Ld(v0, MemOperand(sp, 0 * kPointerSize)); - __ JumpIfRoot(v0, RootIndex::kTheHoleValue, &do_throw); + __ bind(&leave_and_return); + // Restore smi-tagged arguments count from the frame. + __ Ld(a1, MemOperand(fp, ConstructFrameConstants::kLengthOffset)); + // Leave construct frame. + __ LeaveFrame(StackFrame::CONSTRUCT); - __ bind(&leave_frame); - // Restore smi-tagged arguments count from the frame. - __ Ld(a1, MemOperand(fp, ConstructFrameConstants::kLengthOffset)); - // Leave construct frame. - } // Remove caller arguments from the stack and return. __ SmiScale(a4, a1, kPointerSizeLog2); __ Daddu(sp, sp, a4); __ Daddu(sp, sp, kPointerSize); __ Ret(); + + __ bind(&check_receiver); + __ JumpIfSmi(v0, &use_receiver); + + // If the type of the result (stored in its map) is less than + // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense. + __ GetObjectType(v0, t2, t2); + STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); + __ Branch(&leave_and_return, greater_equal, t2, + Operand(FIRST_JS_RECEIVER_TYPE)); + __ Branch(&use_receiver); + + __ bind(&do_throw); + // Restore the context from the frame. + __ Ld(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); + __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject); + __ break_(0xCC); + + __ bind(&stack_overflow); + // Restore the context from the frame. + __ Ld(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); + __ CallRuntime(Runtime::kThrowStackOverflow); + __ break_(0xCC); } void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { @@ -1079,11 +1077,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // If ok, push undefined as the initial value for all register file entries. Label loop_header; Label loop_check; - __ LoadRoot(a5, RootIndex::kUndefinedValue); + __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); __ Branch(&loop_check); __ bind(&loop_header); // TODO(rmcilroy): Consider doing more than one push per loop iteration. - __ push(a5); + __ push(kInterpreterAccumulatorRegister); // Continue loop if not done. __ bind(&loop_check); __ Dsubu(a4, a4, Operand(kPointerSize)); @@ -1109,8 +1107,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Branch(&stack_check_interrupt, lo, sp, Operand(a5)); __ bind(&after_stack_check_interrupt); - // Load accumulator as undefined. - __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); + // The accumulator is already loaded with undefined. // Load the dispatch table into a register and dispatch to the bytecode // handler at the current bytecode offset. @@ -2734,23 +2731,18 @@ void Builtins::Generate_DoubleToI(MacroAssembler* masm) { // Load double input. __ Ldc1(double_scratch, MemOperand(sp, kArgumentOffset)); - // Clear cumulative exception flags and save the FCSR. - __ cfc1(scratch2, FCSR); - __ ctc1(zero_reg, FCSR); - // Try a conversion to a signed integer. __ Trunc_w_d(double_scratch, double_scratch); // Move the converted value into the result register. __ mfc1(scratch3, double_scratch); - // Retrieve and restore the FCSR. + // Retrieve the FCSR. __ cfc1(scratch, FCSR); - __ ctc1(scratch2, FCSR); // Check for overflow and NaNs. - __ And( - scratch, scratch, - kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | kFCSRInvalidOpFlagMask); + __ And(scratch, scratch, + kFCSROverflowCauseMask | kFCSRUnderflowCauseMask | + kFCSRInvalidOpCauseMask); // If we had no exceptions then set result_reg and we are done. Label error; __ Branch(&error, ne, scratch, Operand(zero_reg)); @@ -3412,6 +3404,62 @@ void Builtins::Generate_DeoptimizationEntry_Lazy(MacroAssembler* masm) { Generate_DeoptimizationEntry(masm, DeoptimizeKind::kLazy); } +void Builtins::Generate_DynamicCheckMapsTrampoline(MacroAssembler* masm) { + FrameScope scope(masm, StackFrame::MANUAL); + __ EnterFrame(StackFrame::INTERNAL); + + // Only save the registers that the DynamicCheckMaps builtin can clobber. + DynamicCheckMapsDescriptor descriptor; + RegList registers = descriptor.allocatable_registers(); + // FLAG_debug_code is enabled CSA checks will call C function and so we need + // to save all CallerSaved registers too. + if (FLAG_debug_code) registers |= kJSCallerSaved; + __ SaveRegisters(registers); + + // Load the immediate arguments from the deopt exit to pass to the builtin. + Register slot_arg = + descriptor.GetRegisterParameter(DynamicCheckMapsDescriptor::kSlot); + Register handler_arg = + descriptor.GetRegisterParameter(DynamicCheckMapsDescriptor::kHandler); + __ Ld(handler_arg, MemOperand(fp, CommonFrameConstants::kCallerPCOffset)); + __ Uld(slot_arg, MemOperand(handler_arg, + Deoptimizer::kEagerWithResumeImmedArgs1PcOffset)); + __ Uld( + handler_arg, + MemOperand(handler_arg, Deoptimizer::kEagerWithResumeImmedArgs2PcOffset)); + __ Call(BUILTIN_CODE(masm->isolate(), DynamicCheckMaps), + RelocInfo::CODE_TARGET); + + Label deopt, bailout; + __ Branch(&deopt, ne, v0, + Operand(static_cast<int>(DynamicCheckMapsStatus::kSuccess))); + + __ RestoreRegisters(registers); + __ LeaveFrame(StackFrame::INTERNAL); + __ Ret(); + + __ bind(&deopt); + __ Branch(&bailout, eq, v0, + Operand(static_cast<int>(DynamicCheckMapsStatus::kBailout))); + + if (FLAG_debug_code) { + __ Assert(eq, AbortReason::kUnexpectedDynamicCheckMapsStatus, v0, + Operand(static_cast<int>(DynamicCheckMapsStatus::kDeopt))); + } + __ RestoreRegisters(registers); + __ LeaveFrame(StackFrame::INTERNAL); + Handle<Code> deopt_eager = masm->isolate()->builtins()->builtin_handle( + Deoptimizer::GetDeoptimizationEntry(DeoptimizeKind::kEager)); + __ Jump(deopt_eager, RelocInfo::CODE_TARGET); + + __ bind(&bailout); + __ RestoreRegisters(registers); + __ LeaveFrame(StackFrame::INTERNAL); + Handle<Code> deopt_bailout = masm->isolate()->builtins()->builtin_handle( + Deoptimizer::GetDeoptimizationEntry(DeoptimizeKind::kBailout)); + __ Jump(deopt_bailout, RelocInfo::CODE_TARGET); +} + #undef __ } // namespace internal |