diff --git a/src/arm/interface-descriptors-arm.cc b/src/arm/interface-descriptors-arm.cc index 7e56698f00..5a1e28c818 100644 --- a/src/arm/interface-descriptors-arm.cc +++ b/src/arm/interface-descriptors-arm.cc @@ -324,7 +324,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { r0, // argument count (not including receiver) @@ -334,7 +334,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { r0, // argument count (not including receiver) @@ -346,8 +346,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { r0, // argument count (not including receiver) r1, // target to call checked to be Array function diff --git a/src/arm64/interface-descriptors-arm64.cc b/src/arm64/interface-descriptors-arm64.cc index c73d371e8f..3173bac58d 100644 --- a/src/arm64/interface-descriptors-arm64.cc +++ b/src/arm64/interface-descriptors-arm64.cc @@ -353,7 +353,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { x0, // argument count (not including receiver) @@ -363,7 +363,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { x0, // argument count (not including receiver) @@ -375,8 +375,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { x0, // argument count (not including receiver) x1, // target to call checked to be Array function diff --git a/src/builtins/arm/builtins-arm.cc b/src/builtins/arm/builtins-arm.cc index 05593bd419..777c73fd90 100644 --- a/src/builtins/arm/builtins-arm.cc +++ b/src/builtins/arm/builtins-arm.cc @@ -1082,7 +1082,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register num_args, Register index, - Register limit, Register scratch) { + Register limit, Register scratch, + Label* stack_overflow) { + // Add a stack check before pushing arguments. + Generate_StackOverflowCheck(masm, num_args, scratch, stack_overflow); + // Find the address of the last argument. __ mov(limit, num_args); __ mov(limit, Operand(limit, LSL, kPointerSizeLog2)); @@ -1099,9 +1103,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( - MacroAssembler* masm, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { +void Builtins::Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode, + InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- r0 : the number of arguments (not including the receiver) // -- r2 : the address of the first argument to be pushed. Subsequent @@ -1113,16 +1117,8 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( __ add(r3, r0, Operand(1)); // Add one for receiver. - Generate_StackOverflowCheck(masm, r3, r4, &stack_overflow); - - // Push "undefined" as the receiver arg if we need to. - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - __ PushRoot(Heap::kUndefinedValueRootIndex); - __ mov(r3, r0); // Argument count is correct. - } - // Push the arguments. r2, r4, r5 will be modified. - Generate_InterpreterPushArgs(masm, r3, r2, r4, r5); + Generate_InterpreterPushArgs(masm, r3, r2, r4, r5, &stack_overflow); // Call the target. if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1147,7 +1143,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- r0 : argument count (not including receiver) @@ -1162,10 +1158,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( __ mov(ip, Operand::Zero()); __ push(ip); - Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow); - // Push the arguments. r5, r4, r6 will be modified. - Generate_InterpreterPushArgs(masm, r0, r4, r5, r6); + Generate_InterpreterPushArgs(masm, r0, r4, r5, r6, &stack_overflow); __ AssertUndefinedOrAllocationSite(r2, r5); if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1196,7 +1190,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r0 : argument count (not including receiver) @@ -1206,14 +1200,11 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // ----------------------------------- Label stack_overflow; - // Push a slot for the receiver to be constructed. - __ mov(ip, Operand::Zero()); - __ push(ip); - - Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow); + __ add(r4, r0, Operand(1)); // Add one for receiver. + // TODO(mythria): Add a stack check before pushing arguments. // Push the arguments. r3, r5, r6 will be modified. - Generate_InterpreterPushArgs(masm, r0, r3, r5, r6); + Generate_InterpreterPushArgs(masm, r4, r3, r5, r6, &stack_overflow); // Array constructor expects constructor in r3. It is same as r1 here. __ mov(r3, r1); diff --git a/src/builtins/arm64/builtins-arm64.cc b/src/builtins/arm64/builtins-arm64.cc index 9824ab64a4..1f0b4f7185 100644 --- a/src/builtins/arm64/builtins-arm64.cc +++ b/src/builtins/arm64/builtins-arm64.cc @@ -1100,7 +1100,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register num_args, Register index, Register last_arg, Register stack_addr, - Register scratch) { + Register scratch, + Label* stack_overflow) { + // Add a stack check before pushing arguments. + Generate_StackOverflowCheck(masm, num_args, scratch, stack_overflow); + __ Mov(scratch, num_args); __ lsl(scratch, scratch, kPointerSizeLog2); __ sub(last_arg, index, scratch); @@ -1122,9 +1126,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( - MacroAssembler* masm, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { +void Builtins::Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode, + InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- x0 : the number of arguments (not including the receiver) // -- x2 : the address of the first argument to be pushed. Subsequent @@ -1137,17 +1141,8 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( // Add one for the receiver. __ add(x3, x0, Operand(1)); - // Add a stack check before pushing arguments. - Generate_StackOverflowCheck(masm, x3, x6, &stack_overflow); - - // Push "undefined" as the receiver arg if we need to. - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - __ PushRoot(Heap::kUndefinedValueRootIndex); - __ Mov(x3, x0); // Argument count is correct. - } - // Push the arguments. x2, x4, x5, x6 will be modified. - Generate_InterpreterPushArgs(masm, x3, x2, x4, x5, x6); + Generate_InterpreterPushArgs(masm, x3, x2, x4, x5, x6, &stack_overflow); // Call the target. if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1171,7 +1166,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- x0 : argument count (not including receiver) @@ -1185,11 +1180,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( // Push a slot for the receiver. __ Push(xzr); - // Add a stack check before pushing arguments. - Generate_StackOverflowCheck(masm, x0, x7, &stack_overflow); - // Push the arguments. x5, x4, x6, x7 will be modified. - Generate_InterpreterPushArgs(masm, x0, x4, x5, x6, x7); + Generate_InterpreterPushArgs(masm, x0, x4, x5, x6, x7, &stack_overflow); __ AssertUndefinedOrAllocationSite(x2, x6); if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1219,7 +1211,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- x0 : argument count (not including receiver) @@ -1229,14 +1221,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // ----------------------------------- Label stack_overflow; - // Push a slot for the receiver. - __ Push(xzr); - - // Add a stack check before pushing arguments. - Generate_StackOverflowCheck(masm, x0, x7, &stack_overflow); + __ add(x4, x0, Operand(1)); // Add one for the receiver. // Push the arguments. x3, x5, x6, x7 will be modified. - Generate_InterpreterPushArgs(masm, x0, x3, x5, x6, x7); + Generate_InterpreterPushArgs(masm, x4, x3, x5, x6, x7, &stack_overflow); // Array constructor expects constructor in x3. It is same as call target. __ mov(x3, x1); diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index 53fd43ad53..b19d10f380 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -133,17 +133,15 @@ namespace internal { \ /* Interpreter */ \ ASM(InterpreterEntryTrampoline) \ - ASM(InterpreterPushArgsThenCall) \ - ASM(InterpreterPushUndefinedAndArgsThenCall) \ - ASM(InterpreterPushArgsThenCallFunction) \ - ASM(InterpreterPushUndefinedAndArgsThenCallFunction) \ - ASM(InterpreterPushArgsThenCallWithFinalSpread) \ - ASM(InterpreterPushArgsThenTailCall) \ - ASM(InterpreterPushArgsThenTailCallFunction) \ - ASM(InterpreterPushArgsThenConstruct) \ - ASM(InterpreterPushArgsThenConstructFunction) \ - ASM(InterpreterPushArgsThenConstructArray) \ - ASM(InterpreterPushArgsThenConstructWithFinalSpread) \ + ASM(InterpreterPushArgsAndCall) \ + ASM(InterpreterPushArgsAndCallFunction) \ + ASM(InterpreterPushArgsAndCallWithFinalSpread) \ + ASM(InterpreterPushArgsAndTailCall) \ + ASM(InterpreterPushArgsAndTailCallFunction) \ + ASM(InterpreterPushArgsAndConstruct) \ + ASM(InterpreterPushArgsAndConstructFunction) \ + ASM(InterpreterPushArgsAndConstructArray) \ + ASM(InterpreterPushArgsAndConstructWithFinalSpread) \ ASM(InterpreterEnterBytecodeAdvance) \ ASM(InterpreterEnterBytecodeDispatch) \ ASM(InterpreterOnStackReplacement) \ diff --git a/src/builtins/builtins-interpreter-gen.cc b/src/builtins/builtins-interpreter-gen.cc index d11aa64af0..90e6851f82 100644 --- a/src/builtins/builtins-interpreter-gen.cc +++ b/src/builtins/builtins-interpreter-gen.cc @@ -9,67 +9,48 @@ namespace v8 { namespace internal { -void Builtins::Generate_InterpreterPushArgsThenCall(MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenCallImpl( - masm, ConvertReceiverMode::kAny, TailCallMode::kDisallow, - InterpreterPushArgsMode::kOther); +void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { + return Generate_InterpreterPushArgsAndCallImpl( + masm, TailCallMode::kDisallow, InterpreterPushArgsMode::kOther); } -void Builtins::Generate_InterpreterPushArgsThenCallFunction( +void Builtins::Generate_InterpreterPushArgsAndCallFunction( MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenCallImpl( - masm, ConvertReceiverMode::kAny, TailCallMode::kDisallow, - InterpreterPushArgsMode::kJSFunction); + return Generate_InterpreterPushArgsAndCallImpl( + masm, TailCallMode::kDisallow, InterpreterPushArgsMode::kJSFunction); } -void Builtins::Generate_InterpreterPushUndefinedAndArgsThenCall( +void Builtins::Generate_InterpreterPushArgsAndCallWithFinalSpread( MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenCallImpl( - masm, ConvertReceiverMode::kNullOrUndefined, TailCallMode::kDisallow, - InterpreterPushArgsMode::kOther); + return Generate_InterpreterPushArgsAndCallImpl( + masm, TailCallMode::kDisallow, InterpreterPushArgsMode::kWithFinalSpread); } -void Builtins::Generate_InterpreterPushUndefinedAndArgsThenCallFunction( +void Builtins::Generate_InterpreterPushArgsAndTailCall(MacroAssembler* masm) { + return Generate_InterpreterPushArgsAndCallImpl( + masm, TailCallMode::kAllow, InterpreterPushArgsMode::kOther); +} + +void Builtins::Generate_InterpreterPushArgsAndTailCallFunction( MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenCallImpl( - masm, ConvertReceiverMode::kNullOrUndefined, TailCallMode::kDisallow, - InterpreterPushArgsMode::kJSFunction); + return Generate_InterpreterPushArgsAndCallImpl( + masm, TailCallMode::kAllow, InterpreterPushArgsMode::kJSFunction); } -void Builtins::Generate_InterpreterPushArgsThenCallWithFinalSpread( - MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenCallImpl( - masm, ConvertReceiverMode::kAny, TailCallMode::kDisallow, - InterpreterPushArgsMode::kWithFinalSpread); -} - -void Builtins::Generate_InterpreterPushArgsThenTailCall(MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenCallImpl( - masm, ConvertReceiverMode::kAny, TailCallMode::kAllow, - InterpreterPushArgsMode::kOther); -} - -void Builtins::Generate_InterpreterPushArgsThenTailCallFunction( - MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenCallImpl( - masm, ConvertReceiverMode::kAny, TailCallMode::kAllow, - InterpreterPushArgsMode::kJSFunction); -} - -void Builtins::Generate_InterpreterPushArgsThenConstruct(MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { + return Generate_InterpreterPushArgsAndConstructImpl( masm, InterpreterPushArgsMode::kOther); } -void Builtins::Generate_InterpreterPushArgsThenConstructWithFinalSpread( +void Builtins::Generate_InterpreterPushArgsAndConstructWithFinalSpread( MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenConstructImpl( + return Generate_InterpreterPushArgsAndConstructImpl( masm, InterpreterPushArgsMode::kWithFinalSpread); } -void Builtins::Generate_InterpreterPushArgsThenConstructFunction( +void Builtins::Generate_InterpreterPushArgsAndConstructFunction( MacroAssembler* masm) { - return Generate_InterpreterPushArgsThenConstructImpl( + return Generate_InterpreterPushArgsAndConstructImpl( masm, InterpreterPushArgsMode::kJSFunction); } diff --git a/src/builtins/builtins-interpreter.cc b/src/builtins/builtins-interpreter.cc index dd6ef0d0d0..22843ac89e 100644 --- a/src/builtins/builtins-interpreter.cc +++ b/src/builtins/builtins-interpreter.cc @@ -11,53 +11,38 @@ namespace v8 { namespace internal { -Handle Builtins::InterpreterPushArgsThenCall( - ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode, - InterpreterPushArgsMode mode) { +Handle Builtins::InterpreterPushArgsAndCall( + TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { switch (mode) { case InterpreterPushArgsMode::kJSFunction: if (tail_call_mode == TailCallMode::kDisallow) { - switch (receiver_mode) { - case ConvertReceiverMode::kNullOrUndefined: - return InterpreterPushUndefinedAndArgsThenCallFunction(); - case ConvertReceiverMode::kNotNullOrUndefined: - case ConvertReceiverMode::kAny: - return InterpreterPushArgsThenCallFunction(); - } + return InterpreterPushArgsAndCallFunction(); } else { - CHECK_EQ(receiver_mode, ConvertReceiverMode::kAny); - return InterpreterPushArgsThenTailCallFunction(); + return InterpreterPushArgsAndTailCallFunction(); } case InterpreterPushArgsMode::kWithFinalSpread: CHECK(tail_call_mode == TailCallMode::kDisallow); - return InterpreterPushArgsThenCallWithFinalSpread(); + return InterpreterPushArgsAndCallWithFinalSpread(); case InterpreterPushArgsMode::kOther: if (tail_call_mode == TailCallMode::kDisallow) { - switch (receiver_mode) { - case ConvertReceiverMode::kNullOrUndefined: - return InterpreterPushUndefinedAndArgsThenCall(); - case ConvertReceiverMode::kNotNullOrUndefined: - case ConvertReceiverMode::kAny: - return InterpreterPushArgsThenCall(); - } + return InterpreterPushArgsAndCall(); } else { - CHECK_EQ(receiver_mode, ConvertReceiverMode::kAny); - return InterpreterPushArgsThenTailCall(); + return InterpreterPushArgsAndTailCall(); } } UNREACHABLE(); return Handle::null(); } -Handle Builtins::InterpreterPushArgsThenConstruct( +Handle Builtins::InterpreterPushArgsAndConstruct( InterpreterPushArgsMode mode) { switch (mode) { case InterpreterPushArgsMode::kJSFunction: - return InterpreterPushArgsThenConstructFunction(); + return InterpreterPushArgsAndConstructFunction(); case InterpreterPushArgsMode::kWithFinalSpread: - return InterpreterPushArgsThenConstructWithFinalSpread(); + return InterpreterPushArgsAndConstructWithFinalSpread(); case InterpreterPushArgsMode::kOther: - return InterpreterPushArgsThenConstruct(); + return InterpreterPushArgsAndConstruct(); } UNREACHABLE(); return Handle::null(); diff --git a/src/builtins/builtins.h b/src/builtins/builtins.h index 9da714bc0f..f895e2b138 100644 --- a/src/builtins/builtins.h +++ b/src/builtins/builtins.h @@ -58,10 +58,9 @@ class Builtins { Handle NonPrimitiveToPrimitive( ToPrimitiveHint hint = ToPrimitiveHint::kDefault); Handle OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint); - Handle InterpreterPushArgsThenCall(ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, - InterpreterPushArgsMode mode); - Handle InterpreterPushArgsThenConstruct(InterpreterPushArgsMode mode); + Handle InterpreterPushArgsAndCall(TailCallMode tail_call_mode, + InterpreterPushArgsMode mode); + Handle InterpreterPushArgsAndConstruct(InterpreterPushArgsMode mode); Handle NewFunctionContext(ScopeType scope_type); Handle NewCloneShallowArray(AllocationSiteMode allocation_mode); Handle NewCloneShallowObject(int length); @@ -123,11 +122,11 @@ class Builtins { static void Generate_CallForwardVarargs(MacroAssembler* masm, Handle code); - static void Generate_InterpreterPushArgsThenCallImpl( - MacroAssembler* masm, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode); + static void Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode, + InterpreterPushArgsMode mode); - static void Generate_InterpreterPushArgsThenConstructImpl( + static void Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode); #define DECLARE_ASM(Name, ...) \ diff --git a/src/builtins/ia32/builtins-ia32.cc b/src/builtins/ia32/builtins-ia32.cc index 00e9e720ae..f3b0474fd1 100644 --- a/src/builtins/ia32/builtins-ia32.cc +++ b/src/builtins/ia32/builtins-ia32.cc @@ -751,9 +751,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( - MacroAssembler* masm, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { +void Builtins::Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode, + InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- eax : the number of arguments (not including the receiver) // -- ebx : the address of the first argument to be pushed. Subsequent @@ -776,12 +776,6 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( // Pop return address to allow tail-call after pushing arguments. __ Pop(edx); - // Push "undefined" as the receiver arg if we need to. - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - __ PushRoot(Heap::kUndefinedValueRootIndex); - __ sub(ecx, Immediate(1)); // Subtract one for receiver. - } - // Find the address of the last argument. __ shl(ecx, kPointerSizeLog2); __ neg(ecx); @@ -821,10 +815,10 @@ namespace { // This function modified start_addr, and only reads the contents of num_args // register. scratch1 and scratch2 are used as temporary registers. Their // original values are restored after the use. -void Generate_InterpreterPushZeroAndArgsAndReturnAddress( +void Generate_InterpreterPushArgsAndReturnAddress( MacroAssembler* masm, Register num_args, Register start_addr, - Register scratch1, Register scratch2, int num_slots_above_ret_addr, - Label* stack_overflow) { + Register scratch1, Register scratch2, bool receiver_in_args, + int num_slots_above_ret_addr, Label* stack_overflow) { // We have to move return address and the temporary registers above it // before we can copy arguments onto the stack. To achieve this: // Step 1: Increment the stack pointer by num_args + 1 (for receiver). @@ -837,7 +831,7 @@ void Generate_InterpreterPushZeroAndArgsAndReturnAddress( // | | | return addr | (2) // | | | arg N | (3) // | scratch1 | <-- esp | .... | - // | .... | | arg 1 | + // | .... | | arg 0 | // | scratch-n | | arg 0 | // | return addr | | receiver slot | @@ -881,12 +875,17 @@ void Generate_InterpreterPushZeroAndArgsAndReturnAddress( } // Step 3 copy arguments to correct locations. - // Slot meant for receiver contains return address. Reset it so that - // we will not incorrectly interpret return address as an object. - __ mov(Operand(esp, num_args, times_pointer_size, - (num_slots_above_ret_addr + 1) * kPointerSize), - Immediate(0)); - __ mov(scratch1, num_args); + if (receiver_in_args) { + __ mov(scratch1, num_args); + __ add(scratch1, Immediate(1)); + } else { + // Slot meant for receiver contains return address. Reset it so that + // we will not incorrectly interpret return address as an object. + __ mov(Operand(esp, num_args, times_pointer_size, + (num_slots_above_ret_addr + 1) * kPointerSize), + Immediate(0)); + __ mov(scratch1, num_args); + } Label loop_header, loop_check; __ jmp(&loop_check); @@ -905,7 +904,7 @@ void Generate_InterpreterPushZeroAndArgsAndReturnAddress( } // end anonymous namespace // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- eax : the number of arguments (not including the receiver) @@ -924,8 +923,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( // Push arguments and move return address to the top of stack. // The eax register is readonly. The ecx register will be modified. The edx // and edi registers will be modified but restored to their original values. - Generate_InterpreterPushZeroAndArgsAndReturnAddress(masm, eax, ecx, edx, edi, - 2, &stack_overflow); + Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false, + 2, &stack_overflow); // Restore edi and edx __ Pop(edx); @@ -965,7 +964,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- eax : the number of arguments (not including the receiver) @@ -983,8 +982,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // Push arguments and move return address to the top of stack. // The eax register is readonly. The ecx register will be modified. The edx // and edi registers will be modified but restored to their original values. - Generate_InterpreterPushZeroAndArgsAndReturnAddress(masm, eax, ecx, edx, edi, - 1, &stack_overflow); + Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, true, + 1, &stack_overflow); // Restore edx. __ Pop(edx); diff --git a/src/builtins/mips/builtins-mips.cc b/src/builtins/mips/builtins-mips.cc index 2da3985606..d536138d44 100644 --- a/src/builtins/mips/builtins-mips.cc +++ b/src/builtins/mips/builtins-mips.cc @@ -1077,7 +1077,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register num_args, Register index, - Register scratch, Register scratch2) { + Register scratch, Register scratch2, + Label* stack_overflow) { + Generate_StackOverflowCheck(masm, num_args, scratch, scratch2, + stack_overflow); + // Find the address of the last argument. __ mov(scratch2, num_args); __ sll(scratch2, scratch2, kPointerSizeLog2); @@ -1095,9 +1099,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( - MacroAssembler* masm, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { +void Builtins::Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode, + InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- a0 : the number of arguments (not including the receiver) // -- a2 : the address of the first argument to be pushed. Subsequent @@ -1109,16 +1113,8 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( __ Addu(t0, a0, Operand(1)); // Add one for receiver. - Generate_StackOverflowCheck(masm, t0, t4, t1, &stack_overflow); - - // Push "undefined" as the receiver arg if we need to. - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - __ PushRoot(Heap::kUndefinedValueRootIndex); - __ mov(t0, a0); // No receiver. - } - // This function modifies a2, t4 and t1. - Generate_InterpreterPushArgs(masm, t0, a2, t4, t1); + Generate_InterpreterPushArgs(masm, t0, a2, t4, t1, &stack_overflow); // Call the target. if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1143,7 +1139,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- a0 : argument count (not including receiver) @@ -1157,10 +1153,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( // Push a slot for the receiver. __ push(zero_reg); - Generate_StackOverflowCheck(masm, a0, t1, t0, &stack_overflow); - // This function modified t4, t1 and t0. - Generate_InterpreterPushArgs(masm, a0, t4, t1, t0); + Generate_InterpreterPushArgs(masm, a0, t4, t1, t0, &stack_overflow); __ AssertUndefinedOrAllocationSite(a2, t0); if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1191,7 +1185,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- a0 : the number of arguments (not including the receiver) @@ -1203,13 +1197,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // ----------------------------------- Label stack_overflow; - // Push a slot for the receiver. - __ push(zero_reg); + __ Addu(t0, a0, Operand(1)); // Add one for receiver. - Generate_StackOverflowCheck(masm, a0, t1, t4, &stack_overflow); - - // This function modifies a3, t1, and t4. - Generate_InterpreterPushArgs(masm, a0, a3, t1, t4); + // This function modifies a3, t4, and t1. + Generate_InterpreterPushArgs(masm, t0, a3, t1, t4, &stack_overflow); // ArrayConstructor stub expects constructor in a3. Set it here. __ mov(a3, a1); diff --git a/src/builtins/mips64/builtins-mips64.cc b/src/builtins/mips64/builtins-mips64.cc index ae1edcae8c..42d291feac 100644 --- a/src/builtins/mips64/builtins-mips64.cc +++ b/src/builtins/mips64/builtins-mips64.cc @@ -1070,7 +1070,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register num_args, Register index, - Register scratch, Register scratch2) { + Register scratch, Register scratch2, + Label* stack_overflow) { + // Generate_StackOverflowCheck(masm, num_args, scratch, scratch2, + // stack_overflow); + // Find the address of the last argument. __ mov(scratch2, num_args); __ dsll(scratch2, scratch2, kPointerSizeLog2); @@ -1088,9 +1092,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( - MacroAssembler* masm, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { +void Builtins::Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode, + InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- a0 : the number of arguments (not including the receiver) // -- a2 : the address of the first argument to be pushed. Subsequent @@ -1102,16 +1106,8 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( __ Daddu(a3, a0, Operand(1)); // Add one for receiver. - // Push "undefined" as the receiver arg if we need to. - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - __ PushRoot(Heap::kUndefinedValueRootIndex); - __ Dsubu(a3, a3, Operand(1)); // Subtract one for receiver. - } - - Generate_StackOverflowCheck(masm, a3, a4, t0, &stack_overflow); - // This function modifies a2, t0 and a4. - Generate_InterpreterPushArgs(masm, a3, a2, a4, t0); + Generate_InterpreterPushArgs(masm, a3, a2, a4, t0, &stack_overflow); // Call the target. if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1136,7 +1132,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- a0 : argument count (not including receiver) @@ -1150,10 +1146,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( // Push a slot for the receiver. __ push(zero_reg); - Generate_StackOverflowCheck(masm, a0, a5, t0, &stack_overflow); - // This function modifies t0, a4 and a5. - Generate_InterpreterPushArgs(masm, a0, a4, a5, t0); + Generate_InterpreterPushArgs(masm, a0, a4, a5, t0, &stack_overflow); __ AssertUndefinedOrAllocationSite(a2, t0); if (mode == InterpreterPushArgsMode::kJSFunction) { @@ -1184,7 +1178,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- a0 : the number of arguments (not including the receiver) @@ -1196,13 +1190,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // ----------------------------------- Label stack_overflow; - // Push a slot for the receiver. - __ push(zero_reg); - - Generate_StackOverflowCheck(masm, a4, a5, a6, &stack_overflow); + __ Daddu(a4, a0, Operand(1)); // Add one for receiver. // This function modifies a3, a5 and a6. - Generate_InterpreterPushArgs(masm, a4, a3, a5, a6); + Generate_InterpreterPushArgs(masm, a4, a3, a5, a6, &stack_overflow); // ArrayConstructor stub expects constructor in a3. Set it here. __ mov(a3, a1); diff --git a/src/builtins/ppc/builtins-ppc.cc b/src/builtins/ppc/builtins-ppc.cc index 5deb707f9f..6f2c4f71f0 100644 --- a/src/builtins/ppc/builtins-ppc.cc +++ b/src/builtins/ppc/builtins-ppc.cc @@ -1112,7 +1112,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( +void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- @@ -1153,7 +1153,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- r3 : argument count (not including receiver) @@ -1206,7 +1206,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r3 : argument count (not including receiver) diff --git a/src/builtins/s390/builtins-s390.cc b/src/builtins/s390/builtins-s390.cc index ea5b61ca28..98d918550f 100644 --- a/src/builtins/s390/builtins-s390.cc +++ b/src/builtins/s390/builtins-s390.cc @@ -1118,7 +1118,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( +void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- @@ -1159,7 +1159,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- r2 : argument count (not including receiver) @@ -1211,7 +1211,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r2 : argument count (not including receiver) diff --git a/src/builtins/x64/builtins-x64.cc b/src/builtins/x64/builtins-x64.cc index f4e298f571..51f734567b 100644 --- a/src/builtins/x64/builtins-x64.cc +++ b/src/builtins/x64/builtins-x64.cc @@ -823,9 +823,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( - MacroAssembler* masm, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { +void Builtins::Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode, + InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- rax : the number of arguments (not including the receiver) // -- rbx : the address of the first argument to be pushed. Subsequent @@ -845,12 +845,6 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( // Pop return address to allow tail-call after pushing arguments. __ PopReturnAddressTo(kScratchRegister); - // Push "undefined" as the receiver arg if we need to. - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - __ PushRoot(Heap::kUndefinedValueRootIndex); - __ subp(rcx, Immediate(1)); // Subtract one for receiver. - } - // rbx and rdx will be modified. Generate_InterpreterPushArgs(masm, rcx, rbx, rdx); @@ -858,14 +852,15 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. if (mode == InterpreterPushArgsMode::kJSFunction) { - __ Jump(masm->isolate()->builtins()->CallFunction(receiver_mode, + __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, tail_call_mode), RelocInfo::CODE_TARGET); } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) { __ Jump(masm->isolate()->builtins()->CallWithSpread(), RelocInfo::CODE_TARGET); } else { - __ Jump(masm->isolate()->builtins()->Call(receiver_mode, tail_call_mode), + __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, + tail_call_mode), RelocInfo::CODE_TARGET); } @@ -879,7 +874,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- rax : the number of arguments (not including the receiver) @@ -939,7 +934,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- rax : the number of arguments (not including the receiver) @@ -953,6 +948,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // Number of values to be pushed. __ Move(r8, rax); + __ addp(r8, Immediate(1)); // Add one for receiver. // Add a stack check before pushing arguments. Generate_StackOverflowCheck(masm, r8, rdi, &stack_overflow); @@ -960,9 +956,6 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // Pop return address to allow tail-call after pushing arguments. __ PopReturnAddressTo(kScratchRegister); - // Push slot for the receiver to be constructed. - __ Push(Immediate(0)); - // rcx and rdi will be modified. Generate_InterpreterPushArgs(masm, r8, rcx, rdi); diff --git a/src/builtins/x87/builtins-x87.cc b/src/builtins/x87/builtins-x87.cc index 55b5dc4f56..55aefbcad3 100644 --- a/src/builtins/x87/builtins-x87.cc +++ b/src/builtins/x87/builtins-x87.cc @@ -694,7 +694,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, } // static -void Builtins::Generate_InterpreterPushArgsThenCallImpl( +void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- @@ -758,7 +758,7 @@ namespace { // This function modified start_addr, and only reads the contents of num_args // register. scratch1 and scratch2 are used as temporary registers. Their // original values are restored after the use. -void Generate_InterpreterPushArgsThenReturnAddress( +void Generate_InterpreterPushArgsAndReturnAddress( MacroAssembler* masm, Register num_args, Register start_addr, Register scratch1, Register scratch2, bool receiver_in_args, int num_slots_above_ret_addr, Label* stack_overflow) { @@ -847,7 +847,7 @@ void Generate_InterpreterPushArgsThenReturnAddress( } // end anonymous namespace // static -void Builtins::Generate_InterpreterPushArgsThenConstructImpl( +void Builtins::Generate_InterpreterPushArgsAndConstructImpl( MacroAssembler* masm, InterpreterPushArgsMode mode) { // ----------- S t a t e ------------- // -- eax : the number of arguments (not including the receiver) @@ -866,8 +866,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( // Push arguments and move return address to the top of stack. // The eax register is readonly. The ecx register will be modified. The edx // and edi registers will be modified but restored to their original values. - Generate_InterpreterPushArgsThenReturnAddress(masm, eax, ecx, edx, edi, false, - 2, &stack_overflow); + Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false, + 2, &stack_overflow); // Restore edi and edx __ Pop(edx); @@ -907,7 +907,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl( } // static -void Builtins::Generate_InterpreterPushArgsThenConstructArray( +void Builtins::Generate_InterpreterPushArgsAndConstructArray( MacroAssembler* masm) { // ----------- S t a t e ------------- // -- eax : the number of arguments (not including the receiver) @@ -925,8 +925,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray( // Push arguments and move return address to the top of stack. // The eax register is readonly. The ecx register will be modified. The edx // and edi registers will be modified but restored to their original values. - Generate_InterpreterPushArgsThenReturnAddress(masm, eax, ecx, edx, edi, true, - 1, &stack_overflow); + Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, true, + 1, &stack_overflow); // Restore edx. __ Pop(edx); diff --git a/src/code-factory.cc b/src/code-factory.cc index 71fbb1dbab..1e4c099231 100644 --- a/src/code-factory.cc +++ b/src/code-factory.cc @@ -464,25 +464,25 @@ Callable CodeFactory::ConstructFunction(Isolate* isolate) { } // static -Callable CodeFactory::InterpreterPushArgsThenCall( - Isolate* isolate, ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, InterpreterPushArgsMode mode) { - return Callable(isolate->builtins()->InterpreterPushArgsThenCall( - receiver_mode, tail_call_mode, mode), - InterpreterPushArgsThenCallDescriptor(isolate)); +Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate, + TailCallMode tail_call_mode, + InterpreterPushArgsMode mode) { + return Callable( + isolate->builtins()->InterpreterPushArgsAndCall(tail_call_mode, mode), + InterpreterPushArgsAndCallDescriptor(isolate)); } // static -Callable CodeFactory::InterpreterPushArgsThenConstruct( +Callable CodeFactory::InterpreterPushArgsAndConstruct( Isolate* isolate, InterpreterPushArgsMode mode) { - return Callable(isolate->builtins()->InterpreterPushArgsThenConstruct(mode), - InterpreterPushArgsThenConstructDescriptor(isolate)); + return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(mode), + InterpreterPushArgsAndConstructDescriptor(isolate)); } // static -Callable CodeFactory::InterpreterPushArgsThenConstructArray(Isolate* isolate) { - return Callable(isolate->builtins()->InterpreterPushArgsThenConstructArray(), - InterpreterPushArgsThenConstructArrayDescriptor(isolate)); +Callable CodeFactory::InterpreterPushArgsAndConstructArray(Isolate* isolate) { + return Callable(isolate->builtins()->InterpreterPushArgsAndConstructArray(), + InterpreterPushArgsAndConstructArrayDescriptor(isolate)); } // static diff --git a/src/code-factory.h b/src/code-factory.h index 669f3798aa..ce23364d0b 100644 --- a/src/code-factory.h +++ b/src/code-factory.h @@ -173,13 +173,12 @@ class V8_EXPORT_PRIVATE CodeFactory final { static Callable HasProperty(Isolate* isolate); static Callable ForInFilter(Isolate* isolate); - static Callable InterpreterPushArgsThenCall(Isolate* isolate, - ConvertReceiverMode receiver_mode, - TailCallMode tail_call_mode, - InterpreterPushArgsMode mode); - static Callable InterpreterPushArgsThenConstruct( - Isolate* isolate, InterpreterPushArgsMode mode); - static Callable InterpreterPushArgsThenConstructArray(Isolate* isolate); + static Callable InterpreterPushArgsAndCall(Isolate* isolate, + TailCallMode tail_call_mode, + InterpreterPushArgsMode mode); + static Callable InterpreterPushArgsAndConstruct(Isolate* isolate, + InterpreterPushArgsMode mode); + static Callable InterpreterPushArgsAndConstructArray(Isolate* isolate); static Callable InterpreterCEntry(Isolate* isolate, int result_size = 1); static Callable InterpreterOnStackReplacement(Isolate* isolate); diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc index dcaed97481..3b9784a4dc 100644 --- a/src/compiler/bytecode-graph-builder.cc +++ b/src/compiler/bytecode-graph-builder.cc @@ -1342,55 +1342,37 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() { } Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister( - Node* callee, Node* receiver, interpreter::Register first_arg, - int arg_count) { - // The arity of the Call node -- includes the callee, receiver and function - // arguments. - int arity = 2 + arg_count; - - Node** all = local_zone()->NewArray(static_cast(arity)); - + Node* callee, interpreter::Register receiver, size_t arity) { + Node** all = local_zone()->NewArray(static_cast(arity)); all[0] = callee; - all[1] = receiver; - - // The function arguments are in consecutive registers. - int arg_base = first_arg.index(); - for (int i = 0; i < arg_count; ++i) { - all[2 + i] = - environment()->LookupRegister(interpreter::Register(arg_base + i)); + all[1] = environment()->LookupRegister(receiver); + int receiver_index = receiver.index(); + for (int i = 2; i < static_cast(arity); ++i) { + all[i] = environment()->LookupRegister( + interpreter::Register(receiver_index + i - 1)); } - return all; } Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, Node* const* args, - int arg_count) { - return MakeNode(call_op, arg_count, args, false); + size_t arg_count) { + return MakeNode(call_op, static_cast(arg_count), args, false); } Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, Node* callee, interpreter::Register receiver, - size_t reg_count) { - Node* receiver_node = environment()->LookupRegister(receiver); - // The receiver is followed by the arguments in the consecutive registers. - DCHECK_GE(reg_count, 1); - interpreter::Register first_arg = interpreter::Register(receiver.index() + 1); - int arg_count = static_cast(reg_count) - 1; - - Node* const* call_args = - GetCallArgumentsFromRegister(callee, receiver_node, first_arg, arg_count); - return ProcessCallArguments(call_op, call_args, 2 + arg_count); + size_t arg_count) { + return ProcessCallArguments( + call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count), + arg_count); } void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, - ConvertReceiverMode receiver_mode, + ConvertReceiverMode receiver_hint, Node* const* args, size_t arg_count, int slot_id) { - DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode( - bytecode_iterator().current_bytecode()), - receiver_mode); PrepareEagerCheckpoint(); // Slot index of 0 is used indicate no feedback slot is available. Assert @@ -1400,51 +1382,63 @@ void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, float const frequency = ComputeCallFrequency(slot_id); const Operator* call = javascript()->Call(arg_count, frequency, feedback, - receiver_mode, tail_call_mode); - Node* value = ProcessCallArguments(call, args, static_cast(arg_count)); + receiver_hint, tail_call_mode); + Node* value = ProcessCallArguments(call, args, arg_count); environment()->BindAccumulator(value, Environment::kAttachFrameState); } void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode, - ConvertReceiverMode receiver_mode) { - DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode( - bytecode_iterator().current_bytecode()), - receiver_mode); + ConvertReceiverMode receiver_hint) { Node* callee = environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); - interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); int const slot_id = bytecode_iterator().GetIndexOperand(3); - - Node* receiver_node; - interpreter::Register first_arg; - int arg_count; - - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - // The receiver is implicit (and undefined), the arguments are in - // consecutive registers. - receiver_node = jsgraph()->UndefinedConstant(); - first_arg = first_reg; - arg_count = static_cast(reg_count); - } else { - // The receiver is the first register, followed by the arguments in the - // consecutive registers. - DCHECK_GE(reg_count, 1); - receiver_node = environment()->LookupRegister(first_reg); - first_arg = interpreter::Register(first_reg.index() + 1); - arg_count = static_cast(reg_count) - 1; - } - - Node* const* call_args = - GetCallArgumentsFromRegister(callee, receiver_node, first_arg, arg_count); - BuildCall(tail_call_mode, receiver_mode, call_args, - static_cast(2 + arg_count), slot_id); + BuildCall(tail_call_mode, receiver_hint, + GetCallArgumentsFromRegister(callee, receiver, arg_count + 1), + arg_count + 1, slot_id); } -void BytecodeGraphBuilder::VisitCallAnyReceiver() { +void BytecodeGraphBuilder::VisitCall() { BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kAny); } +void BytecodeGraphBuilder::VisitCall0() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + int const slot_id = bytecode_iterator().GetIndexOperand(2); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, + {callee, receiver}, slot_id); +} + +void BytecodeGraphBuilder::VisitCall1() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + Node* arg0 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); + int const slot_id = bytecode_iterator().GetIndexOperand(3); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, + {callee, receiver, arg0}, slot_id); +} + +void BytecodeGraphBuilder::VisitCall2() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + Node* arg0 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); + Node* arg1 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); + int const slot_id = bytecode_iterator().GetIndexOperand(4); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, + {callee, receiver, arg0, arg1}, slot_id); +} + void BytecodeGraphBuilder::VisitCallProperty() { BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); @@ -1486,54 +1480,16 @@ void BytecodeGraphBuilder::VisitCallProperty2() { {callee, receiver, arg0, arg1}, slot_id); } -void BytecodeGraphBuilder::VisitCallUndefinedReceiver() { - BuildCallVarArgs(TailCallMode::kDisallow, - ConvertReceiverMode::kNullOrUndefined); -} - -void BytecodeGraphBuilder::VisitCallUndefinedReceiver0() { - Node* callee = - environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); - Node* receiver = jsgraph()->UndefinedConstant(); - int const slot_id = bytecode_iterator().GetIndexOperand(1); - BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNullOrUndefined, - {callee, receiver}, slot_id); -} - -void BytecodeGraphBuilder::VisitCallUndefinedReceiver1() { - Node* callee = - environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); - Node* receiver = jsgraph()->UndefinedConstant(); - Node* arg0 = - environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); - int const slot_id = bytecode_iterator().GetIndexOperand(2); - BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNullOrUndefined, - {callee, receiver, arg0}, slot_id); -} - -void BytecodeGraphBuilder::VisitCallUndefinedReceiver2() { - Node* callee = - environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); - Node* receiver = jsgraph()->UndefinedConstant(); - Node* arg0 = - environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); - Node* arg1 = - environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); - int const slot_id = bytecode_iterator().GetIndexOperand(3); - BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNullOrUndefined, - {callee, receiver, arg0, arg1}, slot_id); -} - void BytecodeGraphBuilder::VisitCallWithSpread() { PrepareEagerCheckpoint(); Node* callee = environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); const Operator* call = - javascript()->CallWithSpread(static_cast(reg_count + 1)); + javascript()->CallWithSpread(static_cast(arg_count + 1)); - Node* value = ProcessCallArguments(call, callee, receiver, reg_count); + Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); environment()->BindAccumulator(value, Environment::kAttachFrameState); } @@ -1550,127 +1506,118 @@ void BytecodeGraphBuilder::VisitCallJSRuntime() { Node* callee = BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0)); interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); // Create node to perform the JS runtime call. - const Operator* call = javascript()->Call(reg_count + 1); - Node* value = ProcessCallArguments(call, callee, receiver, reg_count); + const Operator* call = javascript()->Call(arg_count + 1); + Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); environment()->BindAccumulator(value, Environment::kAttachFrameState); } Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( - const Operator* call_runtime_op, interpreter::Register receiver, - size_t reg_count) { - int arg_count = static_cast(reg_count); - // arity is args. - int arity = arg_count; - Node** all = local_zone()->NewArray(static_cast(arity)); - int first_arg_index = receiver.index(); - for (int i = 0; i < static_cast(reg_count); ++i) { + const Operator* call_runtime_op, interpreter::Register first_arg, + size_t arity) { + Node** all = local_zone()->NewArray(arity); + int first_arg_index = first_arg.index(); + for (int i = 0; i < static_cast(arity); ++i) { all[i] = environment()->LookupRegister( interpreter::Register(first_arg_index + i)); } - Node* value = MakeNode(call_runtime_op, arity, all, false); + Node* value = MakeNode(call_runtime_op, static_cast(arity), all, false); return value; } void BytecodeGraphBuilder::VisitCallRuntime() { PrepareEagerCheckpoint(); Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0); - interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); // Create node to perform the runtime call. - const Operator* call = javascript()->CallRuntime(functionId, reg_count); - Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count); + const Operator* call = javascript()->CallRuntime(functionId, arg_count); + Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); environment()->BindAccumulator(value, Environment::kAttachFrameState); } void BytecodeGraphBuilder::VisitCallRuntimeForPair() { PrepareEagerCheckpoint(); Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0); - interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); interpreter::Register first_return = bytecode_iterator().GetRegisterOperand(3); // Create node to perform the runtime call. - const Operator* call = javascript()->CallRuntime(functionId, reg_count); - Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count); + const Operator* call = javascript()->CallRuntime(functionId, arg_count); + Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count); environment()->BindRegistersToProjections(first_return, return_pair, Environment::kAttachFrameState); } Node* BytecodeGraphBuilder::ProcessConstructWithSpreadArguments( const Operator* op, Node* callee, Node* new_target, - interpreter::Register receiver, size_t reg_count) { - int arg_count = static_cast(reg_count); - // arity is args + callee and new target. - int arity = arg_count + 2; - Node** all = local_zone()->NewArray(static_cast(arity)); + interpreter::Register first_arg, size_t arity) { + Node** all = local_zone()->NewArray(arity); all[0] = callee; - int first_arg_index = receiver.index(); - for (int i = 0; i < arg_count; ++i) { - all[1 + i] = environment()->LookupRegister( - interpreter::Register(first_arg_index + i)); + int first_arg_index = first_arg.index(); + for (int i = 1; i < static_cast(arity) - 1; ++i) { + all[i] = environment()->LookupRegister( + interpreter::Register(first_arg_index + i - 1)); } all[arity - 1] = new_target; - Node* value = MakeNode(op, arity, all, false); + Node* value = MakeNode(op, static_cast(arity), all, false); return value; } void BytecodeGraphBuilder::VisitConstructWithSpread() { PrepareEagerCheckpoint(); interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0); - interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); Node* new_target = environment()->LookupAccumulator(); Node* callee = environment()->LookupRegister(callee_reg); const Operator* op = - javascript()->ConstructWithSpread(static_cast(reg_count + 2)); + javascript()->ConstructWithSpread(static_cast(arg_count) + 2); Node* value = ProcessConstructWithSpreadArguments(op, callee, new_target, - receiver, reg_count); + first_arg, arg_count + 2); environment()->BindAccumulator(value, Environment::kAttachFrameState); } void BytecodeGraphBuilder::VisitInvokeIntrinsic() { PrepareEagerCheckpoint(); Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0); - interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); // Create node to perform the runtime call. Turbofan will take care of the // lowering. - const Operator* call = javascript()->CallRuntime(functionId, reg_count); - Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count); + const Operator* call = javascript()->CallRuntime(functionId, arg_count); + Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); environment()->BindAccumulator(value, Environment::kAttachFrameState); } Node* BytecodeGraphBuilder::ProcessConstructArguments( const Operator* call_new_op, Node* callee, Node* new_target, - interpreter::Register receiver, size_t reg_count) { - int arg_count = static_cast(reg_count); - // arity is args + callee and new target. - int arity = arg_count + 2; - Node** all = local_zone()->NewArray(static_cast(arity)); + interpreter::Register first_arg, size_t arity) { + Node** all = local_zone()->NewArray(arity); all[0] = callee; - int first_arg_index = receiver.index(); - for (int i = 0; i < arg_count; ++i) { - all[1 + i] = environment()->LookupRegister( - interpreter::Register(first_arg_index + i)); + int first_arg_index = first_arg.index(); + for (int i = 1; i < static_cast(arity) - 1; ++i) { + all[i] = environment()->LookupRegister( + interpreter::Register(first_arg_index + i - 1)); } all[arity - 1] = new_target; - Node* value = MakeNode(call_new_op, arity, all, false); + Node* value = MakeNode(call_new_op, static_cast(arity), all, false); return value; } void BytecodeGraphBuilder::VisitConstruct() { PrepareEagerCheckpoint(); interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0); - interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); + interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); // Slot index of 0 is used indicate no feedback slot is available. Assert // the assumption that slot index 0 is never a valid feedback slot. STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); @@ -1682,9 +1629,9 @@ void BytecodeGraphBuilder::VisitConstruct() { float const frequency = ComputeCallFrequency(slot_id); const Operator* call = javascript()->Construct( - static_cast(reg_count + 2), frequency, feedback); - Node* value = - ProcessConstructArguments(call, callee, new_target, receiver, reg_count); + static_cast(arg_count) + 2, frequency, feedback); + Node* value = ProcessConstructArguments(call, callee, new_target, first_arg, + arg_count + 2); environment()->BindAccumulator(value, Environment::kAttachFrameState); } diff --git a/src/compiler/bytecode-graph-builder.h b/src/compiler/bytecode-graph-builder.h index 809a995dff..8e61f575ea 100644 --- a/src/compiler/bytecode-graph-builder.h +++ b/src/compiler/bytecode-graph-builder.h @@ -112,24 +112,24 @@ class BytecodeGraphBuilder { Node** EnsureInputBufferSize(int size); - Node* const* GetCallArgumentsFromRegister(Node* callee, Node* receiver, + Node* const* GetCallArgumentsFromRegister(Node* callee, interpreter::Register first_arg, - int arg_count); + size_t arity); Node* ProcessCallArguments(const Operator* call_op, Node* const* args, - int arg_count); + size_t arg_count); Node* ProcessCallArguments(const Operator* call_op, Node* callee, - interpreter::Register receiver, size_t reg_count); + interpreter::Register receiver, size_t arity); Node* ProcessConstructArguments(const Operator* call_new_op, Node* callee, Node* new_target, - interpreter::Register receiver, - size_t reg_count); + interpreter::Register first_arg, + size_t arity); Node* ProcessConstructWithSpreadArguments(const Operator* op, Node* callee, Node* new_target, - interpreter::Register receiver, - size_t reg_count); + interpreter::Register first_arg, + size_t arity); Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, - interpreter::Register receiver, - size_t reg_count); + interpreter::Register first_arg, + size_t arity); // Prepare information for eager deoptimization. This information is carried // by dedicated {Checkpoint} nodes that are wired into the effect chain. @@ -159,12 +159,12 @@ class BytecodeGraphBuilder { void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode); void BuildStaLookupSlot(LanguageMode language_mode); void BuildCallVarArgs(TailCallMode tail_call_mode, - ConvertReceiverMode receiver_mode); - void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_mode, + ConvertReceiverMode receiver_hint); + void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_hint, Node* const* args, size_t arg_count, int slot_id); - void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_mode, + void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_hint, std::initializer_list args, int slot_id) { - BuildCall(tail_call_mode, receiver_mode, args.begin(), args.size(), + BuildCall(tail_call_mode, receiver_hint, args.begin(), args.size(), slot_id); } void BuildBinaryOp(const Operator* op); diff --git a/src/ia32/interface-descriptors-ia32.cc b/src/ia32/interface-descriptors-ia32.cc index 304191bbd2..701db767f0 100644 --- a/src/ia32/interface-descriptors-ia32.cc +++ b/src/ia32/interface-descriptors-ia32.cc @@ -318,7 +318,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { eax, // argument count (not including receiver) @@ -328,7 +328,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { eax, // argument count (not including receiver) @@ -340,8 +340,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { eax, // argument count (not including receiver) edx, // target to the call. It is checked to be Array function. diff --git a/src/interface-descriptors.cc b/src/interface-descriptors.cc index a5dccc3583..55bccf6a64 100644 --- a/src/interface-descriptors.cc +++ b/src/interface-descriptors.cc @@ -607,7 +607,7 @@ void InterpreterDispatchDescriptor::InitializePlatformIndependent( machine_types); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformIndependent( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformIndependent( CallInterfaceDescriptorData* data) { // kNumberOfArguments, kFirstArgument, kFunction MachineType machine_types[] = {MachineType::Int32(), MachineType::Pointer(), @@ -616,7 +616,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformIndependent( machine_types); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformIndependent( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformIndependent( CallInterfaceDescriptorData* data) { // kNumberOfArguments, kNewTarget, kConstructor, kFeedbackElement, // kFirstArgument @@ -627,7 +627,7 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformIndependent( machine_types); } -void InterpreterPushArgsThenConstructArrayDescriptor:: +void InterpreterPushArgsAndConstructArrayDescriptor:: InitializePlatformIndependent(CallInterfaceDescriptorData* data) { // kNumberOfArguments, kFunction, kFeedbackElement, kFirstArgument MachineType machine_types[] = {MachineType::Int32(), MachineType::AnyTagged(), diff --git a/src/interface-descriptors.h b/src/interface-descriptors.h index b97c45cd0e..df6a0e8dab 100644 --- a/src/interface-descriptors.h +++ b/src/interface-descriptors.h @@ -79,9 +79,9 @@ class PlatformInterfaceDescriptor; V(GrowArrayElements) \ V(NewArgumentsElements) \ V(InterpreterDispatch) \ - V(InterpreterPushArgsThenCall) \ - V(InterpreterPushArgsThenConstruct) \ - V(InterpreterPushArgsThenConstructArray) \ + V(InterpreterPushArgsAndCall) \ + V(InterpreterPushArgsAndConstruct) \ + V(InterpreterPushArgsAndConstructArray) \ V(InterpreterCEntry) \ V(ResumeGenerator) \ V(FrameDropperTrampoline) \ @@ -839,29 +839,30 @@ class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor CallInterfaceDescriptor) }; -class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor { +class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor { public: DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction) DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( - InterpreterPushArgsThenCallDescriptor, CallInterfaceDescriptor) + InterpreterPushArgsAndCallDescriptor, CallInterfaceDescriptor) }; -class InterpreterPushArgsThenConstructDescriptor + +class InterpreterPushArgsAndConstructDescriptor : public CallInterfaceDescriptor { public: DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor, kFeedbackElement, kFirstArgument) DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( - InterpreterPushArgsThenConstructDescriptor, CallInterfaceDescriptor) + InterpreterPushArgsAndConstructDescriptor, CallInterfaceDescriptor) }; -class InterpreterPushArgsThenConstructArrayDescriptor +class InterpreterPushArgsAndConstructArrayDescriptor : public CallInterfaceDescriptor { public: DEFINE_PARAMETERS(kNumberOfArguments, kFunction, kFeedbackElement, kFirstArgument) DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( - InterpreterPushArgsThenConstructArrayDescriptor, CallInterfaceDescriptor) + InterpreterPushArgsAndConstructArrayDescriptor, CallInterfaceDescriptor) }; class InterpreterCEntryDescriptor : public CallInterfaceDescriptor { diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc index 27412acb74..e4016b6872 100644 --- a/src/interpreter/bytecode-array-builder.cc +++ b/src/interpreter/bytecode-array-builder.cc @@ -1252,50 +1252,42 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) { return *this; } -BytecodeArrayBuilder& BytecodeArrayBuilder::CallProperty(Register callable, - RegisterList args, - int feedback_slot) { - if (args.register_count() == 1) { - OutputCallProperty0(callable, args[0], feedback_slot); - } else if (args.register_count() == 2) { - OutputCallProperty1(callable, args[0], args[1], feedback_slot); - } else if (args.register_count() == 3) { - OutputCallProperty2(callable, args[0], args[1], args[2], feedback_slot); +BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, + RegisterList args, + int feedback_slot, + Call::CallType call_type, + TailCallMode tail_call_mode) { + if (tail_call_mode == TailCallMode::kDisallow) { + if (call_type == Call::NAMED_PROPERTY_CALL || + call_type == Call::KEYED_PROPERTY_CALL) { + if (args.register_count() == 1) { + OutputCallProperty0(callable, args[0], feedback_slot); + } else if (args.register_count() == 2) { + OutputCallProperty1(callable, args[0], args[1], feedback_slot); + } else if (args.register_count() == 3) { + OutputCallProperty2(callable, args[0], args[1], args[2], feedback_slot); + } else { + OutputCallProperty(callable, args, args.register_count(), + feedback_slot); + } + } else { + if (args.register_count() == 1) { + OutputCall0(callable, args[0], feedback_slot); + } else if (args.register_count() == 2) { + OutputCall1(callable, args[0], args[1], feedback_slot); + } else if (args.register_count() == 3) { + OutputCall2(callable, args[0], args[1], args[2], feedback_slot); + } else { + OutputCall(callable, args, args.register_count(), feedback_slot); + } + } } else { - OutputCallProperty(callable, args, args.register_count(), feedback_slot); + DCHECK(tail_call_mode == TailCallMode::kAllow); + OutputTailCall(callable, args, args.register_count(), feedback_slot); } return *this; } -BytecodeArrayBuilder& BytecodeArrayBuilder::CallUndefinedReceiver( - Register callable, RegisterList args, int feedback_slot) { - if (args.register_count() == 0) { - OutputCallUndefinedReceiver0(callable, feedback_slot); - } else if (args.register_count() == 1) { - OutputCallUndefinedReceiver1(callable, args[0], feedback_slot); - } else if (args.register_count() == 2) { - OutputCallUndefinedReceiver2(callable, args[0], args[1], feedback_slot); - } else { - OutputCallUndefinedReceiver(callable, args, args.register_count(), - feedback_slot); - } - return *this; -} - -BytecodeArrayBuilder& BytecodeArrayBuilder::CallAnyReceiver(Register callable, - RegisterList args, - int feedback_slot) { - OutputCallAnyReceiver(callable, args, args.register_count(), feedback_slot); - return *this; -} - -BytecodeArrayBuilder& BytecodeArrayBuilder::TailCall(Register callable, - RegisterList args, - int feedback_slot) { - OutputTailCall(callable, args, args.register_count(), feedback_slot); - return *this; -} - BytecodeArrayBuilder& BytecodeArrayBuilder::CallWithSpread(Register callable, RegisterList args) { OutputCallWithSpread(callable, args, args.register_count()); diff --git a/src/interpreter/bytecode-array-builder.h b/src/interpreter/bytecode-array-builder.h index bc6d5a39d4..82cb748ea0 100644 --- a/src/interpreter/bytecode-array-builder.h +++ b/src/interpreter/bytecode-array-builder.h @@ -238,35 +238,14 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final // Pop the current context and replace with |context|. BytecodeArrayBuilder& PopContext(Register context); - // Call a JS function which is known to be a property of a JS object. The - // JSFunction or Callable to be called should be in |callable|. The arguments - // should be in |args|, with the receiver in |args[0]|. The call type of the - // expression is in |call_type|. Type feedback is recorded in the - // |feedback_slot| in the type feedback vector. - BytecodeArrayBuilder& CallProperty(Register callable, RegisterList args, - int feedback_slot); - - // Call a JS function with an known undefined receiver. The JSFunction or - // Callable to be called should be in |callable|. The arguments should be in - // |args|, with no receiver as it is implicitly set to undefined. Type - // feedback is recorded in the |feedback_slot| in the type feedback vector. - BytecodeArrayBuilder& CallUndefinedReceiver(Register callable, - RegisterList args, - int feedback_slot); - - // Call a JS function with an any receiver, possibly (but not necessarily) - // undefined. The JSFunction or Callable to be called should be in |callable|. - // The arguments should be in |args|, with the receiver in |args[0]|. Type - // feedback is recorded in the |feedback_slot| in the type feedback vector. - BytecodeArrayBuilder& CallAnyReceiver(Register callable, RegisterList args, - int feedback_slot); - - // Tail call into a JS function. The JSFunction or Callable to be called - // should be in |callable|. The arguments should be in |args|, with the - // receiver in |args[0]|. Type feedback is recorded in the |feedback_slot| in - // the type feedback vector. - BytecodeArrayBuilder& TailCall(Register callable, RegisterList args, - int feedback_slot); + // Call a JS function. The JSFunction or Callable to be called should be in + // |callable|. The arguments should be in |args|, with the receiver in + // |args[0]|. The call type of the expression is in |call_type|. Type feedback + // is recorded in the |feedback_slot| in the type feedback vector. + BytecodeArrayBuilder& Call( + Register callable, RegisterList args, int feedback_slot, + Call::CallType call_type, + TailCallMode tail_call_mode = TailCallMode::kDisallow); // Call a JS function. The JSFunction or Callable to be called should be in // |callable|, the receiver in |args[0]| and the arguments in |args[1]| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc index 7e424f16cc..75d892aef0 100644 --- a/src/interpreter/bytecode-generator.cc +++ b/src/interpreter/bytecode-generator.cc @@ -2597,12 +2597,6 @@ void BytecodeGenerator::VisitCall(Call* expr) { Register callee = register_allocator()->NewRegister(); RegisterList args = register_allocator()->NewGrowableRegisterList(); - bool implicit_undefined_receiver = false; - bool is_tail_call = (expr->tail_call_mode() == TailCallMode::kAllow); - // When a call contains a spread, a Call AST node is only created if there is - // exactly one spread, and it is the last argument. - bool is_spread_call = expr->only_last_arg_is_spread(); - // TODO(petermarshall): We have a lot of call bytecodes that are very similar, // see if we can reduce the number by adding a separate argument which // specifies the call type (e.g., property, spread, tailcall, etc.). @@ -2619,13 +2613,7 @@ void BytecodeGenerator::VisitCall(Call* expr) { } case Call::GLOBAL_CALL: { // Receiver is undefined for global calls. - if (!is_tail_call && !is_spread_call) { - implicit_undefined_receiver = true; - } else { - // TODO(leszeks): There's no special bytecode for tail calls or spread - // calls with an undefined receiver, so just push undefined ourselves. - BuildPushUndefinedIntoRegisterList(&args); - } + BuildPushUndefinedIntoRegisterList(&args); // Load callee as a global variable. VariableProxy* proxy = callee_expr->AsVariableProxy(); BuildVariableLoadForAccumulatorValue(proxy->var(), @@ -2645,7 +2633,6 @@ void BytecodeGenerator::VisitCall(Call* expr) { DCHECK(Register::AreContiguous(callee, receiver)); RegisterList result_pair(callee.index(), 2); USE(receiver); - Variable* variable = callee_expr->AsVariableProxy()->var(); builder() ->LoadLiteral(variable->raw_name()) @@ -2656,14 +2643,7 @@ void BytecodeGenerator::VisitCall(Call* expr) { break; } case Call::OTHER_CALL: { - // Receiver is undefined for other calls. - if (!is_tail_call && !is_spread_call) { - implicit_undefined_receiver = true; - } else { - // TODO(leszeks): There's no special bytecode for tail calls or spread - // calls with an undefined receiver, so just push undefined ourselves. - BuildPushUndefinedIntoRegisterList(&args); - } + BuildPushUndefinedIntoRegisterList(&args); VisitForRegisterValue(callee_expr, callee); break; } @@ -2689,9 +2669,7 @@ void BytecodeGenerator::VisitCall(Call* expr) { // Evaluate all arguments to the function call and store in sequential args // registers. VisitArguments(expr->arguments(), &args); - int reciever_arg_count = implicit_undefined_receiver ? 0 : 1; - CHECK_EQ(reciever_arg_count + expr->arguments()->length(), - args.register_count()); + CHECK_EQ(expr->arguments()->length() + 1, args.register_count()); // Resolve callee for a potential direct eval call. This block will mutate the // callee value. @@ -2700,11 +2678,10 @@ void BytecodeGenerator::VisitCall(Call* expr) { // Set up arguments for ResolvePossiblyDirectEval by copying callee, source // strings and function closure, and loading language and // position. - Register first_arg = args[reciever_arg_count]; RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); builder() ->MoveRegister(callee, runtime_call_args[0]) - .MoveRegister(first_arg, runtime_call_args[1]) + .MoveRegister(args[1], runtime_call_args[1]) .MoveRegister(Register::function_closure(), runtime_call_args[2]) .LoadLiteral(Smi::FromInt(language_mode())) .StoreAccumulatorInRegister(runtime_call_args[3]) @@ -2721,23 +2698,15 @@ void BytecodeGenerator::VisitCall(Call* expr) { builder()->SetExpressionPosition(expr); - int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); - - if (is_spread_call) { - DCHECK(!is_tail_call); - DCHECK(!implicit_undefined_receiver); + // When a call contains a spread, a Call AST node is only created if there is + // exactly one spread, and it is the last argument. + if (expr->only_last_arg_is_spread()) { + DCHECK_EQ(TailCallMode::kDisallow, expr->tail_call_mode()); builder()->CallWithSpread(callee, args); - } else if (is_tail_call) { - DCHECK(!implicit_undefined_receiver); - builder()->TailCall(callee, args, feedback_slot_index); - } else if (call_type == Call::NAMED_PROPERTY_CALL || - call_type == Call::KEYED_PROPERTY_CALL) { - DCHECK(!implicit_undefined_receiver); - builder()->CallProperty(callee, args, feedback_slot_index); - } else if (implicit_undefined_receiver) { - builder()->CallUndefinedReceiver(callee, args, feedback_slot_index); } else { - builder()->CallAnyReceiver(callee, args, feedback_slot_index); + int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); + builder()->Call(callee, args, feedback_slot_index, call_type, + expr->tail_call_mode()); } } @@ -2799,8 +2768,6 @@ void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { if (expr->is_jsruntime()) { RegisterList args = register_allocator()->NewGrowableRegisterList(); // Allocate a register for the receiver and load it with undefined. - // TODO(leszeks): If CallJSRuntime always has an undefined receiver, use the - // same mechanism as CallUndefinedReceiver. BuildPushUndefinedIntoRegisterList(&args); VisitArguments(expr->arguments(), &args); builder()->CallJSRuntime(expr->context_index(), args); @@ -3186,8 +3153,9 @@ void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { builder()->JumpIfNull(&async_iterator_null); // Let iterator be Call(method, obj) - builder()->StoreAccumulatorInRegister(method).CallProperty( - method, args, feedback_index(async_call_slot)); + builder()->StoreAccumulatorInRegister(method).Call( + method, args, feedback_index(async_call_slot), + Call::NAMED_PROPERTY_CALL); // If Type(iterator) is not Object, throw a TypeError exception. builder()->JumpIfJSReceiver(&done); @@ -3202,7 +3170,8 @@ void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { .StoreAccumulatorInRegister(method); // Let syncIterator be Call(syncMethod, obj) - builder()->CallProperty(method, args, feedback_index(call_slot)); + builder()->Call(method, args, feedback_index(call_slot), + Call::NAMED_PROPERTY_CALL); // Return CreateAsyncFromSyncIterator(syncIterator) // alias `method` register as it's no longer used @@ -3219,7 +3188,8 @@ void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { .StoreAccumulatorInRegister(method); // Let iterator be Call(method, obj). - builder()->CallProperty(method, args, feedback_index(call_slot)); + builder()->Call(method, args, feedback_index(call_slot), + Call::NAMED_PROPERTY_CALL); // If Type(iterator) is not Object, throw a TypeError exception. BytecodeLabel no_type_error; diff --git a/src/interpreter/bytecodes.cc b/src/interpreter/bytecodes.cc index d0665b9ea9..f7fb7edde1 100644 --- a/src/interpreter/bytecodes.cc +++ b/src/interpreter/bytecodes.cc @@ -238,15 +238,8 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) { case Bytecode::kInc: case Bytecode::kDec: case Bytecode::kTypeOf: - case Bytecode::kCallAnyReceiver: + case Bytecode::kCall: case Bytecode::kCallProperty: - case Bytecode::kCallProperty0: - case Bytecode::kCallProperty1: - case Bytecode::kCallProperty2: - case Bytecode::kCallUndefinedReceiver: - case Bytecode::kCallUndefinedReceiver0: - case Bytecode::kCallUndefinedReceiver1: - case Bytecode::kCallUndefinedReceiver2: case Bytecode::kConstruct: case Bytecode::kConstructWithSpread: return true; diff --git a/src/interpreter/bytecodes.h b/src/interpreter/bytecodes.h index baf9e88963..530e8a748d 100644 --- a/src/interpreter/bytecodes.h +++ b/src/interpreter/bytecodes.h @@ -158,8 +158,14 @@ namespace interpreter { V(GetSuperConstructor, AccumulatorUse::kRead, OperandType::kRegOut) \ \ /* Call operations */ \ - V(CallAnyReceiver, AccumulatorUse::kWrite, OperandType::kReg, \ - OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ + V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kRegList, \ + OperandType::kRegCount, OperandType::kIdx) \ + V(Call0, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ + OperandType::kIdx) \ + V(Call1, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ + OperandType::kReg, OperandType::kIdx) \ + V(Call2, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ + OperandType::kReg, OperandType::kReg, OperandType::kIdx) \ V(CallProperty, AccumulatorUse::kWrite, OperandType::kReg, \ OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ V(CallProperty0, AccumulatorUse::kWrite, OperandType::kReg, \ @@ -169,14 +175,6 @@ namespace interpreter { V(CallProperty2, AccumulatorUse::kWrite, OperandType::kReg, \ OperandType::kReg, OperandType::kReg, OperandType::kReg, \ OperandType::kIdx) \ - V(CallUndefinedReceiver, AccumulatorUse::kWrite, OperandType::kReg, \ - OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \ - V(CallUndefinedReceiver0, AccumulatorUse::kWrite, OperandType::kReg, \ - OperandType::kIdx) \ - V(CallUndefinedReceiver1, AccumulatorUse::kWrite, OperandType::kReg, \ - OperandType::kReg, OperandType::kIdx) \ - V(CallUndefinedReceiver2, AccumulatorUse::kWrite, OperandType::kReg, \ - OperandType::kReg, OperandType::kReg, OperandType::kIdx) \ V(CallWithSpread, AccumulatorUse::kWrite, OperandType::kReg, \ OperandType::kRegList, OperandType::kRegCount) \ V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, \ @@ -434,7 +432,7 @@ enum class Bytecode : uint8_t { class V8_EXPORT_PRIVATE Bytecodes final { public: - // The maximum number of operands a bytecode may have. + // The maximum number of operands a bytecode may have. static const int kMaxOperands = 5; // Returns string representation of |bytecode|. @@ -627,15 +625,13 @@ class V8_EXPORT_PRIVATE Bytecodes final { // Returns true if the bytecode is a call or a constructor call. static constexpr bool IsCallOrConstruct(Bytecode bytecode) { - return bytecode == Bytecode::kCallAnyReceiver || - bytecode == Bytecode::kCallProperty || + return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty || + bytecode == Bytecode::kCall0 || bytecode == Bytecode::kCallProperty0 || + bytecode == Bytecode::kCall1 || bytecode == Bytecode::kCallProperty1 || + bytecode == Bytecode::kCall2 || bytecode == Bytecode::kCallProperty2 || - bytecode == Bytecode::kCallUndefinedReceiver || - bytecode == Bytecode::kCallUndefinedReceiver0 || - bytecode == Bytecode::kCallUndefinedReceiver1 || - bytecode == Bytecode::kCallUndefinedReceiver2 || bytecode == Bytecode::kTailCall || bytecode == Bytecode::kConstruct || bytecode == Bytecode::kCallWithSpread || @@ -750,34 +746,6 @@ class V8_EXPORT_PRIVATE Bytecodes final { // through the bytecode's handler. static bool MakesCallAlongCriticalPath(Bytecode bytecode); - // Returns the receiver mode of the given call bytecode. - static ConvertReceiverMode GetReceiverMode(Bytecode bytecode) { - DCHECK(IsCallOrConstruct(bytecode)); - switch (bytecode) { - case Bytecode::kCallProperty: - case Bytecode::kCallProperty0: - case Bytecode::kCallProperty1: - case Bytecode::kCallProperty2: - return ConvertReceiverMode::kNotNullOrUndefined; - case Bytecode::kCallUndefinedReceiver: - case Bytecode::kCallUndefinedReceiver0: - case Bytecode::kCallUndefinedReceiver1: - case Bytecode::kCallUndefinedReceiver2: - return ConvertReceiverMode::kNullOrUndefined; - case Bytecode::kCallAnyReceiver: - case Bytecode::kTailCall: - case Bytecode::kConstruct: - case Bytecode::kCallWithSpread: - case Bytecode::kConstructWithSpread: - case Bytecode::kInvokeIntrinsic: - case Bytecode::kCallJSRuntime: - return ConvertReceiverMode::kAny; - default: - UNREACHABLE(); - return ConvertReceiverMode::kAny; - } - } - // Returns true if the bytecode is a debug break. static bool IsDebugBreak(Bytecode bytecode); diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc index e76a9ed407..9fdfa615b1 100644 --- a/src/interpreter/interpreter-assembler.cc +++ b/src/interpreter/interpreter-assembler.cc @@ -555,11 +555,11 @@ Node* InterpreterAssembler::IncrementCallCount(Node* feedback_vector, SKIP_WRITE_BARRIER); } -Node* InterpreterAssembler::CallJSWithFeedback( - compiler::Node* function, compiler::Node* context, - compiler::Node* first_arg, compiler::Node* arg_count, - compiler::Node* slot_id, compiler::Node* feedback_vector, - ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode) { +Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, + Node* first_arg, Node* arg_count, + Node* slot_id, + Node* feedback_vector, + TailCallMode tail_call_mode) { // Static checks to assert it is safe to examine the type feedback element. // We don't know that we have a weak cell. We might have a private symbol // or an AllocationSite, but the memory is safe to examine. @@ -572,8 +572,6 @@ Node* InterpreterAssembler::CallJSWithFeedback( // to be a pointer. DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); DCHECK(Bytecodes::IsCallOrConstruct(bytecode_)); - DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), receiver_mode); - STATIC_ASSERT(WeakCell::kSize >= kPointerSize); STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == WeakCell::kValueOffset && @@ -600,9 +598,8 @@ Node* InterpreterAssembler::CallJSWithFeedback( IncrementCallCount(feedback_vector, slot_id); // Call using call function builtin. - Callable callable = CodeFactory::InterpreterPushArgsThenCall( - isolate(), receiver_mode, tail_call_mode, - InterpreterPushArgsMode::kJSFunction); + Callable callable = CodeFactory::InterpreterPushArgsAndCall( + isolate(), tail_call_mode, InterpreterPushArgsMode::kJSFunction); Node* code_target = HeapConstant(callable.code()); Node* ret_value = CallStub(callable.descriptor(), code_target, context, arg_count, first_arg, function); @@ -626,33 +623,24 @@ Node* InterpreterAssembler::CallJSWithFeedback( GotoIfNot(IsAllocationSiteMap(LoadMap(feedback_element)), &check_initialized); - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - // For undefined receivers (mostly global calls), do an additional check - // for the monomorphic Array function, which would otherwise appear - // megamorphic. + // If it is not the Array() function, mark megamorphic. + Node* context_slot = LoadContextElement(LoadNativeContext(context), + Context::ARRAY_FUNCTION_INDEX); + Node* is_array_function = WordEqual(context_slot, function); + GotoIfNot(is_array_function, &mark_megamorphic); - // If it is not the Array() function, mark megamorphic. - Node* context_slot = LoadContextElement(LoadNativeContext(context), - Context::ARRAY_FUNCTION_INDEX); - Node* is_array_function = WordEqual(context_slot, function); - GotoIfNot(is_array_function, &mark_megamorphic); + // It is a monomorphic Array function. Increment the call count. + IncrementCallCount(feedback_vector, slot_id); - // It is a monomorphic Array function. Increment the call count. - IncrementCallCount(feedback_vector, slot_id); - - // Call ArrayConstructorStub. - Callable callable_call = - CodeFactory::InterpreterPushArgsThenConstructArray(isolate()); - Node* code_target_call = HeapConstant(callable_call.code()); - Node* ret_value = - CallStub(callable_call.descriptor(), code_target_call, context, - arg_count, function, feedback_element, first_arg); - return_value.Bind(ret_value); - Goto(&end); - - } else { - Goto(&mark_megamorphic); - } + // Call ArrayConstructorStub. + Callable callable_call = + CodeFactory::InterpreterPushArgsAndConstructArray(isolate()); + Node* code_target_call = HeapConstant(callable_call.code()); + Node* ret_value = + CallStub(callable_call.descriptor(), code_target_call, context, + arg_count, function, feedback_element, first_arg); + return_value.Bind(ret_value); + Goto(&end); Bind(&check_initialized); { @@ -663,7 +651,7 @@ Node* InterpreterAssembler::CallJSWithFeedback( HeapConstant(FeedbackVector::UninitializedSentinel(isolate()))); GotoIfNot(is_uninitialized, &mark_megamorphic); - Comment("handle_uninitialized"); + Comment("handle_unitinitialized"); // If it is not a JSFunction mark it as megamorphic. Node* is_smi = TaggedIsSmi(function); GotoIf(is_smi, &mark_megamorphic); @@ -725,9 +713,8 @@ Node* InterpreterAssembler::CallJSWithFeedback( IncrementCallCount(feedback_vector, slot_id); // Call using call builtin. - Callable callable_call = CodeFactory::InterpreterPushArgsThenCall( - isolate(), receiver_mode, tail_call_mode, - InterpreterPushArgsMode::kOther); + Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( + isolate(), tail_call_mode, InterpreterPushArgsMode::kOther); Node* code_target_call = HeapConstant(callable_call.code()); Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, context, arg_count, first_arg, function); @@ -741,14 +728,11 @@ Node* InterpreterAssembler::CallJSWithFeedback( Node* InterpreterAssembler::CallJS(Node* function, Node* context, Node* first_arg, Node* arg_count, - ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode) { DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); DCHECK(Bytecodes::IsCallOrConstruct(bytecode_)); - DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), receiver_mode); - Callable callable = CodeFactory::InterpreterPushArgsThenCall( - isolate(), receiver_mode, tail_call_mode, - InterpreterPushArgsMode::kOther); + Callable callable = CodeFactory::InterpreterPushArgsAndCall( + isolate(), tail_call_mode, InterpreterPushArgsMode::kOther); Node* code_target = HeapConstant(callable.code()); return CallStub(callable.descriptor(), code_target, context, arg_count, @@ -758,9 +742,8 @@ Node* InterpreterAssembler::CallJS(Node* function, Node* context, Node* InterpreterAssembler::CallJSWithSpread(Node* function, Node* context, Node* first_arg, Node* arg_count) { DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); - DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), ConvertReceiverMode::kAny); - Callable callable = CodeFactory::InterpreterPushArgsThenCall( - isolate(), ConvertReceiverMode::kAny, TailCallMode::kDisallow, + Callable callable = CodeFactory::InterpreterPushArgsAndCall( + isolate(), TailCallMode::kDisallow, InterpreterPushArgsMode::kWithFinalSpread); Node* code_target = HeapConstant(callable.code()); @@ -804,7 +787,7 @@ Node* InterpreterAssembler::Construct(Node* constructor, Node* context, { Comment("call using ConstructFunction"); IncrementCallCount(feedback_vector, slot_id); - Callable callable_function = CodeFactory::InterpreterPushArgsThenConstruct( + Callable callable_function = CodeFactory::InterpreterPushArgsAndConstruct( isolate(), InterpreterPushArgsMode::kJSFunction); return_value.Bind(CallStub(callable_function.descriptor(), HeapConstant(callable_function.code()), context, @@ -907,7 +890,7 @@ Node* InterpreterAssembler::Construct(Node* constructor, Node* context, Bind(&call_construct); { Comment("call using Construct builtin"); - Callable callable = CodeFactory::InterpreterPushArgsThenConstruct( + Callable callable = CodeFactory::InterpreterPushArgsAndConstruct( isolate(), InterpreterPushArgsMode::kOther); Node* code_target = HeapConstant(callable.code()); return_value.Bind(CallStub(callable.descriptor(), code_target, context, @@ -927,7 +910,7 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* constructor, DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); Variable return_value(this, MachineRepresentation::kTagged); Comment("call using ConstructWithSpread"); - Callable callable = CodeFactory::InterpreterPushArgsThenConstruct( + Callable callable = CodeFactory::InterpreterPushArgsAndConstruct( isolate(), InterpreterPushArgsMode::kWithFinalSpread); Node* code_target = HeapConstant(callable.code()); return_value.Bind(CallStub(callable.descriptor(), code_target, context, diff --git a/src/interpreter/interpreter-assembler.h b/src/interpreter/interpreter-assembler.h index f534ea3ba7..498f50aae5 100644 --- a/src/interpreter/interpreter-assembler.h +++ b/src/interpreter/interpreter-assembler.h @@ -118,25 +118,23 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { compiler::Node* IncrementCallCount(compiler::Node* feedback_vector, compiler::Node* slot_id); - // Call JSFunction or Callable |function| with |arg_count| arguments (not - // including receiver) and the first argument located at |first_arg|. Type - // feedback is collected in the slot at index |slot_id|. - // - // If the |receiver_mode| is kNullOrUndefined, then the receiver is implicitly - // undefined and |first_arg| is the first parameter. Otherwise, |first_arg| is - // the receiver and it is converted according to |receiver_mode|. - compiler::Node* CallJSWithFeedback( - compiler::Node* function, compiler::Node* context, - compiler::Node* first_arg, compiler::Node* arg_count, - compiler::Node* slot_id, compiler::Node* feedback_vector, - ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode); + // Call JSFunction or Callable |function| with |arg_count| + // arguments (not including receiver) and the first argument + // located at |first_arg|. Type feedback is collected in the + // slot at index |slot_id|. + compiler::Node* CallJSWithFeedback(compiler::Node* function, + compiler::Node* context, + compiler::Node* first_arg, + compiler::Node* arg_count, + compiler::Node* slot_id, + compiler::Node* feedback_vector, + TailCallMode tail_call_mode); - // Call JSFunction or Callable |function| with |arg_count| arguments (not - // including receiver) and the first argument located at |first_arg|, possibly - // including the receiver depending on |receiver_mode|. + // Call JSFunction or Callable |function| with |arg_count| + // arguments (not including receiver) and the first argument + // located at |first_arg|. compiler::Node* CallJS(compiler::Node* function, compiler::Node* context, compiler::Node* first_arg, compiler::Node* arg_count, - ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode); // Call JSFunction or Callable |function| with |arg_count| diff --git a/src/interpreter/interpreter-generator.cc b/src/interpreter/interpreter-generator.cc index 5edcb384b8..9b78a19087 100644 --- a/src/interpreter/interpreter-generator.cc +++ b/src/interpreter/interpreter-generator.cc @@ -73,13 +73,11 @@ class InterpreterGenerator { void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler); // Generates code to perform a JS call that collects type feedback. - void DoJSCall(InterpreterAssembler* assembler, - ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode); + void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode); // Generates code to perform a JS call with a known number of arguments that // collects type feedback. - void DoJSCallN(InterpreterAssembler* assembler, int n, - ConvertReceiverMode receiver_mode); + void DoJSCallN(InterpreterAssembler* assembler, int n); // Generates code to perform delete via function_id. void DoDelete(Runtime::FunctionId function_id, @@ -2324,78 +2322,50 @@ void InterpreterGenerator::DoGetSuperConstructor( } void InterpreterGenerator::DoJSCall(InterpreterAssembler* assembler, - ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode) { Node* function_reg = __ BytecodeOperandReg(0); Node* function = __ LoadRegister(function_reg); - Node* first_arg_reg = __ BytecodeOperandReg(1); - Node* first_arg = __ RegisterLocation(first_arg_reg); - Node* arg_list_count = __ BytecodeOperandCount(2); - Node* args_count; - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - // The receiver is implied, so it is not in the argument list. - args_count = arg_list_count; - } else { - // Subtract the receiver from the argument count. - Node* receiver_count = __ Int32Constant(1); - args_count = __ Int32Sub(arg_list_count, receiver_count); - } + Node* receiver_reg = __ BytecodeOperandReg(1); + Node* receiver_arg = __ RegisterLocation(receiver_reg); + Node* receiver_args_count = __ BytecodeOperandCount(2); + Node* receiver_count = __ Int32Constant(1); + Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); Node* slot_id = __ BytecodeOperandIdx(3); Node* feedback_vector = __ LoadFeedbackVector(); Node* context = __ GetContext(); Node* result = - __ CallJSWithFeedback(function, context, first_arg, args_count, slot_id, - feedback_vector, receiver_mode, tail_call_mode); + __ CallJSWithFeedback(function, context, receiver_arg, args_count, + slot_id, feedback_vector, tail_call_mode); __ SetAccumulator(result); __ Dispatch(); } void InterpreterGenerator::DoJSCallN(InterpreterAssembler* assembler, - int arg_count, - ConvertReceiverMode receiver_mode) { - // Indices and counts of operands on the bytecode. - const int kFirstArgumentOperandIndex = 1; - const int kReceiverOperandCount = - (receiver_mode == ConvertReceiverMode::kNullOrUndefined) ? 0 : 1; + int arg_count) { + const int kReceiverOperandIndex = 1; + const int kReceiverOperandCount = 1; const int kSlotOperandIndex = - kFirstArgumentOperandIndex + kReceiverOperandCount + arg_count; - // Indices and counts of parameters to the call stub. - const int kBoilerplateParameterCount = 7; + kReceiverOperandIndex + kReceiverOperandCount + arg_count; + const int kBoilerplatParameterCount = 7; const int kReceiverParameterIndex = 5; - const int kReceiverParameterCount = 1; - // Only used in a DCHECK. - USE(kReceiverParameterCount); Node* function_reg = __ BytecodeOperandReg(0); Node* function = __ LoadRegister(function_reg); - std::array temp; + std::array temp; Callable call_ic = CodeFactory::CallIC(isolate_); temp[0] = __ HeapConstant(call_ic.code()); temp[1] = function; temp[2] = __ Int32Constant(arg_count); temp[3] = __ BytecodeOperandIdxInt32(kSlotOperandIndex); temp[4] = __ LoadFeedbackVector(); - - int parameter_index = kReceiverParameterIndex; - if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { - // The first argument parameter (the receiver) is implied to be undefined. - Node* undefined_value = - __ HeapConstant(isolate_->factory()->undefined_value()); - temp[parameter_index++] = undefined_value; + for (int i = 0; i < (arg_count + kReceiverOperandCount); ++i) { + Node* reg = __ BytecodeOperandReg(i + kReceiverOperandIndex); + temp[kReceiverParameterIndex + i] = __ LoadRegister(reg); } - // The bytecode argument operands are copied into the remaining argument - // parameters. - for (int i = 0; i < (kReceiverOperandCount + arg_count); ++i) { - Node* reg = __ BytecodeOperandReg(kFirstArgumentOperandIndex + i); - temp[parameter_index++] = __ LoadRegister(reg); - } - - DCHECK_EQ(parameter_index, - kReceiverParameterIndex + kReceiverParameterCount + arg_count); - temp[parameter_index] = __ GetContext(); - + temp[kReceiverParameterIndex + arg_count + kReceiverOperandCount] = + __ GetContext(); Node* result = __ CallStubN(call_ic.descriptor(), 1, - arg_count + kBoilerplateParameterCount, &temp[0]); + arg_count + kBoilerplatParameterCount, &temp[0]); __ SetAccumulator(result); __ Dispatch(); } @@ -2405,46 +2375,40 @@ void InterpreterGenerator::DoJSCallN(InterpreterAssembler* assembler, // Call a JSfunction or Callable in |callable| with the |receiver| and // |arg_count| arguments in subsequent registers. Collect type feedback // into |feedback_slot_id| -void InterpreterGenerator::DoCallAnyReceiver(InterpreterAssembler* assembler) { - DoJSCall(assembler, ConvertReceiverMode::kAny, TailCallMode::kDisallow); +void InterpreterGenerator::DoCall(InterpreterAssembler* assembler) { + DoJSCall(assembler, TailCallMode::kDisallow); +} + +void InterpreterGenerator::DoCall0(InterpreterAssembler* assembler) { + DoJSCallN(assembler, 0); +} + +void InterpreterGenerator::DoCall1(InterpreterAssembler* assembler) { + DoJSCallN(assembler, 1); +} + +void InterpreterGenerator::DoCall2(InterpreterAssembler* assembler) { + DoJSCallN(assembler, 2); } void InterpreterGenerator::DoCallProperty(InterpreterAssembler* assembler) { - DoJSCall(assembler, ConvertReceiverMode::kNotNullOrUndefined, - TailCallMode::kDisallow); + // Same as Call + UNREACHABLE(); } void InterpreterGenerator::DoCallProperty0(InterpreterAssembler* assembler) { - DoJSCallN(assembler, 0, ConvertReceiverMode::kNotNullOrUndefined); + // Same as Call0 + UNREACHABLE(); } void InterpreterGenerator::DoCallProperty1(InterpreterAssembler* assembler) { - DoJSCallN(assembler, 1, ConvertReceiverMode::kNotNullOrUndefined); + // Same as Call1 + UNREACHABLE(); } void InterpreterGenerator::DoCallProperty2(InterpreterAssembler* assembler) { - DoJSCallN(assembler, 2, ConvertReceiverMode::kNotNullOrUndefined); -} - -void InterpreterGenerator::DoCallUndefinedReceiver( - InterpreterAssembler* assembler) { - DoJSCall(assembler, ConvertReceiverMode::kNullOrUndefined, - TailCallMode::kDisallow); -} - -void InterpreterGenerator::DoCallUndefinedReceiver0( - InterpreterAssembler* assembler) { - DoJSCallN(assembler, 0, ConvertReceiverMode::kNullOrUndefined); -} - -void InterpreterGenerator::DoCallUndefinedReceiver1( - InterpreterAssembler* assembler) { - DoJSCallN(assembler, 1, ConvertReceiverMode::kNullOrUndefined); -} - -void InterpreterGenerator::DoCallUndefinedReceiver2( - InterpreterAssembler* assembler) { - DoJSCallN(assembler, 2, ConvertReceiverMode::kNullOrUndefined); + // Same as Call2 + UNREACHABLE(); } // TailCall @@ -2453,7 +2417,7 @@ void InterpreterGenerator::DoCallUndefinedReceiver2( // |arg_count| arguments in subsequent registers. Collect type feedback // into |feedback_slot_id| void InterpreterGenerator::DoTailCall(InterpreterAssembler* assembler) { - DoJSCall(assembler, ConvertReceiverMode::kAny, TailCallMode::kAllow); + DoJSCall(assembler, TailCallMode::kAllow); } // CallRuntime @@ -2533,7 +2497,7 @@ void InterpreterGenerator::DoCallJSRuntime(InterpreterAssembler* assembler) { // Call the function. Node* result = __ CallJS(function, context, first_arg, args_count, - ConvertReceiverMode::kAny, TailCallMode::kDisallow); + TailCallMode::kDisallow); __ SetAccumulator(result); __ Dispatch(); } diff --git a/src/interpreter/interpreter-intrinsics-generator.cc b/src/interpreter/interpreter-intrinsics-generator.cc index bdd079ab84..923dec97a8 100644 --- a/src/interpreter/interpreter-intrinsics-generator.cc +++ b/src/interpreter/interpreter-intrinsics-generator.cc @@ -309,7 +309,7 @@ Node* IntrinsicsGenerator::Call(Node* args_reg, Node* arg_count, } Node* result = __ CallJS(function, context, receiver_arg, target_args_count, - ConvertReceiverMode::kAny, TailCallMode::kDisallow); + TailCallMode::kDisallow); return result; } diff --git a/src/interpreter/setup-interpreter-internal.cc b/src/interpreter/setup-interpreter-internal.cc index 0fb03f8d55..1477ee8c7b 100644 --- a/src/interpreter/setup-interpreter-internal.cc +++ b/src/interpreter/setup-interpreter-internal.cc @@ -52,8 +52,28 @@ void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) { bool SetupInterpreter::ReuseExistingHandler(Address* dispatch_table, Bytecode bytecode, OperandScale operand_scale) { - // TODO(leszeks): reuse Lda[Immutable][Current]ContextSlot - return false; + size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale); + switch (bytecode) { + case Bytecode::kCallProperty: + case Bytecode::kCallProperty0: + case Bytecode::kCallProperty1: + case Bytecode::kCallProperty2: { + const int offset = static_cast(Bytecode::kCallProperty) - + static_cast(Bytecode::kCall); + STATIC_ASSERT(offset == static_cast(Bytecode::kCallProperty0) - + static_cast(Bytecode::kCall0)); + STATIC_ASSERT(offset == static_cast(Bytecode::kCallProperty1) - + static_cast(Bytecode::kCall1)); + STATIC_ASSERT(offset == static_cast(Bytecode::kCallProperty2) - + static_cast(Bytecode::kCall2)); + CHECK_LT(offset, index); + dispatch_table[index] = dispatch_table[index - offset]; + return true; + break; + } + default: + return false; + } } // static diff --git a/src/mips/interface-descriptors-mips.cc b/src/mips/interface-descriptors-mips.cc index 6e77ee835a..0c6a42cb48 100644 --- a/src/mips/interface-descriptors-mips.cc +++ b/src/mips/interface-descriptors-mips.cc @@ -314,7 +314,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { a0, // argument count (not including receiver) @@ -324,7 +324,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { a0, // argument count (not including receiver) @@ -336,8 +336,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { a0, // argument count (not including receiver) a1, // the target to call verified to be Array function diff --git a/src/mips64/interface-descriptors-mips64.cc b/src/mips64/interface-descriptors-mips64.cc index 8deb518c3b..1630851f52 100644 --- a/src/mips64/interface-descriptors-mips64.cc +++ b/src/mips64/interface-descriptors-mips64.cc @@ -313,7 +313,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { a0, // argument count (not including receiver) @@ -323,7 +323,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { a0, // argument count (not including receiver) @@ -335,8 +335,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { a0, // argument count (not including receiver) a1, // the target to call verified to be Array function diff --git a/src/ppc/interface-descriptors-ppc.cc b/src/ppc/interface-descriptors-ppc.cc index 734ed4af36..73280be373 100644 --- a/src/ppc/interface-descriptors-ppc.cc +++ b/src/ppc/interface-descriptors-ppc.cc @@ -315,7 +315,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { r3, // argument count (not including receiver) @@ -325,7 +325,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { r3, // argument count (not including receiver) @@ -337,8 +337,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { r3, // argument count (not including receiver) r4, // target to call checked to be Array function diff --git a/src/s390/interface-descriptors-s390.cc b/src/s390/interface-descriptors-s390.cc index 091a64583a..5606f2388b 100644 --- a/src/s390/interface-descriptors-s390.cc +++ b/src/s390/interface-descriptors-s390.cc @@ -299,7 +299,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { r2, // argument count (not including receiver) @@ -309,7 +309,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { r2, // argument count (not including receiver) @@ -321,8 +321,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { r2, // argument count (not including receiver) r3, // target to call checked to be Array function diff --git a/src/x64/interface-descriptors-x64.cc b/src/x64/interface-descriptors-x64.cc index dd03f19cbc..f47d221df6 100644 --- a/src/x64/interface-descriptors-x64.cc +++ b/src/x64/interface-descriptors-x64.cc @@ -316,7 +316,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { rax, // argument count (not including receiver) @@ -326,7 +326,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { rax, // argument count (not including receiver) @@ -338,8 +338,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { rax, // argument count (not including receiver) rdx, // target to the call. It is checked to be Array function. diff --git a/src/x87/interface-descriptors-x87.cc b/src/x87/interface-descriptors-x87.cc index 4601e98785..12a90266dd 100644 --- a/src/x87/interface-descriptors-x87.cc +++ b/src/x87/interface-descriptors-x87.cc @@ -330,7 +330,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { eax, // argument count (not including receiver) @@ -340,7 +340,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( +void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = { eax, // argument count (not including receiver) @@ -352,8 +352,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(arraysize(registers), registers); } -void InterpreterPushArgsThenConstructArrayDescriptor:: - InitializePlatformSpecific(CallInterfaceDescriptorData* data) { +void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { Register registers[] = { eax, // argument count (not including receiver) edx, // target to the call. It is checked to be Array function. diff --git a/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden b/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden index c9c96e7a1f..6555c650c3 100644 --- a/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden +++ b/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden @@ -12,14 +12,16 @@ snippet: " function f() { return t(); } f(); " -frame size: 1 +frame size: 2 parameter count: 1 -bytecode array length: 10 +bytecode array length: 14 bytecodes: [ /* 27 E> */ B(StackCheck), - /* 32 S> */ B(LdaGlobal), U8(0), U8(4), + /* 32 S> */ B(LdaUndefined), + B(Star), R(1), + B(LdaGlobal), U8(0), U8(4), B(Star), R(0), - /* 39 E> */ B(CallUndefinedReceiver0), R(0), U8(2), + /* 39 E> */ B(Call0), R(0), R(1), U8(2), /* 44 S> */ B(Return), ] constant pool: [ @@ -34,20 +36,22 @@ snippet: " function f() { return t(1, 2, 3); } f(); " -frame size: 4 +frame size: 5 parameter count: 1 -bytecode array length: 24 +bytecode array length: 27 bytecodes: [ /* 34 E> */ B(StackCheck), - /* 39 S> */ B(LdaGlobal), U8(0), U8(4), + /* 39 S> */ B(LdaUndefined), + B(Star), R(1), + B(LdaGlobal), U8(0), U8(4), B(Star), R(0), B(LdaSmi), I8(1), - B(Star), R(1), - B(LdaSmi), I8(2), B(Star), R(2), - B(LdaSmi), I8(3), + B(LdaSmi), I8(2), B(Star), R(3), - /* 46 E> */ B(CallUndefinedReceiver), R(0), R(1), U8(3), U8(2), + B(LdaSmi), I8(3), + B(Star), R(4), + /* 46 E> */ B(Call), R(0), R(1), U8(4), U8(2), /* 58 S> */ B(Return), ] constant pool: [ diff --git a/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden b/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden index 33681df144..7625179120 100644 --- a/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden +++ b/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden @@ -9,9 +9,9 @@ wrap: yes snippet: " g = function(){}; eval(''); return g(); " -frame size: 9 +frame size: 10 parameter count: 1 -bytecode array length: 73 +bytecode array length: 81 bytecodes: [ B(CreateFunctionContext), U8(3), B(PushContext), R(0), @@ -24,25 +24,29 @@ bytecodes: [ /* 30 E> */ B(StackCheck), /* 34 S> */ B(CreateClosure), U8(0), U8(2), U8(2), /* 36 E> */ B(StaLookupSlotSloppy), U8(1), - /* 52 S> */ B(LdaLookupGlobalSlot), U8(2), U8(5), U8(1), + /* 52 S> */ B(LdaUndefined), + B(Star), R(2), + /* 52 E> */ B(LdaLookupGlobalSlot), U8(2), U8(5), U8(1), B(Star), R(1), B(LdaConstant), U8(3), - B(Star), R(2), + B(Star), R(3), B(LdaZero), - B(Star), R(6), - B(LdaSmi), I8(30), B(Star), R(7), - B(LdaSmi), I8(52), + B(LdaSmi), I8(30), B(Star), R(8), - B(Mov), R(1), R(3), - B(Mov), R(2), R(4), - B(Mov), R(closure), R(5), - B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6), + B(LdaSmi), I8(52), + B(Star), R(9), + B(Mov), R(1), R(4), + B(Mov), R(3), R(5), + B(Mov), R(closure), R(6), + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6), B(Star), R(1), - /* 52 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(3), - /* 62 S> */ B(LdaLookupGlobalSlot), U8(1), U8(9), U8(1), + /* 52 E> */ B(Call1), R(1), R(2), R(3), U8(3), + /* 62 S> */ B(LdaUndefined), + B(Star), R(2), + /* 69 E> */ B(LdaLookupGlobalSlot), U8(1), U8(9), U8(1), B(Star), R(1), - /* 69 E> */ B(CallUndefinedReceiver0), R(1), U8(7), + /* 69 E> */ B(Call0), R(1), R(2), U8(7), /* 74 S> */ B(Return), ] constant pool: [ diff --git a/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden b/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden index 6c57aaf3cd..216ca4060e 100644 --- a/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden +++ b/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden @@ -22,7 +22,7 @@ snippet: " " frame size: 6 parameter count: 1 -bytecode array length: 34 +bytecode array length: 33 bytecodes: [ B(Mov), R(closure), R(0), /* 99 E> */ B(StackCheck), @@ -34,7 +34,7 @@ bytecodes: [ B(Mov), R(this), R(3), B(CallRuntime), U16(Runtime::kLoadFromSuper), R(3), U8(3), B(Star), R(1), - /* 117 E> */ B(CallAnyReceiver), R(1), R(this), U8(1), U8(2), + /* 117 E> */ B(Call0), R(1), R(this), U8(2), /* 126 E> */ B(AddSmi), I8(1), U8(8), /* 131 S> */ B(Return), ] diff --git a/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden b/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden index c763cca3e9..671c4c7fc3 100644 --- a/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden +++ b/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden @@ -75,16 +75,18 @@ handlers: [ snippet: " var a; (function() { a = 2; })(); return a; " -frame size: 2 +frame size: 3 parameter count: 1 -bytecode array length: 17 +bytecode array length: 21 bytecodes: [ B(CreateFunctionContext), U8(1), B(PushContext), R(0), /* 30 E> */ B(StackCheck), - /* 41 S> */ B(CreateClosure), U8(0), U8(4), U8(2), + /* 41 S> */ B(LdaUndefined), + B(Star), R(2), + B(CreateClosure), U8(0), U8(4), U8(2), B(Star), R(1), - /* 64 E> */ B(CallUndefinedReceiver0), R(1), U8(2), + /* 64 E> */ B(Call0), R(1), R(2), U8(2), /* 68 S> */ B(LdaCurrentContextSlot), U8(4), /* 78 S> */ B(Return), ] @@ -386,9 +388,9 @@ snippet: " var b = 100; return b " -frame size: 2 +frame size: 3 parameter count: 1 -bytecode array length: 787 +bytecode array length: 791 bytecodes: [ B(CreateFunctionContext), U8(254), B(PushContext), R(0), @@ -899,9 +901,11 @@ bytecodes: [ /* 3421 E> */ B(StaCurrentContextSlot), U8(254), /* 3435 S> */ B(LdaZero), /* 3435 E> */ B(StaCurrentContextSlot), U8(255), - /* 3438 S> */ B(LdaGlobal), U8(0), U8(4), + /* 3438 S> */ B(LdaUndefined), + B(Star), R(2), + B(LdaGlobal), U8(0), U8(4), B(Star), R(1), - /* 3438 E> */ B(CallUndefinedReceiver0), R(1), U8(2), + /* 3438 E> */ B(Call0), R(1), R(2), U8(2), /* 3454 S> */ B(LdaSmi), I8(100), /* 3454 E> */ B(Wide), B(StaCurrentContextSlot), U16(256), /* 3459 S> */ B(Wide), B(LdaCurrentContextSlot), U16(256), diff --git a/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden b/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden index bf7a371605..1b3ce9a1fd 100644 --- a/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden +++ b/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden @@ -104,7 +104,7 @@ snippet: " " frame size: 4 parameter count: 1 -bytecode array length: 27 +bytecode array length: 31 bytecodes: [ B(LdaConstant), U8(0), B(Star), R(1), @@ -113,9 +113,11 @@ bytecodes: [ B(Mov), R(closure), R(3), B(CallRuntime), U16(Runtime::kDeclareGlobalsForInterpreter), R(1), U8(3), /* 0 E> */ B(StackCheck), - /* 16 S> */ B(LdaGlobal), U8(1), U8(2), + /* 16 S> */ B(LdaUndefined), + B(Star), R(2), + B(LdaGlobal), U8(1), U8(2), B(Star), R(1), - /* 16 E> */ B(CallUndefinedReceiver0), R(1), U8(5), + /* 16 E> */ B(Call0), R(1), R(2), U8(5), B(Star), R(0), /* 20 S> */ B(Return), ] diff --git a/test/cctest/interpreter/bytecode_expectations/Eval.golden b/test/cctest/interpreter/bytecode_expectations/Eval.golden index 4ef1c7654c..05e9517392 100644 --- a/test/cctest/interpreter/bytecode_expectations/Eval.golden +++ b/test/cctest/interpreter/bytecode_expectations/Eval.golden @@ -9,9 +9,9 @@ wrap: yes snippet: " return eval('1;'); " -frame size: 9 +frame size: 10 parameter count: 1 -bytecode array length: 58 +bytecode array length: 62 bytecodes: [ B(CreateFunctionContext), U8(3), B(PushContext), R(0), @@ -22,22 +22,24 @@ bytecodes: [ B(Ldar), R(new_target), B(StaCurrentContextSlot), U8(5), /* 30 E> */ B(StackCheck), - /* 34 S> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), + /* 34 S> */ B(LdaUndefined), + B(Star), R(2), + /* 41 E> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), B(Star), R(1), B(LdaConstant), U8(1), - B(Star), R(2), + B(Star), R(3), B(LdaZero), - B(Star), R(6), - B(LdaSmi), I8(30), B(Star), R(7), - B(LdaSmi), I8(41), + B(LdaSmi), I8(30), B(Star), R(8), - B(Mov), R(1), R(3), - B(Mov), R(2), R(4), - B(Mov), R(closure), R(5), - B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6), + B(LdaSmi), I8(41), + B(Star), R(9), + B(Mov), R(1), R(4), + B(Mov), R(3), R(5), + B(Mov), R(closure), R(6), + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6), B(Star), R(1), - /* 41 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(2), + /* 41 E> */ B(Call1), R(1), R(2), R(3), U8(2), /* 53 S> */ B(Return), ] constant pool: [ diff --git a/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden b/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden index a9ba5bbf32..a9590edeeb 100644 --- a/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden +++ b/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden @@ -27,14 +27,16 @@ handlers: [ snippet: " return (function(){ })() " -frame size: 1 +frame size: 2 parameter count: 1 -bytecode array length: 11 +bytecode array length: 15 bytecodes: [ /* 30 E> */ B(StackCheck), - /* 34 S> */ B(CreateClosure), U8(0), U8(4), U8(2), + /* 34 S> */ B(LdaUndefined), + B(Star), R(1), + B(CreateClosure), U8(0), U8(4), U8(2), B(Star), R(0), - /* 56 E> */ B(CallUndefinedReceiver0), R(0), U8(2), + /* 56 E> */ B(Call0), R(0), R(1), U8(2), /* 59 S> */ B(Return), ] constant pool: [ @@ -47,16 +49,18 @@ handlers: [ snippet: " return (function(x){ return x; })(1) " -frame size: 2 +frame size: 3 parameter count: 1 -bytecode array length: 16 +bytecode array length: 20 bytecodes: [ /* 30 E> */ B(StackCheck), - /* 34 S> */ B(CreateClosure), U8(0), U8(4), U8(2), + /* 34 S> */ B(LdaUndefined), + B(Star), R(1), + B(CreateClosure), U8(0), U8(4), U8(2), B(Star), R(0), B(LdaSmi), I8(1), - B(Star), R(1), - /* 67 E> */ B(CallUndefinedReceiver1), R(0), R(1), U8(2), + B(Star), R(2), + /* 67 E> */ B(Call1), R(0), R(1), R(2), U8(2), /* 71 S> */ B(Return), ] constant pool: [ diff --git a/test/cctest/interpreter/bytecode_expectations/LookupSlot.golden b/test/cctest/interpreter/bytecode_expectations/LookupSlot.golden index 8ecf2c316d..4256c16a75 100644 --- a/test/cctest/interpreter/bytecode_expectations/LookupSlot.golden +++ b/test/cctest/interpreter/bytecode_expectations/LookupSlot.golden @@ -10,9 +10,9 @@ test function name: f snippet: " eval('var x = 10;'); return x; " -frame size: 9 +frame size: 10 parameter count: 1 -bytecode array length: 62 +bytecode array length: 66 bytecodes: [ B(CreateFunctionContext), U8(3), B(PushContext), R(0), @@ -23,22 +23,24 @@ bytecodes: [ B(Ldar), R(new_target), B(StaCurrentContextSlot), U8(5), /* 10 E> */ B(StackCheck), - /* 14 S> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), + /* 14 S> */ B(LdaUndefined), + B(Star), R(2), + /* 14 E> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), B(Star), R(1), B(LdaConstant), U8(1), - B(Star), R(2), + B(Star), R(3), B(LdaZero), - B(Star), R(6), - B(LdaSmi), I8(10), B(Star), R(7), - B(LdaSmi), I8(14), + B(LdaSmi), I8(10), B(Star), R(8), - B(Mov), R(1), R(3), - B(Mov), R(2), R(4), - B(Mov), R(closure), R(5), - B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6), + B(LdaSmi), I8(14), + B(Star), R(9), + B(Mov), R(1), R(4), + B(Mov), R(3), R(5), + B(Mov), R(closure), R(6), + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6), B(Star), R(1), - /* 14 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(2), + /* 14 E> */ B(Call1), R(1), R(2), R(3), U8(2), /* 35 S> */ B(LdaLookupGlobalSlot), U8(2), U8(6), U8(1), /* 45 S> */ B(Return), ] @@ -54,9 +56,9 @@ handlers: [ snippet: " eval('var x = 10;'); return typeof x; " -frame size: 9 +frame size: 10 parameter count: 1 -bytecode array length: 63 +bytecode array length: 67 bytecodes: [ B(CreateFunctionContext), U8(3), B(PushContext), R(0), @@ -67,22 +69,24 @@ bytecodes: [ B(Ldar), R(new_target), B(StaCurrentContextSlot), U8(5), /* 10 E> */ B(StackCheck), - /* 14 S> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), + /* 14 S> */ B(LdaUndefined), + B(Star), R(2), + /* 14 E> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), B(Star), R(1), B(LdaConstant), U8(1), - B(Star), R(2), + B(Star), R(3), B(LdaZero), - B(Star), R(6), - B(LdaSmi), I8(10), B(Star), R(7), - B(LdaSmi), I8(14), + B(LdaSmi), I8(10), B(Star), R(8), - B(Mov), R(1), R(3), - B(Mov), R(2), R(4), - B(Mov), R(closure), R(5), - B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6), + B(LdaSmi), I8(14), + B(Star), R(9), + B(Mov), R(1), R(4), + B(Mov), R(3), R(5), + B(Mov), R(closure), R(6), + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6), B(Star), R(1), - /* 14 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(2), + /* 14 E> */ B(Call1), R(1), R(2), R(3), U8(2), /* 35 S> */ B(LdaLookupGlobalSlotInsideTypeof), U8(2), U8(6), U8(1), B(TypeOf), /* 52 S> */ B(Return), @@ -99,9 +103,9 @@ handlers: [ snippet: " x = 20; return eval(''); " -frame size: 9 +frame size: 10 parameter count: 1 -bytecode array length: 62 +bytecode array length: 66 bytecodes: [ B(CreateFunctionContext), U8(3), B(PushContext), R(0), @@ -114,22 +118,24 @@ bytecodes: [ /* 10 E> */ B(StackCheck), /* 14 S> */ B(LdaSmi), I8(20), /* 16 E> */ B(StaLookupSlotSloppy), U8(0), - /* 22 S> */ B(LdaLookupGlobalSlot), U8(1), U8(4), U8(1), + /* 22 S> */ B(LdaUndefined), + B(Star), R(2), + /* 29 E> */ B(LdaLookupGlobalSlot), U8(1), U8(4), U8(1), B(Star), R(1), B(LdaConstant), U8(2), - B(Star), R(2), + B(Star), R(3), B(LdaZero), - B(Star), R(6), - B(LdaSmi), I8(10), B(Star), R(7), - B(LdaSmi), I8(29), + B(LdaSmi), I8(10), B(Star), R(8), - B(Mov), R(1), R(3), - B(Mov), R(2), R(4), - B(Mov), R(closure), R(5), - B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6), + B(LdaSmi), I8(29), + B(Star), R(9), + B(Mov), R(1), R(4), + B(Mov), R(3), R(5), + B(Mov), R(closure), R(6), + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6), B(Star), R(1), - /* 29 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(2), + /* 29 E> */ B(Call1), R(1), R(2), R(3), U8(2), /* 39 S> */ B(Return), ] constant pool: [ @@ -149,9 +155,9 @@ snippet: " } f(); " -frame size: 9 +frame size: 10 parameter count: 1 -bytecode array length: 62 +bytecode array length: 66 bytecodes: [ B(CreateFunctionContext), U8(3), B(PushContext), R(0), @@ -162,22 +168,24 @@ bytecodes: [ B(Ldar), R(new_target), B(StaCurrentContextSlot), U8(5), /* 38 E> */ B(StackCheck), - /* 44 S> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), + /* 44 S> */ B(LdaUndefined), + B(Star), R(2), + /* 44 E> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), B(Star), R(1), B(LdaConstant), U8(1), - B(Star), R(2), + B(Star), R(3), B(LdaZero), - B(Star), R(6), - B(LdaSmi), I8(38), B(Star), R(7), - B(LdaSmi), I8(44), + B(LdaSmi), I8(38), B(Star), R(8), - B(Mov), R(1), R(3), - B(Mov), R(2), R(4), - B(Mov), R(closure), R(5), - B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6), + B(LdaSmi), I8(44), + B(Star), R(9), + B(Mov), R(1), R(4), + B(Mov), R(3), R(5), + B(Mov), R(closure), R(6), + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6), B(Star), R(1), - /* 44 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(2), + /* 44 E> */ B(Call1), R(1), R(2), R(3), U8(2), /* 66 S> */ B(LdaLookupContextSlot), U8(2), U8(6), U8(1), /* 76 S> */ B(Return), ] @@ -198,9 +206,9 @@ snippet: " } f(); " -frame size: 9 +frame size: 10 parameter count: 1 -bytecode array length: 62 +bytecode array length: 66 bytecodes: [ B(CreateFunctionContext), U8(3), B(PushContext), R(0), @@ -211,22 +219,24 @@ bytecodes: [ B(Ldar), R(new_target), B(StaCurrentContextSlot), U8(5), /* 34 E> */ B(StackCheck), - /* 40 S> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), + /* 40 S> */ B(LdaUndefined), + B(Star), R(2), + /* 40 E> */ B(LdaLookupGlobalSlot), U8(0), U8(4), U8(1), B(Star), R(1), B(LdaConstant), U8(1), - B(Star), R(2), + B(Star), R(3), B(LdaZero), - B(Star), R(6), - B(LdaSmi), I8(34), B(Star), R(7), - B(LdaSmi), I8(40), + B(LdaSmi), I8(34), B(Star), R(8), - B(Mov), R(1), R(3), - B(Mov), R(2), R(4), - B(Mov), R(closure), R(5), - B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6), + B(LdaSmi), I8(40), + B(Star), R(9), + B(Mov), R(1), R(4), + B(Mov), R(3), R(5), + B(Mov), R(closure), R(6), + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6), B(Star), R(1), - /* 40 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(2), + /* 40 E> */ B(Call1), R(1), R(2), R(3), U8(2), /* 62 S> */ B(LdaLookupGlobalSlot), U8(2), U8(6), U8(1), /* 72 S> */ B(Return), ] diff --git a/test/cctest/interpreter/bytecode_expectations/Modules.golden b/test/cctest/interpreter/bytecode_expectations/Modules.golden index 76398ec1fc..8501a627cd 100644 --- a/test/cctest/interpreter/bytecode_expectations/Modules.golden +++ b/test/cctest/interpreter/bytecode_expectations/Modules.golden @@ -171,7 +171,7 @@ snippet: " " frame size: 10 parameter count: 2 -bytecode array length: 205 +bytecode array length: 213 bytecodes: [ B(Ldar), R(new_target), B(JumpIfUndefined), U8(27), @@ -228,15 +228,17 @@ bytecodes: [ /* 64 S> */ B(Return), B(Ldar), R(6), /* 0 E> */ B(Throw), - /* 32 S> */ B(LdaModuleVariable), I8(-1), U8(0), + /* 32 S> */ B(LdaUndefined), + B(Star), R(5), + /* 32 E> */ B(LdaModuleVariable), I8(-1), U8(0), B(JumpIfNotHole), U8(11), B(LdaConstant), U8(1), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kThrowReferenceError), R(6), U8(1), B(Star), R(4), B(LdaSmi), I8(42), - B(Star), R(5), - /* 32 E> */ B(CallUndefinedReceiver1), R(4), R(5), U8(2), + B(Star), R(6), + /* 32 E> */ B(Call1), R(4), R(5), R(6), U8(2), B(Ldar), R(closure), B(CreateBlockContext), U8(2), B(PushContext), R(1), @@ -244,15 +246,17 @@ bytecodes: [ B(StaCurrentContextSlot), U8(4), /* 47 S> */ B(LdaUndefined), /* 47 E> */ B(StaCurrentContextSlot), U8(4), - /* 52 S> */ B(LdaModuleVariable), I8(-1), U8(1), + /* 52 S> */ B(LdaUndefined), + B(Star), R(5), + /* 52 E> */ B(LdaModuleVariable), I8(-1), U8(1), B(JumpIfNotHole), U8(11), B(LdaConstant), U8(1), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kThrowReferenceError), R(6), U8(1), B(Star), R(4), B(LdaSmi), I8(42), - B(Star), R(5), - /* 52 E> */ B(CallUndefinedReceiver1), R(4), R(5), U8(4), + B(Star), R(6), + /* 52 E> */ B(Call1), R(4), R(5), R(6), U8(4), B(StaContextSlot), R(1), U8(6), U8(0), B(PopContext), R(1), B(LdaCurrentContextSlot), U8(6), diff --git a/test/cctest/interpreter/test-interpreter.cc b/test/cctest/interpreter/test-interpreter.cc index f58740ea20..973a67c8c5 100644 --- a/test/cctest/interpreter/test-interpreter.cc +++ b/test/cctest/interpreter/test-interpreter.cc @@ -1298,11 +1298,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) { .StoreAccumulatorInRegister(reg) .MoveRegister(builder.Receiver(), args[0]); - if (tail_call_mode == TailCallMode::kAllow) { - builder.TailCall(reg, args, call_slot_index); - } else { - builder.CallProperty(reg, args, call_slot_index); - } + builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); builder.Return(); ast_factory.Internalize(isolate); @@ -1325,11 +1321,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) { builder.LoadNamedProperty(builder.Receiver(), name, slot_index) .StoreAccumulatorInRegister(reg) .MoveRegister(builder.Receiver(), args[0]); - if (tail_call_mode == TailCallMode::kAllow) { - builder.TailCall(reg, args, call_slot_index); - } else { - builder.CallProperty(reg, args, call_slot_index); - } + builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); builder.Return(); ast_factory.Internalize(isolate); Handle bytecode_array = builder.ToBytecodeArray(isolate); @@ -1361,11 +1353,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) { .LoadLiteral(Smi::FromInt(11)) .StoreAccumulatorInRegister(args[2]); - if (tail_call_mode == TailCallMode::kAllow) { - builder.TailCall(reg, args, call_slot_index); - } else { - builder.CallProperty(reg, args, call_slot_index); - } + builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); builder.Return(); @@ -1414,11 +1402,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) { .LoadLiteral(ast_factory.NewString(ast_factory.GetOneByteString("j"))) .StoreAccumulatorInRegister(args[10]); - if (tail_call_mode == TailCallMode::kAllow) { - builder.TailCall(reg, args, call_slot_index); - } else { - builder.CallProperty(reg, args, call_slot_index); - } + builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); builder.Return(); diff --git a/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/test/unittests/interpreter/bytecode-array-builder-unittest.cc index 75b72a7b3d..eea67e91e2 100644 --- a/test/unittests/interpreter/bytecode-array-builder-unittest.cc +++ b/test/unittests/interpreter/bytecode-array-builder-unittest.cc @@ -39,8 +39,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { Register reg(0); Register other(reg.index() + 1); Register wide(128); - RegisterList reg_list(0, 10); - RegisterList empty, single(0, 1), pair(0, 2), triple(0, 3); + RegisterList reg_list; + RegisterList single(0, 1), pair(0, 2), triple(0, 3); // Emit argument creation operations. builder.CreateArguments(CreateArgumentsType::kMappedArguments) @@ -145,16 +145,16 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { builder.CreateObjectLiteral(0, 0, 0, reg); // Call operations. - builder.CallAnyReceiver(reg, reg_list, 1) - .CallProperty(reg, reg_list, 1) - .CallProperty(reg, single, 1) - .CallProperty(reg, pair, 1) - .CallProperty(reg, triple, 1) - .CallUndefinedReceiver(reg, reg_list, 1) - .CallUndefinedReceiver(reg, empty, 1) - .CallUndefinedReceiver(reg, single, 1) - .CallUndefinedReceiver(reg, pair, 1) - .TailCall(reg, reg_list, 1) + builder.Call(reg, reg_list, 1, Call::GLOBAL_CALL) + .Call(reg, single, 1, Call::GLOBAL_CALL) + .Call(reg, pair, 1, Call::GLOBAL_CALL) + .Call(reg, triple, 1, Call::GLOBAL_CALL) + .Call(reg, reg_list, 1, Call::NAMED_PROPERTY_CALL, + TailCallMode::kDisallow) + .Call(reg, single, 1, Call::NAMED_PROPERTY_CALL) + .Call(reg, pair, 1, Call::NAMED_PROPERTY_CALL) + .Call(reg, triple, 1, Call::NAMED_PROPERTY_CALL) + .Call(reg, reg_list, 1, Call::GLOBAL_CALL, TailCallMode::kAllow) .CallRuntime(Runtime::kIsArray, reg) .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg_list, pair) .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg_list) diff --git a/test/unittests/interpreter/bytecode-decoder-unittest.cc b/test/unittests/interpreter/bytecode-decoder-unittest.cc index f9c0877664..14972259da 100644 --- a/test/unittests/interpreter/bytecode-decoder-unittest.cc +++ b/test/unittests/interpreter/bytecode-decoder-unittest.cc @@ -38,10 +38,10 @@ TEST(BytecodeDecoder, DecodeBytecodeAndOperands) { "LdaSmi.ExtraWide [-100000]"}, {{B(Star), R8(5)}, 2, 0, " Star r5"}, {{B(Wide), B(Star), R16(136)}, 4, 0, " Star.Wide r136"}, - {{B(Wide), B(CallAnyReceiver), R16(134), R16(135), U16(10), U16(177)}, + {{B(Wide), B(Call), R16(134), R16(135), U16(10), U16(177)}, 10, 0, - "CallAnyReceiver.Wide r134, r135-r144, [177]"}, + "Call.Wide r134, r135-r144, [177]"}, {{B(ForInPrepare), R8(10), R8(11)}, 3, 0, diff --git a/test/unittests/interpreter/interpreter-assembler-unittest.cc b/test/unittests/interpreter/interpreter-assembler-unittest.cc index b79f0690b8..1cb1afdbc1 100644 --- a/test/unittests/interpreter/interpreter-assembler-unittest.cc +++ b/test/unittests/interpreter/interpreter-assembler-unittest.cc @@ -616,27 +616,25 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { } TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { - TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { - if (Bytecodes::IsCallOrConstruct(bytecode) && - bytecode != Bytecode::kCallWithSpread) { - InterpreterAssemblerTestState state(this, bytecode); - InterpreterAssemblerForTest m(&state, bytecode); - ConvertReceiverMode receiver_mode = Bytecodes::GetReceiverMode(bytecode); - TailCallMode tail_call_mode = (bytecode == Bytecode::kTailCall) - ? TailCallMode::kAllow - : TailCallMode::kDisallow; - - Callable builtin = CodeFactory::InterpreterPushArgsThenCall( - isolate(), receiver_mode, tail_call_mode, - InterpreterPushArgsMode::kOther); - Node* function = m.IntPtrConstant(0); - Node* first_arg = m.IntPtrConstant(1); - Node* arg_count = m.Int32Constant(2); - Node* context = m.IntPtrConstant(3); - Node* call_js = m.CallJS(function, context, first_arg, arg_count, - receiver_mode, tail_call_mode); - EXPECT_THAT(call_js, IsCall(_, IsHeapConstant(builtin.code()), arg_count, - first_arg, function, context, _, _)); + TailCallMode tail_call_modes[] = {TailCallMode::kDisallow, + TailCallMode::kAllow}; + TRACED_FOREACH(TailCallMode, tail_call_mode, tail_call_modes) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + if (Bytecodes::IsCallOrConstruct(bytecode)) { + InterpreterAssemblerTestState state(this, bytecode); + InterpreterAssemblerForTest m(&state, bytecode); + Callable builtin = CodeFactory::InterpreterPushArgsAndCall( + isolate(), tail_call_mode, InterpreterPushArgsMode::kOther); + Node* function = m.IntPtrConstant(0); + Node* first_arg = m.IntPtrConstant(1); + Node* arg_count = m.Int32Constant(2); + Node* context = m.IntPtrConstant(3); + Node* call_js = + m.CallJS(function, context, first_arg, arg_count, tail_call_mode); + EXPECT_THAT(call_js, + IsCall(_, IsHeapConstant(builtin.code()), arg_count, + first_arg, function, context, _, _)); + } } } }