[cleanup] Remove arguments adaptor code
Removes: - v8_disable_arguments_adaptor GN flag - ArgumentsAdaptorTrampoline - ArgumentsAdaptorFrame class Change-Id: I382ebe6c25c3c172bee5df3e86e762fca10fa392 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2622911 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/master@{#72133}
This commit is contained in:
parent
7d167bde93
commit
574ac5d626
10
BUILD.gn
10
BUILD.gn
@ -115,13 +115,6 @@ declare_args() {
|
||||
v8_enable_pointer_compression = ""
|
||||
v8_enable_31bit_smis_on_64bit_arch = false
|
||||
|
||||
# Disable arguments adaptor frame (sets -dV8_NO_ARGUMENTS_ADAPTOR).
|
||||
v8_disable_arguments_adaptor =
|
||||
v8_current_cpu == "x86" || v8_current_cpu == "x64" ||
|
||||
v8_current_cpu == "arm" || v8_current_cpu == "arm64" ||
|
||||
v8_current_cpu == "mipsel" || v8_current_cpu == "mips64el" ||
|
||||
v8_current_cpu == "ppc64" || v8_current_cpu == "s390x"
|
||||
|
||||
# Sets -dOBJECT_PRINT.
|
||||
v8_enable_object_print = ""
|
||||
|
||||
@ -545,9 +538,6 @@ config("v8_header_features") {
|
||||
if (v8_imminent_deprecation_warnings) {
|
||||
defines += [ "V8_IMMINENT_DEPRECATION_WARNINGS" ]
|
||||
}
|
||||
if (v8_disable_arguments_adaptor) {
|
||||
defines += [ "V8_NO_ARGUMENTS_ADAPTOR" ]
|
||||
}
|
||||
if (v8_use_perfetto) {
|
||||
defines += [ "V8_USE_PERFETTO" ]
|
||||
}
|
||||
|
@ -469,20 +469,9 @@ Handle<JSObject> GetFrameArguments(Isolate* isolate,
|
||||
return ArgumentsForInlinedFunction(frame, function_index);
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
const int length = frame->GetActualArgumentCount();
|
||||
#else
|
||||
// Find the frame that holds the actual arguments passed to the function.
|
||||
if (it->frame()->has_adapted_arguments()) {
|
||||
it->AdvanceOneFrame();
|
||||
DCHECK(it->frame()->is_arguments_adaptor());
|
||||
}
|
||||
frame = it->frame();
|
||||
const int length = frame->ComputeParametersCount();
|
||||
#endif
|
||||
|
||||
// Construct an arguments object mirror for the right frame and the underlying
|
||||
// function.
|
||||
const int length = frame->GetActualArgumentCount();
|
||||
Handle<JSFunction> function(frame->function(), isolate);
|
||||
Handle<JSObject> arguments =
|
||||
isolate->factory()->NewArgumentsObject(function, length);
|
||||
|
@ -800,7 +800,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ ldr(params_size,
|
||||
FieldMemOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ ldr(actual_params_size,
|
||||
@ -812,7 +811,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
// arguments.
|
||||
__ cmp(params_size, actual_params_size);
|
||||
__ mov(params_size, actual_params_size, LeaveCC, lt);
|
||||
#endif
|
||||
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ LeaveFrame(StackFrame::INTERPRETED);
|
||||
@ -1767,29 +1765,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ SmiTag(r0);
|
||||
__ mov(r4, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() |
|
||||
fp.bit() | lr.bit());
|
||||
__ Push(Smi::zero()); // Padding.
|
||||
__ add(fp, sp,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
|
||||
}
|
||||
|
||||
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : result being passed through
|
||||
// -----------------------------------
|
||||
// Get the number of arguments passed (as a smi), tear down the frame and
|
||||
// then tear down the parameters.
|
||||
__ ldr(r1, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
|
||||
__ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR);
|
||||
__ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
|
||||
__ add(sp, sp, Operand(kPointerSize)); // adjust for receiver
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
Handle<Code> code) {
|
||||
@ -1902,36 +1877,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ bind(&new_target_constructor);
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ mov(r4, fp);
|
||||
__ ldr(r5, MemOperand(fp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
Label arguments_adaptor, arguments_done;
|
||||
__ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ ldr(scratch,
|
||||
MemOperand(r4, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ cmp(scratch,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ b(eq, &arguments_adaptor);
|
||||
{
|
||||
__ ldr(r5, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ ldr(r5, FieldMemOperand(r5, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldrh(r5, FieldMemOperand(
|
||||
r5, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ mov(r4, fp);
|
||||
}
|
||||
__ b(&arguments_done);
|
||||
__ bind(&arguments_adaptor);
|
||||
{
|
||||
// Load the length from the ArgumentsAdaptorFrame.
|
||||
__ ldr(r5, MemOperand(r4, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(r5);
|
||||
}
|
||||
__ bind(&arguments_done);
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ sub(r5, r5, r2, SetCC);
|
||||
@ -2353,146 +2302,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : actual number of arguments
|
||||
// -- r1 : function (passed through to callee)
|
||||
// -- r2 : expected number of arguments
|
||||
// -- r3 : new target (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
Label dont_adapt_arguments, stack_overflow;
|
||||
__ cmp(r2, Operand(kDontAdaptArgumentsSentinel));
|
||||
__ b(eq, &dont_adapt_arguments);
|
||||
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kFlagsOffset));
|
||||
|
||||
// -------------------------------------------
|
||||
// Adapt arguments.
|
||||
// -------------------------------------------
|
||||
{
|
||||
Label under_application, over_application, invoke;
|
||||
__ cmp(r0, r2);
|
||||
__ b(lt, &under_application);
|
||||
|
||||
// Enough parameters: actual >= expected
|
||||
__ bind(&over_application);
|
||||
{
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(r2, r5, &stack_overflow);
|
||||
|
||||
// Calculate copy start address into r0 and copy end address into r4.
|
||||
// r0: actual number of arguments as a smi
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
__ add(r0, fp, Operand(r2, LSL, kSystemPointerSizeLog2));
|
||||
// adjust for return address and receiver
|
||||
__ add(r0, r0, Operand(2 * kSystemPointerSize));
|
||||
__ sub(r4, r0, Operand(r2, LSL, kSystemPointerSizeLog2));
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// r0: copy start address
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
// r4: copy end address
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ ldr(r5, MemOperand(r0, 0));
|
||||
__ push(r5);
|
||||
__ cmp(r0, r4); // Compare before moving to next argument.
|
||||
__ sub(r0, r0, Operand(kSystemPointerSize));
|
||||
__ b(ne, ©);
|
||||
|
||||
__ b(&invoke);
|
||||
}
|
||||
|
||||
// Too few parameters: Actual < expected
|
||||
__ bind(&under_application);
|
||||
{
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(r2, r5, &stack_overflow);
|
||||
|
||||
// Fill the remaining expected arguments with undefined.
|
||||
// r0: actual number of arguments as a smi
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
__ LoadRoot(r5, RootIndex::kUndefinedValue);
|
||||
__ sub(r6, r2, Operand::SmiUntag(r0));
|
||||
__ sub(r4, fp, Operand(r6, LSL, kPointerSizeLog2));
|
||||
// Adjust for frame.
|
||||
__ sub(r4, r4,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
|
||||
kPointerSize));
|
||||
|
||||
Label fill;
|
||||
__ bind(&fill);
|
||||
__ push(r5);
|
||||
__ cmp(sp, r4);
|
||||
__ b(ne, &fill);
|
||||
|
||||
// Calculate copy start address into r0 and copy end address is fp.
|
||||
// r0: actual number of arguments as a smi
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
__ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// r0: copy start address
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
|
||||
// Adjust load for return address and receiver.
|
||||
__ ldr(r5, MemOperand(r0, 2 * kPointerSize));
|
||||
__ push(r5);
|
||||
|
||||
__ cmp(r0, fp); // Compare before moving to next argument.
|
||||
__ sub(r0, r0, Operand(kPointerSize));
|
||||
__ b(ne, ©);
|
||||
}
|
||||
|
||||
// Call the entry point.
|
||||
__ bind(&invoke);
|
||||
__ mov(r0, r2);
|
||||
// r0 : expected number of arguments
|
||||
// r1 : function (passed through to callee)
|
||||
// r3 : new target (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == r2, "ABI mismatch");
|
||||
__ ldr(r2, FieldMemOperand(r1, JSFunction::kCodeOffset));
|
||||
__ CallCodeObject(r2);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(
|
||||
masm->pc_offset());
|
||||
|
||||
// Exit frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ Jump(lr);
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// Dont adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ bind(&dont_adapt_arguments);
|
||||
static_assert(kJavaScriptCallCodeStartRegister == r2, "ABI mismatch");
|
||||
__ ldr(r2, FieldMemOperand(r1, JSFunction::kCodeOffset));
|
||||
__ JumpCodeObject(r2);
|
||||
|
||||
__ bind(&stack_overflow);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ bkpt(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
|
||||
// The function index was put in a register by the jump table trampoline.
|
||||
// Convert to Smi for the runtime call.
|
||||
|
@ -950,7 +950,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ Ldr(params_size.W(),
|
||||
FieldMemOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ Ldr(actual_params_size,
|
||||
@ -965,7 +964,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ B(ge, &corrected_args_count);
|
||||
__ Mov(params_size, actual_params_size);
|
||||
__ Bind(&corrected_args_count);
|
||||
#endif
|
||||
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ LeaveFrame(StackFrame::INTERPRETED);
|
||||
@ -2074,30 +2072,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
|
||||
namespace {
|
||||
|
||||
void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ Push<TurboAssembler::kSignLR>(lr, fp);
|
||||
__ Mov(x11, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ Push(x11, x1); // x1: function
|
||||
__ SmiTag(x11, x0); // x0: number of arguments.
|
||||
__ Push(x11, padreg);
|
||||
__ Add(fp, sp, ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp);
|
||||
}
|
||||
|
||||
void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : result being passed through
|
||||
// -----------------------------------
|
||||
// Get the number of arguments passed (as a smi), tear down the frame and
|
||||
// then drop the parameters and the receiver.
|
||||
__ Ldr(x10, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ Mov(sp, fp);
|
||||
__ Pop<TurboAssembler::kAuthLR>(fp, lr);
|
||||
|
||||
// Drop actual parameters and receiver.
|
||||
__ SmiUntag(x10);
|
||||
__ DropArguments(x10, TurboAssembler::kCountExcludesReceiver);
|
||||
}
|
||||
|
||||
// Prepares the stack for copying the varargs. First we claim the necessary
|
||||
// slots, taking care of potential padding. Then we copy the existing arguments
|
||||
// one slot up or one slot down, as needed.
|
||||
@ -2249,45 +2223,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
|
||||
Register args_fp = x5;
|
||||
Register len = x6;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ Mov(args_fp, fp);
|
||||
__ Ldr(len, MemOperand(fp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
// args_fp will point to the frame that contains the actual arguments, which
|
||||
// will be the current frame unless we have an arguments adaptor frame, in
|
||||
// which case args_fp points to the arguments adaptor frame.
|
||||
{
|
||||
Label arguments_adaptor, arguments_done;
|
||||
Register scratch = x10;
|
||||
__ Ldr(args_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ Ldr(x4, MemOperand(args_fp,
|
||||
CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ CmpTagged(x4, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ B(eq, &arguments_adaptor);
|
||||
{
|
||||
__ Ldr(scratch, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ LoadTaggedPointerField(
|
||||
scratch,
|
||||
FieldMemOperand(scratch, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldrh(len,
|
||||
FieldMemOperand(scratch,
|
||||
SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ Mov(args_fp, fp);
|
||||
}
|
||||
__ B(&arguments_done);
|
||||
__ Bind(&arguments_adaptor);
|
||||
{
|
||||
// Just load the length from ArgumentsAdaptorFrame.
|
||||
__ SmiUntag(
|
||||
len,
|
||||
MemOperand(args_fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
}
|
||||
__ Bind(&arguments_done);
|
||||
}
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ Subs(len, len, start_index);
|
||||
@ -2735,188 +2674,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline");
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : actual number of arguments
|
||||
// -- x1 : function (passed through to callee)
|
||||
// -- x2 : expected number of arguments
|
||||
// -- x3 : new target (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
// The frame we are about to construct will look like:
|
||||
//
|
||||
// slot Adaptor frame
|
||||
// +-----------------+--------------------------------
|
||||
// -n-1 | receiver | ^
|
||||
// | (parameter 0) | |
|
||||
// |- - - - - - - - -| |
|
||||
// -n | | Caller
|
||||
// ... | ... | frame slots --> actual args
|
||||
// -2 | parameter n-1 | |
|
||||
// |- - - - - - - - -| |
|
||||
// -1 | parameter n | v
|
||||
// -----+-----------------+--------------------------------
|
||||
// 0 | return addr | ^
|
||||
// |- - - - - - - - -| |
|
||||
// 1 | saved frame ptr | <-- frame ptr |
|
||||
// |- - - - - - - - -| |
|
||||
// 2 |Frame Type Marker| |
|
||||
// |- - - - - - - - -| |
|
||||
// 3 | function | Callee
|
||||
// |- - - - - - - - -| frame slots
|
||||
// 4 | num of | |
|
||||
// | actual args | |
|
||||
// |- - - - - - - - -| |
|
||||
// 5 | padding | |
|
||||
// |-----------------+---- |
|
||||
// [6] | [padding] | ^ |
|
||||
// |- - - - - - - - -| | |
|
||||
// 6+pad | receiver | | |
|
||||
// | (parameter 0) | | |
|
||||
// |- - - - - - - - -| | |
|
||||
// 7+pad | parameter 1 | | |
|
||||
// |- - - - - - - - -| Frame slots ----> expected args
|
||||
// 8+pad | parameter 2 | | |
|
||||
// |- - - - - - - - -| | |
|
||||
// | | | |
|
||||
// ... | ... | | |
|
||||
// | parameter m | | |
|
||||
// |- - - - - - - - -| | |
|
||||
// | [undefined] | | |
|
||||
// |- - - - - - - - -| | |
|
||||
// | | | |
|
||||
// | ... | | |
|
||||
// | [undefined] | v <-- stack ptr v
|
||||
// -----+-----------------+---------------------------------
|
||||
//
|
||||
// There is an optional slot of padding above the receiver to ensure stack
|
||||
// alignment of the arguments.
|
||||
// If the number of expected arguments is larger than the number of actual
|
||||
// arguments, the remaining expected slots will be filled with undefined.
|
||||
// TODO(v8:10201) update comment once reversed arguments order sticks
|
||||
|
||||
Register argc_actual = x0; // Excluding the receiver.
|
||||
Register argc_expected = x2; // Excluding the receiver.
|
||||
Register function = x1;
|
||||
|
||||
Label create_adaptor_frame, dont_adapt_arguments, stack_overflow;
|
||||
|
||||
__ Cmp(argc_expected, kDontAdaptArgumentsSentinel);
|
||||
__ B(eq, &dont_adapt_arguments);
|
||||
|
||||
// -------------------------------------------
|
||||
// Create an arguments adaptor frame.
|
||||
// -------------------------------------------
|
||||
__ Bind(&create_adaptor_frame);
|
||||
{
|
||||
__ RecordComment("-- Adapt arguments --");
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
|
||||
Register copy_from = x10;
|
||||
Register copy_to = x12;
|
||||
Register copy_end = x11;
|
||||
Register argc_to_copy = x13;
|
||||
Register scratch1 = x15;
|
||||
|
||||
// We need slots for the expected arguments, with one extra slot for the
|
||||
// receiver.
|
||||
__ RecordComment("-- Stack check --");
|
||||
__ Add(scratch1, argc_expected, 1);
|
||||
__ StackOverflowCheck(scratch1, &stack_overflow);
|
||||
|
||||
// Round up number of slots to be even, to maintain stack alignment.
|
||||
__ RecordComment("-- Allocate callee frame slots --");
|
||||
__ Add(scratch1, scratch1, 1);
|
||||
__ Bic(scratch1, scratch1, 1);
|
||||
__ Claim(scratch1, kSystemPointerSize);
|
||||
|
||||
// If we don't have enough arguments, fill the remaining expected
|
||||
// arguments with undefined, otherwise skip this step.
|
||||
Label enough_arguments;
|
||||
__ Cmp(argc_actual, argc_expected);
|
||||
__ Csel(argc_to_copy, argc_expected, argc_actual, ge);
|
||||
__ Add(argc_to_copy, argc_to_copy, 1); // Include receiver.
|
||||
__ B(ge, &enough_arguments);
|
||||
|
||||
// Fill the remaining expected arguments with undefined.
|
||||
__ RecordComment("-- Fill slots with undefined --");
|
||||
Label fill;
|
||||
// scratch1 still contains the size of the claimed area,
|
||||
// which is RoundUp(argc_expected + 1, 2).
|
||||
__ SlotAddress(copy_to, scratch1);
|
||||
__ SlotAddress(copy_end, argc_to_copy);
|
||||
__ LoadRoot(scratch1, RootIndex::kUndefinedValue);
|
||||
// Now we can write pairs of undefineds, potentially overwriting one word
|
||||
// below copy_end, but that's ok because that slot is still within claimed
|
||||
// region. This loop will execute at least once because at this point we
|
||||
// know that there's at least one undefined to be pushed and
|
||||
// argc_to_copy >= 1.
|
||||
__ Bind(&fill);
|
||||
__ Stp(scratch1, scratch1,
|
||||
MemOperand(copy_to, -2 * kSystemPointerSize, PreIndex));
|
||||
__ Cmp(copy_to, copy_end);
|
||||
__ B(hi, &fill);
|
||||
|
||||
// Enough arguments.
|
||||
__ Bind(&enough_arguments);
|
||||
|
||||
// Store padding if needed, when expected arguments is even.
|
||||
__ RecordComment("-- Store padding --");
|
||||
Label skip_padding;
|
||||
__ Tbnz(argc_expected, 0, &skip_padding);
|
||||
__ SlotAddress(scratch1, argc_expected);
|
||||
__ Str(padreg, MemOperand(scratch1, kSystemPointerSize));
|
||||
__ bind(&skip_padding);
|
||||
|
||||
// Copy arguments.
|
||||
__ RecordComment("-- Copy actual arguments --");
|
||||
__ Mov(copy_to, sp);
|
||||
__ Add(copy_from, fp, 2 * kSystemPointerSize);
|
||||
__ CopyDoubleWords(copy_to, copy_from, argc_to_copy);
|
||||
|
||||
// Arguments have been adapted. Now call the entry point.
|
||||
__ RecordComment("-- Call entry point --");
|
||||
__ Mov(argc_actual, argc_expected);
|
||||
// x0 : expected number of arguments
|
||||
// x1 : function (passed through to callee)
|
||||
// x3 : new target (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(
|
||||
x2, FieldMemOperand(function, JSFunction::kCodeOffset));
|
||||
__ CallCodeObject(x2);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(
|
||||
masm->pc_offset());
|
||||
|
||||
// Exit frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// Dont adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ Bind(&dont_adapt_arguments);
|
||||
{
|
||||
// Call the entry point without adapting the arguments.
|
||||
__ RecordComment("-- Call without adapting args --");
|
||||
static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(
|
||||
x2, FieldMemOperand(function, JSFunction::kCodeOffset));
|
||||
__ JumpCodeObject(x2);
|
||||
}
|
||||
|
||||
__ Bind(&stack_overflow);
|
||||
__ RecordComment("-- Stack overflow --");
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ Unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
|
||||
// The function index was put in w8 by the jump table trampoline.
|
||||
// Sign extend and convert to Smi for the runtime call.
|
||||
@ -3818,12 +3575,10 @@ void Generate_DeoptimizationEntry(MacroAssembler* masm,
|
||||
__ Lsr(unwind_limit, unwind_limit, kSystemPointerSizeLog2);
|
||||
__ Mov(x5, unwind_limit);
|
||||
__ CopyDoubleWords(x3, x1, x5);
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Since {unwind_limit} is the frame size up to the parameter count, we might
|
||||
// end up with a unaligned stack pointer. This is later recovered when
|
||||
// setting the stack pointer to {caller_frame_top_offset}.
|
||||
__ Bic(unwind_limit, unwind_limit, 1);
|
||||
#endif
|
||||
__ Drop(unwind_limit);
|
||||
|
||||
// Compute the output frame in the deoptimizer.
|
||||
|
@ -40,7 +40,6 @@ namespace internal {
|
||||
TFC(AdaptorWithBuiltinExitFrame, CppBuiltinAdaptor) \
|
||||
\
|
||||
/* Calls */ \
|
||||
ASM(ArgumentsAdaptorTrampoline, ArgumentsAdaptor) \
|
||||
/* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \
|
||||
ASM(CallFunction_ReceiverIsNullOrUndefined, CallTrampoline) \
|
||||
ASM(CallFunction_ReceiverIsNotNullOrUndefined, CallTrampoline) \
|
||||
|
@ -750,7 +750,6 @@ TF_BUILTIN(AdaptorWithBuiltinExitFrame, CodeStubAssembler) {
|
||||
|
||||
TVARIABLE(Int32T, pushed_argc, actual_argc);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
TNode<SharedFunctionInfo> shared = LoadJSFunctionSharedFunctionInfo(target);
|
||||
|
||||
TNode<Int32T> formal_count =
|
||||
@ -770,7 +769,6 @@ TF_BUILTIN(AdaptorWithBuiltinExitFrame, CodeStubAssembler) {
|
||||
pushed_argc = formal_count;
|
||||
Goto(&done_argc);
|
||||
BIND(&done_argc);
|
||||
#endif
|
||||
|
||||
// Update arguments count for CEntry to contain the number of arguments
|
||||
// including the receiver and the extra arguments.
|
||||
@ -1089,7 +1087,6 @@ TF_BUILTIN(InstantiateAsmJs, CodeStubAssembler) {
|
||||
Runtime::kInstantiateAsmJs, context, function, stdlib, foreign, heap);
|
||||
GotoIf(TaggedIsSmi(maybe_result_or_smi_zero), &tailcall_to_function);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
TNode<SharedFunctionInfo> shared = LoadJSFunctionSharedFunctionInfo(function);
|
||||
TNode<Int32T> parameter_count =
|
||||
UncheckedCast<Int32T>(LoadSharedFunctionInfoFormalParameterCount(shared));
|
||||
@ -1103,7 +1100,6 @@ TF_BUILTIN(InstantiateAsmJs, CodeStubAssembler) {
|
||||
PopAndReturn(Int32Add(parameter_count, Int32Constant(1)),
|
||||
maybe_result_or_smi_zero);
|
||||
BIND(&argc_ge_param_count);
|
||||
#endif
|
||||
args.PopAndReturn(maybe_result_or_smi_zero);
|
||||
|
||||
BIND(&tailcall_to_function);
|
||||
|
@ -483,7 +483,6 @@ bool Builtins::CodeObjectIsExecutable(int builtin_index) {
|
||||
case Builtins::kCall_ReceiverIsNullOrUndefined:
|
||||
case Builtins::kCall_ReceiverIsNotNullOrUndefined:
|
||||
case Builtins::kCall_ReceiverIsAny:
|
||||
case Builtins::kArgumentsAdaptorTrampoline:
|
||||
case Builtins::kHandleApiCall:
|
||||
case Builtins::kInstantiateAsmJs:
|
||||
case Builtins::kGenericJSToWasmWrapper:
|
||||
|
@ -11,8 +11,6 @@ struct Arguments {
|
||||
|
||||
extern operator '[]' macro GetArgumentValue(Arguments, intptr): JSAny;
|
||||
extern macro GetFrameArguments(FrameWithArguments, intptr): Arguments;
|
||||
const kNoArgumentsAdaptor:
|
||||
constexpr bool generates 'kNoArgumentsAdaptor';
|
||||
|
||||
struct ArgumentsIterator {
|
||||
macro Next(): Object labels NoMore {
|
||||
@ -49,30 +47,13 @@ macro GetFrameWithArgumentsInfo(implicit context: Context)():
|
||||
const shared: SharedFunctionInfo = f.shared_function_info;
|
||||
const formalParameterCount: bint =
|
||||
Convert<bint>(Convert<int32>(shared.formal_parameter_count));
|
||||
if constexpr (kNoArgumentsAdaptor) {
|
||||
// TODO(victorgomes): When removing the v8_disable_arguments_adaptor flag,
|
||||
// FrameWithArgumentsInfo can be simplified, since the frame field already
|
||||
// contains the argument count.
|
||||
const argumentCount: bint = Convert<bint>(frame.argument_count);
|
||||
return FrameWithArgumentsInfo{
|
||||
frame,
|
||||
argument_count: argumentCount,
|
||||
formal_parameter_count: formalParameterCount
|
||||
};
|
||||
} else {
|
||||
const argumentCount: bint = formalParameterCount;
|
||||
|
||||
const adaptor = Cast<ArgumentsAdaptorFrame>(frame.caller)
|
||||
otherwise return FrameWithArgumentsInfo{
|
||||
frame,
|
||||
argument_count: argumentCount,
|
||||
formal_parameter_count: formalParameterCount
|
||||
};
|
||||
|
||||
return FrameWithArgumentsInfo{
|
||||
frame: adaptor,
|
||||
argument_count: Convert<bint>(adaptor.length),
|
||||
formal_parameter_count: formalParameterCount
|
||||
};
|
||||
}
|
||||
// TODO(victorgomes): When removing the v8_disable_arguments_adaptor flag,
|
||||
// FrameWithArgumentsInfo can be simplified, since the frame field already
|
||||
// contains the argument count.
|
||||
const argumentCount: bint = Convert<bint>(frame.argument_count);
|
||||
return FrameWithArgumentsInfo{
|
||||
frame,
|
||||
argument_count: argumentCount,
|
||||
formal_parameter_count: formalParameterCount
|
||||
};
|
||||
}
|
||||
|
@ -3,8 +3,6 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
type FrameType extends Smi constexpr 'StackFrame::Type';
|
||||
const ARGUMENTS_ADAPTOR_FRAME: constexpr FrameType
|
||||
generates 'StackFrame::ARGUMENTS_ADAPTOR';
|
||||
const STUB_FRAME: constexpr FrameType
|
||||
generates 'StackFrame::STUB';
|
||||
const kFrameTypeCount:
|
||||
@ -31,9 +29,8 @@ Cast<FrameType>(o: Object): FrameType
|
||||
|
||||
type FrameBase extends RawPtr constexpr 'void*';
|
||||
type StandardFrame extends FrameBase constexpr 'void*';
|
||||
type ArgumentsAdaptorFrame extends FrameBase constexpr 'void*';
|
||||
type StubFrame extends FrameBase constexpr 'void*';
|
||||
type FrameWithArguments = StandardFrame|ArgumentsAdaptorFrame;
|
||||
type FrameWithArguments = StandardFrame;
|
||||
type Frame = FrameWithArguments|StubFrame;
|
||||
|
||||
extern macro LoadFramePointer(): Frame;
|
||||
@ -46,9 +43,6 @@ macro LoadObjectFromFrame(f: Frame, o: constexpr int32): Object {
|
||||
macro LoadPointerFromFrame(f: Frame, o: constexpr int32): RawPtr {
|
||||
return LoadBufferPointer(f, o);
|
||||
}
|
||||
macro LoadSmiFromFrame(f: Frame, o: constexpr int32): Smi {
|
||||
return LoadBufferSmi(f, o);
|
||||
}
|
||||
macro LoadIntptrFromFrame(f: Frame, o: constexpr int32): intptr {
|
||||
return LoadBufferIntptr(f, o);
|
||||
}
|
||||
@ -102,14 +96,6 @@ macro LoadContextOrFrameTypeFromFrame(implicit context: Context)(f: Frame):
|
||||
LoadObjectFromFrame(f, kStandardFrameContextOrFrameTypeOffset));
|
||||
}
|
||||
|
||||
const kArgumentsAdaptorFrameLengthOffset: constexpr int31
|
||||
generates 'ArgumentsAdaptorFrameConstants::kLengthOffset';
|
||||
operator '.length'
|
||||
macro LoadLengthFromAdapterFrame(implicit context: Context)(
|
||||
f: ArgumentsAdaptorFrame): Smi {
|
||||
return LoadSmiFromFrame(f, kArgumentsAdaptorFrameLengthOffset);
|
||||
}
|
||||
|
||||
operator '==' macro FrameTypeEquals(f1: FrameType, f2: FrameType): bool {
|
||||
return TaggedEqual(f1, f2);
|
||||
}
|
||||
@ -135,16 +121,6 @@ Cast<StandardFrame>(implicit context: Context)(f: Frame):
|
||||
goto CastError;
|
||||
}
|
||||
|
||||
Cast<ArgumentsAdaptorFrame>(implicit context: Context)(f: Frame):
|
||||
ArgumentsAdaptorFrame labels CastError {
|
||||
const t: FrameType =
|
||||
Cast<FrameType>(f.context_or_frame_type) otherwise CastError;
|
||||
if (t == ARGUMENTS_ADAPTOR_FRAME) {
|
||||
return %RawDownCast<ArgumentsAdaptorFrame>(f);
|
||||
}
|
||||
goto CastError;
|
||||
}
|
||||
|
||||
// Load target function from the current JS frame.
|
||||
// This is an alternative way of getting the target function in addition to
|
||||
// Parameter(Descriptor::kJSTarget). The latter should be used near the
|
||||
|
@ -714,7 +714,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ mov(params_size,
|
||||
FieldOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ mov(actual_params_size, Operand(ebp, StandardFrameConstants::kArgCOffset));
|
||||
@ -729,7 +728,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ j(greater_equal, &corrected_args_count, Label::kNear);
|
||||
__ mov(params_size, actual_params_size);
|
||||
__ bind(&corrected_args_count);
|
||||
#endif
|
||||
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ leave();
|
||||
@ -1863,41 +1861,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ push(ebp);
|
||||
__ mov(ebp, esp);
|
||||
|
||||
// Store the arguments adaptor context sentinel.
|
||||
__ push(Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
|
||||
// Push the function on the stack.
|
||||
__ push(edi);
|
||||
|
||||
// Preserve the number of arguments on the stack. Must preserve eax,
|
||||
// ebx and ecx because these registers are used when copying the
|
||||
// arguments and the receiver.
|
||||
STATIC_ASSERT(kSmiTagSize == 1);
|
||||
__ lea(edi, Operand(eax, eax, times_1, kSmiTag));
|
||||
__ push(edi);
|
||||
|
||||
__ Push(Immediate(0)); // Padding.
|
||||
}
|
||||
|
||||
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// Retrieve the number of arguments from the stack.
|
||||
__ mov(edi, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
|
||||
// Leave the frame.
|
||||
__ leave();
|
||||
|
||||
// Remove caller arguments from the stack.
|
||||
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
|
||||
__ PopReturnAddressTo(ecx);
|
||||
__ lea(esp, Operand(esp, edi, times_half_system_pointer_size,
|
||||
1 * kSystemPointerSize)); // 1 ~ receiver
|
||||
__ PushReturnAddressFrom(ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
Handle<Code> code) {
|
||||
@ -2051,35 +2014,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
|
||||
__ movd(xmm1, edx); // Preserve new.target (in case of [[Construct]]).
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ mov(scratch, ebp);
|
||||
__ mov(edx, Operand(ebp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
Label arguments_adaptor, arguments_done;
|
||||
__ mov(scratch, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ cmp(Operand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset),
|
||||
Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(equal, &arguments_adaptor, Label::kNear);
|
||||
{
|
||||
__ mov(edx, Operand(ebp, StandardFrameConstants::kFunctionOffset));
|
||||
__ mov(edx, FieldOperand(edx, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movzx_w(edx, FieldOperand(
|
||||
edx, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ mov(scratch, ebp);
|
||||
}
|
||||
__ jmp(&arguments_done, Label::kNear);
|
||||
__ bind(&arguments_adaptor);
|
||||
{
|
||||
// Just load the length from the ArgumentsAdaptorFrame.
|
||||
__ mov(edx,
|
||||
Operand(scratch, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(edx);
|
||||
}
|
||||
__ bind(&arguments_done);
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ sub(edx, ecx);
|
||||
@ -2550,123 +2488,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : actual number of arguments
|
||||
// -- ecx : expected number of arguments
|
||||
// -- edx : new target (passed through to callee)
|
||||
// -- edi : function (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
const Register kExpectedNumberOfArgumentsRegister = ecx;
|
||||
|
||||
Label invoke, dont_adapt_arguments, stack_overflow, enough, too_few;
|
||||
__ cmp(kExpectedNumberOfArgumentsRegister, kDontAdaptArgumentsSentinel);
|
||||
__ j(equal, &dont_adapt_arguments);
|
||||
__ cmp(eax, kExpectedNumberOfArgumentsRegister);
|
||||
__ j(less, &too_few);
|
||||
|
||||
{ // Enough parameters: Actual >= expected.
|
||||
__ bind(&enough);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
// edi is used as a scratch register. It should be restored from the frame
|
||||
// when needed.
|
||||
__ StackOverflowCheck(kExpectedNumberOfArgumentsRegister, edi,
|
||||
&stack_overflow);
|
||||
|
||||
// Copy receiver and all expected arguments.
|
||||
const int offset = StandardFrameConstants::kCallerSPOffset;
|
||||
__ lea(edi, Operand(ebp, ecx, times_system_pointer_size, offset));
|
||||
__ mov(eax, -1); // account for receiver
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ inc(eax);
|
||||
__ push(Operand(edi, 0));
|
||||
__ sub(edi, Immediate(kSystemPointerSize));
|
||||
__ cmp(eax, kExpectedNumberOfArgumentsRegister);
|
||||
__ j(less, ©);
|
||||
// eax now contains the expected number of arguments.
|
||||
__ jmp(&invoke);
|
||||
}
|
||||
|
||||
{ // Too few parameters: Actual < expected.
|
||||
__ bind(&too_few);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
// edi is used as a scratch register. It should be restored from the frame
|
||||
// when needed.
|
||||
__ StackOverflowCheck(kExpectedNumberOfArgumentsRegister, edi,
|
||||
&stack_overflow);
|
||||
|
||||
// Remember expected arguments in xmm0.
|
||||
__ movd(xmm0, kExpectedNumberOfArgumentsRegister);
|
||||
|
||||
// Remember new target.
|
||||
__ movd(xmm1, edx);
|
||||
|
||||
// Fill remaining expected arguments with undefined values.
|
||||
Label fill;
|
||||
__ mov(edx, ecx);
|
||||
__ sub(edx, eax);
|
||||
__ bind(&fill);
|
||||
__ Push(Immediate(masm->isolate()->factory()->undefined_value()));
|
||||
__ dec(edx);
|
||||
__ j(greater, &fill);
|
||||
|
||||
// Copy receiver and all actual arguments.
|
||||
const int offset = StandardFrameConstants::kCallerSPOffset;
|
||||
__ lea(edi, Operand(ebp, eax, times_system_pointer_size, offset));
|
||||
__ mov(edx, Immediate(-1));
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ inc(edx);
|
||||
__ push(Operand(edi, 0));
|
||||
__ sub(edi, Immediate(kSystemPointerSize));
|
||||
__ cmp(edx, eax);
|
||||
__ j(less, ©);
|
||||
|
||||
// Restore new.target
|
||||
__ movd(edx, xmm1);
|
||||
|
||||
// Restore expected arguments.
|
||||
__ movd(eax, xmm0);
|
||||
}
|
||||
|
||||
// Call the entry point.
|
||||
__ bind(&invoke);
|
||||
// Restore function pointer.
|
||||
__ mov(edi, Operand(ebp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
|
||||
// eax : expected number of arguments
|
||||
// edx : new target (passed through to callee)
|
||||
// edi : function (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == ecx, "ABI mismatch");
|
||||
__ mov(ecx, FieldOperand(edi, JSFunction::kCodeOffset));
|
||||
__ CallCodeObject(ecx);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
|
||||
|
||||
// Leave frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ ret(0);
|
||||
|
||||
// -------------------------------------------
|
||||
// Dont adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ bind(&dont_adapt_arguments);
|
||||
static_assert(kJavaScriptCallCodeStartRegister == ecx, "ABI mismatch");
|
||||
__ mov(ecx, FieldOperand(edi, JSFunction::kCodeOffset));
|
||||
__ JumpCodeObject(ecx);
|
||||
|
||||
__ bind(&stack_overflow);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ int3();
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
|
@ -766,7 +766,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ lw(params_size,
|
||||
FieldMemOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ Lw(actual_params_size,
|
||||
@ -778,7 +777,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
// arguments.
|
||||
__ slt(t2, params_size, actual_params_size);
|
||||
__ movn(params_size, actual_params_size, t2);
|
||||
#endif
|
||||
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ LeaveFrame(StackFrame::INTERPRETED);
|
||||
@ -1735,29 +1733,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ sll(a0, a0, kSmiTagSize);
|
||||
__ li(t0, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit());
|
||||
__ Push(Smi::zero()); // Padding.
|
||||
__ Addu(fp, sp,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
|
||||
}
|
||||
|
||||
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- v0 : result being passed through
|
||||
// -----------------------------------
|
||||
// Get the number of arguments passed (as a smi), tear down the frame and
|
||||
// then tear down the parameters.
|
||||
__ lw(a1, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ mov(sp, fp);
|
||||
__ MultiPop(fp.bit() | ra.bit());
|
||||
__ Lsa(sp, sp, a1, kPointerSizeLog2 - kSmiTagSize);
|
||||
// Adjust for the receiver.
|
||||
__ Addu(sp, sp, Operand(kPointerSize));
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
Handle<Code> code) {
|
||||
@ -1864,35 +1839,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ bind(&new_target_constructor);
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ mov(t3, fp);
|
||||
__ Lw(t2, MemOperand(fp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
Label arguments_adaptor, arguments_done;
|
||||
__ lw(t3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ lw(t2, MemOperand(t3, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ Branch(&arguments_adaptor, eq, t2,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
{
|
||||
__ lw(t2, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ lw(t2, FieldMemOperand(t2, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lhu(t2, FieldMemOperand(
|
||||
t2, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ mov(t3, fp);
|
||||
}
|
||||
__ Branch(&arguments_done);
|
||||
__ bind(&arguments_adaptor);
|
||||
{
|
||||
// Just get the length from the ArgumentsAdaptorFrame.
|
||||
__ lw(t2, MemOperand(t3, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(t2);
|
||||
}
|
||||
__ bind(&arguments_done);
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ Subu(t2, t2, a2);
|
||||
@ -2329,128 +2279,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
// State setup as expected by MacroAssembler::InvokePrologue.
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0: actual arguments count
|
||||
// -- a1: function (passed through to callee)
|
||||
// -- a2: expected arguments count
|
||||
// -- a3: new target (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
Label invoke, dont_adapt_arguments, stack_overflow;
|
||||
|
||||
Label enough, too_few;
|
||||
__ Branch(&dont_adapt_arguments, eq, a2,
|
||||
Operand(kDontAdaptArgumentsSentinel));
|
||||
// We use Uless as the number of argument should always be greater than 0.
|
||||
__ Branch(&too_few, Uless, a0, Operand(a2));
|
||||
|
||||
{ // Enough parameters: actual >= expected.
|
||||
// a0: actual number of arguments as a smi
|
||||
// a1: function
|
||||
// a2: expected number of arguments
|
||||
// a3: new target (passed through to callee)
|
||||
__ bind(&enough);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(a2, t1, kScratchReg, &stack_overflow);
|
||||
|
||||
// Calculate copy start address into a0 and copy end address into t1.
|
||||
__ Lsa(a0, fp, a2, kPointerSizeLog2);
|
||||
// Adjust for return address and receiver.
|
||||
__ Addu(a0, a0, Operand(2 * kPointerSize));
|
||||
// Compute copy end address.
|
||||
__ sll(t1, a2, kPointerSizeLog2);
|
||||
__ subu(t1, a0, t1);
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// a0: copy start address
|
||||
// a1: function
|
||||
// a2: expected number of arguments
|
||||
// a3: new target (passed through to callee)
|
||||
// t1: copy end address
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ lw(t0, MemOperand(a0));
|
||||
__ push(t0);
|
||||
__ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(t1));
|
||||
__ addiu(a0, a0, -kPointerSize); // In delay slot.
|
||||
|
||||
__ jmp(&invoke);
|
||||
}
|
||||
|
||||
{ // Too few parameters: Actual < expected.
|
||||
__ bind(&too_few);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(a2, t1, kScratchReg, &stack_overflow);
|
||||
|
||||
// Fill the remaining expected arguments with undefined.
|
||||
__ LoadRoot(t0, RootIndex::kUndefinedValue);
|
||||
__ SmiUntag(t2, a0);
|
||||
__ Subu(t2, a2, Operand(t2));
|
||||
__ sll(t1, t2, kSystemPointerSizeLog2);
|
||||
__ Subu(t1, fp, t1);
|
||||
// Adjust for frame.
|
||||
__ Subu(t1, t1,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
|
||||
kSystemPointerSize));
|
||||
|
||||
Label fill;
|
||||
__ bind(&fill);
|
||||
__ push(t0);
|
||||
__ Branch(&fill, ne, sp, Operand(t1));
|
||||
|
||||
// Calculate copy start address into a0 and copy end address is fp.
|
||||
__ Lsa(a0, fp, a0, kPointerSizeLog2 - kSmiTagSize);
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
|
||||
// Adjust load for return address and receiver.
|
||||
__ Lw(t0, MemOperand(a0, 2 * kSystemPointerSize));
|
||||
__ push(t0);
|
||||
|
||||
__ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(fp));
|
||||
__ Subu(a0, a0, Operand(kSystemPointerSize));
|
||||
}
|
||||
|
||||
// Call the entry point.
|
||||
__ bind(&invoke);
|
||||
__ mov(a0, a2);
|
||||
// a0 : expected number of arguments
|
||||
// a1 : function (passed through to callee)
|
||||
// a3 : new target (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == a2, "ABI mismatch");
|
||||
__ lw(a2, FieldMemOperand(a1, JSFunction::kCodeOffset));
|
||||
__ Addu(a2, a2, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Call(a2);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
|
||||
|
||||
// Exit frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ Ret();
|
||||
|
||||
// -------------------------------------------
|
||||
// Don't adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ bind(&dont_adapt_arguments);
|
||||
static_assert(kJavaScriptCallCodeStartRegister == a2, "ABI mismatch");
|
||||
__ lw(a2, FieldMemOperand(a1, JSFunction::kCodeOffset));
|
||||
__ Addu(a2, a2, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Jump(a2);
|
||||
|
||||
__ bind(&stack_overflow);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ break_(0xCC);
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
|
||||
// The function index was put in t0 by the jump table trampoline.
|
||||
// Convert to Smi for the runtime call.
|
||||
|
@ -781,7 +781,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ Lw(params_size,
|
||||
FieldMemOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ Ld(actual_params_size,
|
||||
@ -793,7 +792,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
// arguments.
|
||||
__ slt(t2, params_size, actual_params_size);
|
||||
__ movn(params_size, actual_params_size, t2);
|
||||
#endif
|
||||
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ LeaveFrame(StackFrame::INTERPRETED);
|
||||
@ -1790,30 +1788,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ SmiTag(a0);
|
||||
__ li(a4, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ MultiPush(a0.bit() | a1.bit() | a4.bit() | fp.bit() | ra.bit());
|
||||
__ Push(Smi::zero()); // Padding.
|
||||
__ Daddu(fp, sp,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
|
||||
}
|
||||
|
||||
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- v0 : result being passed through
|
||||
// -----------------------------------
|
||||
// Get the number of arguments passed (as a smi), tear down the frame and
|
||||
// then tear down the parameters.
|
||||
__ Ld(a1, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ mov(sp, fp);
|
||||
__ MultiPop(fp.bit() | ra.bit());
|
||||
__ SmiScale(a4, a1, kPointerSizeLog2);
|
||||
__ Daddu(sp, sp, a4);
|
||||
// Adjust for the receiver.
|
||||
__ Daddu(sp, sp, Operand(kPointerSize));
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
Handle<Code> code) {
|
||||
@ -1928,35 +1902,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ bind(&new_target_constructor);
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ mov(a6, fp);
|
||||
__ Ld(a7, MemOperand(fp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
Label arguments_adaptor, arguments_done;
|
||||
__ Ld(a6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ Ld(a7, MemOperand(a6, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ Branch(&arguments_adaptor, eq, a7,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
{
|
||||
__ Ld(a7, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ Ld(a7, FieldMemOperand(a7, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Lhu(a7, FieldMemOperand(
|
||||
a7, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ mov(a6, fp);
|
||||
}
|
||||
__ Branch(&arguments_done);
|
||||
__ bind(&arguments_adaptor);
|
||||
{
|
||||
// Just get the length from the ArgumentsAdaptorFrame.
|
||||
__ SmiUntag(a7,
|
||||
MemOperand(a6, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
}
|
||||
__ bind(&arguments_done);
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ Subu(a7, a7, a2);
|
||||
@ -2392,131 +2341,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
// State setup as expected by MacroAssembler::InvokePrologue.
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0: actual arguments count
|
||||
// -- a1: function (passed through to callee)
|
||||
// -- a2: expected arguments count
|
||||
// -- a3: new target (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
Label invoke, dont_adapt_arguments, stack_overflow;
|
||||
|
||||
Label enough, too_few;
|
||||
__ Branch(&dont_adapt_arguments, eq, a2,
|
||||
Operand(kDontAdaptArgumentsSentinel));
|
||||
// We use Uless as the number of argument should always be greater than 0.
|
||||
__ Branch(&too_few, Uless, a0, Operand(a2));
|
||||
|
||||
{ // Enough parameters: actual >= expected.
|
||||
// a0: actual number of arguments as a smi
|
||||
// a1: function
|
||||
// a2: expected number of arguments
|
||||
// a3: new target (passed through to callee)
|
||||
__ bind(&enough);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(a2, a5, kScratchReg, &stack_overflow);
|
||||
|
||||
// Calculate copy start address into a0 and copy end address into a4.
|
||||
__ dsll(a0, a2, kPointerSizeLog2);
|
||||
__ Daddu(a0, fp, a0);
|
||||
|
||||
// Adjust for return address and receiver.
|
||||
__ Daddu(a0, a0, Operand(2 * kPointerSize));
|
||||
// Compute copy end address.
|
||||
__ dsll(a4, a2, kPointerSizeLog2);
|
||||
__ dsubu(a4, a0, a4);
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// a0: copy start address
|
||||
// a1: function
|
||||
// a2: expected number of arguments
|
||||
// a3: new target (passed through to callee)
|
||||
// a4: copy end address
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ Ld(a5, MemOperand(a0));
|
||||
__ push(a5);
|
||||
__ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(a4));
|
||||
__ daddiu(a0, a0, -kPointerSize); // In delay slot.
|
||||
|
||||
__ jmp(&invoke);
|
||||
}
|
||||
|
||||
{ // Too few parameters: Actual < expected.
|
||||
__ bind(&too_few);
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(a2, a5, kScratchReg, &stack_overflow);
|
||||
|
||||
// Fill the remaining expected arguments with undefined.
|
||||
__ LoadRoot(t0, RootIndex::kUndefinedValue);
|
||||
__ SmiUntag(t1, a0);
|
||||
__ Dsubu(t2, a2, Operand(t1));
|
||||
__ dsll(a4, t2, kSystemPointerSizeLog2);
|
||||
__ Dsubu(a4, fp, a4);
|
||||
// Adjust for frame.
|
||||
__ Dsubu(a4, a4,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
|
||||
kSystemPointerSize));
|
||||
|
||||
Label fill;
|
||||
__ bind(&fill);
|
||||
__ push(t0);
|
||||
__ Branch(&fill, ne, sp, Operand(a4));
|
||||
|
||||
// Calculate copy start address into r0 and copy end address is fp.
|
||||
__ SmiScale(a0, a0, kPointerSizeLog2);
|
||||
__ Daddu(a0, fp, a0);
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
|
||||
// Adjust load for return address and receiver.
|
||||
__ Ld(t0, MemOperand(a0, 2 * kSystemPointerSize));
|
||||
__ push(t0);
|
||||
|
||||
__ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(fp));
|
||||
__ Dsubu(a0, a0, Operand(kSystemPointerSize));
|
||||
}
|
||||
|
||||
// Call the entry point.
|
||||
__ bind(&invoke);
|
||||
__ mov(a0, a2);
|
||||
// a0 : expected number of arguments
|
||||
// a1 : function (passed through to callee)
|
||||
// a3: new target (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == a2, "ABI mismatch");
|
||||
__ Ld(a2, FieldMemOperand(a1, JSFunction::kCodeOffset));
|
||||
__ Daddu(a2, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Call(a2);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
|
||||
|
||||
// Exit frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ Ret();
|
||||
|
||||
// -------------------------------------------
|
||||
// Don't adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ bind(&dont_adapt_arguments);
|
||||
static_assert(kJavaScriptCallCodeStartRegister == a2, "ABI mismatch");
|
||||
__ Ld(a2, FieldMemOperand(a1, JSFunction::kCodeOffset));
|
||||
__ Daddu(a2, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(a2);
|
||||
|
||||
__ bind(&stack_overflow);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ break_(0xCC);
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
|
||||
// The function index was put in t0 by the jump table trampoline.
|
||||
// Convert to Smi for the runtime call
|
||||
|
@ -803,7 +803,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ lwz(params_size,
|
||||
FieldMemOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ LoadP(actual_params_size,
|
||||
@ -819,7 +818,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ bge(&corrected_args_count);
|
||||
__ mr(params_size, actual_params_size);
|
||||
__ bind(&corrected_args_count);
|
||||
#endif
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ LeaveFrame(StackFrame::INTERPRETED);
|
||||
|
||||
@ -1834,34 +1832,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ SmiTag(r3);
|
||||
__ mov(r7, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ mflr(r0);
|
||||
__ push(r0);
|
||||
if (FLAG_enable_embedded_constant_pool) {
|
||||
__ Push(fp, kConstantPoolRegister, r7, r4, r3);
|
||||
} else {
|
||||
__ Push(fp, r7, r4, r3);
|
||||
}
|
||||
__ Push(Smi::zero()); // Padding.
|
||||
__ addi(fp, sp,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
|
||||
}
|
||||
|
||||
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : result being passed through
|
||||
// -----------------------------------
|
||||
// Get the number of arguments passed (as a smi), tear down the frame and
|
||||
// then tear down the parameters.
|
||||
__ LoadP(r4, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
int stack_adjustment = kSystemPointerSize; // adjust for receiver
|
||||
__ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment);
|
||||
__ SmiToPtrArrayOffset(r0, r4);
|
||||
__ add(sp, sp, r0);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
Handle<Code> code) {
|
||||
@ -1978,38 +1948,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ bind(&new_target_constructor);
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ mr(r7, fp);
|
||||
__ LoadP(r8, MemOperand(fp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
Label arguments_adaptor, arguments_done;
|
||||
__ LoadP(r7, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ LoadP(scratch,
|
||||
MemOperand(r7, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ cmpi(scratch,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ beq(&arguments_adaptor);
|
||||
{
|
||||
__ LoadP(r8, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ LoadTaggedPointerField(
|
||||
r8, FieldMemOperand(r8, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadHalfWord(
|
||||
r8,
|
||||
FieldMemOperand(r8, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ mr(r7, fp);
|
||||
}
|
||||
__ b(&arguments_done);
|
||||
__ bind(&arguments_adaptor);
|
||||
{
|
||||
// Load the length from the ArgumentsAdaptorFrame.
|
||||
__ LoadP(r8, MemOperand(r7, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(r8);
|
||||
}
|
||||
__ bind(&arguments_done);
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ sub(r8, r8, r5, LeaveOE, SetRC);
|
||||
@ -2439,153 +2381,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : actual number of arguments
|
||||
// -- r4 : function (passed through to callee)
|
||||
// -- r5 : expected number of arguments
|
||||
// -- r6 : new target (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
Label dont_adapt_arguments, stack_overflow;
|
||||
__ cmpli(r5, Operand(kDontAdaptArgumentsSentinel));
|
||||
__ beq(&dont_adapt_arguments);
|
||||
__ LoadTaggedPointerField(
|
||||
r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kFlagsOffset));
|
||||
|
||||
// -------------------------------------------
|
||||
// Adapt arguments.
|
||||
// -------------------------------------------
|
||||
{
|
||||
Label under_application, over_application, invoke;
|
||||
__ cmp(r3, r5);
|
||||
__ blt(&under_application);
|
||||
|
||||
// Enough parameters: actual >= expected
|
||||
__ bind(&over_application);
|
||||
{
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(r5, r8, &stack_overflow);
|
||||
|
||||
// Calculate copy start address into r3 and copy end address into r7.
|
||||
// r3: actual number of arguments as a smi
|
||||
// r4: function
|
||||
// r5: expected number of arguments
|
||||
// r6: new target (passed through to callee)
|
||||
__ ShiftLeftImm(r3, r5, Operand(kSystemPointerSizeLog2));
|
||||
__ add(r3, r3, fp);
|
||||
// adjust for return address and receiver
|
||||
__ addi(r3, r3, Operand(2 * kSystemPointerSize));
|
||||
__ ShiftLeftImm(r7, r5, Operand(kSystemPointerSizeLog2));
|
||||
__ sub(r7, r3, r7);
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// r3: copy start address
|
||||
// r4: function
|
||||
// r5: expected number of arguments
|
||||
// r6: new target (passed through to callee)
|
||||
// r7: copy end address
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ LoadP(r0, MemOperand(r3, 0));
|
||||
__ push(r0);
|
||||
__ cmp(r3, r7); // Compare before moving to next argument.
|
||||
__ subi(r3, r3, Operand(kSystemPointerSize));
|
||||
__ bne(©);
|
||||
|
||||
__ b(&invoke);
|
||||
}
|
||||
|
||||
// Too few parameters: Actual < expected
|
||||
__ bind(&under_application);
|
||||
{
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(r5, r8, &stack_overflow);
|
||||
|
||||
// Fill the remaining expected arguments with undefined.
|
||||
// r0: actual number of arguments as a smi
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
__ LoadRoot(r8, RootIndex::kUndefinedValue);
|
||||
__ SmiUntag(r0, r3);
|
||||
__ sub(r9, r5, r0);
|
||||
__ ShiftLeftImm(r7, r9, Operand(kSystemPointerSizeLog2));
|
||||
__ sub(r7, fp, r7);
|
||||
// Adjust for frame.
|
||||
__ subi(r7, r7,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
|
||||
kSystemPointerSize));
|
||||
|
||||
Label fill;
|
||||
__ bind(&fill);
|
||||
__ push(r8);
|
||||
__ cmp(sp, r7);
|
||||
__ b(ne, &fill);
|
||||
|
||||
// Calculate copy start address into r0 and copy end address is fp.
|
||||
// r0: actual number of arguments as a smi
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
__ SmiToPtrArrayOffset(r3, r3);
|
||||
__ add(r3, r3, fp);
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// r0: copy start address
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
|
||||
// Adjust load for return address and receiver.
|
||||
__ LoadP(r8, MemOperand(r3, 2 * kSystemPointerSize));
|
||||
__ push(r8);
|
||||
|
||||
__ cmp(r3, fp); // Compare before moving to next argument.
|
||||
__ subi(r3, r3, Operand(kSystemPointerSize));
|
||||
__ b(ne, ©);
|
||||
}
|
||||
|
||||
// Call the entry point.
|
||||
__ bind(&invoke);
|
||||
__ mr(r3, r5);
|
||||
// r3 : expected number of arguments
|
||||
// r4 : function (passed through to callee)
|
||||
// r6 : new target (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == r5, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(r5, FieldMemOperand(r4, JSFunction::kCodeOffset));
|
||||
__ CallCodeObject(r5);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(
|
||||
masm->pc_offset());
|
||||
|
||||
// Exit frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ blr();
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// Dont adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ bind(&dont_adapt_arguments);
|
||||
__ RecordComment("-- Call without adapting args --");
|
||||
static_assert(kJavaScriptCallCodeStartRegister == r5, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(r5, FieldMemOperand(r4, JSFunction::kCodeOffset));
|
||||
__ JumpCodeObject(r5);
|
||||
|
||||
__ bind(&stack_overflow);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ bkpt(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
|
||||
// The function index was put in a register by the jump table trampoline.
|
||||
// Convert to Smi for the runtime call.
|
||||
|
@ -860,7 +860,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ LoadU32(params_size,
|
||||
FieldMemOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ LoadU64(actual_params_size,
|
||||
@ -877,7 +876,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ bge(&corrected_args_count);
|
||||
__ mov(params_size, actual_params_size);
|
||||
__ bind(&corrected_args_count);
|
||||
#endif
|
||||
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ LeaveFrame(StackFrame::INTERPRETED);
|
||||
@ -1878,44 +1876,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ SmiTag(r2);
|
||||
__ mov(r6, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
// Stack updated as such:
|
||||
// old SP --->
|
||||
// R14 Return Addr
|
||||
// Old FP <--- New FP
|
||||
// Argument Adapter SMI
|
||||
// Function
|
||||
// ArgC as SMI
|
||||
// Padding <--- New SP
|
||||
__ lay(sp, MemOperand(sp, -5 * kSystemPointerSize));
|
||||
|
||||
// Cleanse the top nibble of 31-bit pointers.
|
||||
__ CleanseP(r14);
|
||||
__ StoreU64(r14, MemOperand(sp, 4 * kSystemPointerSize));
|
||||
__ StoreU64(fp, MemOperand(sp, 3 * kSystemPointerSize));
|
||||
__ StoreU64(r6, MemOperand(sp, 2 * kSystemPointerSize));
|
||||
__ StoreU64(r3, MemOperand(sp, 1 * kSystemPointerSize));
|
||||
__ StoreU64(r2, MemOperand(sp, 0 * kSystemPointerSize));
|
||||
__ Push(Smi::zero()); // Padding.
|
||||
__ la(fp,
|
||||
MemOperand(sp, ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp));
|
||||
}
|
||||
|
||||
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : result being passed through
|
||||
// -----------------------------------
|
||||
// Get the number of arguments passed (as a smi), tear down the frame and
|
||||
// then tear down the parameters.
|
||||
__ LoadU64(r3, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
int stack_adjustment = kSystemPointerSize; // adjust for receiver
|
||||
__ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment);
|
||||
__ SmiToPtrArrayOffset(r3, r3);
|
||||
__ lay(sp, MemOperand(sp, r3));
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
Handle<Code> code) {
|
||||
@ -2036,39 +1996,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ bind(&new_target_constructor);
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ mov(r6, fp);
|
||||
__ LoadU64(r7, MemOperand(fp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
Label arguments_adaptor, arguments_done;
|
||||
__ LoadU64(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ LoadU64(scratch,
|
||||
MemOperand(r6, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ CmpS64(scratch,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ beq(&arguments_adaptor);
|
||||
{
|
||||
__ LoadU64(r7, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ LoadTaggedPointerField(
|
||||
r7, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadU16(
|
||||
r7,
|
||||
FieldMemOperand(r7, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ mov(r6, fp);
|
||||
}
|
||||
__ b(&arguments_done);
|
||||
__ bind(&arguments_adaptor);
|
||||
{
|
||||
// Load the length from the ArgumentsAdaptorFrame.
|
||||
__ LoadU64(r7,
|
||||
MemOperand(r6, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(r7);
|
||||
}
|
||||
__ bind(&arguments_done);
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ SubS64(r7, r7, r4);
|
||||
@ -2500,153 +2431,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : actual number of arguments
|
||||
// -- r3 : function (passed through to callee)
|
||||
// -- r4 : expected number of arguments
|
||||
// -- r5 : new target (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
Label dont_adapt_arguments, stack_overflow;
|
||||
__ tmll(r4, Operand(kDontAdaptArgumentsSentinel));
|
||||
__ b(Condition(1), &dont_adapt_arguments);
|
||||
__ LoadTaggedPointerField(
|
||||
r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadU32(r6, FieldMemOperand(r6, SharedFunctionInfo::kFlagsOffset));
|
||||
|
||||
// -------------------------------------------
|
||||
// Adapt arguments.
|
||||
// -------------------------------------------
|
||||
{
|
||||
Label under_application, over_application, invoke;
|
||||
__ CmpS64(r2, r4);
|
||||
__ blt(&under_application);
|
||||
|
||||
// Enough parameters: actual >= expected
|
||||
__ bind(&over_application);
|
||||
{
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(r4, r7, &stack_overflow);
|
||||
|
||||
// Calculate copy start address into r2 and copy end address into r6.
|
||||
// r2: actual number of arguments as a smi
|
||||
// r3: function
|
||||
// r4: expected number of arguments
|
||||
// r5: new target (passed through to callee)
|
||||
__ ShiftLeftU64(r2, r4, Operand(kSystemPointerSizeLog2));
|
||||
__ AddS64(r2, fp);
|
||||
// adjust for return address and receiver
|
||||
__ AddS64(r2, r2, Operand(2 * kSystemPointerSize));
|
||||
__ ShiftLeftU64(r6, r4, Operand(kSystemPointerSizeLog2));
|
||||
__ SubS64(r6, r2, r6);
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// r2: copy start address
|
||||
// r3: function
|
||||
// r4: expected number of arguments
|
||||
// r5: new target (passed through to callee)
|
||||
// r6: copy end address
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ LoadU64(r0, MemOperand(r2, 0));
|
||||
__ push(r0);
|
||||
__ CmpS64(r2, r6); // Compare before moving to next argument.
|
||||
__ lay(r2, MemOperand(r2, -kSystemPointerSize));
|
||||
__ bne(©);
|
||||
|
||||
__ b(&invoke);
|
||||
}
|
||||
|
||||
// Too few parameters: Actual < expected
|
||||
__ bind(&under_application);
|
||||
{
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(r4, r7, &stack_overflow);
|
||||
|
||||
// Fill the remaining expected arguments with undefined.
|
||||
// r0: actual number of arguments as a smi
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
__ LoadRoot(r7, RootIndex::kUndefinedValue);
|
||||
__ SmiUntag(r1, r2);
|
||||
__ SubS64(r8, r4, r1);
|
||||
__ ShiftLeftU64(r1, r8, Operand(kSystemPointerSizeLog2));
|
||||
__ SubS64(r6, fp, r1);
|
||||
// Adjust for frame.
|
||||
__ SubS64(r6, r6,
|
||||
Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp +
|
||||
kSystemPointerSize));
|
||||
|
||||
Label fill;
|
||||
__ bind(&fill);
|
||||
__ push(r7);
|
||||
__ CmpS64(sp, r6);
|
||||
__ b(ne, &fill);
|
||||
|
||||
// Calculate copy start address into r0 and copy end address is fp.
|
||||
// r0: actual number of arguments as a smi
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
__ SmiToPtrArrayOffset(r2, r2);
|
||||
__ lay(r2, MemOperand(r2, fp));
|
||||
|
||||
// Copy the arguments (including the receiver) to the new stack frame.
|
||||
// r0: copy start address
|
||||
// r1: function
|
||||
// r2: expected number of arguments
|
||||
// r3: new target (passed through to callee)
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
|
||||
// Adjust load for return address and receiver.
|
||||
__ LoadU64(r7, MemOperand(r2, 2 * kSystemPointerSize));
|
||||
__ push(r7);
|
||||
|
||||
__ CmpS64(r2, fp); // Compare before moving to next argument.
|
||||
__ lay(r2, MemOperand(r2, -kSystemPointerSize));
|
||||
__ b(ne, ©);
|
||||
}
|
||||
|
||||
// Call the entry point.
|
||||
__ bind(&invoke);
|
||||
__ mov(r2, r4);
|
||||
// r2 : expected number of arguments
|
||||
// r3 : function (passed through to callee)
|
||||
// r5 : new target (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == r4, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(r4, FieldMemOperand(r3, JSFunction::kCodeOffset));
|
||||
__ CallCodeObject(r4);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(
|
||||
masm->pc_offset());
|
||||
|
||||
// Exit frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// Dont adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ bind(&dont_adapt_arguments);
|
||||
__ RecordComment("-- Call without adapting args --");
|
||||
static_assert(kJavaScriptCallCodeStartRegister == r4, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(r4, FieldMemOperand(r3, JSFunction::kCodeOffset));
|
||||
__ JumpCodeObject(r4);
|
||||
|
||||
__ bind(&stack_overflow);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ bkpt(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
|
||||
// The function index was put in a register by the jump table trampoline.
|
||||
// Convert to Smi for the runtime call.
|
||||
|
@ -820,7 +820,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ movl(params_size,
|
||||
FieldOperand(params_size, BytecodeArray::kParameterSizeOffset));
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Register actual_params_size = scratch2;
|
||||
// Compute the size of the actual parameters + receiver (in bytes).
|
||||
__ movq(actual_params_size,
|
||||
@ -836,7 +835,6 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
|
||||
__ j(greater_equal, &corrected_args_count, Label::kNear);
|
||||
__ movq(params_size, actual_params_size);
|
||||
__ bind(&corrected_args_count);
|
||||
#endif
|
||||
|
||||
// Leave the frame (also dropping the register file).
|
||||
__ leave();
|
||||
@ -1835,147 +1833,6 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
__ pushq(rbp);
|
||||
__ movq(rbp, rsp);
|
||||
|
||||
// Store the arguments adaptor context sentinel.
|
||||
__ Push(Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
|
||||
// Push the function on the stack.
|
||||
__ Push(rdi);
|
||||
|
||||
// Preserve the number of arguments on the stack. Must preserve rax,
|
||||
// rbx and rcx because these registers are used when copying the
|
||||
// arguments and the receiver.
|
||||
__ SmiTag(r8, rax);
|
||||
__ Push(r8);
|
||||
|
||||
__ Push(Immediate(0)); // Padding.
|
||||
}
|
||||
|
||||
static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
|
||||
// Retrieve the number of arguments from the stack. Number is a Smi.
|
||||
__ movq(rbx, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
|
||||
// Leave the frame.
|
||||
__ movq(rsp, rbp);
|
||||
__ popq(rbp);
|
||||
|
||||
// Remove caller arguments from the stack.
|
||||
__ PopReturnAddressTo(rcx);
|
||||
SmiIndex index = masm->SmiToIndex(rbx, rbx, kSystemPointerSizeLog2);
|
||||
__ leaq(rsp, Operand(rsp, index.reg, index.scale, 1 * kSystemPointerSize));
|
||||
__ PushReturnAddressFrom(rcx);
|
||||
}
|
||||
|
||||
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : actual number of arguments
|
||||
// -- rbx : expected number of arguments
|
||||
// -- rdx : new target (passed through to callee)
|
||||
// -- rdi : function (passed through to callee)
|
||||
// -----------------------------------
|
||||
|
||||
Label dont_adapt_arguments, stack_overflow;
|
||||
__ cmpq(rbx, Immediate(kDontAdaptArgumentsSentinel));
|
||||
__ j(equal, &dont_adapt_arguments);
|
||||
__ LoadTaggedPointerField(
|
||||
rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
|
||||
|
||||
// -------------------------------------------
|
||||
// Adapt arguments.
|
||||
// -------------------------------------------
|
||||
{
|
||||
EnterArgumentsAdaptorFrame(masm);
|
||||
__ StackOverflowCheck(rbx, rcx, &stack_overflow);
|
||||
|
||||
Label under_application, over_application, invoke;
|
||||
__ cmpq(rax, rbx);
|
||||
__ j(less, &under_application, Label::kNear);
|
||||
|
||||
// Enough parameters: Actual >= expected.
|
||||
__ bind(&over_application);
|
||||
{
|
||||
// Copy receiver and all expected arguments.
|
||||
const int offset = StandardFrameConstants::kCallerSPOffset;
|
||||
__ leaq(r8, Operand(rbp, rbx, times_system_pointer_size, offset));
|
||||
__ Set(rax, -1); // account for receiver
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ incq(rax);
|
||||
__ Push(Operand(r8, 0));
|
||||
__ subq(r8, Immediate(kSystemPointerSize));
|
||||
__ cmpq(rax, rbx);
|
||||
__ j(less, ©);
|
||||
__ jmp(&invoke, Label::kNear);
|
||||
}
|
||||
|
||||
// Too few parameters: Actual < expected.
|
||||
__ bind(&under_application);
|
||||
{
|
||||
// Fill remaining expected arguments with undefined values.
|
||||
Label fill;
|
||||
__ LoadRoot(kScratchRegister, RootIndex::kUndefinedValue);
|
||||
__ movq(r8, rbx);
|
||||
__ subq(r8, rax);
|
||||
__ bind(&fill);
|
||||
__ Push(kScratchRegister);
|
||||
__ decq(r8);
|
||||
__ j(greater, &fill);
|
||||
|
||||
// Copy receiver and all actual arguments.
|
||||
const int offset = StandardFrameConstants::kCallerSPOffset;
|
||||
__ leaq(r9, Operand(rbp, rax, times_system_pointer_size, offset));
|
||||
__ Set(r8, -1); // account for receiver
|
||||
|
||||
Label copy;
|
||||
__ bind(©);
|
||||
__ incq(r8);
|
||||
__ Push(Operand(r9, 0));
|
||||
__ subq(r9, Immediate(kSystemPointerSize));
|
||||
__ cmpq(r8, rax);
|
||||
__ j(less, ©);
|
||||
|
||||
// Update actual number of arguments.
|
||||
__ movq(rax, rbx);
|
||||
}
|
||||
|
||||
// Call the entry point.
|
||||
__ bind(&invoke);
|
||||
// rax : expected number of arguments
|
||||
// rdx : new target (passed through to callee)
|
||||
// rdi : function (passed through to callee)
|
||||
static_assert(kJavaScriptCallCodeStartRegister == rcx, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(rcx, FieldOperand(rdi, JSFunction::kCodeOffset));
|
||||
__ CallCodeObject(rcx);
|
||||
|
||||
// Store offset of return address for deoptimizer.
|
||||
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(
|
||||
masm->pc_offset());
|
||||
|
||||
// Leave frame and return.
|
||||
LeaveArgumentsAdaptorFrame(masm);
|
||||
__ ret(0);
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// Don't adapt arguments.
|
||||
// -------------------------------------------
|
||||
__ bind(&dont_adapt_arguments);
|
||||
static_assert(kJavaScriptCallCodeStartRegister == rcx, "ABI mismatch");
|
||||
__ LoadTaggedPointerField(rcx, FieldOperand(rdi, JSFunction::kCodeOffset));
|
||||
__ JumpCodeObject(rcx);
|
||||
|
||||
__ bind(&stack_overflow);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::MANUAL);
|
||||
__ CallRuntime(Runtime::kThrowStackOverflow);
|
||||
__ int3();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
|
||||
Handle<Code> code) {
|
||||
@ -2095,34 +1952,10 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ bind(&new_target_constructor);
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// TODO(victorgomes): Remove this copy when all the arguments adaptor frame
|
||||
// code is erased.
|
||||
__ movq(rbx, rbp);
|
||||
__ movq(r8, Operand(rbp, StandardFrameConstants::kArgCOffset));
|
||||
#else
|
||||
// Check if we have an arguments adaptor frame below the function frame.
|
||||
Label arguments_adaptor, arguments_done;
|
||||
__ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ cmpq(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset),
|
||||
Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(equal, &arguments_adaptor, Label::kNear);
|
||||
{
|
||||
__ movq(r8, Operand(rbp, StandardFrameConstants::kFunctionOffset));
|
||||
__ LoadTaggedPointerField(
|
||||
r8, FieldOperand(r8, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movzxwq(
|
||||
r8, FieldOperand(r8, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ movq(rbx, rbp);
|
||||
}
|
||||
__ jmp(&arguments_done, Label::kNear);
|
||||
__ bind(&arguments_adaptor);
|
||||
{
|
||||
__ SmiUntag(r8,
|
||||
Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
}
|
||||
__ bind(&arguments_done);
|
||||
#endif
|
||||
|
||||
Label stack_done, stack_overflow;
|
||||
__ subl(r8, rcx);
|
||||
|
@ -215,17 +215,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r1, // JSFunction
|
||||
r3, // the new target
|
||||
r0, // actual number of arguments
|
||||
r2, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -1609,7 +1609,6 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
DCHECK_EQ(actual_parameter_count, r0);
|
||||
DCHECK_EQ(expected_parameter_count, r2);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If the expected parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
cmp(expected_parameter_count, Operand(kDontAdaptArgumentsSentinel));
|
||||
@ -1663,20 +1662,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
bkpt(0);
|
||||
}
|
||||
#else
|
||||
// Check whether the expected and actual arguments count match. If not,
|
||||
// setup registers according to contract with ArgumentsAdaptorTrampoline.
|
||||
cmp(expected_parameter_count, actual_parameter_count);
|
||||
b(eq, ®ular_invoke);
|
||||
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor);
|
||||
b(done);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
bind(®ular_invoke);
|
||||
}
|
||||
|
||||
|
@ -219,17 +219,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
x1, // JSFunction
|
||||
x3, // the new target
|
||||
x0, // actual number of arguments
|
||||
x2, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -2128,7 +2128,6 @@ void MacroAssembler::InvokePrologue(Register formal_parameter_count,
|
||||
DCHECK_EQ(actual_argument_count, x0);
|
||||
DCHECK_EQ(formal_parameter_count, x2);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If the formal parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
Cmp(formal_parameter_count, Operand(kDontAdaptArgumentsSentinel));
|
||||
@ -2222,24 +2221,6 @@ void MacroAssembler::InvokePrologue(Register formal_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
Unreachable();
|
||||
}
|
||||
#else
|
||||
// Check whether the expected and actual arguments count match. The registers
|
||||
// are set up according to contract with ArgumentsAdaptorTrampoline.ct.
|
||||
// If actual == expected perform a regular invocation.
|
||||
Cmp(formal_parameter_count, actual_argument_count);
|
||||
B(eq, ®ular_invoke);
|
||||
|
||||
// The argument counts mismatch, generate a call to the argument adaptor.
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor);
|
||||
// If the arg counts don't match, no extra code is emitted by
|
||||
// MAsm::InvokeFunctionCode and we can just fall through.
|
||||
B(done);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
|
||||
Bind(®ular_invoke);
|
||||
}
|
||||
|
@ -257,11 +257,6 @@ Callable CodeFactory::FastNewFunctionContext(Isolate* isolate,
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
|
||||
return Builtins::CallableFor(isolate, Builtins::kArgumentsAdaptorTrampoline);
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode) {
|
||||
return Callable(isolate->builtins()->Call(mode), CallTrampolineDescriptor{});
|
||||
|
@ -68,7 +68,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
|
||||
static Callable FastNewFunctionContext(Isolate* isolate,
|
||||
ScopeType scope_type);
|
||||
|
||||
static Callable ArgumentAdaptor(Isolate* isolate);
|
||||
static Callable Call(Isolate* isolate,
|
||||
ConvertReceiverMode mode = ConvertReceiverMode::kAny);
|
||||
static Callable Call_WithFeedback(Isolate* isolate, ConvertReceiverMode mode);
|
||||
|
@ -294,13 +294,6 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
|
||||
#define CSA_SLOW_ASSERT(csa, ...) ((void)0)
|
||||
#endif
|
||||
|
||||
// Provides a constexpr boolean to be used inside Torque.
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
constexpr bool kNoArgumentsAdaptor = true;
|
||||
#else
|
||||
constexpr bool kNoArgumentsAdaptor = false;
|
||||
#endif
|
||||
|
||||
// Provides JavaScript-specific "macro-assembler" functionality on top of the
|
||||
// CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler,
|
||||
// it's possible to add JavaScript-specific useful CodeAssembler "macros"
|
||||
|
@ -219,17 +219,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
edi, // JSFunction
|
||||
edx, // the new target
|
||||
eax, // actual number of arguments
|
||||
ecx, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -1336,7 +1336,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
DCHECK_EQ(actual_parameter_count, eax);
|
||||
DCHECK_EQ(expected_parameter_count, ecx);
|
||||
Label regular_invoke;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
|
||||
// If the expected parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
cmp(expected_parameter_count, Immediate(kDontAdaptArgumentsSentinel));
|
||||
@ -1408,17 +1408,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
int3(); // This should be unreachable.
|
||||
}
|
||||
#else
|
||||
cmp(expected_parameter_count, actual_parameter_count);
|
||||
j(equal, ®ular_invoke);
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor, RelocInfo::CODE_TARGET);
|
||||
jmp(done, Label::kNear);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
|
||||
bind(®ular_invoke);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace internal {
|
||||
V(Allocate) \
|
||||
V(ApiCallback) \
|
||||
V(ApiGetter) \
|
||||
V(ArgumentsAdaptor) \
|
||||
V(ArrayConstructor) \
|
||||
V(ArrayNArgumentsConstructor) \
|
||||
V(ArrayNoArgumentConstructor) \
|
||||
@ -1238,13 +1237,6 @@ class StringSubstringDescriptor final : public CallInterfaceDescriptor {
|
||||
DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
class ArgumentsAdaptorDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DEFINE_JS_PARAMETERS(kExpectedArgumentsCount)
|
||||
DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
|
||||
DECLARE_DESCRIPTOR(ArgumentsAdaptorDescriptor, CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DEFINE_JS_PARAMETERS(kCFunction)
|
||||
|
@ -241,17 +241,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a1, // JSFunction
|
||||
a3, // the new target
|
||||
a0, // actual number of arguments
|
||||
a2, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -4375,7 +4375,6 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
DCHECK_EQ(actual_parameter_count, a0);
|
||||
DCHECK_EQ(expected_parameter_count, a2);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If the expected parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
Branch(®ular_invoke, eq, expected_parameter_count,
|
||||
@ -4429,20 +4428,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
break_(0xCC);
|
||||
}
|
||||
#else
|
||||
// Check whether the expected and actual arguments count match. The registers
|
||||
// are set up according to contract with ArgumentsAdaptorTrampoline:
|
||||
Branch(®ular_invoke, eq, expected_parameter_count,
|
||||
Operand(actual_parameter_count));
|
||||
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor);
|
||||
Branch(done);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
bind(®ular_invoke);
|
||||
}
|
||||
|
||||
|
@ -241,17 +241,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a1, // JSFunction
|
||||
a3, // the new target
|
||||
a0, // actual number of arguments
|
||||
a2, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -4815,7 +4815,6 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
DCHECK_EQ(actual_parameter_count, a0);
|
||||
DCHECK_EQ(expected_parameter_count, a2);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If the expected parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
Branch(®ular_invoke, eq, expected_parameter_count,
|
||||
@ -4869,21 +4868,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
break_(0xCC);
|
||||
}
|
||||
#else
|
||||
// Check whether the expected and actual arguments count match. The registers
|
||||
// are set up according to contract with ArgumentsAdaptorTrampoline:
|
||||
|
||||
Branch(®ular_invoke, eq, expected_parameter_count,
|
||||
Operand(actual_parameter_count));
|
||||
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor);
|
||||
Branch(done);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
bind(®ular_invoke);
|
||||
}
|
||||
|
||||
|
@ -215,17 +215,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r4, // JSFunction
|
||||
r6, // the new target
|
||||
r3, // actual number of arguments
|
||||
r5, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -1391,7 +1391,6 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
DCHECK_EQ(actual_parameter_count, r3);
|
||||
DCHECK_EQ(expected_parameter_count, r5);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If the expected parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
mov(r0, Operand(kDontAdaptArgumentsSentinel));
|
||||
@ -1445,20 +1444,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
bkpt(0);
|
||||
}
|
||||
#else
|
||||
// Check whether the expected and actual arguments count match. If not,
|
||||
// setup registers according to contract with ArgumentsAdaptorTrampoline.
|
||||
cmp(expected_parameter_count, actual_parameter_count);
|
||||
beq(®ular_invoke);
|
||||
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor);
|
||||
b(done);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
bind(®ular_invoke);
|
||||
}
|
||||
|
||||
|
@ -215,17 +215,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r3, // JSFunction
|
||||
r5, // the new target
|
||||
r2, // actual number of arguments
|
||||
r4, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -1519,7 +1519,6 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
DCHECK_EQ(actual_parameter_count, r2);
|
||||
DCHECK_EQ(expected_parameter_count, r4);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If the expected parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
CmpS64(expected_parameter_count, Operand(kDontAdaptArgumentsSentinel));
|
||||
@ -1576,20 +1575,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
bkpt(0);
|
||||
}
|
||||
#else
|
||||
// Check whether the expected and actual arguments count match. If not,
|
||||
// setup registers according to contract with ArgumentsAdaptorTrampoline.
|
||||
CmpS64(expected_parameter_count, actual_parameter_count);
|
||||
beq(®ular_invoke);
|
||||
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor);
|
||||
b(done);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
bind(®ular_invoke);
|
||||
}
|
||||
|
||||
|
@ -222,17 +222,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rdi, // JSFunction
|
||||
rdx, // the new target
|
||||
rax, // actual number of arguments
|
||||
rbx, // expected number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
|
@ -2786,7 +2786,6 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
Label* done, InvokeFlag flag) {
|
||||
if (expected_parameter_count != actual_parameter_count) {
|
||||
Label regular_invoke;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If the expected parameter count is equal to the adaptor sentinel, no need
|
||||
// to push undefined value as arguments.
|
||||
cmpl(expected_parameter_count, Immediate(kDontAdaptArgumentsSentinel));
|
||||
@ -2844,22 +2843,6 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
|
||||
CallRuntime(Runtime::kThrowStackOverflow);
|
||||
int3(); // This should be unreachable.
|
||||
}
|
||||
#else
|
||||
// Both expected and actual are in (different) registers. This
|
||||
// is the case when we invoke functions using call and apply.
|
||||
cmpq(expected_parameter_count, actual_parameter_count);
|
||||
j(equal, ®ular_invoke, Label::kNear);
|
||||
DCHECK_EQ(actual_parameter_count, rax);
|
||||
DCHECK_EQ(expected_parameter_count, rbx);
|
||||
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor, RelocInfo::CODE_TARGET);
|
||||
jmp(done, Label::kNear);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
#endif
|
||||
|
||||
bind(®ular_invoke);
|
||||
} else {
|
||||
Move(rax, actual_parameter_count);
|
||||
|
@ -558,30 +558,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ ldr(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ cmp(scratch1,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ b(ne, &done);
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ ldr(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void FlushPendingPushRegisters(TurboAssembler* tasm,
|
||||
@ -788,11 +764,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
case kArchTailCallCodeObject: {
|
||||
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
@ -3935,7 +3906,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
}
|
||||
|
||||
Register argc_reg = r3;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -3943,9 +3913,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
|
@ -1747,8 +1747,6 @@ void InstructionSelector::EmitPrepareResults(
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
|
||||
|
||||
namespace {
|
||||
|
||||
// Shared routine for multiple compare operations.
|
||||
|
@ -560,30 +560,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ Ldr(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ Cmp(scratch1,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ B(ne, &done);
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ Ldr(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void AdjustStackPointerForTailCall(TurboAssembler* tasm,
|
||||
@ -722,11 +698,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
case kArchTailCallCodeObject: {
|
||||
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
@ -3172,7 +3143,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
}
|
||||
|
||||
Register argc_reg = x3;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -3180,9 +3150,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
|
@ -2142,8 +2142,6 @@ void InstructionSelector::EmitPrepareResults(
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
|
||||
|
||||
namespace {
|
||||
|
||||
// Shared routine for multiple compare operations.
|
||||
|
@ -298,10 +298,6 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
|
||||
// Generates code to manipulate the stack in preparation for a tail call.
|
||||
void AssemblePrepareTailCall();
|
||||
|
||||
// Generates code to pop current frame if it is an arguments adaptor frame.
|
||||
void AssemblePopArgumentsAdaptorFrame(Register args_reg, Register scratch1,
|
||||
Register scratch2, Register scratch3);
|
||||
|
||||
enum PushTypeFlag {
|
||||
kImmediatePush = 0x1,
|
||||
kRegisterPush = 0x2,
|
||||
|
@ -574,43 +574,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register, Register,
|
||||
Register) {
|
||||
// There are not enough temp registers left on ia32 for a call instruction
|
||||
// so we pick some scratch registers and save/restore them manually here.
|
||||
int scratch_count = 3;
|
||||
Register scratch1 = esi;
|
||||
Register scratch2 = ecx;
|
||||
Register scratch3 = edx;
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ cmp(Operand(ebp, StandardFrameConstants::kContextOffset),
|
||||
Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(not_equal, &done, Label::kNear);
|
||||
|
||||
__ push(scratch1);
|
||||
__ push(scratch2);
|
||||
__ push(scratch3);
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ mov(caller_args_count_reg,
|
||||
Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3,
|
||||
scratch_count);
|
||||
__ pop(scratch3);
|
||||
__ pop(scratch2);
|
||||
__ pop(scratch1);
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void AdjustStackPointerForTailCall(TurboAssembler* tasm,
|
||||
@ -796,10 +759,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
case kArchTailCallCodeObject: {
|
||||
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
no_reg, no_reg, no_reg);
|
||||
}
|
||||
if (HasImmediateInput(instr, 0)) {
|
||||
Handle<Code> code = i.InputCode(0);
|
||||
__ Jump(code, RelocInfo::CODE_TARGET);
|
||||
@ -4996,7 +4955,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
}
|
||||
|
||||
Register argc_reg = ecx;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -5004,9 +4962,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
|
@ -1429,8 +1429,6 @@ void InstructionSelector::EmitPrepareResults(
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return true; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 0; }
|
||||
|
||||
namespace {
|
||||
|
||||
void VisitCompareWithMemoryOperand(InstructionSelector* selector,
|
||||
|
@ -3049,10 +3049,6 @@ void InstructionSelector::VisitTailCall(Node* node) {
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
int temps_count = GetTempsCountForTailCallFromJSFunction();
|
||||
for (int i = 0; i < temps_count; i++) {
|
||||
temps.push_back(g.TempRegister());
|
||||
}
|
||||
} else {
|
||||
switch (call_descriptor->kind()) {
|
||||
case CallDescriptor::kCallCodeObject:
|
||||
|
@ -561,7 +561,6 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
|
||||
CallBufferFlags flags, bool is_tail_call,
|
||||
int stack_slot_delta = 0);
|
||||
bool IsTailCallAddressImmediate();
|
||||
int GetTempsCountForTailCallFromJSFunction();
|
||||
|
||||
void UpdateMaxPushedArgumentCount(size_t count);
|
||||
|
||||
|
@ -546,30 +546,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
}
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ lw(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ Branch(&done, ne, scratch1,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ lw(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void AdjustStackPointerForTailCall(TurboAssembler* tasm,
|
||||
@ -696,11 +672,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
case kArchTailCallCodeObject: {
|
||||
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
@ -4162,7 +4133,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
Operand(static_cast<int64_t>(0)));
|
||||
}
|
||||
}
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -4170,9 +4140,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
|
@ -1395,8 +1395,6 @@ void InstructionSelector::EmitPrepareResults(
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
|
||||
|
||||
void InstructionSelector::VisitUnalignedLoad(Node* node) {
|
||||
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
|
||||
MipsOperandGenerator g(this);
|
||||
|
@ -509,29 +509,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ Ld(scratch3, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ Branch(&done, ne, scratch3,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ Ld(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void AdjustStackPointerForTailCall(TurboAssembler* tasm,
|
||||
@ -646,11 +623,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
break;
|
||||
}
|
||||
case kArchCallWasmFunction: {
|
||||
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
Constant constant = i.ToConstant(instr->InputAt(0));
|
||||
Address wasm_code = static_cast<Address>(constant.ToInt64());
|
||||
@ -665,11 +637,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
case kArchTailCallCodeObject: {
|
||||
if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
@ -4418,7 +4385,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
Operand(static_cast<int64_t>(0)));
|
||||
}
|
||||
}
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -4426,9 +4393,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
|
@ -1839,8 +1839,6 @@ void InstructionSelector::EmitPrepareResults(
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
|
||||
|
||||
void InstructionSelector::VisitUnalignedLoad(Node* node) {
|
||||
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
|
||||
Mips64OperandGenerator g(this);
|
||||
|
@ -697,30 +697,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ LoadP(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ cmpi(scratch1,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ bne(&done);
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ LoadP(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void FlushPendingPushRegisters(TurboAssembler* tasm,
|
||||
@ -917,11 +893,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
case kArchTailCallCodeObject: {
|
||||
if (opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (HasRegisterInput(instr, 0)) {
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
@ -4170,7 +4141,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
}
|
||||
|
||||
Register argc_reg = r6;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -4178,9 +4148,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
|
@ -1876,8 +1876,6 @@ void InstructionSelector::EmitPrepareArguments(
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
|
||||
|
||||
void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
|
||||
PPCOperandGenerator g(this);
|
||||
Emit(kPPC_DoubleExtractLowWord32, g.DefineAsRegister(node),
|
||||
|
@ -1004,30 +1004,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ LoadU64(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ CmpS64(scratch1,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ bne(&done);
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ LoadU64(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void FlushPendingPushRegisters(TurboAssembler* tasm,
|
||||
@ -1237,11 +1213,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
case kArchTailCallCodeObject: {
|
||||
if (opcode == kArchTailCallCodeObjectFromJSFunction) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (HasRegisterInput(instr, 0)) {
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
@ -4649,7 +4620,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
}
|
||||
|
||||
Register argc_reg = r5;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -4657,9 +4627,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
|
@ -2138,8 +2138,6 @@ void InstructionSelector::VisitMemoryBarrier(Node* node) {
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
|
||||
|
||||
void InstructionSelector::VisitWord32AtomicLoad(Node* node) {
|
||||
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
|
||||
DCHECK(load_rep.representation() == MachineRepresentation::kWord8 ||
|
||||
|
@ -710,28 +710,6 @@ void CodeGenerator::AssemblePrepareTailCall() {
|
||||
frame_access_state()->SetFrameAccessToSP();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
|
||||
Register scratch1,
|
||||
Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Label done;
|
||||
|
||||
// Check if current frame is an arguments adaptor frame.
|
||||
__ cmpq(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset),
|
||||
Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(not_equal, &done, Label::kNear);
|
||||
|
||||
// Load arguments count from current arguments adaptor frame (note, it
|
||||
// does not include receiver).
|
||||
Register caller_args_count_reg = scratch1;
|
||||
__ SmiUntag(caller_args_count_reg,
|
||||
Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
|
||||
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void AdjustStackPointerForTailCall(Instruction* instr,
|
||||
@ -923,13 +901,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
frame_access_state()->ClearSPDelta();
|
||||
break;
|
||||
}
|
||||
// TODO(victorgomes): Remove kArchTailCallCodeObjectFromJSFunction.
|
||||
case kArchTailCallCodeObjectFromJSFunction:
|
||||
if (!instr->HasCallDescriptorFlag(CallDescriptor::kIsTailCallForTierUp)) {
|
||||
AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
|
||||
i.TempRegister(0), i.TempRegister(1),
|
||||
i.TempRegister(2));
|
||||
}
|
||||
V8_FALLTHROUGH;
|
||||
case kArchTailCallCodeObject: {
|
||||
if (HasImmediateInput(instr, 0)) {
|
||||
Handle<Code> code = i.InputCode(0);
|
||||
@ -4730,7 +4703,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
}
|
||||
|
||||
Register argc_reg = rcx;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// Functions with JS linkage have at least one parameter (the receiver).
|
||||
// If {parameter_count} == 0, it means it is a builtin with
|
||||
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
|
||||
@ -4738,9 +4710,6 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
|
||||
const bool drop_jsargs = frame_access_state()->has_frame() &&
|
||||
call_descriptor->IsJSFunctionCall() &&
|
||||
parameter_count != 0;
|
||||
#else
|
||||
const bool drop_jsargs = false;
|
||||
#endif
|
||||
if (call_descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
|
@ -1854,8 +1854,6 @@ void InstructionSelector::EmitPrepareResults(
|
||||
|
||||
bool InstructionSelector::IsTailCallAddressImmediate() { return true; }
|
||||
|
||||
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
|
||||
|
||||
namespace {
|
||||
|
||||
void VisitCompareWithMemoryOperand(InstructionSelector* selector,
|
||||
|
@ -3676,34 +3676,9 @@ Node* EffectControlLinearizer::LowerToBoolean(Node* node) {
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerArgumentsLength(Node* node) {
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
return ChangeIntPtrToSmi(
|
||||
__ Load(MachineType::Pointer(), __ LoadFramePointer(),
|
||||
__ IntPtrConstant(StandardFrameConstants::kArgCOffset)));
|
||||
#else
|
||||
auto done = __ MakeLabel(MachineRepresentation::kTaggedSigned);
|
||||
Node* frame = __ LoadFramePointer();
|
||||
|
||||
Node* arguments_frame = NodeProperties::GetValueInput(node, 0);
|
||||
int formal_parameter_count = FormalParameterCountOf(node->op());
|
||||
DCHECK_LE(0, formal_parameter_count);
|
||||
|
||||
// The ArgumentsLength node is computing the actual number of arguments.
|
||||
// We have to distinguish the case when there is an arguments adaptor frame
|
||||
// (i.e., arguments_frame != LoadFramePointer()).
|
||||
auto if_adaptor_frame = __ MakeLabel();
|
||||
__ GotoIf(__ TaggedEqual(arguments_frame, frame), &done,
|
||||
__ SmiConstant(formal_parameter_count));
|
||||
__ Goto(&if_adaptor_frame);
|
||||
|
||||
__ Bind(&if_adaptor_frame);
|
||||
Node* arguments_length = __ BitcastWordToTaggedSigned(__ Load(
|
||||
MachineType::Pointer(), arguments_frame,
|
||||
__ IntPtrConstant(ArgumentsAdaptorFrameConstants::kLengthOffset)));
|
||||
__ Goto(&done, arguments_length);
|
||||
__ Bind(&done);
|
||||
return done.PhiAt(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerRestLength(Node* node) {
|
||||
@ -3713,27 +3688,9 @@ Node* EffectControlLinearizer::LowerRestLength(Node* node) {
|
||||
auto done = __ MakeLabel(MachineRepresentation::kTaggedSigned);
|
||||
Node* frame = __ LoadFramePointer();
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Node* arguments_length = ChangeIntPtrToSmi(
|
||||
__ Load(MachineType::Pointer(), frame,
|
||||
__ IntPtrConstant(StandardFrameConstants::kArgCOffset)));
|
||||
#else
|
||||
Node* arguments_frame = NodeProperties::GetValueInput(node, 0);
|
||||
|
||||
// The RestLength node is computing the number of rest parameters,
|
||||
// which is max(0, actual_parameter_count - formal_parameter_count).
|
||||
// We have to distinguish the case, when there is an arguments adaptor frame
|
||||
// (i.e., arguments_frame != LoadFramePointer()).
|
||||
auto if_adaptor_frame = __ MakeLabel();
|
||||
__ GotoIf(__ TaggedEqual(arguments_frame, frame), &done, __ SmiConstant(0));
|
||||
__ Goto(&if_adaptor_frame);
|
||||
|
||||
__ Bind(&if_adaptor_frame);
|
||||
Node* arguments_length = __ BitcastWordToTaggedSigned(__ Load(
|
||||
MachineType::Pointer(), arguments_frame,
|
||||
__ IntPtrConstant(ArgumentsAdaptorFrameConstants::kLengthOffset)));
|
||||
#endif
|
||||
|
||||
Node* rest_length =
|
||||
__ SmiSub(arguments_length, __ SmiConstant(formal_parameter_count));
|
||||
__ GotoIf(__ SmiLessThan(rest_length, __ SmiConstant(0)), &done,
|
||||
@ -3745,24 +3702,7 @@ Node* EffectControlLinearizer::LowerRestLength(Node* node) {
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerArgumentsFrame(Node* node) {
|
||||
auto done = __ MakeLabel(MachineType::PointerRepresentation());
|
||||
|
||||
Node* frame = __ LoadFramePointer();
|
||||
Node* parent_frame =
|
||||
__ Load(MachineType::Pointer(), frame,
|
||||
__ IntPtrConstant(StandardFrameConstants::kCallerFPOffset));
|
||||
Node* parent_frame_type = __ Load(
|
||||
MachineType::IntPtr(), parent_frame,
|
||||
__ IntPtrConstant(CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
|
||||
__ GotoIf(__ IntPtrEqual(parent_frame_type,
|
||||
__ IntPtrConstant(StackFrame::TypeToMarker(
|
||||
StackFrame::ARGUMENTS_ADAPTOR))),
|
||||
&done, parent_frame);
|
||||
__ Goto(&done, frame);
|
||||
|
||||
__ Bind(&done);
|
||||
return done.PhiAt(0);
|
||||
return __ LoadFramePointer();
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerNewDoubleElements(Node* node) {
|
||||
|
@ -1569,15 +1569,6 @@ void ReduceBuiltin(JSGraph* jsgraph, Node* node, int builtin_index, int arity,
|
||||
|
||||
NodeProperties::ChangeOp(node, jsgraph->common()->Call(call_descriptor));
|
||||
}
|
||||
|
||||
#ifndef V8_NO_ARGUMENTS_ADAPTOR
|
||||
bool NeedsArgumentAdaptorFrame(SharedFunctionInfoRef shared, int arity) {
|
||||
static const int sentinel = kDontAdaptArgumentsSentinel;
|
||||
const int num_decl_parms = shared.internal_formal_parameter_count();
|
||||
return (num_decl_parms != arity && num_decl_parms != sentinel);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSConstructForwardVarargs(Node* node) {
|
||||
@ -1762,7 +1753,6 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
|
||||
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
|
||||
Node* new_target = jsgraph()->UndefinedConstant();
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
int formal_count = shared->internal_formal_parameter_count();
|
||||
if (formal_count != kDontAdaptArgumentsSentinel && formal_count > arity) {
|
||||
node->RemoveInput(n.FeedbackVectorIndex());
|
||||
@ -1781,22 +1771,6 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
|
||||
common()->Call(Linkage::GetJSCallDescriptor(
|
||||
graph()->zone(), false, 1 + formal_count,
|
||||
flags | CallDescriptor::kCanUseRoots)));
|
||||
#else
|
||||
if (NeedsArgumentAdaptorFrame(*shared, arity)) {
|
||||
node->RemoveInput(n.FeedbackVectorIndex());
|
||||
// Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline.
|
||||
Callable callable = CodeFactory::ArgumentAdaptor(isolate());
|
||||
node->InsertInput(graph()->zone(), 0,
|
||||
jsgraph()->HeapConstant(callable.code()));
|
||||
node->InsertInput(graph()->zone(), 2, new_target);
|
||||
node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
|
||||
node->InsertInput(
|
||||
graph()->zone(), 4,
|
||||
jsgraph()->Constant(shared->internal_formal_parameter_count()));
|
||||
NodeProperties::ChangeOp(
|
||||
node, common()->Call(Linkage::GetStubCallDescriptor(
|
||||
graph()->zone(), callable.descriptor(), 1 + arity, flags)));
|
||||
#endif
|
||||
} else if (shared->HasBuiltinId() &&
|
||||
Builtins::IsCpp(shared->builtin_id())) {
|
||||
// Patch {node} to a direct CEntry call.
|
||||
|
@ -6871,7 +6871,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
args.begin());
|
||||
break;
|
||||
}
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// =======================================================================
|
||||
// === JS Functions with mismatching arity ===============================
|
||||
// =======================================================================
|
||||
@ -6906,51 +6905,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
args.begin());
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// =======================================================================
|
||||
// === JS Functions with mismatching arity ===============================
|
||||
// =======================================================================
|
||||
case WasmImportCallKind::kJSFunctionArityMismatch: {
|
||||
base::SmallVector<Node*, 16> args(wasm_count + 9);
|
||||
int pos = 0;
|
||||
Node* function_context =
|
||||
gasm_->LoadContextFromJSFunction(callable_node);
|
||||
args[pos++] =
|
||||
GetBuiltinPointerTarget(Builtins::kArgumentsAdaptorTrampoline);
|
||||
args[pos++] = callable_node; // target callable
|
||||
args[pos++] = undefined_node; // new target
|
||||
args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
|
||||
|
||||
// Load shared function info, and then the formal parameter count.
|
||||
Node* shared_function_info =
|
||||
gasm_->LoadSharedFunctionInfo(callable_node);
|
||||
Node* formal_param_count =
|
||||
gasm_->Load(MachineType::Uint16(), shared_function_info,
|
||||
wasm::ObjectAccess::
|
||||
FormalParameterCountOffsetInSharedFunctionInfo());
|
||||
args[pos++] = formal_param_count;
|
||||
|
||||
// Determine receiver at runtime.
|
||||
args[pos++] =
|
||||
BuildReceiverNode(callable_node, native_context, undefined_node);
|
||||
|
||||
auto call_descriptor = Linkage::GetStubCallDescriptor(
|
||||
mcgraph()->zone(), ArgumentsAdaptorDescriptor{}, 1 + wasm_count,
|
||||
CallDescriptor::kNoFlags, Operator::kNoProperties,
|
||||
StubCallMode::kCallBuiltinPointer);
|
||||
|
||||
// Convert wasm numbers to JS values.
|
||||
pos = AddArgumentNodes(VectorOf(args), pos, wasm_count, sig_);
|
||||
args[pos++] = function_context;
|
||||
args[pos++] = effect();
|
||||
args[pos++] = control();
|
||||
|
||||
DCHECK_EQ(pos, args.size());
|
||||
call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor), pos,
|
||||
args.begin());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// =======================================================================
|
||||
// === General case of unknown callable ==================================
|
||||
// =======================================================================
|
||||
|
@ -33,7 +33,6 @@ FrameInspector::FrameInspector(CommonFrame* frame, int inlined_frame_index,
|
||||
JavaScriptFrame* js_frame =
|
||||
frame->is_java_script() ? javascript_frame() : nullptr;
|
||||
DCHECK(js_frame || frame->is_wasm());
|
||||
has_adapted_arguments_ = js_frame && js_frame->has_adapted_arguments();
|
||||
is_optimized_ = frame_->is_optimized();
|
||||
is_interpreted_ = frame_->is_interpreted();
|
||||
|
||||
@ -50,8 +49,7 @@ FrameInspector::FrameInspector(CommonFrame* frame, int inlined_frame_index,
|
||||
FrameInspector::~FrameInspector() = default;
|
||||
|
||||
JavaScriptFrame* FrameInspector::javascript_frame() {
|
||||
return frame_->is_arguments_adaptor() ? ArgumentsAdaptorFrame::cast(frame_)
|
||||
: JavaScriptFrame::cast(frame_);
|
||||
return JavaScriptFrame::cast(frame_);
|
||||
}
|
||||
|
||||
Handle<Object> FrameInspector::GetParameter(int index) {
|
||||
|
@ -60,7 +60,6 @@ class FrameInspector {
|
||||
int source_position_ = -1;
|
||||
bool is_optimized_ = false;
|
||||
bool is_interpreted_ = false;
|
||||
bool has_adapted_arguments_ = false;
|
||||
bool is_constructor_ = false;
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,6 @@ void Builtins_ContinueToCodeStubBuiltinWithResult();
|
||||
void Builtins_ContinueToCodeStubBuiltin();
|
||||
void Builtins_ContinueToJavaScriptBuiltinWithResult();
|
||||
void Builtins_ContinueToJavaScriptBuiltin();
|
||||
void arguments_adaptor_deopt_addr();
|
||||
void construct_stub_create_deopt_addr();
|
||||
void construct_stub_invoke_deopt_addr();
|
||||
typedef void (*function_ptr)();
|
||||
@ -31,7 +30,6 @@ constexpr function_ptr builtins[] = {
|
||||
&Builtins_ContinueToJavaScriptBuiltin,
|
||||
&construct_stub_create_deopt_addr,
|
||||
&construct_stub_invoke_deopt_addr,
|
||||
&arguments_adaptor_deopt_addr,
|
||||
};
|
||||
|
||||
bool Deoptimizer::IsValidReturnAddress(Address address) {
|
||||
|
@ -998,7 +998,6 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
|
||||
|
||||
const int parameters_count = InternalFormalParameterCountWithReceiver(shared);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// If this is the bottom most frame or the previous frame was the arguments
|
||||
// adaptor fake frame, then we already have extra arguments in the stack
|
||||
// (including any extra padding). Therefore we should not try to add any
|
||||
@ -1006,9 +1005,6 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
|
||||
bool should_pad_arguments =
|
||||
!is_bottommost && (translated_state_.frames()[frame_index - 1]).kind() !=
|
||||
TranslatedFrame::kArgumentsAdaptor;
|
||||
#else
|
||||
bool should_pad_arguments = true;
|
||||
#endif
|
||||
|
||||
const int locals_count = translated_frame->height();
|
||||
InterpretedFrameInfo frame_info = InterpretedFrameInfo::Precise(
|
||||
@ -1286,12 +1282,12 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(
|
||||
CHECK_GT(frame_index, 0);
|
||||
CHECK_NULL(output_[frame_index]);
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// During execution, V8 does not understand arguments adaptor frames anymore,
|
||||
// so during deoptimization we only push the extra arguments (arguments with
|
||||
// index greater than the formal parameter count). Therefore we call this
|
||||
// TranslatedFrame the fake adaptor frame. For more info, see the design
|
||||
// document shorturl.at/fKT49.
|
||||
// TranslatedFrame the fake adaptor frame.
|
||||
// For more info, see the design document:
|
||||
// https://docs.google.com/document/d/150wGaUREaZI6YWqOQFD5l2mWQXaPbbZjcAIJLOFrzMs
|
||||
|
||||
TranslatedFrame::iterator value_iterator = translated_frame->begin();
|
||||
const int argument_count_without_receiver = translated_frame->height() - 1;
|
||||
@ -1342,104 +1338,6 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(
|
||||
for (int i = 0; i < formal_parameter_count; i++) value_iterator++;
|
||||
frame_writer.PushStackJSArguments(value_iterator, extra_argument_count);
|
||||
}
|
||||
#else
|
||||
TranslatedFrame::iterator value_iterator = translated_frame->begin();
|
||||
const bool is_bottommost = (0 == frame_index);
|
||||
|
||||
const int parameters_count = translated_frame->height();
|
||||
ArgumentsAdaptorFrameInfo frame_info =
|
||||
ArgumentsAdaptorFrameInfo::Precise(parameters_count);
|
||||
const uint32_t output_frame_size = frame_info.frame_size_in_bytes();
|
||||
|
||||
TranslatedFrame::iterator function_iterator = value_iterator++;
|
||||
if (verbose_tracing_enabled()) {
|
||||
PrintF(trace_scope()->file(),
|
||||
" translating arguments adaptor => variable_frame_size=%d, "
|
||||
"frame_size=%d\n",
|
||||
frame_info.frame_size_in_bytes_without_fixed(), output_frame_size);
|
||||
}
|
||||
|
||||
// Allocate and store the output frame description.
|
||||
FrameDescription* output_frame = new (output_frame_size)
|
||||
FrameDescription(output_frame_size, parameters_count);
|
||||
FrameWriter frame_writer(this, output_frame, verbose_trace_scope());
|
||||
|
||||
// Arguments adaptor can not be topmost.
|
||||
CHECK(frame_index < output_count_ - 1);
|
||||
CHECK_NULL(output_[frame_index]);
|
||||
output_[frame_index] = output_frame;
|
||||
|
||||
// The top address of the frame is computed from the previous frame's top and
|
||||
// this frame's size.
|
||||
const intptr_t top_address =
|
||||
is_bottommost ? caller_frame_top_ - output_frame_size
|
||||
: output_[frame_index - 1]->GetTop() - output_frame_size;
|
||||
output_frame->SetTop(top_address);
|
||||
|
||||
ReadOnlyRoots roots(isolate());
|
||||
if (ShouldPadArguments(parameters_count)) {
|
||||
frame_writer.PushRawObject(roots.the_hole_value(), "padding\n");
|
||||
}
|
||||
|
||||
// Compute the incoming parameter translation.
|
||||
frame_writer.PushStackJSArguments(value_iterator, parameters_count);
|
||||
|
||||
DCHECK_EQ(output_frame->GetLastArgumentSlotOffset(),
|
||||
frame_writer.top_offset());
|
||||
|
||||
// Read caller's PC from the previous frame.
|
||||
if (is_bottommost) {
|
||||
frame_writer.PushBottommostCallerPc(caller_pc_);
|
||||
} else {
|
||||
frame_writer.PushApprovedCallerPc(output_[frame_index - 1]->GetPc());
|
||||
}
|
||||
|
||||
// Read caller's FP from the previous frame, and set this frame's FP.
|
||||
const intptr_t caller_fp =
|
||||
is_bottommost ? caller_fp_ : output_[frame_index - 1]->GetFp();
|
||||
frame_writer.PushCallerFp(caller_fp);
|
||||
|
||||
intptr_t fp_value = top_address + frame_writer.top_offset();
|
||||
output_frame->SetFp(fp_value);
|
||||
|
||||
if (FLAG_enable_embedded_constant_pool) {
|
||||
// Read the caller's constant pool from the previous frame.
|
||||
const intptr_t caller_cp =
|
||||
is_bottommost ? caller_constant_pool_
|
||||
: output_[frame_index - 1]->GetConstantPool();
|
||||
frame_writer.PushCallerConstantPool(caller_cp);
|
||||
}
|
||||
|
||||
// A marker value is used in place of the context.
|
||||
intptr_t marker = StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR);
|
||||
frame_writer.PushRawValue(marker, "context (adaptor sentinel)\n");
|
||||
|
||||
// The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
|
||||
frame_writer.PushTranslatedValue(function_iterator, "function\n");
|
||||
|
||||
// Number of incoming arguments.
|
||||
const uint32_t parameters_count_without_receiver = parameters_count - 1;
|
||||
frame_writer.PushRawObject(Smi::FromInt(parameters_count_without_receiver),
|
||||
"argc\n");
|
||||
|
||||
frame_writer.PushRawObject(roots.the_hole_value(), "padding\n");
|
||||
|
||||
CHECK_EQ(translated_frame->end(), value_iterator);
|
||||
DCHECK_EQ(0, frame_writer.top_offset());
|
||||
|
||||
Builtins* builtins = isolate_->builtins();
|
||||
Code adaptor_trampoline =
|
||||
builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
|
||||
intptr_t pc_value = static_cast<intptr_t>(
|
||||
adaptor_trampoline.InstructionStart() +
|
||||
isolate_->heap()->arguments_adaptor_deopt_pc_offset().value());
|
||||
output_frame->SetPc(pc_value);
|
||||
if (FLAG_enable_embedded_constant_pool) {
|
||||
intptr_t constant_pool_value =
|
||||
static_cast<intptr_t>(adaptor_trampoline.constant_pool());
|
||||
output_frame->SetConstantPool(constant_pool_value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
|
||||
@ -2068,9 +1966,6 @@ unsigned Deoptimizer::ComputeInputFrameSize() const {
|
||||
// static
|
||||
unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo shared) {
|
||||
int parameter_slots = InternalFormalParameterCountWithReceiver(shared);
|
||||
#ifndef V8_NO_ARGUMENTS_ADAPTOR
|
||||
if (ShouldPadArguments(parameter_slots)) parameter_slots++;
|
||||
#endif
|
||||
return parameter_slots * kSystemPointerSize;
|
||||
}
|
||||
|
||||
@ -3087,30 +2982,6 @@ void TranslatedFrame::AdvanceIterator(
|
||||
}
|
||||
}
|
||||
|
||||
Address TranslatedState::ComputeArgumentsPosition(Address input_frame_pointer,
|
||||
int* length) {
|
||||
Address parent_frame_pointer = *reinterpret_cast<Address*>(
|
||||
input_frame_pointer + StandardFrameConstants::kCallerFPOffset);
|
||||
intptr_t parent_frame_type = Memory<intptr_t>(
|
||||
parent_frame_pointer + CommonFrameConstants::kContextOrFrameTypeOffset);
|
||||
|
||||
Address arguments_frame;
|
||||
if (parent_frame_type ==
|
||||
StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)) {
|
||||
if (length)
|
||||
*length = Smi::cast(*FullObjectSlot(
|
||||
parent_frame_pointer +
|
||||
ArgumentsAdaptorFrameConstants::kLengthOffset))
|
||||
.value();
|
||||
arguments_frame = parent_frame_pointer;
|
||||
} else {
|
||||
if (length) *length = formal_parameter_count_;
|
||||
arguments_frame = input_frame_pointer;
|
||||
}
|
||||
|
||||
return arguments_frame;
|
||||
}
|
||||
|
||||
// Creates translated values for an arguments backing store, or the backing
|
||||
// store for rest parameters depending on the given {type}. The TranslatedValue
|
||||
// objects for the fields are not read from the TranslationIterator, but instead
|
||||
@ -3119,19 +2990,10 @@ void TranslatedState::CreateArgumentsElementsTranslatedValues(
|
||||
int frame_index, Address input_frame_pointer, CreateArgumentsType type,
|
||||
FILE* trace_file) {
|
||||
TranslatedFrame& frame = frames_[frame_index];
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
int arguments_length = actual_argument_count_;
|
||||
#else
|
||||
int arguments_length;
|
||||
Address arguments_frame =
|
||||
ComputeArgumentsPosition(input_frame_pointer, &arguments_length);
|
||||
#endif
|
||||
|
||||
int length = type == CreateArgumentsType::kRestParameter
|
||||
? std::max(0, arguments_length - formal_parameter_count_)
|
||||
: arguments_length;
|
||||
|
||||
int length =
|
||||
type == CreateArgumentsType::kRestParameter
|
||||
? std::max(0, actual_argument_count_ - formal_parameter_count_)
|
||||
: actual_argument_count_;
|
||||
int object_index = static_cast<int>(object_positions_.size());
|
||||
int value_index = static_cast<int>(frame.values_.size());
|
||||
if (trace_file != nullptr) {
|
||||
@ -3164,11 +3026,9 @@ void TranslatedState::CreateArgumentsElementsTranslatedValues(
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// Skip the receiver.
|
||||
int offset = i + start_index + 1;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
Address arguments_frame = offset > formal_parameter_count_
|
||||
? stack_frame_pointer_
|
||||
: input_frame_pointer;
|
||||
#endif
|
||||
Address argument_slot = arguments_frame +
|
||||
CommonFrameConstants::kFixedFrameSizeAboveFp +
|
||||
offset * kSystemPointerSize;
|
||||
@ -3229,17 +3089,11 @@ int TranslatedState::CreateNextTranslatedValue(
|
||||
}
|
||||
|
||||
case Translation::ARGUMENTS_LENGTH: {
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
int arguments_length = actual_argument_count_;
|
||||
#else
|
||||
int arguments_length;
|
||||
ComputeArgumentsPosition(fp, &arguments_length);
|
||||
#endif
|
||||
if (trace_file != nullptr) {
|
||||
PrintF(trace_file, "arguments length field (length = %d)",
|
||||
arguments_length);
|
||||
actual_argument_count_);
|
||||
}
|
||||
frame.Add(TranslatedValue::NewInt32(this, arguments_length));
|
||||
frame.Add(TranslatedValue::NewInt32(this, actual_argument_count_));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3519,11 +3373,7 @@ TranslatedState::TranslatedState(const JavaScriptFrame* frame) {
|
||||
DCHECK(!data.is_null() && deopt_index != Safepoint::kNoDeoptimizationIndex);
|
||||
TranslationIterator it(data.TranslationByteArray(),
|
||||
data.TranslationIndex(deopt_index).value());
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
int actual_argc = frame->GetActualArgumentCount();
|
||||
#else
|
||||
int actual_argc = 0;
|
||||
#endif
|
||||
Init(frame->isolate(), frame->fp(), frame->fp(), &it, data.LiteralArray(),
|
||||
nullptr /* registers */, nullptr /* trace file */,
|
||||
frame->function().shared().internal_formal_parameter_count(),
|
||||
|
@ -360,7 +360,6 @@ class TranslatedState {
|
||||
FixedArray literal_array, Address fp,
|
||||
RegisterValues* registers, FILE* trace_file);
|
||||
Address DecompressIfNeeded(intptr_t value);
|
||||
Address ComputeArgumentsPosition(Address input_frame_pointer, int* length);
|
||||
void CreateArgumentsElementsTranslatedValues(int frame_index,
|
||||
Address input_frame_pointer,
|
||||
CreateArgumentsType type,
|
||||
@ -732,14 +731,10 @@ class FrameDescription {
|
||||
}
|
||||
|
||||
Address GetFramePointerAddress() {
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
// We should not pad arguments in the bottom frame, since this
|
||||
// already contain a padding if necessary and it might contain
|
||||
// extra arguments (actual argument count > parameter count).
|
||||
const bool pad_arguments_bottom_frame = false;
|
||||
#else
|
||||
const bool pad_arguments_bottom_frame = true;
|
||||
#endif
|
||||
int fp_offset = GetLastArgumentSlotOffset(pad_arguments_bottom_frame) -
|
||||
StandardFrameConstants::kCallerSPOffset;
|
||||
return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset));
|
||||
|
@ -196,15 +196,6 @@ class TypedFrameConstants : public CommonFrameConstants {
|
||||
#define DEFINE_TYPED_FRAME_SIZES(count) \
|
||||
DEFINE_FRAME_SIZES(TypedFrameConstants, count)
|
||||
|
||||
class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
|
||||
public:
|
||||
// FP-relative.
|
||||
static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
|
||||
static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
|
||||
static constexpr int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
|
||||
DEFINE_TYPED_FRAME_SIZES(3);
|
||||
};
|
||||
|
||||
class BuiltinFrameConstants : public TypedFrameConstants {
|
||||
public:
|
||||
// FP-relative.
|
||||
|
@ -178,12 +178,6 @@ inline Address CommonFrame::ComputeConstantPoolAddress(Address fp) {
|
||||
return fp + StandardFrameConstants::kConstantPoolOffset;
|
||||
}
|
||||
|
||||
inline bool CommonFrame::IsArgumentsAdaptorFrame(Address fp) {
|
||||
intptr_t frame_type =
|
||||
base::Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
|
||||
return frame_type == StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR);
|
||||
}
|
||||
|
||||
inline bool CommonFrameWithJSLinkage::IsConstructFrame(Address fp) {
|
||||
intptr_t frame_type =
|
||||
base::Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
|
||||
@ -195,31 +189,20 @@ inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
|
||||
|
||||
Address CommonFrameWithJSLinkage::GetParameterSlot(int index) const {
|
||||
DCHECK_LE(-1, index);
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
DCHECK_LT(index,
|
||||
std::max(GetActualArgumentCount(), ComputeParametersCount()));
|
||||
#else
|
||||
DCHECK(index < ComputeParametersCount() ||
|
||||
ComputeParametersCount() == kDontAdaptArgumentsSentinel);
|
||||
#endif
|
||||
int parameter_offset = (index + 1) * kSystemPointerSize;
|
||||
return caller_sp() + parameter_offset;
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
inline int CommonFrameWithJSLinkage::GetActualArgumentCount() const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void JavaScriptFrame::set_receiver(Object value) {
|
||||
base::Memory<Address>(GetParameterSlot(-1)) = value.ptr();
|
||||
}
|
||||
|
||||
inline bool JavaScriptFrame::has_adapted_arguments() const {
|
||||
return IsArgumentsAdaptorFrame(caller_fp());
|
||||
}
|
||||
|
||||
inline Object JavaScriptFrame::function_slot_object() const {
|
||||
const int offset = StandardFrameConstants::kFunctionOffset;
|
||||
return Object(base::Memory<Address>(fp() + offset));
|
||||
@ -235,11 +218,6 @@ inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
|
||||
inline InterpretedFrame::InterpretedFrame(StackFrameIteratorBase* iterator)
|
||||
: JavaScriptFrame(iterator) {}
|
||||
|
||||
|
||||
inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
|
||||
StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) {
|
||||
}
|
||||
|
||||
inline BuiltinFrame::BuiltinFrame(StackFrameIteratorBase* iterator)
|
||||
: TypedFrameWithJSLinkage(iterator) {}
|
||||
|
||||
@ -299,19 +277,13 @@ inline JavaScriptFrameIterator::JavaScriptFrameIterator(
|
||||
}
|
||||
|
||||
inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
|
||||
// TODO(1233797): The frame hierarchy needs to change. It's
|
||||
// problematic that we can't use the safe-cast operator to cast to
|
||||
// the JavaScript frame type, because we may encounter arguments
|
||||
// adaptor frames.
|
||||
StackFrame* frame = iterator_.frame();
|
||||
DCHECK(frame->is_java_script() || frame->is_arguments_adaptor());
|
||||
return static_cast<JavaScriptFrame*>(frame);
|
||||
return JavaScriptFrame::cast(frame);
|
||||
}
|
||||
|
||||
inline CommonFrame* StackTraceFrameIterator::frame() const {
|
||||
StackFrame* frame = iterator_.frame();
|
||||
DCHECK(frame->is_java_script() || frame->is_arguments_adaptor() ||
|
||||
frame->is_wasm());
|
||||
DCHECK(frame->is_java_script() || frame->is_wasm());
|
||||
return static_cast<CommonFrame*>(frame);
|
||||
}
|
||||
|
||||
|
@ -434,15 +434,6 @@ bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
|
||||
Address caller_fp =
|
||||
Memory<Address>(frame->fp() + EntryFrameConstants::kCallerFPOffset);
|
||||
if (!IsValidExitFrame(caller_fp)) return false;
|
||||
} else if (frame->is_arguments_adaptor()) {
|
||||
// See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
|
||||
// the number of arguments is stored on stack as Smi. We need to check
|
||||
// that it really an Smi.
|
||||
Object number_of_args =
|
||||
reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->GetExpression(0);
|
||||
if (!number_of_args.IsSmi()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
frame->ComputeCallerState(&state);
|
||||
return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
|
||||
@ -636,7 +627,6 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
|
||||
case STUB:
|
||||
case INTERNAL:
|
||||
case CONSTRUCT:
|
||||
case ARGUMENTS_ADAPTOR:
|
||||
case WASM_TO_JS:
|
||||
case WASM:
|
||||
case WASM_COMPILE_LAZY:
|
||||
@ -957,7 +947,6 @@ void CommonFrame::IterateCompiledFrame(RootVisitor* v) const {
|
||||
case JAVA_SCRIPT_BUILTIN_CONTINUATION:
|
||||
case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
|
||||
case BUILTIN_EXIT:
|
||||
case ARGUMENTS_ADAPTOR:
|
||||
case STUB:
|
||||
case INTERNAL:
|
||||
case CONSTRUCT:
|
||||
@ -1086,12 +1075,7 @@ void JavaScriptFrame::SetParameterValue(int index, Object value) const {
|
||||
}
|
||||
|
||||
bool JavaScriptFrame::IsConstructor() const {
|
||||
Address fp = caller_fp();
|
||||
if (has_adapted_arguments()) {
|
||||
// Skip the arguments adaptor frame and look at the real caller.
|
||||
fp = Memory<Address>(fp + StandardFrameConstants::kCallerFPOffset);
|
||||
}
|
||||
return IsConstructFrame(fp);
|
||||
return IsConstructFrame(caller_fp());
|
||||
}
|
||||
|
||||
bool JavaScriptFrame::HasInlinedFrames() const {
|
||||
@ -1283,12 +1267,10 @@ int CommonFrameWithJSLinkage::ComputeParametersCount() const {
|
||||
return function().shared().internal_formal_parameter_count();
|
||||
}
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
int JavaScriptFrame::GetActualArgumentCount() const {
|
||||
return static_cast<int>(
|
||||
Memory<intptr_t>(fp() + StandardFrameConstants::kArgCOffset));
|
||||
}
|
||||
#endif
|
||||
|
||||
Handle<FixedArray> CommonFrameWithJSLinkage::GetParameters() const {
|
||||
if (V8_LIKELY(!FLAG_detailed_error_stack_trace)) {
|
||||
@ -1786,15 +1768,6 @@ void InterpretedFrame::Summarize(std::vector<FrameSummary>* functions) const {
|
||||
functions->push_back(summary);
|
||||
}
|
||||
|
||||
int ArgumentsAdaptorFrame::ComputeParametersCount() const {
|
||||
const int offset = ArgumentsAdaptorFrameConstants::kLengthOffset;
|
||||
return Smi::ToInt(Object(base::Memory<Address>(fp() + offset)));
|
||||
}
|
||||
|
||||
Code ArgumentsAdaptorFrame::unchecked_code() const {
|
||||
return isolate()->builtins()->builtin(Builtins::kArgumentsAdaptorTrampoline);
|
||||
}
|
||||
|
||||
JSFunction BuiltinFrame::function() const {
|
||||
const int offset = BuiltinFrameConstants::kFunctionOffset;
|
||||
return JSFunction::cast(Object(base::Memory<Address>(fp() + offset)));
|
||||
@ -2116,34 +2089,6 @@ void JavaScriptFrame::Print(StringStream* accumulator, PrintMode mode,
|
||||
accumulator->Add("}\n\n");
|
||||
}
|
||||
|
||||
void ArgumentsAdaptorFrame::Print(StringStream* accumulator, PrintMode mode,
|
||||
int index) const {
|
||||
int actual = ComputeParametersCount();
|
||||
int expected = -1;
|
||||
JSFunction function = this->function();
|
||||
expected = function.shared().internal_formal_parameter_count();
|
||||
|
||||
PrintIndex(accumulator, mode, index);
|
||||
accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
|
||||
if (mode == OVERVIEW) {
|
||||
accumulator->Add("\n");
|
||||
return;
|
||||
}
|
||||
accumulator->Add(" {\n");
|
||||
|
||||
// Print actual arguments.
|
||||
if (actual > 0) accumulator->Add(" // actual arguments\n");
|
||||
for (int i = 0; i < actual; i++) {
|
||||
accumulator->Add(" [%02d] : %o", i, GetParameter(i));
|
||||
if (expected != -1 && i >= expected) {
|
||||
accumulator->Add(" // not passed to callee");
|
||||
}
|
||||
accumulator->Add("\n");
|
||||
}
|
||||
|
||||
accumulator->Add("}\n\n");
|
||||
}
|
||||
|
||||
void EntryFrame::Iterate(RootVisitor* v) const {
|
||||
IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
|
||||
}
|
||||
@ -2287,8 +2232,7 @@ ArgumentsAdaptorFrameInfo::ArgumentsAdaptorFrameInfo(int translation_height) {
|
||||
frame_size_in_bytes_without_fixed_ =
|
||||
(parameters_count + ArgumentPaddingSlots(parameters_count)) *
|
||||
kSystemPointerSize;
|
||||
frame_size_in_bytes_ = frame_size_in_bytes_without_fixed_ +
|
||||
ArgumentsAdaptorFrameConstants::kFixedFrameSize;
|
||||
frame_size_in_bytes_ = frame_size_in_bytes_without_fixed_;
|
||||
}
|
||||
|
||||
ConstructStubFrameInfo::ConstructStubFrameInfo(int translation_height,
|
||||
|
@ -18,7 +18,6 @@
|
||||
// - JavaScriptFrame (aka StandardFrame)
|
||||
// - InterpretedFrame
|
||||
// - OptimizedFrame
|
||||
// - ArgumentsAdaptorFrame (technically a TypedFrame)
|
||||
// - TypedFrameWithJSLinkage
|
||||
// - BuiltinFrame
|
||||
// - JavaScriptBuiltinContinuationFrame
|
||||
@ -110,7 +109,6 @@ class StackHandler {
|
||||
JavaScriptBuiltinContinuationWithCatchFrame) \
|
||||
V(INTERNAL, InternalFrame) \
|
||||
V(CONSTRUCT, ConstructFrame) \
|
||||
V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) \
|
||||
V(BUILTIN, BuiltinFrame) \
|
||||
V(BUILTIN_EXIT, BuiltinExitFrame) \
|
||||
V(NATIVE, NativeFrame)
|
||||
@ -212,7 +210,6 @@ class StackFrame {
|
||||
bool is_wasm() const { return this->type() == WASM; }
|
||||
bool is_wasm_compile_lazy() const { return type() == WASM_COMPILE_LAZY; }
|
||||
bool is_wasm_debug_break() const { return type() == WASM_DEBUG_BREAK; }
|
||||
bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
|
||||
bool is_builtin() const { return type() == BUILTIN; }
|
||||
bool is_internal() const { return type() == INTERNAL; }
|
||||
bool is_builtin_continuation() const {
|
||||
@ -509,10 +506,6 @@ class CommonFrame : public StackFrame {
|
||||
// Returns the address of the n'th expression stack element.
|
||||
virtual Address GetExpressionAddress(int n) const;
|
||||
|
||||
// Determines if the standard frame for the given frame pointer is
|
||||
// an arguments adaptor frame.
|
||||
static inline bool IsArgumentsAdaptorFrame(Address fp);
|
||||
|
||||
// Used by OptimizedFrames and StubFrames.
|
||||
void IterateCompiledFrame(RootVisitor* v) const;
|
||||
|
||||
@ -540,9 +533,7 @@ class CommonFrameWithJSLinkage : public CommonFrame {
|
||||
virtual Object GetParameter(int index) const;
|
||||
virtual int ComputeParametersCount() const;
|
||||
Handle<FixedArray> GetParameters() const;
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
virtual int GetActualArgumentCount() const;
|
||||
#endif
|
||||
|
||||
// Determine the code for the frame.
|
||||
Code unchecked_code() const override;
|
||||
@ -586,10 +577,7 @@ class JavaScriptFrame : public CommonFrameWithJSLinkage {
|
||||
Object unchecked_function() const;
|
||||
Script script() const;
|
||||
Object context() const override;
|
||||
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
int GetActualArgumentCount() const override;
|
||||
#endif
|
||||
|
||||
inline void set_receiver(Object value);
|
||||
|
||||
@ -603,11 +591,6 @@ class JavaScriptFrame : public CommonFrameWithJSLinkage {
|
||||
// about the inlined frames use {GetFunctions} and {Summarize}.
|
||||
bool HasInlinedFrames() const;
|
||||
|
||||
// Check if this frame has "adapted" arguments in the sense that the
|
||||
// actual passed arguments are available in an arguments adaptor
|
||||
// frame below it on the stack.
|
||||
inline bool has_adapted_arguments() const;
|
||||
|
||||
// Garbage collection support.
|
||||
void Iterate(RootVisitor* v) const override;
|
||||
|
||||
@ -882,38 +865,6 @@ class InterpretedFrame : public JavaScriptFrame {
|
||||
friend class StackFrameIteratorBase;
|
||||
};
|
||||
|
||||
// Arguments adaptor frames are automatically inserted below
|
||||
// JavaScript frames when the actual number of parameters does not
|
||||
// match the formal number of parameters.
|
||||
// NOTE: this inheritance is wrong, an ArgumentsAdaptorFrame should be
|
||||
// of type TypedFrame, but due to FrameInspector::javascript_frame(),
|
||||
// it needs to be seen as JavaScriptFrame.
|
||||
// This frame will however be deleted soon.
|
||||
class ArgumentsAdaptorFrame : public JavaScriptFrame {
|
||||
public:
|
||||
Type type() const override { return ARGUMENTS_ADAPTOR; }
|
||||
|
||||
// Determine the code for the frame.
|
||||
Code unchecked_code() const override;
|
||||
|
||||
static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
|
||||
DCHECK(frame->is_arguments_adaptor());
|
||||
return static_cast<ArgumentsAdaptorFrame*>(frame);
|
||||
}
|
||||
|
||||
int ComputeParametersCount() const override;
|
||||
|
||||
// Printing support.
|
||||
void Print(StringStream* accumulator, PrintMode mode,
|
||||
int index) const override;
|
||||
|
||||
protected:
|
||||
inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
|
||||
|
||||
private:
|
||||
friend class StackFrameIteratorBase;
|
||||
};
|
||||
|
||||
// Builtin frames are built for builtins with JavaScript linkage, such as
|
||||
// various standard library functions (i.e. Math.asin, Math.floor, etc.).
|
||||
class BuiltinFrame final : public TypedFrameWithJSLinkage {
|
||||
@ -1367,6 +1318,8 @@ class InterpretedFrameInfo {
|
||||
uint32_t frame_size_in_bytes_;
|
||||
};
|
||||
|
||||
// TODO(v8:11312): Now that we don't have arguments adaptor frames anymore, we
|
||||
// might be able to remove this class.
|
||||
class ArgumentsAdaptorFrameInfo {
|
||||
public:
|
||||
static ArgumentsAdaptorFrameInfo Precise(int translation_height) {
|
||||
|
@ -4257,8 +4257,7 @@ void Isolate::PrepareBuiltinLabelInfoMap() {
|
||||
if (embedded_file_writer_ != nullptr) {
|
||||
embedded_file_writer_->PrepareBuiltinLabelInfoMap(
|
||||
heap()->construct_stub_create_deopt_pc_offset().value(),
|
||||
heap()->construct_stub_invoke_deopt_pc_offset().value(),
|
||||
heap()->arguments_adaptor_deopt_pc_offset().value());
|
||||
heap()->construct_stub_invoke_deopt_pc_offset().value());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -380,17 +380,7 @@ std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate,
|
||||
|
||||
return param_data;
|
||||
} else {
|
||||
#ifdef V8_NO_ARGUMENTS_ADAPTOR
|
||||
int args_count = frame->GetActualArgumentCount();
|
||||
#else
|
||||
if (it.frame()->has_adapted_arguments()) {
|
||||
it.AdvanceOneFrame();
|
||||
DCHECK(it.frame()->is_arguments_adaptor());
|
||||
}
|
||||
frame = it.frame();
|
||||
int args_count = frame->ComputeParametersCount();
|
||||
#endif
|
||||
|
||||
*total_argc = args_count;
|
||||
std::unique_ptr<Handle<Object>[]> param_data(
|
||||
NewArray<Handle<Object>>(*total_argc));
|
||||
|
@ -78,10 +78,9 @@ void EmbeddedFileWriter::WriteBuiltin(PlatformEmbeddedFileWriterBase* w,
|
||||
CHECK(positions.done()); // Release builds must not contain debug infos.
|
||||
#endif
|
||||
|
||||
// Some builtins (ArgumentsAdaptorTrampoline and JSConstructStubGeneric) have
|
||||
// entry points located in the middle of them, we need to store their
|
||||
// addresses since they are part of the list of allowed return addresses in
|
||||
// the deoptimizer.
|
||||
// Some builtins (JSConstructStubGeneric) have entry points located in the
|
||||
// middle of them, we need to store their addresses since they are part of
|
||||
// the list of allowed return addresses in the deoptimizer.
|
||||
const std::vector<LabelInfo>& current_labels = label_info_[builtin_id];
|
||||
auto label = current_labels.begin();
|
||||
|
||||
@ -297,14 +296,12 @@ void EmbeddedFileWriter::PrepareBuiltinSourcePositionMap(Builtins* builtins) {
|
||||
}
|
||||
}
|
||||
|
||||
void EmbeddedFileWriter::PrepareBuiltinLabelInfoMap(
|
||||
int create_offset, int invoke_offset, int arguments_adaptor_offset) {
|
||||
void EmbeddedFileWriter::PrepareBuiltinLabelInfoMap(int create_offset,
|
||||
int invoke_offset) {
|
||||
label_info_[Builtins::kJSConstructStubGeneric].push_back(
|
||||
{create_offset, "construct_stub_create_deopt_addr"});
|
||||
label_info_[Builtins::kJSConstructStubGeneric].push_back(
|
||||
{invoke_offset, "construct_stub_invoke_deopt_addr"});
|
||||
label_info_[Builtins::kArgumentsAdaptorTrampoline].push_back(
|
||||
{arguments_adaptor_offset, "arguments_adaptor_deopt_addr"});
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -42,8 +42,8 @@ class EmbeddedFileWriterInterface {
|
||||
// compiled builtin Code objects with trampolines.
|
||||
virtual void PrepareBuiltinSourcePositionMap(Builtins* builtins) = 0;
|
||||
|
||||
virtual void PrepareBuiltinLabelInfoMap(int create_offset, int invoke_offset,
|
||||
int arguments_adaptor_offset) = 0;
|
||||
virtual void PrepareBuiltinLabelInfoMap(int create_offset,
|
||||
int invoke_offset) = 0;
|
||||
|
||||
#if defined(V8_OS_WIN64)
|
||||
virtual void SetBuiltinUnwindData(
|
||||
@ -69,8 +69,8 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
|
||||
|
||||
void PrepareBuiltinSourcePositionMap(Builtins* builtins) override;
|
||||
|
||||
void PrepareBuiltinLabelInfoMap(int create_offset, int invoke_create,
|
||||
int arguments_adaptor_offset) override;
|
||||
void PrepareBuiltinLabelInfoMap(int create_offset,
|
||||
int invoke_create) override;
|
||||
|
||||
#if defined(V8_OS_WIN64)
|
||||
void SetBuiltinUnwindData(
|
||||
|
@ -77,7 +77,6 @@ struct WasmModule;
|
||||
V(WasmTraceEnter) \
|
||||
V(WasmTraceExit) \
|
||||
V(WasmTraceMemory) \
|
||||
V(ArgumentsAdaptorTrampoline) \
|
||||
V(BigIntToI32Pair) \
|
||||
V(BigIntToI64) \
|
||||
V(DoubleToI) \
|
||||
|
@ -711,9 +711,6 @@ macro TestFrame1(implicit context: Context)() {
|
||||
case (_f: StandardFrame): {
|
||||
unreachable;
|
||||
}
|
||||
case (_f: ArgumentsAdaptorFrame): {
|
||||
unreachable;
|
||||
}
|
||||
case (_f: StubFrame): {
|
||||
}
|
||||
}
|
||||
|
@ -508,7 +508,6 @@ FRAME_MARKERS = (
|
||||
"JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH",
|
||||
"INTERNAL",
|
||||
"CONSTRUCT",
|
||||
"ARGUMENTS_ADAPTOR",
|
||||
"BUILTIN",
|
||||
"BUILTIN_EXIT",
|
||||
"NATIVE",
|
||||
|
Loading…
Reference in New Issue
Block a user