summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/mips64
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2021-02-24 14:47:06 +0100
committerMichaël Zasso <targos@protonmail.com>2021-02-25 00:14:47 +0100
commitc5ff019a4e93891106859cb272ded1197a92c7e5 (patch)
treecaf6b7e50b0ceac09878ac4402d9f725b8685dd7 /deps/v8/src/builtins/mips64
parent67dc2bf2084b125dec43689874d237d125562cdf (diff)
downloadnode-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.cc342
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,
- &not_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(&not_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,
+ &not_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(&not_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