Revert "[ignition] Add call bytecodes for undefined receiver"
This reverts commit 751e893591
.
Reason for revert: Breaks layout tests:
https://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/14885
See:
https://github.com/v8/v8/wiki/Blink-layout-tests
Original change's description:
> [ignition] Add call bytecodes for undefined receiver
>
> Adds a collection of call bytecodes which have an implicit undefined
> receiver argument, for cases such as global calls where we know that the
> receiver has to be undefined. This way we can skip an LdaUndefined,
> decrease bytecode register pressure, and set a more accurate
> ConvertReceiverMode on the interpreter and TurboFan call.
>
> As a side effect, the "normal" Call bytecode now becomes a rare case
> (only with calls and super property calls), so we get rid of its 0-2
> argument special cases and modify CallProperty[N] to use the
> NotNullOrUndefined ConvertReceiverMode.
>
> Change-Id: I9374a32fefd66fc0251b5193bae7a6b7dc31eefc
> Reviewed-on: https://chromium-review.googlesource.com/463287
> Commit-Queue: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#44530}
TBR=rmcilroy@chromium.org,mstarzinger@chromium.org,leszeks@chromium.org,v8-reviews@googlegroups.com,v8-mips-ports@googlegroups.com,v8-ppc-ports@googlegroups.com,v8-x87-ports@googlegroups.com,bmeurer@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Change-Id: I7629dec609d0ec938ce7105d6c1c74884e5f9272
Reviewed-on: https://chromium-review.googlesource.com/474744
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44548}
This commit is contained in:
parent
817a5c0a32
commit
925212a1cf
@ -324,7 +324,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r0, // argument count (not including receiver)
|
r0, // argument count (not including receiver)
|
||||||
@ -334,7 +334,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r0, // argument count (not including receiver)
|
r0, // argument count (not including receiver)
|
||||||
@ -346,8 +346,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r0, // argument count (not including receiver)
|
r0, // argument count (not including receiver)
|
||||||
r1, // target to call checked to be Array function
|
r1, // target to call checked to be Array function
|
||||||
|
@ -353,7 +353,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
x0, // argument count (not including receiver)
|
x0, // argument count (not including receiver)
|
||||||
@ -363,7 +363,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
x0, // argument count (not including receiver)
|
x0, // argument count (not including receiver)
|
||||||
@ -375,8 +375,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
x0, // argument count (not including receiver)
|
x0, // argument count (not including receiver)
|
||||||
x1, // target to call checked to be Array function
|
x1, // target to call checked to be Array function
|
||||||
|
@ -1082,7 +1082,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
|
|||||||
|
|
||||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||||
Register num_args, Register index,
|
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.
|
// Find the address of the last argument.
|
||||||
__ mov(limit, num_args);
|
__ mov(limit, num_args);
|
||||||
__ mov(limit, Operand(limit, LSL, kPointerSizeLog2));
|
__ mov(limit, Operand(limit, LSL, kPointerSizeLog2));
|
||||||
@ -1099,9 +1103,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r0 : the number of arguments (not including the receiver)
|
// -- r0 : the number of arguments (not including the receiver)
|
||||||
// -- r2 : the address of the first argument to be pushed. Subsequent
|
// -- 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.
|
__ 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.
|
// 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.
|
// Call the target.
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1147,7 +1143,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r0 : argument count (not including receiver)
|
// -- r0 : argument count (not including receiver)
|
||||||
@ -1162,10 +1158,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
__ mov(ip, Operand::Zero());
|
__ mov(ip, Operand::Zero());
|
||||||
__ push(ip);
|
__ push(ip);
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow);
|
|
||||||
|
|
||||||
// Push the arguments. r5, r4, r6 will be modified.
|
// 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);
|
__ AssertUndefinedOrAllocationSite(r2, r5);
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1196,7 +1190,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r0 : argument count (not including receiver)
|
// -- r0 : argument count (not including receiver)
|
||||||
@ -1206,14 +1200,11 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
|||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
Label stack_overflow;
|
Label stack_overflow;
|
||||||
|
|
||||||
// Push a slot for the receiver to be constructed.
|
__ add(r4, r0, Operand(1)); // Add one for receiver.
|
||||||
__ mov(ip, Operand::Zero());
|
|
||||||
__ push(ip);
|
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, r0, r5, &stack_overflow);
|
|
||||||
|
|
||||||
|
// TODO(mythria): Add a stack check before pushing arguments.
|
||||||
// Push the arguments. r3, r5, r6 will be modified.
|
// 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.
|
// Array constructor expects constructor in r3. It is same as r1 here.
|
||||||
__ mov(r3, r1);
|
__ mov(r3, r1);
|
||||||
|
@ -1100,7 +1100,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
|
|||||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||||
Register num_args, Register index,
|
Register num_args, Register index,
|
||||||
Register last_arg, Register stack_addr,
|
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);
|
__ Mov(scratch, num_args);
|
||||||
__ lsl(scratch, scratch, kPointerSizeLog2);
|
__ lsl(scratch, scratch, kPointerSizeLog2);
|
||||||
__ sub(last_arg, index, scratch);
|
__ sub(last_arg, index, scratch);
|
||||||
@ -1122,9 +1126,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- x0 : the number of arguments (not including the receiver)
|
// -- x0 : the number of arguments (not including the receiver)
|
||||||
// -- x2 : the address of the first argument to be pushed. Subsequent
|
// -- 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 one for the receiver.
|
||||||
__ add(x3, x0, Operand(1));
|
__ 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.
|
// 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.
|
// Call the target.
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1171,7 +1166,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- x0 : argument count (not including receiver)
|
// -- x0 : argument count (not including receiver)
|
||||||
@ -1185,11 +1180,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
// Push a slot for the receiver.
|
// Push a slot for the receiver.
|
||||||
__ Push(xzr);
|
__ 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.
|
// 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);
|
__ AssertUndefinedOrAllocationSite(x2, x6);
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1219,7 +1211,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- x0 : argument count (not including receiver)
|
// -- x0 : argument count (not including receiver)
|
||||||
@ -1229,14 +1221,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
|||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
Label stack_overflow;
|
Label stack_overflow;
|
||||||
|
|
||||||
// Push a slot for the receiver.
|
__ add(x4, x0, Operand(1)); // Add one for the receiver.
|
||||||
__ Push(xzr);
|
|
||||||
|
|
||||||
// Add a stack check before pushing arguments.
|
|
||||||
Generate_StackOverflowCheck(masm, x0, x7, &stack_overflow);
|
|
||||||
|
|
||||||
// Push the arguments. x3, x5, x6, x7 will be modified.
|
// 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.
|
// Array constructor expects constructor in x3. It is same as call target.
|
||||||
__ mov(x3, x1);
|
__ mov(x3, x1);
|
||||||
|
@ -133,17 +133,15 @@ namespace internal {
|
|||||||
\
|
\
|
||||||
/* Interpreter */ \
|
/* Interpreter */ \
|
||||||
ASM(InterpreterEntryTrampoline) \
|
ASM(InterpreterEntryTrampoline) \
|
||||||
ASM(InterpreterPushArgsThenCall) \
|
ASM(InterpreterPushArgsAndCall) \
|
||||||
ASM(InterpreterPushUndefinedAndArgsThenCall) \
|
ASM(InterpreterPushArgsAndCallFunction) \
|
||||||
ASM(InterpreterPushArgsThenCallFunction) \
|
ASM(InterpreterPushArgsAndCallWithFinalSpread) \
|
||||||
ASM(InterpreterPushUndefinedAndArgsThenCallFunction) \
|
ASM(InterpreterPushArgsAndTailCall) \
|
||||||
ASM(InterpreterPushArgsThenCallWithFinalSpread) \
|
ASM(InterpreterPushArgsAndTailCallFunction) \
|
||||||
ASM(InterpreterPushArgsThenTailCall) \
|
ASM(InterpreterPushArgsAndConstruct) \
|
||||||
ASM(InterpreterPushArgsThenTailCallFunction) \
|
ASM(InterpreterPushArgsAndConstructFunction) \
|
||||||
ASM(InterpreterPushArgsThenConstruct) \
|
ASM(InterpreterPushArgsAndConstructArray) \
|
||||||
ASM(InterpreterPushArgsThenConstructFunction) \
|
ASM(InterpreterPushArgsAndConstructWithFinalSpread) \
|
||||||
ASM(InterpreterPushArgsThenConstructArray) \
|
|
||||||
ASM(InterpreterPushArgsThenConstructWithFinalSpread) \
|
|
||||||
ASM(InterpreterEnterBytecodeAdvance) \
|
ASM(InterpreterEnterBytecodeAdvance) \
|
||||||
ASM(InterpreterEnterBytecodeDispatch) \
|
ASM(InterpreterEnterBytecodeDispatch) \
|
||||||
ASM(InterpreterOnStackReplacement) \
|
ASM(InterpreterOnStackReplacement) \
|
||||||
|
@ -9,67 +9,48 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCall(MacroAssembler* masm) {
|
void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
|
||||||
return Generate_InterpreterPushArgsThenCallImpl(
|
return Generate_InterpreterPushArgsAndCallImpl(
|
||||||
masm, ConvertReceiverMode::kAny, TailCallMode::kDisallow,
|
masm, TailCallMode::kDisallow, InterpreterPushArgsMode::kOther);
|
||||||
InterpreterPushArgsMode::kOther);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallFunction(
|
void Builtins::Generate_InterpreterPushArgsAndCallFunction(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
return Generate_InterpreterPushArgsThenCallImpl(
|
return Generate_InterpreterPushArgsAndCallImpl(
|
||||||
masm, ConvertReceiverMode::kAny, TailCallMode::kDisallow,
|
masm, TailCallMode::kDisallow, InterpreterPushArgsMode::kJSFunction);
|
||||||
InterpreterPushArgsMode::kJSFunction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterPushUndefinedAndArgsThenCall(
|
void Builtins::Generate_InterpreterPushArgsAndCallWithFinalSpread(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
return Generate_InterpreterPushArgsThenCallImpl(
|
return Generate_InterpreterPushArgsAndCallImpl(
|
||||||
masm, ConvertReceiverMode::kNullOrUndefined, TailCallMode::kDisallow,
|
masm, TailCallMode::kDisallow, InterpreterPushArgsMode::kWithFinalSpread);
|
||||||
InterpreterPushArgsMode::kOther);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterPushUndefinedAndArgsThenCallFunction(
|
void Builtins::Generate_InterpreterPushArgsAndTailCall(MacroAssembler* masm) {
|
||||||
|
return Generate_InterpreterPushArgsAndCallImpl(
|
||||||
|
masm, TailCallMode::kAllow, InterpreterPushArgsMode::kOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builtins::Generate_InterpreterPushArgsAndTailCallFunction(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
return Generate_InterpreterPushArgsThenCallImpl(
|
return Generate_InterpreterPushArgsAndCallImpl(
|
||||||
masm, ConvertReceiverMode::kNullOrUndefined, TailCallMode::kDisallow,
|
masm, TailCallMode::kAllow, InterpreterPushArgsMode::kJSFunction);
|
||||||
InterpreterPushArgsMode::kJSFunction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallWithFinalSpread(
|
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||||
MacroAssembler* masm) {
|
return Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
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(
|
|
||||||
masm, InterpreterPushArgsMode::kOther);
|
masm, InterpreterPushArgsMode::kOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructWithFinalSpread(
|
void Builtins::Generate_InterpreterPushArgsAndConstructWithFinalSpread(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
return Generate_InterpreterPushArgsThenConstructImpl(
|
return Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
masm, InterpreterPushArgsMode::kWithFinalSpread);
|
masm, InterpreterPushArgsMode::kWithFinalSpread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructFunction(
|
void Builtins::Generate_InterpreterPushArgsAndConstructFunction(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
return Generate_InterpreterPushArgsThenConstructImpl(
|
return Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
masm, InterpreterPushArgsMode::kJSFunction);
|
masm, InterpreterPushArgsMode::kJSFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,53 +11,38 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
Handle<Code> Builtins::InterpreterPushArgsThenCall(
|
Handle<Code> Builtins::InterpreterPushArgsAndCall(
|
||||||
ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode,
|
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
||||||
InterpreterPushArgsMode mode) {
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case InterpreterPushArgsMode::kJSFunction:
|
case InterpreterPushArgsMode::kJSFunction:
|
||||||
if (tail_call_mode == TailCallMode::kDisallow) {
|
if (tail_call_mode == TailCallMode::kDisallow) {
|
||||||
switch (receiver_mode) {
|
return InterpreterPushArgsAndCallFunction();
|
||||||
case ConvertReceiverMode::kNullOrUndefined:
|
|
||||||
return InterpreterPushUndefinedAndArgsThenCallFunction();
|
|
||||||
case ConvertReceiverMode::kNotNullOrUndefined:
|
|
||||||
case ConvertReceiverMode::kAny:
|
|
||||||
return InterpreterPushArgsThenCallFunction();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
CHECK_EQ(receiver_mode, ConvertReceiverMode::kAny);
|
return InterpreterPushArgsAndTailCallFunction();
|
||||||
return InterpreterPushArgsThenTailCallFunction();
|
|
||||||
}
|
}
|
||||||
case InterpreterPushArgsMode::kWithFinalSpread:
|
case InterpreterPushArgsMode::kWithFinalSpread:
|
||||||
CHECK(tail_call_mode == TailCallMode::kDisallow);
|
CHECK(tail_call_mode == TailCallMode::kDisallow);
|
||||||
return InterpreterPushArgsThenCallWithFinalSpread();
|
return InterpreterPushArgsAndCallWithFinalSpread();
|
||||||
case InterpreterPushArgsMode::kOther:
|
case InterpreterPushArgsMode::kOther:
|
||||||
if (tail_call_mode == TailCallMode::kDisallow) {
|
if (tail_call_mode == TailCallMode::kDisallow) {
|
||||||
switch (receiver_mode) {
|
return InterpreterPushArgsAndCall();
|
||||||
case ConvertReceiverMode::kNullOrUndefined:
|
|
||||||
return InterpreterPushUndefinedAndArgsThenCall();
|
|
||||||
case ConvertReceiverMode::kNotNullOrUndefined:
|
|
||||||
case ConvertReceiverMode::kAny:
|
|
||||||
return InterpreterPushArgsThenCall();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
CHECK_EQ(receiver_mode, ConvertReceiverMode::kAny);
|
return InterpreterPushArgsAndTailCall();
|
||||||
return InterpreterPushArgsThenTailCall();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return Handle<Code>::null();
|
return Handle<Code>::null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Code> Builtins::InterpreterPushArgsThenConstruct(
|
Handle<Code> Builtins::InterpreterPushArgsAndConstruct(
|
||||||
InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case InterpreterPushArgsMode::kJSFunction:
|
case InterpreterPushArgsMode::kJSFunction:
|
||||||
return InterpreterPushArgsThenConstructFunction();
|
return InterpreterPushArgsAndConstructFunction();
|
||||||
case InterpreterPushArgsMode::kWithFinalSpread:
|
case InterpreterPushArgsMode::kWithFinalSpread:
|
||||||
return InterpreterPushArgsThenConstructWithFinalSpread();
|
return InterpreterPushArgsAndConstructWithFinalSpread();
|
||||||
case InterpreterPushArgsMode::kOther:
|
case InterpreterPushArgsMode::kOther:
|
||||||
return InterpreterPushArgsThenConstruct();
|
return InterpreterPushArgsAndConstruct();
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return Handle<Code>::null();
|
return Handle<Code>::null();
|
||||||
|
@ -58,10 +58,9 @@ class Builtins {
|
|||||||
Handle<Code> NonPrimitiveToPrimitive(
|
Handle<Code> NonPrimitiveToPrimitive(
|
||||||
ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
|
ToPrimitiveHint hint = ToPrimitiveHint::kDefault);
|
||||||
Handle<Code> OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint);
|
Handle<Code> OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint);
|
||||||
Handle<Code> InterpreterPushArgsThenCall(ConvertReceiverMode receiver_mode,
|
Handle<Code> InterpreterPushArgsAndCall(TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode,
|
InterpreterPushArgsMode mode);
|
||||||
InterpreterPushArgsMode mode);
|
Handle<Code> InterpreterPushArgsAndConstruct(InterpreterPushArgsMode mode);
|
||||||
Handle<Code> InterpreterPushArgsThenConstruct(InterpreterPushArgsMode mode);
|
|
||||||
Handle<Code> NewFunctionContext(ScopeType scope_type);
|
Handle<Code> NewFunctionContext(ScopeType scope_type);
|
||||||
Handle<Code> NewCloneShallowArray(AllocationSiteMode allocation_mode);
|
Handle<Code> NewCloneShallowArray(AllocationSiteMode allocation_mode);
|
||||||
Handle<Code> NewCloneShallowObject(int length);
|
Handle<Code> NewCloneShallowObject(int length);
|
||||||
@ -123,11 +122,11 @@ class Builtins {
|
|||||||
static void Generate_CallForwardVarargs(MacroAssembler* masm,
|
static void Generate_CallForwardVarargs(MacroAssembler* masm,
|
||||||
Handle<Code> code);
|
Handle<Code> code);
|
||||||
|
|
||||||
static void Generate_InterpreterPushArgsThenCallImpl(
|
static void Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode);
|
InterpreterPushArgsMode mode);
|
||||||
|
|
||||||
static void Generate_InterpreterPushArgsThenConstructImpl(
|
static void Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode);
|
MacroAssembler* masm, InterpreterPushArgsMode mode);
|
||||||
|
|
||||||
#define DECLARE_ASM(Name, ...) \
|
#define DECLARE_ASM(Name, ...) \
|
||||||
|
@ -751,9 +751,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- eax : the number of arguments (not including the receiver)
|
// -- eax : the number of arguments (not including the receiver)
|
||||||
// -- ebx : the address of the first argument to be pushed. Subsequent
|
// -- 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 return address to allow tail-call after pushing arguments.
|
||||||
__ Pop(edx);
|
__ 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.
|
// Find the address of the last argument.
|
||||||
__ shl(ecx, kPointerSizeLog2);
|
__ shl(ecx, kPointerSizeLog2);
|
||||||
__ neg(ecx);
|
__ neg(ecx);
|
||||||
@ -821,10 +815,10 @@ namespace {
|
|||||||
// This function modified start_addr, and only reads the contents of num_args
|
// This function modified start_addr, and only reads the contents of num_args
|
||||||
// register. scratch1 and scratch2 are used as temporary registers. Their
|
// register. scratch1 and scratch2 are used as temporary registers. Their
|
||||||
// original values are restored after the use.
|
// original values are restored after the use.
|
||||||
void Generate_InterpreterPushZeroAndArgsAndReturnAddress(
|
void Generate_InterpreterPushArgsAndReturnAddress(
|
||||||
MacroAssembler* masm, Register num_args, Register start_addr,
|
MacroAssembler* masm, Register num_args, Register start_addr,
|
||||||
Register scratch1, Register scratch2, int num_slots_above_ret_addr,
|
Register scratch1, Register scratch2, bool receiver_in_args,
|
||||||
Label* stack_overflow) {
|
int num_slots_above_ret_addr, Label* stack_overflow) {
|
||||||
// We have to move return address and the temporary registers above it
|
// We have to move return address and the temporary registers above it
|
||||||
// before we can copy arguments onto the stack. To achieve this:
|
// before we can copy arguments onto the stack. To achieve this:
|
||||||
// Step 1: Increment the stack pointer by num_args + 1 (for receiver).
|
// Step 1: Increment the stack pointer by num_args + 1 (for receiver).
|
||||||
@ -837,7 +831,7 @@ void Generate_InterpreterPushZeroAndArgsAndReturnAddress(
|
|||||||
// | | | return addr | (2)
|
// | | | return addr | (2)
|
||||||
// | | | arg N | (3)
|
// | | | arg N | (3)
|
||||||
// | scratch1 | <-- esp | .... |
|
// | scratch1 | <-- esp | .... |
|
||||||
// | .... | | arg 1 |
|
// | .... | | arg 0 |
|
||||||
// | scratch-n | | arg 0 |
|
// | scratch-n | | arg 0 |
|
||||||
// | return addr | | receiver slot |
|
// | return addr | | receiver slot |
|
||||||
|
|
||||||
@ -881,12 +875,17 @@ void Generate_InterpreterPushZeroAndArgsAndReturnAddress(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Step 3 copy arguments to correct locations.
|
// Step 3 copy arguments to correct locations.
|
||||||
// Slot meant for receiver contains return address. Reset it so that
|
if (receiver_in_args) {
|
||||||
// we will not incorrectly interpret return address as an object.
|
__ mov(scratch1, num_args);
|
||||||
__ mov(Operand(esp, num_args, times_pointer_size,
|
__ add(scratch1, Immediate(1));
|
||||||
(num_slots_above_ret_addr + 1) * kPointerSize),
|
} else {
|
||||||
Immediate(0));
|
// Slot meant for receiver contains return address. Reset it so that
|
||||||
__ mov(scratch1, num_args);
|
// 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;
|
Label loop_header, loop_check;
|
||||||
__ jmp(&loop_check);
|
__ jmp(&loop_check);
|
||||||
@ -905,7 +904,7 @@ void Generate_InterpreterPushZeroAndArgsAndReturnAddress(
|
|||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- eax : the number of arguments (not including the receiver)
|
// -- 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.
|
// Push arguments and move return address to the top of stack.
|
||||||
// The eax register is readonly. The ecx register will be modified. The edx
|
// 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.
|
// and edi registers will be modified but restored to their original values.
|
||||||
Generate_InterpreterPushZeroAndArgsAndReturnAddress(masm, eax, ecx, edx, edi,
|
Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false,
|
||||||
2, &stack_overflow);
|
2, &stack_overflow);
|
||||||
|
|
||||||
// Restore edi and edx
|
// Restore edi and edx
|
||||||
__ Pop(edx);
|
__ Pop(edx);
|
||||||
@ -965,7 +964,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- eax : the number of arguments (not including the receiver)
|
// -- 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.
|
// Push arguments and move return address to the top of stack.
|
||||||
// The eax register is readonly. The ecx register will be modified. The edx
|
// 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.
|
// and edi registers will be modified but restored to their original values.
|
||||||
Generate_InterpreterPushZeroAndArgsAndReturnAddress(masm, eax, ecx, edx, edi,
|
Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, true,
|
||||||
1, &stack_overflow);
|
1, &stack_overflow);
|
||||||
|
|
||||||
// Restore edx.
|
// Restore edx.
|
||||||
__ Pop(edx);
|
__ Pop(edx);
|
||||||
|
@ -1077,7 +1077,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
|
|||||||
|
|
||||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||||
Register num_args, Register index,
|
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.
|
// Find the address of the last argument.
|
||||||
__ mov(scratch2, num_args);
|
__ mov(scratch2, num_args);
|
||||||
__ sll(scratch2, scratch2, kPointerSizeLog2);
|
__ sll(scratch2, scratch2, kPointerSizeLog2);
|
||||||
@ -1095,9 +1099,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- a0 : the number of arguments (not including the receiver)
|
// -- a0 : the number of arguments (not including the receiver)
|
||||||
// -- a2 : the address of the first argument to be pushed. Subsequent
|
// -- 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.
|
__ 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.
|
// 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.
|
// Call the target.
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1143,7 +1139,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- a0 : argument count (not including receiver)
|
// -- a0 : argument count (not including receiver)
|
||||||
@ -1157,10 +1153,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
// Push a slot for the receiver.
|
// Push a slot for the receiver.
|
||||||
__ push(zero_reg);
|
__ push(zero_reg);
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, a0, t1, t0, &stack_overflow);
|
|
||||||
|
|
||||||
// This function modified t4, t1 and t0.
|
// 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);
|
__ AssertUndefinedOrAllocationSite(a2, t0);
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1191,7 +1185,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- a0 : the number of arguments (not including the receiver)
|
// -- a0 : the number of arguments (not including the receiver)
|
||||||
@ -1203,13 +1197,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
|||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
Label stack_overflow;
|
Label stack_overflow;
|
||||||
|
|
||||||
// Push a slot for the receiver.
|
__ Addu(t0, a0, Operand(1)); // Add one for receiver.
|
||||||
__ push(zero_reg);
|
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, a0, t1, t4, &stack_overflow);
|
// This function modifies a3, t4, and t1.
|
||||||
|
Generate_InterpreterPushArgs(masm, t0, a3, t1, t4, &stack_overflow);
|
||||||
// This function modifies a3, t1, and t4.
|
|
||||||
Generate_InterpreterPushArgs(masm, a0, a3, t1, t4);
|
|
||||||
|
|
||||||
// ArrayConstructor stub expects constructor in a3. Set it here.
|
// ArrayConstructor stub expects constructor in a3. Set it here.
|
||||||
__ mov(a3, a1);
|
__ mov(a3, a1);
|
||||||
|
@ -1070,7 +1070,11 @@ static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
|
|||||||
|
|
||||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||||
Register num_args, Register index,
|
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.
|
// Find the address of the last argument.
|
||||||
__ mov(scratch2, num_args);
|
__ mov(scratch2, num_args);
|
||||||
__ dsll(scratch2, scratch2, kPointerSizeLog2);
|
__ dsll(scratch2, scratch2, kPointerSizeLog2);
|
||||||
@ -1088,9 +1092,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- a0 : the number of arguments (not including the receiver)
|
// -- a0 : the number of arguments (not including the receiver)
|
||||||
// -- a2 : the address of the first argument to be pushed. Subsequent
|
// -- 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.
|
__ 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.
|
// 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.
|
// Call the target.
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1136,7 +1132,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- a0 : argument count (not including receiver)
|
// -- a0 : argument count (not including receiver)
|
||||||
@ -1150,10 +1146,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
// Push a slot for the receiver.
|
// Push a slot for the receiver.
|
||||||
__ push(zero_reg);
|
__ push(zero_reg);
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, a0, a5, t0, &stack_overflow);
|
|
||||||
|
|
||||||
// This function modifies t0, a4 and a5.
|
// 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);
|
__ AssertUndefinedOrAllocationSite(a2, t0);
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
@ -1184,7 +1178,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- a0 : the number of arguments (not including the receiver)
|
// -- a0 : the number of arguments (not including the receiver)
|
||||||
@ -1196,13 +1190,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
|||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
Label stack_overflow;
|
Label stack_overflow;
|
||||||
|
|
||||||
// Push a slot for the receiver.
|
__ Daddu(a4, a0, Operand(1)); // Add one for receiver.
|
||||||
__ push(zero_reg);
|
|
||||||
|
|
||||||
Generate_StackOverflowCheck(masm, a4, a5, a6, &stack_overflow);
|
|
||||||
|
|
||||||
// This function modifies a3, a5 and a6.
|
// 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.
|
// ArrayConstructor stub expects constructor in a3. Set it here.
|
||||||
__ mov(a3, a1);
|
__ mov(a3, a1);
|
||||||
|
@ -1112,7 +1112,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, TailCallMode tail_call_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
@ -1153,7 +1153,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r3 : argument count (not including receiver)
|
// -- r3 : argument count (not including receiver)
|
||||||
@ -1206,7 +1206,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r3 : argument count (not including receiver)
|
// -- r3 : argument count (not including receiver)
|
||||||
|
@ -1118,7 +1118,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, TailCallMode tail_call_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
@ -1159,7 +1159,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r2 : argument count (not including receiver)
|
// -- r2 : argument count (not including receiver)
|
||||||
@ -1211,7 +1211,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- r2 : argument count (not including receiver)
|
// -- r2 : argument count (not including receiver)
|
||||||
|
@ -823,9 +823,9 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- rax : the number of arguments (not including the receiver)
|
// -- rax : the number of arguments (not including the receiver)
|
||||||
// -- rbx : the address of the first argument to be pushed. Subsequent
|
// -- 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.
|
// Pop return address to allow tail-call after pushing arguments.
|
||||||
__ PopReturnAddressTo(kScratchRegister);
|
__ 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.
|
// rbx and rdx will be modified.
|
||||||
Generate_InterpreterPushArgs(masm, rcx, rbx, rdx);
|
Generate_InterpreterPushArgs(masm, rcx, rbx, rdx);
|
||||||
|
|
||||||
@ -858,14 +852,15 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
__ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
|
__ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
|
||||||
|
|
||||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||||
__ Jump(masm->isolate()->builtins()->CallFunction(receiver_mode,
|
__ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
|
||||||
tail_call_mode),
|
tail_call_mode),
|
||||||
RelocInfo::CODE_TARGET);
|
RelocInfo::CODE_TARGET);
|
||||||
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
|
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
|
||||||
__ Jump(masm->isolate()->builtins()->CallWithSpread(),
|
__ Jump(masm->isolate()->builtins()->CallWithSpread(),
|
||||||
RelocInfo::CODE_TARGET);
|
RelocInfo::CODE_TARGET);
|
||||||
} else {
|
} else {
|
||||||
__ Jump(masm->isolate()->builtins()->Call(receiver_mode, tail_call_mode),
|
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
|
||||||
|
tail_call_mode),
|
||||||
RelocInfo::CODE_TARGET);
|
RelocInfo::CODE_TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,7 +874,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- rax : the number of arguments (not including the receiver)
|
// -- rax : the number of arguments (not including the receiver)
|
||||||
@ -939,7 +934,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- rax : the number of arguments (not including the receiver)
|
// -- rax : the number of arguments (not including the receiver)
|
||||||
@ -953,6 +948,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
|||||||
|
|
||||||
// Number of values to be pushed.
|
// Number of values to be pushed.
|
||||||
__ Move(r8, rax);
|
__ Move(r8, rax);
|
||||||
|
__ addp(r8, Immediate(1)); // Add one for receiver.
|
||||||
|
|
||||||
// Add a stack check before pushing arguments.
|
// Add a stack check before pushing arguments.
|
||||||
Generate_StackOverflowCheck(masm, r8, rdi, &stack_overflow);
|
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.
|
// Pop return address to allow tail-call after pushing arguments.
|
||||||
__ PopReturnAddressTo(kScratchRegister);
|
__ PopReturnAddressTo(kScratchRegister);
|
||||||
|
|
||||||
// Push slot for the receiver to be constructed.
|
|
||||||
__ Push(Immediate(0));
|
|
||||||
|
|
||||||
// rcx and rdi will be modified.
|
// rcx and rdi will be modified.
|
||||||
Generate_InterpreterPushArgs(masm, r8, rcx, rdi);
|
Generate_InterpreterPushArgs(masm, r8, rcx, rdi);
|
||||||
|
|
||||||
|
@ -694,7 +694,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
|
||||||
MacroAssembler* masm, TailCallMode tail_call_mode,
|
MacroAssembler* masm, TailCallMode tail_call_mode,
|
||||||
InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
@ -758,7 +758,7 @@ namespace {
|
|||||||
// This function modified start_addr, and only reads the contents of num_args
|
// This function modified start_addr, and only reads the contents of num_args
|
||||||
// register. scratch1 and scratch2 are used as temporary registers. Their
|
// register. scratch1 and scratch2 are used as temporary registers. Their
|
||||||
// original values are restored after the use.
|
// original values are restored after the use.
|
||||||
void Generate_InterpreterPushArgsThenReturnAddress(
|
void Generate_InterpreterPushArgsAndReturnAddress(
|
||||||
MacroAssembler* masm, Register num_args, Register start_addr,
|
MacroAssembler* masm, Register num_args, Register start_addr,
|
||||||
Register scratch1, Register scratch2, bool receiver_in_args,
|
Register scratch1, Register scratch2, bool receiver_in_args,
|
||||||
int num_slots_above_ret_addr, Label* stack_overflow) {
|
int num_slots_above_ret_addr, Label* stack_overflow) {
|
||||||
@ -847,7 +847,7 @@ void Generate_InterpreterPushArgsThenReturnAddress(
|
|||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
|
||||||
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
MacroAssembler* masm, InterpreterPushArgsMode mode) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- eax : the number of arguments (not including the receiver)
|
// -- 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.
|
// Push arguments and move return address to the top of stack.
|
||||||
// The eax register is readonly. The ecx register will be modified. The edx
|
// 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.
|
// and edi registers will be modified but restored to their original values.
|
||||||
Generate_InterpreterPushArgsThenReturnAddress(masm, eax, ecx, edx, edi, false,
|
Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false,
|
||||||
2, &stack_overflow);
|
2, &stack_overflow);
|
||||||
|
|
||||||
// Restore edi and edx
|
// Restore edi and edx
|
||||||
__ Pop(edx);
|
__ Pop(edx);
|
||||||
@ -907,7 +907,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Builtins::Generate_InterpreterPushArgsThenConstructArray(
|
void Builtins::Generate_InterpreterPushArgsAndConstructArray(
|
||||||
MacroAssembler* masm) {
|
MacroAssembler* masm) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- eax : the number of arguments (not including the receiver)
|
// -- 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.
|
// Push arguments and move return address to the top of stack.
|
||||||
// The eax register is readonly. The ecx register will be modified. The edx
|
// 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.
|
// and edi registers will be modified but restored to their original values.
|
||||||
Generate_InterpreterPushArgsThenReturnAddress(masm, eax, ecx, edx, edi, true,
|
Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, true,
|
||||||
1, &stack_overflow);
|
1, &stack_overflow);
|
||||||
|
|
||||||
// Restore edx.
|
// Restore edx.
|
||||||
__ Pop(edx);
|
__ Pop(edx);
|
||||||
|
@ -464,25 +464,25 @@ Callable CodeFactory::ConstructFunction(Isolate* isolate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Callable CodeFactory::InterpreterPushArgsThenCall(
|
Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
|
||||||
Isolate* isolate, ConvertReceiverMode receiver_mode,
|
TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
InterpreterPushArgsMode mode) {
|
||||||
return Callable(isolate->builtins()->InterpreterPushArgsThenCall(
|
return Callable(
|
||||||
receiver_mode, tail_call_mode, mode),
|
isolate->builtins()->InterpreterPushArgsAndCall(tail_call_mode, mode),
|
||||||
InterpreterPushArgsThenCallDescriptor(isolate));
|
InterpreterPushArgsAndCallDescriptor(isolate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Callable CodeFactory::InterpreterPushArgsThenConstruct(
|
Callable CodeFactory::InterpreterPushArgsAndConstruct(
|
||||||
Isolate* isolate, InterpreterPushArgsMode mode) {
|
Isolate* isolate, InterpreterPushArgsMode mode) {
|
||||||
return Callable(isolate->builtins()->InterpreterPushArgsThenConstruct(mode),
|
return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(mode),
|
||||||
InterpreterPushArgsThenConstructDescriptor(isolate));
|
InterpreterPushArgsAndConstructDescriptor(isolate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Callable CodeFactory::InterpreterPushArgsThenConstructArray(Isolate* isolate) {
|
Callable CodeFactory::InterpreterPushArgsAndConstructArray(Isolate* isolate) {
|
||||||
return Callable(isolate->builtins()->InterpreterPushArgsThenConstructArray(),
|
return Callable(isolate->builtins()->InterpreterPushArgsAndConstructArray(),
|
||||||
InterpreterPushArgsThenConstructArrayDescriptor(isolate));
|
InterpreterPushArgsAndConstructArrayDescriptor(isolate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -173,13 +173,12 @@ class V8_EXPORT_PRIVATE CodeFactory final {
|
|||||||
static Callable HasProperty(Isolate* isolate);
|
static Callable HasProperty(Isolate* isolate);
|
||||||
static Callable ForInFilter(Isolate* isolate);
|
static Callable ForInFilter(Isolate* isolate);
|
||||||
|
|
||||||
static Callable InterpreterPushArgsThenCall(Isolate* isolate,
|
static Callable InterpreterPushArgsAndCall(Isolate* isolate,
|
||||||
ConvertReceiverMode receiver_mode,
|
TailCallMode tail_call_mode,
|
||||||
TailCallMode tail_call_mode,
|
InterpreterPushArgsMode mode);
|
||||||
InterpreterPushArgsMode mode);
|
static Callable InterpreterPushArgsAndConstruct(Isolate* isolate,
|
||||||
static Callable InterpreterPushArgsThenConstruct(
|
InterpreterPushArgsMode mode);
|
||||||
Isolate* isolate, InterpreterPushArgsMode mode);
|
static Callable InterpreterPushArgsAndConstructArray(Isolate* isolate);
|
||||||
static Callable InterpreterPushArgsThenConstructArray(Isolate* isolate);
|
|
||||||
static Callable InterpreterCEntry(Isolate* isolate, int result_size = 1);
|
static Callable InterpreterCEntry(Isolate* isolate, int result_size = 1);
|
||||||
static Callable InterpreterOnStackReplacement(Isolate* isolate);
|
static Callable InterpreterOnStackReplacement(Isolate* isolate);
|
||||||
|
|
||||||
|
@ -1342,55 +1342,37 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister(
|
Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister(
|
||||||
Node* callee, Node* receiver, interpreter::Register first_arg,
|
Node* callee, interpreter::Register receiver, size_t arity) {
|
||||||
int arg_count) {
|
Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
|
||||||
// The arity of the Call node -- includes the callee, receiver and function
|
|
||||||
// arguments.
|
|
||||||
int arity = 2 + arg_count;
|
|
||||||
|
|
||||||
Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
|
|
||||||
|
|
||||||
all[0] = callee;
|
all[0] = callee;
|
||||||
all[1] = receiver;
|
all[1] = environment()->LookupRegister(receiver);
|
||||||
|
int receiver_index = receiver.index();
|
||||||
// The function arguments are in consecutive registers.
|
for (int i = 2; i < static_cast<int>(arity); ++i) {
|
||||||
int arg_base = first_arg.index();
|
all[i] = environment()->LookupRegister(
|
||||||
for (int i = 0; i < arg_count; ++i) {
|
interpreter::Register(receiver_index + i - 1));
|
||||||
all[2 + i] =
|
|
||||||
environment()->LookupRegister(interpreter::Register(arg_base + i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
|
Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
|
||||||
Node* const* args,
|
Node* const* args,
|
||||||
int arg_count) {
|
size_t arg_count) {
|
||||||
return MakeNode(call_op, arg_count, args, false);
|
return MakeNode(call_op, static_cast<int>(arg_count), args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
|
Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
|
||||||
Node* callee,
|
Node* callee,
|
||||||
interpreter::Register receiver,
|
interpreter::Register receiver,
|
||||||
size_t reg_count) {
|
size_t arg_count) {
|
||||||
Node* receiver_node = environment()->LookupRegister(receiver);
|
return ProcessCallArguments(
|
||||||
// The receiver is followed by the arguments in the consecutive registers.
|
call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count),
|
||||||
DCHECK_GE(reg_count, 1);
|
arg_count);
|
||||||
interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
|
|
||||||
int arg_count = static_cast<int>(reg_count) - 1;
|
|
||||||
|
|
||||||
Node* const* call_args =
|
|
||||||
GetCallArgumentsFromRegister(callee, receiver_node, first_arg, arg_count);
|
|
||||||
return ProcessCallArguments(call_op, call_args, 2 + arg_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode,
|
void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode,
|
||||||
ConvertReceiverMode receiver_mode,
|
ConvertReceiverMode receiver_hint,
|
||||||
Node* const* args, size_t arg_count,
|
Node* const* args, size_t arg_count,
|
||||||
int slot_id) {
|
int slot_id) {
|
||||||
DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
|
|
||||||
bytecode_iterator().current_bytecode()),
|
|
||||||
receiver_mode);
|
|
||||||
PrepareEagerCheckpoint();
|
PrepareEagerCheckpoint();
|
||||||
|
|
||||||
// Slot index of 0 is used indicate no feedback slot is available. Assert
|
// 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);
|
float const frequency = ComputeCallFrequency(slot_id);
|
||||||
const Operator* call = javascript()->Call(arg_count, frequency, feedback,
|
const Operator* call = javascript()->Call(arg_count, frequency, feedback,
|
||||||
receiver_mode, tail_call_mode);
|
receiver_hint, tail_call_mode);
|
||||||
Node* value = ProcessCallArguments(call, args, static_cast<int>(arg_count));
|
Node* value = ProcessCallArguments(call, args, arg_count);
|
||||||
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode,
|
void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode,
|
||||||
ConvertReceiverMode receiver_mode) {
|
ConvertReceiverMode receiver_hint) {
|
||||||
DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
|
|
||||||
bytecode_iterator().current_bytecode()),
|
|
||||||
receiver_mode);
|
|
||||||
Node* callee =
|
Node* callee =
|
||||||
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
||||||
interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
|
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
||||||
size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
||||||
int const slot_id = bytecode_iterator().GetIndexOperand(3);
|
int const slot_id = bytecode_iterator().GetIndexOperand(3);
|
||||||
|
BuildCall(tail_call_mode, receiver_hint,
|
||||||
Node* receiver_node;
|
GetCallArgumentsFromRegister(callee, receiver, arg_count + 1),
|
||||||
interpreter::Register first_arg;
|
arg_count + 1, slot_id);
|
||||||
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<int>(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<int>(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<size_t>(2 + arg_count), slot_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::VisitCallAnyReceiver() {
|
void BytecodeGraphBuilder::VisitCall() {
|
||||||
BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kAny);
|
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() {
|
void BytecodeGraphBuilder::VisitCallProperty() {
|
||||||
BuildCallVarArgs(TailCallMode::kDisallow,
|
BuildCallVarArgs(TailCallMode::kDisallow,
|
||||||
ConvertReceiverMode::kNotNullOrUndefined);
|
ConvertReceiverMode::kNotNullOrUndefined);
|
||||||
@ -1486,54 +1480,16 @@ void BytecodeGraphBuilder::VisitCallProperty2() {
|
|||||||
{callee, receiver, arg0, arg1}, slot_id);
|
{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() {
|
void BytecodeGraphBuilder::VisitCallWithSpread() {
|
||||||
PrepareEagerCheckpoint();
|
PrepareEagerCheckpoint();
|
||||||
Node* callee =
|
Node* callee =
|
||||||
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
||||||
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
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 =
|
const Operator* call =
|
||||||
javascript()->CallWithSpread(static_cast<int>(reg_count + 1));
|
javascript()->CallWithSpread(static_cast<int>(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);
|
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1550,127 +1506,118 @@ void BytecodeGraphBuilder::VisitCallJSRuntime() {
|
|||||||
Node* callee =
|
Node* callee =
|
||||||
BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
|
BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
|
||||||
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
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.
|
// Create node to perform the JS runtime call.
|
||||||
const Operator* call = javascript()->Call(reg_count + 1);
|
const Operator* call = javascript()->Call(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);
|
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
|
Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
|
||||||
const Operator* call_runtime_op, interpreter::Register receiver,
|
const Operator* call_runtime_op, interpreter::Register first_arg,
|
||||||
size_t reg_count) {
|
size_t arity) {
|
||||||
int arg_count = static_cast<int>(reg_count);
|
Node** all = local_zone()->NewArray<Node*>(arity);
|
||||||
// arity is args.
|
int first_arg_index = first_arg.index();
|
||||||
int arity = arg_count;
|
for (int i = 0; i < static_cast<int>(arity); ++i) {
|
||||||
Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
|
|
||||||
int first_arg_index = receiver.index();
|
|
||||||
for (int i = 0; i < static_cast<int>(reg_count); ++i) {
|
|
||||||
all[i] = environment()->LookupRegister(
|
all[i] = environment()->LookupRegister(
|
||||||
interpreter::Register(first_arg_index + i));
|
interpreter::Register(first_arg_index + i));
|
||||||
}
|
}
|
||||||
Node* value = MakeNode(call_runtime_op, arity, all, false);
|
Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::VisitCallRuntime() {
|
void BytecodeGraphBuilder::VisitCallRuntime() {
|
||||||
PrepareEagerCheckpoint();
|
PrepareEagerCheckpoint();
|
||||||
Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
|
Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
|
||||||
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
interpreter::Register first_arg = 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 runtime call.
|
// Create node to perform the runtime call.
|
||||||
const Operator* call = javascript()->CallRuntime(functionId, reg_count);
|
const Operator* call = javascript()->CallRuntime(functionId, arg_count);
|
||||||
Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
|
Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
|
||||||
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
|
void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
|
||||||
PrepareEagerCheckpoint();
|
PrepareEagerCheckpoint();
|
||||||
Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
|
Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
|
||||||
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
|
||||||
size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
||||||
interpreter::Register first_return =
|
interpreter::Register first_return =
|
||||||
bytecode_iterator().GetRegisterOperand(3);
|
bytecode_iterator().GetRegisterOperand(3);
|
||||||
|
|
||||||
// Create node to perform the runtime call.
|
// Create node to perform the runtime call.
|
||||||
const Operator* call = javascript()->CallRuntime(functionId, reg_count);
|
const Operator* call = javascript()->CallRuntime(functionId, arg_count);
|
||||||
Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
|
Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
|
||||||
environment()->BindRegistersToProjections(first_return, return_pair,
|
environment()->BindRegistersToProjections(first_return, return_pair,
|
||||||
Environment::kAttachFrameState);
|
Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* BytecodeGraphBuilder::ProcessConstructWithSpreadArguments(
|
Node* BytecodeGraphBuilder::ProcessConstructWithSpreadArguments(
|
||||||
const Operator* op, Node* callee, Node* new_target,
|
const Operator* op, Node* callee, Node* new_target,
|
||||||
interpreter::Register receiver, size_t reg_count) {
|
interpreter::Register first_arg, size_t arity) {
|
||||||
int arg_count = static_cast<int>(reg_count);
|
Node** all = local_zone()->NewArray<Node*>(arity);
|
||||||
// arity is args + callee and new target.
|
|
||||||
int arity = arg_count + 2;
|
|
||||||
Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
|
|
||||||
all[0] = callee;
|
all[0] = callee;
|
||||||
int first_arg_index = receiver.index();
|
int first_arg_index = first_arg.index();
|
||||||
for (int i = 0; i < arg_count; ++i) {
|
for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
|
||||||
all[1 + i] = environment()->LookupRegister(
|
all[i] = environment()->LookupRegister(
|
||||||
interpreter::Register(first_arg_index + i));
|
interpreter::Register(first_arg_index + i - 1));
|
||||||
}
|
}
|
||||||
all[arity - 1] = new_target;
|
all[arity - 1] = new_target;
|
||||||
Node* value = MakeNode(op, arity, all, false);
|
Node* value = MakeNode(op, static_cast<int>(arity), all, false);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::VisitConstructWithSpread() {
|
void BytecodeGraphBuilder::VisitConstructWithSpread() {
|
||||||
PrepareEagerCheckpoint();
|
PrepareEagerCheckpoint();
|
||||||
interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
|
interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
|
||||||
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
|
||||||
size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
||||||
|
|
||||||
Node* new_target = environment()->LookupAccumulator();
|
Node* new_target = environment()->LookupAccumulator();
|
||||||
Node* callee = environment()->LookupRegister(callee_reg);
|
Node* callee = environment()->LookupRegister(callee_reg);
|
||||||
|
|
||||||
const Operator* op =
|
const Operator* op =
|
||||||
javascript()->ConstructWithSpread(static_cast<uint32_t>(reg_count + 2));
|
javascript()->ConstructWithSpread(static_cast<int>(arg_count) + 2);
|
||||||
Node* value = ProcessConstructWithSpreadArguments(op, callee, new_target,
|
Node* value = ProcessConstructWithSpreadArguments(op, callee, new_target,
|
||||||
receiver, reg_count);
|
first_arg, arg_count + 2);
|
||||||
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
|
void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
|
||||||
PrepareEagerCheckpoint();
|
PrepareEagerCheckpoint();
|
||||||
Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
|
Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
|
||||||
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
interpreter::Register first_arg = 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 runtime call. Turbofan will take care of the
|
// Create node to perform the runtime call. Turbofan will take care of the
|
||||||
// lowering.
|
// lowering.
|
||||||
const Operator* call = javascript()->CallRuntime(functionId, reg_count);
|
const Operator* call = javascript()->CallRuntime(functionId, arg_count);
|
||||||
Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
|
Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
|
||||||
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* BytecodeGraphBuilder::ProcessConstructArguments(
|
Node* BytecodeGraphBuilder::ProcessConstructArguments(
|
||||||
const Operator* call_new_op, Node* callee, Node* new_target,
|
const Operator* call_new_op, Node* callee, Node* new_target,
|
||||||
interpreter::Register receiver, size_t reg_count) {
|
interpreter::Register first_arg, size_t arity) {
|
||||||
int arg_count = static_cast<int>(reg_count);
|
Node** all = local_zone()->NewArray<Node*>(arity);
|
||||||
// arity is args + callee and new target.
|
|
||||||
int arity = arg_count + 2;
|
|
||||||
Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
|
|
||||||
all[0] = callee;
|
all[0] = callee;
|
||||||
int first_arg_index = receiver.index();
|
int first_arg_index = first_arg.index();
|
||||||
for (int i = 0; i < arg_count; ++i) {
|
for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
|
||||||
all[1 + i] = environment()->LookupRegister(
|
all[i] = environment()->LookupRegister(
|
||||||
interpreter::Register(first_arg_index + i));
|
interpreter::Register(first_arg_index + i - 1));
|
||||||
}
|
}
|
||||||
all[arity - 1] = new_target;
|
all[arity - 1] = new_target;
|
||||||
Node* value = MakeNode(call_new_op, arity, all, false);
|
Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGraphBuilder::VisitConstruct() {
|
void BytecodeGraphBuilder::VisitConstruct() {
|
||||||
PrepareEagerCheckpoint();
|
PrepareEagerCheckpoint();
|
||||||
interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
|
interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
|
||||||
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
|
||||||
size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
||||||
// Slot index of 0 is used indicate no feedback slot is available. Assert
|
// 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.
|
// the assumption that slot index 0 is never a valid feedback slot.
|
||||||
STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0);
|
STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0);
|
||||||
@ -1682,9 +1629,9 @@ void BytecodeGraphBuilder::VisitConstruct() {
|
|||||||
|
|
||||||
float const frequency = ComputeCallFrequency(slot_id);
|
float const frequency = ComputeCallFrequency(slot_id);
|
||||||
const Operator* call = javascript()->Construct(
|
const Operator* call = javascript()->Construct(
|
||||||
static_cast<uint32_t>(reg_count + 2), frequency, feedback);
|
static_cast<int>(arg_count) + 2, frequency, feedback);
|
||||||
Node* value =
|
Node* value = ProcessConstructArguments(call, callee, new_target, first_arg,
|
||||||
ProcessConstructArguments(call, callee, new_target, receiver, reg_count);
|
arg_count + 2);
|
||||||
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,24 +112,24 @@ class BytecodeGraphBuilder {
|
|||||||
|
|
||||||
Node** EnsureInputBufferSize(int size);
|
Node** EnsureInputBufferSize(int size);
|
||||||
|
|
||||||
Node* const* GetCallArgumentsFromRegister(Node* callee, Node* receiver,
|
Node* const* GetCallArgumentsFromRegister(Node* callee,
|
||||||
interpreter::Register first_arg,
|
interpreter::Register first_arg,
|
||||||
int arg_count);
|
size_t arity);
|
||||||
Node* ProcessCallArguments(const Operator* call_op, Node* const* args,
|
Node* ProcessCallArguments(const Operator* call_op, Node* const* args,
|
||||||
int arg_count);
|
size_t arg_count);
|
||||||
Node* ProcessCallArguments(const Operator* call_op, Node* callee,
|
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* ProcessConstructArguments(const Operator* call_new_op, Node* callee,
|
||||||
Node* new_target,
|
Node* new_target,
|
||||||
interpreter::Register receiver,
|
interpreter::Register first_arg,
|
||||||
size_t reg_count);
|
size_t arity);
|
||||||
Node* ProcessConstructWithSpreadArguments(const Operator* op, Node* callee,
|
Node* ProcessConstructWithSpreadArguments(const Operator* op, Node* callee,
|
||||||
Node* new_target,
|
Node* new_target,
|
||||||
interpreter::Register receiver,
|
interpreter::Register first_arg,
|
||||||
size_t reg_count);
|
size_t arity);
|
||||||
Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
|
Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
|
||||||
interpreter::Register receiver,
|
interpreter::Register first_arg,
|
||||||
size_t reg_count);
|
size_t arity);
|
||||||
|
|
||||||
// Prepare information for eager deoptimization. This information is carried
|
// Prepare information for eager deoptimization. This information is carried
|
||||||
// by dedicated {Checkpoint} nodes that are wired into the effect chain.
|
// by dedicated {Checkpoint} nodes that are wired into the effect chain.
|
||||||
@ -159,12 +159,12 @@ class BytecodeGraphBuilder {
|
|||||||
void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode);
|
void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode);
|
||||||
void BuildStaLookupSlot(LanguageMode language_mode);
|
void BuildStaLookupSlot(LanguageMode language_mode);
|
||||||
void BuildCallVarArgs(TailCallMode tail_call_mode,
|
void BuildCallVarArgs(TailCallMode tail_call_mode,
|
||||||
ConvertReceiverMode receiver_mode);
|
ConvertReceiverMode receiver_hint);
|
||||||
void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_mode,
|
void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_hint,
|
||||||
Node* const* args, size_t arg_count, int slot_id);
|
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<Node*> args, int slot_id) {
|
std::initializer_list<Node*> 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);
|
slot_id);
|
||||||
}
|
}
|
||||||
void BuildBinaryOp(const Operator* op);
|
void BuildBinaryOp(const Operator* op);
|
||||||
|
@ -318,7 +318,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
eax, // argument count (not including receiver)
|
eax, // argument count (not including receiver)
|
||||||
@ -328,7 +328,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
eax, // argument count (not including receiver)
|
eax, // argument count (not including receiver)
|
||||||
@ -340,8 +340,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
eax, // argument count (not including receiver)
|
eax, // argument count (not including receiver)
|
||||||
edx, // target to the call. It is checked to be Array function.
|
edx, // target to the call. It is checked to be Array function.
|
||||||
|
@ -607,7 +607,7 @@ void InterpreterDispatchDescriptor::InitializePlatformIndependent(
|
|||||||
machine_types);
|
machine_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformIndependent(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformIndependent(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
// kNumberOfArguments, kFirstArgument, kFunction
|
// kNumberOfArguments, kFirstArgument, kFunction
|
||||||
MachineType machine_types[] = {MachineType::Int32(), MachineType::Pointer(),
|
MachineType machine_types[] = {MachineType::Int32(), MachineType::Pointer(),
|
||||||
@ -616,7 +616,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformIndependent(
|
|||||||
machine_types);
|
machine_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformIndependent(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformIndependent(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
// kNumberOfArguments, kNewTarget, kConstructor, kFeedbackElement,
|
// kNumberOfArguments, kNewTarget, kConstructor, kFeedbackElement,
|
||||||
// kFirstArgument
|
// kFirstArgument
|
||||||
@ -627,7 +627,7 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformIndependent(
|
|||||||
machine_types);
|
machine_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::
|
||||||
InitializePlatformIndependent(CallInterfaceDescriptorData* data) {
|
InitializePlatformIndependent(CallInterfaceDescriptorData* data) {
|
||||||
// kNumberOfArguments, kFunction, kFeedbackElement, kFirstArgument
|
// kNumberOfArguments, kFunction, kFeedbackElement, kFirstArgument
|
||||||
MachineType machine_types[] = {MachineType::Int32(), MachineType::AnyTagged(),
|
MachineType machine_types[] = {MachineType::Int32(), MachineType::AnyTagged(),
|
||||||
|
@ -79,9 +79,9 @@ class PlatformInterfaceDescriptor;
|
|||||||
V(GrowArrayElements) \
|
V(GrowArrayElements) \
|
||||||
V(NewArgumentsElements) \
|
V(NewArgumentsElements) \
|
||||||
V(InterpreterDispatch) \
|
V(InterpreterDispatch) \
|
||||||
V(InterpreterPushArgsThenCall) \
|
V(InterpreterPushArgsAndCall) \
|
||||||
V(InterpreterPushArgsThenConstruct) \
|
V(InterpreterPushArgsAndConstruct) \
|
||||||
V(InterpreterPushArgsThenConstructArray) \
|
V(InterpreterPushArgsAndConstructArray) \
|
||||||
V(InterpreterCEntry) \
|
V(InterpreterCEntry) \
|
||||||
V(ResumeGenerator) \
|
V(ResumeGenerator) \
|
||||||
V(FrameDropperTrampoline) \
|
V(FrameDropperTrampoline) \
|
||||||
@ -839,29 +839,30 @@ class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
|
|||||||
CallInterfaceDescriptor)
|
CallInterfaceDescriptor)
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
|
class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor {
|
||||||
public:
|
public:
|
||||||
DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
|
DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
|
||||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
|
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
|
||||||
InterpreterPushArgsThenCallDescriptor, CallInterfaceDescriptor)
|
InterpreterPushArgsAndCallDescriptor, CallInterfaceDescriptor)
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterpreterPushArgsThenConstructDescriptor
|
|
||||||
|
class InterpreterPushArgsAndConstructDescriptor
|
||||||
: public CallInterfaceDescriptor {
|
: public CallInterfaceDescriptor {
|
||||||
public:
|
public:
|
||||||
DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor,
|
DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor,
|
||||||
kFeedbackElement, kFirstArgument)
|
kFeedbackElement, kFirstArgument)
|
||||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
|
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
|
||||||
InterpreterPushArgsThenConstructDescriptor, CallInterfaceDescriptor)
|
InterpreterPushArgsAndConstructDescriptor, CallInterfaceDescriptor)
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterpreterPushArgsThenConstructArrayDescriptor
|
class InterpreterPushArgsAndConstructArrayDescriptor
|
||||||
: public CallInterfaceDescriptor {
|
: public CallInterfaceDescriptor {
|
||||||
public:
|
public:
|
||||||
DEFINE_PARAMETERS(kNumberOfArguments, kFunction, kFeedbackElement,
|
DEFINE_PARAMETERS(kNumberOfArguments, kFunction, kFeedbackElement,
|
||||||
kFirstArgument)
|
kFirstArgument)
|
||||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
|
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
|
||||||
InterpreterPushArgsThenConstructArrayDescriptor, CallInterfaceDescriptor)
|
InterpreterPushArgsAndConstructArrayDescriptor, CallInterfaceDescriptor)
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
|
class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
|
||||||
|
@ -1252,50 +1252,42 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
BytecodeArrayBuilder& BytecodeArrayBuilder::CallProperty(Register callable,
|
BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
|
||||||
RegisterList args,
|
RegisterList args,
|
||||||
int feedback_slot) {
|
int feedback_slot,
|
||||||
if (args.register_count() == 1) {
|
Call::CallType call_type,
|
||||||
OutputCallProperty0(callable, args[0], feedback_slot);
|
TailCallMode tail_call_mode) {
|
||||||
} else if (args.register_count() == 2) {
|
if (tail_call_mode == TailCallMode::kDisallow) {
|
||||||
OutputCallProperty1(callable, args[0], args[1], feedback_slot);
|
if (call_type == Call::NAMED_PROPERTY_CALL ||
|
||||||
} else if (args.register_count() == 3) {
|
call_type == Call::KEYED_PROPERTY_CALL) {
|
||||||
OutputCallProperty2(callable, args[0], args[1], args[2], 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);
|
||||||
|
} 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 {
|
} 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;
|
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,
|
BytecodeArrayBuilder& BytecodeArrayBuilder::CallWithSpread(Register callable,
|
||||||
RegisterList args) {
|
RegisterList args) {
|
||||||
OutputCallWithSpread(callable, args, args.register_count());
|
OutputCallWithSpread(callable, args, args.register_count());
|
||||||
|
@ -238,35 +238,14 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
|
|||||||
// Pop the current context and replace with |context|.
|
// Pop the current context and replace with |context|.
|
||||||
BytecodeArrayBuilder& PopContext(Register context);
|
BytecodeArrayBuilder& PopContext(Register context);
|
||||||
|
|
||||||
// Call a JS function which is known to be a property of a JS object. The
|
// Call a JS function. The JSFunction or Callable to be called should be in
|
||||||
// JSFunction or Callable to be called should be in |callable|. The arguments
|
// |callable|. The arguments should be in |args|, with the receiver in
|
||||||
// should be in |args|, with the receiver in |args[0]|. The call type of the
|
// |args[0]|. The call type of the expression is in |call_type|. Type feedback
|
||||||
// expression is in |call_type|. Type feedback is recorded in the
|
// is recorded in the |feedback_slot| in the type feedback vector.
|
||||||
// |feedback_slot| in the type feedback vector.
|
BytecodeArrayBuilder& Call(
|
||||||
BytecodeArrayBuilder& CallProperty(Register callable, RegisterList args,
|
Register callable, RegisterList args, int feedback_slot,
|
||||||
int feedback_slot);
|
Call::CallType call_type,
|
||||||
|
TailCallMode tail_call_mode = TailCallMode::kDisallow);
|
||||||
// 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
|
// 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]|
|
// |callable|, the receiver in |args[0]| and the arguments in |args[1]|
|
||||||
|
@ -2597,12 +2597,6 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
Register callee = register_allocator()->NewRegister();
|
Register callee = register_allocator()->NewRegister();
|
||||||
RegisterList args = register_allocator()->NewGrowableRegisterList();
|
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,
|
// 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
|
// see if we can reduce the number by adding a separate argument which
|
||||||
// specifies the call type (e.g., property, spread, tailcall, etc.).
|
// specifies the call type (e.g., property, spread, tailcall, etc.).
|
||||||
@ -2619,13 +2613,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
}
|
}
|
||||||
case Call::GLOBAL_CALL: {
|
case Call::GLOBAL_CALL: {
|
||||||
// Receiver is undefined for global calls.
|
// Receiver is undefined for global calls.
|
||||||
if (!is_tail_call && !is_spread_call) {
|
BuildPushUndefinedIntoRegisterList(&args);
|
||||||
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);
|
|
||||||
}
|
|
||||||
// Load callee as a global variable.
|
// Load callee as a global variable.
|
||||||
VariableProxy* proxy = callee_expr->AsVariableProxy();
|
VariableProxy* proxy = callee_expr->AsVariableProxy();
|
||||||
BuildVariableLoadForAccumulatorValue(proxy->var(),
|
BuildVariableLoadForAccumulatorValue(proxy->var(),
|
||||||
@ -2645,7 +2633,6 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
DCHECK(Register::AreContiguous(callee, receiver));
|
DCHECK(Register::AreContiguous(callee, receiver));
|
||||||
RegisterList result_pair(callee.index(), 2);
|
RegisterList result_pair(callee.index(), 2);
|
||||||
USE(receiver);
|
USE(receiver);
|
||||||
|
|
||||||
Variable* variable = callee_expr->AsVariableProxy()->var();
|
Variable* variable = callee_expr->AsVariableProxy()->var();
|
||||||
builder()
|
builder()
|
||||||
->LoadLiteral(variable->raw_name())
|
->LoadLiteral(variable->raw_name())
|
||||||
@ -2656,14 +2643,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Call::OTHER_CALL: {
|
case Call::OTHER_CALL: {
|
||||||
// Receiver is undefined for other calls.
|
BuildPushUndefinedIntoRegisterList(&args);
|
||||||
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);
|
|
||||||
}
|
|
||||||
VisitForRegisterValue(callee_expr, callee);
|
VisitForRegisterValue(callee_expr, callee);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2689,9 +2669,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
// Evaluate all arguments to the function call and store in sequential args
|
// Evaluate all arguments to the function call and store in sequential args
|
||||||
// registers.
|
// registers.
|
||||||
VisitArguments(expr->arguments(), &args);
|
VisitArguments(expr->arguments(), &args);
|
||||||
int reciever_arg_count = implicit_undefined_receiver ? 0 : 1;
|
CHECK_EQ(expr->arguments()->length() + 1, args.register_count());
|
||||||
CHECK_EQ(reciever_arg_count + expr->arguments()->length(),
|
|
||||||
args.register_count());
|
|
||||||
|
|
||||||
// Resolve callee for a potential direct eval call. This block will mutate the
|
// Resolve callee for a potential direct eval call. This block will mutate the
|
||||||
// callee value.
|
// callee value.
|
||||||
@ -2700,11 +2678,10 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
// Set up arguments for ResolvePossiblyDirectEval by copying callee, source
|
// Set up arguments for ResolvePossiblyDirectEval by copying callee, source
|
||||||
// strings and function closure, and loading language and
|
// strings and function closure, and loading language and
|
||||||
// position.
|
// position.
|
||||||
Register first_arg = args[reciever_arg_count];
|
|
||||||
RegisterList runtime_call_args = register_allocator()->NewRegisterList(6);
|
RegisterList runtime_call_args = register_allocator()->NewRegisterList(6);
|
||||||
builder()
|
builder()
|
||||||
->MoveRegister(callee, runtime_call_args[0])
|
->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])
|
.MoveRegister(Register::function_closure(), runtime_call_args[2])
|
||||||
.LoadLiteral(Smi::FromInt(language_mode()))
|
.LoadLiteral(Smi::FromInt(language_mode()))
|
||||||
.StoreAccumulatorInRegister(runtime_call_args[3])
|
.StoreAccumulatorInRegister(runtime_call_args[3])
|
||||||
@ -2721,23 +2698,15 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
|||||||
|
|
||||||
builder()->SetExpressionPosition(expr);
|
builder()->SetExpressionPosition(expr);
|
||||||
|
|
||||||
int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
|
// 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 (is_spread_call) {
|
if (expr->only_last_arg_is_spread()) {
|
||||||
DCHECK(!is_tail_call);
|
DCHECK_EQ(TailCallMode::kDisallow, expr->tail_call_mode());
|
||||||
DCHECK(!implicit_undefined_receiver);
|
|
||||||
builder()->CallWithSpread(callee, args);
|
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 {
|
} 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()) {
|
if (expr->is_jsruntime()) {
|
||||||
RegisterList args = register_allocator()->NewGrowableRegisterList();
|
RegisterList args = register_allocator()->NewGrowableRegisterList();
|
||||||
// Allocate a register for the receiver and load it with undefined.
|
// 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);
|
BuildPushUndefinedIntoRegisterList(&args);
|
||||||
VisitArguments(expr->arguments(), &args);
|
VisitArguments(expr->arguments(), &args);
|
||||||
builder()->CallJSRuntime(expr->context_index(), args);
|
builder()->CallJSRuntime(expr->context_index(), args);
|
||||||
@ -3186,8 +3153,9 @@ void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
|
|||||||
builder()->JumpIfNull(&async_iterator_null);
|
builder()->JumpIfNull(&async_iterator_null);
|
||||||
|
|
||||||
// Let iterator be Call(method, obj)
|
// Let iterator be Call(method, obj)
|
||||||
builder()->StoreAccumulatorInRegister(method).CallProperty(
|
builder()->StoreAccumulatorInRegister(method).Call(
|
||||||
method, args, feedback_index(async_call_slot));
|
method, args, feedback_index(async_call_slot),
|
||||||
|
Call::NAMED_PROPERTY_CALL);
|
||||||
|
|
||||||
// If Type(iterator) is not Object, throw a TypeError exception.
|
// If Type(iterator) is not Object, throw a TypeError exception.
|
||||||
builder()->JumpIfJSReceiver(&done);
|
builder()->JumpIfJSReceiver(&done);
|
||||||
@ -3202,7 +3170,8 @@ void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
|
|||||||
.StoreAccumulatorInRegister(method);
|
.StoreAccumulatorInRegister(method);
|
||||||
|
|
||||||
// Let syncIterator be Call(syncMethod, obj)
|
// 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)
|
// Return CreateAsyncFromSyncIterator(syncIterator)
|
||||||
// alias `method` register as it's no longer used
|
// alias `method` register as it's no longer used
|
||||||
@ -3219,7 +3188,8 @@ void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
|
|||||||
.StoreAccumulatorInRegister(method);
|
.StoreAccumulatorInRegister(method);
|
||||||
|
|
||||||
// Let iterator be Call(method, obj).
|
// 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.
|
// If Type(iterator) is not Object, throw a TypeError exception.
|
||||||
BytecodeLabel no_type_error;
|
BytecodeLabel no_type_error;
|
||||||
|
@ -238,15 +238,8 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
|
|||||||
case Bytecode::kInc:
|
case Bytecode::kInc:
|
||||||
case Bytecode::kDec:
|
case Bytecode::kDec:
|
||||||
case Bytecode::kTypeOf:
|
case Bytecode::kTypeOf:
|
||||||
case Bytecode::kCallAnyReceiver:
|
case Bytecode::kCall:
|
||||||
case Bytecode::kCallProperty:
|
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::kConstruct:
|
||||||
case Bytecode::kConstructWithSpread:
|
case Bytecode::kConstructWithSpread:
|
||||||
return true;
|
return true;
|
||||||
|
@ -158,8 +158,14 @@ namespace interpreter {
|
|||||||
V(GetSuperConstructor, AccumulatorUse::kRead, OperandType::kRegOut) \
|
V(GetSuperConstructor, AccumulatorUse::kRead, OperandType::kRegOut) \
|
||||||
\
|
\
|
||||||
/* Call operations */ \
|
/* Call operations */ \
|
||||||
V(CallAnyReceiver, AccumulatorUse::kWrite, OperandType::kReg, \
|
V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kRegList, \
|
||||||
OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \
|
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, \
|
V(CallProperty, AccumulatorUse::kWrite, OperandType::kReg, \
|
||||||
OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \
|
OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx) \
|
||||||
V(CallProperty0, AccumulatorUse::kWrite, OperandType::kReg, \
|
V(CallProperty0, AccumulatorUse::kWrite, OperandType::kReg, \
|
||||||
@ -169,14 +175,6 @@ namespace interpreter {
|
|||||||
V(CallProperty2, AccumulatorUse::kWrite, OperandType::kReg, \
|
V(CallProperty2, AccumulatorUse::kWrite, OperandType::kReg, \
|
||||||
OperandType::kReg, OperandType::kReg, OperandType::kReg, \
|
OperandType::kReg, OperandType::kReg, OperandType::kReg, \
|
||||||
OperandType::kIdx) \
|
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, \
|
V(CallWithSpread, AccumulatorUse::kWrite, OperandType::kReg, \
|
||||||
OperandType::kRegList, OperandType::kRegCount) \
|
OperandType::kRegList, OperandType::kRegCount) \
|
||||||
V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, \
|
V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, \
|
||||||
@ -434,7 +432,7 @@ enum class Bytecode : uint8_t {
|
|||||||
|
|
||||||
class V8_EXPORT_PRIVATE Bytecodes final {
|
class V8_EXPORT_PRIVATE Bytecodes final {
|
||||||
public:
|
public:
|
||||||
// The maximum number of operands a bytecode may have.
|
// The maximum number of operands a bytecode may have.
|
||||||
static const int kMaxOperands = 5;
|
static const int kMaxOperands = 5;
|
||||||
|
|
||||||
// Returns string representation of |bytecode|.
|
// 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.
|
// Returns true if the bytecode is a call or a constructor call.
|
||||||
static constexpr bool IsCallOrConstruct(Bytecode bytecode) {
|
static constexpr bool IsCallOrConstruct(Bytecode bytecode) {
|
||||||
return bytecode == Bytecode::kCallAnyReceiver ||
|
return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty ||
|
||||||
bytecode == Bytecode::kCallProperty ||
|
bytecode == Bytecode::kCall0 ||
|
||||||
bytecode == Bytecode::kCallProperty0 ||
|
bytecode == Bytecode::kCallProperty0 ||
|
||||||
|
bytecode == Bytecode::kCall1 ||
|
||||||
bytecode == Bytecode::kCallProperty1 ||
|
bytecode == Bytecode::kCallProperty1 ||
|
||||||
|
bytecode == Bytecode::kCall2 ||
|
||||||
bytecode == Bytecode::kCallProperty2 ||
|
bytecode == Bytecode::kCallProperty2 ||
|
||||||
bytecode == Bytecode::kCallUndefinedReceiver ||
|
|
||||||
bytecode == Bytecode::kCallUndefinedReceiver0 ||
|
|
||||||
bytecode == Bytecode::kCallUndefinedReceiver1 ||
|
|
||||||
bytecode == Bytecode::kCallUndefinedReceiver2 ||
|
|
||||||
bytecode == Bytecode::kTailCall ||
|
bytecode == Bytecode::kTailCall ||
|
||||||
bytecode == Bytecode::kConstruct ||
|
bytecode == Bytecode::kConstruct ||
|
||||||
bytecode == Bytecode::kCallWithSpread ||
|
bytecode == Bytecode::kCallWithSpread ||
|
||||||
@ -750,34 +746,6 @@ class V8_EXPORT_PRIVATE Bytecodes final {
|
|||||||
// through the bytecode's handler.
|
// through the bytecode's handler.
|
||||||
static bool MakesCallAlongCriticalPath(Bytecode bytecode);
|
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.
|
// Returns true if the bytecode is a debug break.
|
||||||
static bool IsDebugBreak(Bytecode bytecode);
|
static bool IsDebugBreak(Bytecode bytecode);
|
||||||
|
|
||||||
|
@ -555,11 +555,11 @@ Node* InterpreterAssembler::IncrementCallCount(Node* feedback_vector,
|
|||||||
SKIP_WRITE_BARRIER);
|
SKIP_WRITE_BARRIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* InterpreterAssembler::CallJSWithFeedback(
|
Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context,
|
||||||
compiler::Node* function, compiler::Node* context,
|
Node* first_arg, Node* arg_count,
|
||||||
compiler::Node* first_arg, compiler::Node* arg_count,
|
Node* slot_id,
|
||||||
compiler::Node* slot_id, compiler::Node* feedback_vector,
|
Node* feedback_vector,
|
||||||
ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode) {
|
TailCallMode tail_call_mode) {
|
||||||
// Static checks to assert it is safe to examine the type feedback element.
|
// 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
|
// 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.
|
// or an AllocationSite, but the memory is safe to examine.
|
||||||
@ -572,8 +572,6 @@ Node* InterpreterAssembler::CallJSWithFeedback(
|
|||||||
// to be a pointer.
|
// to be a pointer.
|
||||||
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
||||||
DCHECK(Bytecodes::IsCallOrConstruct(bytecode_));
|
DCHECK(Bytecodes::IsCallOrConstruct(bytecode_));
|
||||||
DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), receiver_mode);
|
|
||||||
|
|
||||||
STATIC_ASSERT(WeakCell::kSize >= kPointerSize);
|
STATIC_ASSERT(WeakCell::kSize >= kPointerSize);
|
||||||
STATIC_ASSERT(AllocationSite::kTransitionInfoOffset ==
|
STATIC_ASSERT(AllocationSite::kTransitionInfoOffset ==
|
||||||
WeakCell::kValueOffset &&
|
WeakCell::kValueOffset &&
|
||||||
@ -600,9 +598,8 @@ Node* InterpreterAssembler::CallJSWithFeedback(
|
|||||||
IncrementCallCount(feedback_vector, slot_id);
|
IncrementCallCount(feedback_vector, slot_id);
|
||||||
|
|
||||||
// Call using call function builtin.
|
// Call using call function builtin.
|
||||||
Callable callable = CodeFactory::InterpreterPushArgsThenCall(
|
Callable callable = CodeFactory::InterpreterPushArgsAndCall(
|
||||||
isolate(), receiver_mode, tail_call_mode,
|
isolate(), tail_call_mode, InterpreterPushArgsMode::kJSFunction);
|
||||||
InterpreterPushArgsMode::kJSFunction);
|
|
||||||
Node* code_target = HeapConstant(callable.code());
|
Node* code_target = HeapConstant(callable.code());
|
||||||
Node* ret_value = CallStub(callable.descriptor(), code_target, context,
|
Node* ret_value = CallStub(callable.descriptor(), code_target, context,
|
||||||
arg_count, first_arg, function);
|
arg_count, first_arg, function);
|
||||||
@ -626,33 +623,24 @@ Node* InterpreterAssembler::CallJSWithFeedback(
|
|||||||
GotoIfNot(IsAllocationSiteMap(LoadMap(feedback_element)),
|
GotoIfNot(IsAllocationSiteMap(LoadMap(feedback_element)),
|
||||||
&check_initialized);
|
&check_initialized);
|
||||||
|
|
||||||
if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
|
// If it is not the Array() function, mark megamorphic.
|
||||||
// For undefined receivers (mostly global calls), do an additional check
|
Node* context_slot = LoadContextElement(LoadNativeContext(context),
|
||||||
// for the monomorphic Array function, which would otherwise appear
|
Context::ARRAY_FUNCTION_INDEX);
|
||||||
// megamorphic.
|
Node* is_array_function = WordEqual(context_slot, function);
|
||||||
|
GotoIfNot(is_array_function, &mark_megamorphic);
|
||||||
|
|
||||||
// If it is not the Array() function, mark megamorphic.
|
// It is a monomorphic Array function. Increment the call count.
|
||||||
Node* context_slot = LoadContextElement(LoadNativeContext(context),
|
IncrementCallCount(feedback_vector, slot_id);
|
||||||
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.
|
// Call ArrayConstructorStub.
|
||||||
IncrementCallCount(feedback_vector, slot_id);
|
Callable callable_call =
|
||||||
|
CodeFactory::InterpreterPushArgsAndConstructArray(isolate());
|
||||||
// Call ArrayConstructorStub.
|
Node* code_target_call = HeapConstant(callable_call.code());
|
||||||
Callable callable_call =
|
Node* ret_value =
|
||||||
CodeFactory::InterpreterPushArgsThenConstructArray(isolate());
|
CallStub(callable_call.descriptor(), code_target_call, context,
|
||||||
Node* code_target_call = HeapConstant(callable_call.code());
|
arg_count, function, feedback_element, first_arg);
|
||||||
Node* ret_value =
|
return_value.Bind(ret_value);
|
||||||
CallStub(callable_call.descriptor(), code_target_call, context,
|
Goto(&end);
|
||||||
arg_count, function, feedback_element, first_arg);
|
|
||||||
return_value.Bind(ret_value);
|
|
||||||
Goto(&end);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Goto(&mark_megamorphic);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bind(&check_initialized);
|
Bind(&check_initialized);
|
||||||
{
|
{
|
||||||
@ -663,7 +651,7 @@ Node* InterpreterAssembler::CallJSWithFeedback(
|
|||||||
HeapConstant(FeedbackVector::UninitializedSentinel(isolate())));
|
HeapConstant(FeedbackVector::UninitializedSentinel(isolate())));
|
||||||
GotoIfNot(is_uninitialized, &mark_megamorphic);
|
GotoIfNot(is_uninitialized, &mark_megamorphic);
|
||||||
|
|
||||||
Comment("handle_uninitialized");
|
Comment("handle_unitinitialized");
|
||||||
// If it is not a JSFunction mark it as megamorphic.
|
// If it is not a JSFunction mark it as megamorphic.
|
||||||
Node* is_smi = TaggedIsSmi(function);
|
Node* is_smi = TaggedIsSmi(function);
|
||||||
GotoIf(is_smi, &mark_megamorphic);
|
GotoIf(is_smi, &mark_megamorphic);
|
||||||
@ -725,9 +713,8 @@ Node* InterpreterAssembler::CallJSWithFeedback(
|
|||||||
IncrementCallCount(feedback_vector, slot_id);
|
IncrementCallCount(feedback_vector, slot_id);
|
||||||
|
|
||||||
// Call using call builtin.
|
// Call using call builtin.
|
||||||
Callable callable_call = CodeFactory::InterpreterPushArgsThenCall(
|
Callable callable_call = CodeFactory::InterpreterPushArgsAndCall(
|
||||||
isolate(), receiver_mode, tail_call_mode,
|
isolate(), tail_call_mode, InterpreterPushArgsMode::kOther);
|
||||||
InterpreterPushArgsMode::kOther);
|
|
||||||
Node* code_target_call = HeapConstant(callable_call.code());
|
Node* code_target_call = HeapConstant(callable_call.code());
|
||||||
Node* ret_value = CallStub(callable_call.descriptor(), code_target_call,
|
Node* ret_value = CallStub(callable_call.descriptor(), code_target_call,
|
||||||
context, arg_count, first_arg, function);
|
context, arg_count, first_arg, function);
|
||||||
@ -741,14 +728,11 @@ Node* InterpreterAssembler::CallJSWithFeedback(
|
|||||||
|
|
||||||
Node* InterpreterAssembler::CallJS(Node* function, Node* context,
|
Node* InterpreterAssembler::CallJS(Node* function, Node* context,
|
||||||
Node* first_arg, Node* arg_count,
|
Node* first_arg, Node* arg_count,
|
||||||
ConvertReceiverMode receiver_mode,
|
|
||||||
TailCallMode tail_call_mode) {
|
TailCallMode tail_call_mode) {
|
||||||
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
||||||
DCHECK(Bytecodes::IsCallOrConstruct(bytecode_));
|
DCHECK(Bytecodes::IsCallOrConstruct(bytecode_));
|
||||||
DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), receiver_mode);
|
Callable callable = CodeFactory::InterpreterPushArgsAndCall(
|
||||||
Callable callable = CodeFactory::InterpreterPushArgsThenCall(
|
isolate(), tail_call_mode, InterpreterPushArgsMode::kOther);
|
||||||
isolate(), receiver_mode, tail_call_mode,
|
|
||||||
InterpreterPushArgsMode::kOther);
|
|
||||||
Node* code_target = HeapConstant(callable.code());
|
Node* code_target = HeapConstant(callable.code());
|
||||||
|
|
||||||
return CallStub(callable.descriptor(), code_target, context, arg_count,
|
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* InterpreterAssembler::CallJSWithSpread(Node* function, Node* context,
|
||||||
Node* first_arg, Node* arg_count) {
|
Node* first_arg, Node* arg_count) {
|
||||||
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
||||||
DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), ConvertReceiverMode::kAny);
|
Callable callable = CodeFactory::InterpreterPushArgsAndCall(
|
||||||
Callable callable = CodeFactory::InterpreterPushArgsThenCall(
|
isolate(), TailCallMode::kDisallow,
|
||||||
isolate(), ConvertReceiverMode::kAny, TailCallMode::kDisallow,
|
|
||||||
InterpreterPushArgsMode::kWithFinalSpread);
|
InterpreterPushArgsMode::kWithFinalSpread);
|
||||||
Node* code_target = HeapConstant(callable.code());
|
Node* code_target = HeapConstant(callable.code());
|
||||||
|
|
||||||
@ -804,7 +787,7 @@ Node* InterpreterAssembler::Construct(Node* constructor, Node* context,
|
|||||||
{
|
{
|
||||||
Comment("call using ConstructFunction");
|
Comment("call using ConstructFunction");
|
||||||
IncrementCallCount(feedback_vector, slot_id);
|
IncrementCallCount(feedback_vector, slot_id);
|
||||||
Callable callable_function = CodeFactory::InterpreterPushArgsThenConstruct(
|
Callable callable_function = CodeFactory::InterpreterPushArgsAndConstruct(
|
||||||
isolate(), InterpreterPushArgsMode::kJSFunction);
|
isolate(), InterpreterPushArgsMode::kJSFunction);
|
||||||
return_value.Bind(CallStub(callable_function.descriptor(),
|
return_value.Bind(CallStub(callable_function.descriptor(),
|
||||||
HeapConstant(callable_function.code()), context,
|
HeapConstant(callable_function.code()), context,
|
||||||
@ -907,7 +890,7 @@ Node* InterpreterAssembler::Construct(Node* constructor, Node* context,
|
|||||||
Bind(&call_construct);
|
Bind(&call_construct);
|
||||||
{
|
{
|
||||||
Comment("call using Construct builtin");
|
Comment("call using Construct builtin");
|
||||||
Callable callable = CodeFactory::InterpreterPushArgsThenConstruct(
|
Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(
|
||||||
isolate(), InterpreterPushArgsMode::kOther);
|
isolate(), InterpreterPushArgsMode::kOther);
|
||||||
Node* code_target = HeapConstant(callable.code());
|
Node* code_target = HeapConstant(callable.code());
|
||||||
return_value.Bind(CallStub(callable.descriptor(), code_target, context,
|
return_value.Bind(CallStub(callable.descriptor(), code_target, context,
|
||||||
@ -927,7 +910,7 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* constructor,
|
|||||||
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
|
||||||
Variable return_value(this, MachineRepresentation::kTagged);
|
Variable return_value(this, MachineRepresentation::kTagged);
|
||||||
Comment("call using ConstructWithSpread");
|
Comment("call using ConstructWithSpread");
|
||||||
Callable callable = CodeFactory::InterpreterPushArgsThenConstruct(
|
Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(
|
||||||
isolate(), InterpreterPushArgsMode::kWithFinalSpread);
|
isolate(), InterpreterPushArgsMode::kWithFinalSpread);
|
||||||
Node* code_target = HeapConstant(callable.code());
|
Node* code_target = HeapConstant(callable.code());
|
||||||
return_value.Bind(CallStub(callable.descriptor(), code_target, context,
|
return_value.Bind(CallStub(callable.descriptor(), code_target, context,
|
||||||
|
@ -118,25 +118,23 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
|
|||||||
compiler::Node* IncrementCallCount(compiler::Node* feedback_vector,
|
compiler::Node* IncrementCallCount(compiler::Node* feedback_vector,
|
||||||
compiler::Node* slot_id);
|
compiler::Node* slot_id);
|
||||||
|
|
||||||
// Call JSFunction or Callable |function| with |arg_count| arguments (not
|
// Call JSFunction or Callable |function| with |arg_count|
|
||||||
// including receiver) and the first argument located at |first_arg|. Type
|
// arguments (not including receiver) and the first argument
|
||||||
// feedback is collected in the slot at index |slot_id|.
|
// 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
|
compiler::Node* CallJSWithFeedback(compiler::Node* function,
|
||||||
// undefined and |first_arg| is the first parameter. Otherwise, |first_arg| is
|
compiler::Node* context,
|
||||||
// the receiver and it is converted according to |receiver_mode|.
|
compiler::Node* first_arg,
|
||||||
compiler::Node* CallJSWithFeedback(
|
compiler::Node* arg_count,
|
||||||
compiler::Node* function, compiler::Node* context,
|
compiler::Node* slot_id,
|
||||||
compiler::Node* first_arg, compiler::Node* arg_count,
|
compiler::Node* feedback_vector,
|
||||||
compiler::Node* slot_id, compiler::Node* feedback_vector,
|
TailCallMode tail_call_mode);
|
||||||
ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode);
|
|
||||||
|
|
||||||
// Call JSFunction or Callable |function| with |arg_count| arguments (not
|
// Call JSFunction or Callable |function| with |arg_count|
|
||||||
// including receiver) and the first argument located at |first_arg|, possibly
|
// arguments (not including receiver) and the first argument
|
||||||
// including the receiver depending on |receiver_mode|.
|
// located at |first_arg|.
|
||||||
compiler::Node* CallJS(compiler::Node* function, compiler::Node* context,
|
compiler::Node* CallJS(compiler::Node* function, compiler::Node* context,
|
||||||
compiler::Node* first_arg, compiler::Node* arg_count,
|
compiler::Node* first_arg, compiler::Node* arg_count,
|
||||||
ConvertReceiverMode receiver_mode,
|
|
||||||
TailCallMode tail_call_mode);
|
TailCallMode tail_call_mode);
|
||||||
|
|
||||||
// Call JSFunction or Callable |function| with |arg_count|
|
// Call JSFunction or Callable |function| with |arg_count|
|
||||||
|
@ -73,13 +73,11 @@ class InterpreterGenerator {
|
|||||||
void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler);
|
void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler);
|
||||||
|
|
||||||
// Generates code to perform a JS call that collects type feedback.
|
// Generates code to perform a JS call that collects type feedback.
|
||||||
void DoJSCall(InterpreterAssembler* assembler,
|
void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);
|
||||||
ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode);
|
|
||||||
|
|
||||||
// Generates code to perform a JS call with a known number of arguments that
|
// Generates code to perform a JS call with a known number of arguments that
|
||||||
// collects type feedback.
|
// collects type feedback.
|
||||||
void DoJSCallN(InterpreterAssembler* assembler, int n,
|
void DoJSCallN(InterpreterAssembler* assembler, int n);
|
||||||
ConvertReceiverMode receiver_mode);
|
|
||||||
|
|
||||||
// Generates code to perform delete via function_id.
|
// Generates code to perform delete via function_id.
|
||||||
void DoDelete(Runtime::FunctionId function_id,
|
void DoDelete(Runtime::FunctionId function_id,
|
||||||
@ -2324,78 +2322,50 @@ void InterpreterGenerator::DoGetSuperConstructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterGenerator::DoJSCall(InterpreterAssembler* assembler,
|
void InterpreterGenerator::DoJSCall(InterpreterAssembler* assembler,
|
||||||
ConvertReceiverMode receiver_mode,
|
|
||||||
TailCallMode tail_call_mode) {
|
TailCallMode tail_call_mode) {
|
||||||
Node* function_reg = __ BytecodeOperandReg(0);
|
Node* function_reg = __ BytecodeOperandReg(0);
|
||||||
Node* function = __ LoadRegister(function_reg);
|
Node* function = __ LoadRegister(function_reg);
|
||||||
Node* first_arg_reg = __ BytecodeOperandReg(1);
|
Node* receiver_reg = __ BytecodeOperandReg(1);
|
||||||
Node* first_arg = __ RegisterLocation(first_arg_reg);
|
Node* receiver_arg = __ RegisterLocation(receiver_reg);
|
||||||
Node* arg_list_count = __ BytecodeOperandCount(2);
|
Node* receiver_args_count = __ BytecodeOperandCount(2);
|
||||||
Node* args_count;
|
Node* receiver_count = __ Int32Constant(1);
|
||||||
if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
|
Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
|
||||||
// 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* slot_id = __ BytecodeOperandIdx(3);
|
Node* slot_id = __ BytecodeOperandIdx(3);
|
||||||
Node* feedback_vector = __ LoadFeedbackVector();
|
Node* feedback_vector = __ LoadFeedbackVector();
|
||||||
Node* context = __ GetContext();
|
Node* context = __ GetContext();
|
||||||
Node* result =
|
Node* result =
|
||||||
__ CallJSWithFeedback(function, context, first_arg, args_count, slot_id,
|
__ CallJSWithFeedback(function, context, receiver_arg, args_count,
|
||||||
feedback_vector, receiver_mode, tail_call_mode);
|
slot_id, feedback_vector, tail_call_mode);
|
||||||
__ SetAccumulator(result);
|
__ SetAccumulator(result);
|
||||||
__ Dispatch();
|
__ Dispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterGenerator::DoJSCallN(InterpreterAssembler* assembler,
|
void InterpreterGenerator::DoJSCallN(InterpreterAssembler* assembler,
|
||||||
int arg_count,
|
int arg_count) {
|
||||||
ConvertReceiverMode receiver_mode) {
|
const int kReceiverOperandIndex = 1;
|
||||||
// Indices and counts of operands on the bytecode.
|
const int kReceiverOperandCount = 1;
|
||||||
const int kFirstArgumentOperandIndex = 1;
|
|
||||||
const int kReceiverOperandCount =
|
|
||||||
(receiver_mode == ConvertReceiverMode::kNullOrUndefined) ? 0 : 1;
|
|
||||||
const int kSlotOperandIndex =
|
const int kSlotOperandIndex =
|
||||||
kFirstArgumentOperandIndex + kReceiverOperandCount + arg_count;
|
kReceiverOperandIndex + kReceiverOperandCount + arg_count;
|
||||||
// Indices and counts of parameters to the call stub.
|
const int kBoilerplatParameterCount = 7;
|
||||||
const int kBoilerplateParameterCount = 7;
|
|
||||||
const int kReceiverParameterIndex = 5;
|
const int kReceiverParameterIndex = 5;
|
||||||
const int kReceiverParameterCount = 1;
|
|
||||||
// Only used in a DCHECK.
|
|
||||||
USE(kReceiverParameterCount);
|
|
||||||
|
|
||||||
Node* function_reg = __ BytecodeOperandReg(0);
|
Node* function_reg = __ BytecodeOperandReg(0);
|
||||||
Node* function = __ LoadRegister(function_reg);
|
Node* function = __ LoadRegister(function_reg);
|
||||||
std::array<Node*, Bytecodes::kMaxOperands + kBoilerplateParameterCount> temp;
|
std::array<Node*, Bytecodes::kMaxOperands + kBoilerplatParameterCount> temp;
|
||||||
Callable call_ic = CodeFactory::CallIC(isolate_);
|
Callable call_ic = CodeFactory::CallIC(isolate_);
|
||||||
temp[0] = __ HeapConstant(call_ic.code());
|
temp[0] = __ HeapConstant(call_ic.code());
|
||||||
temp[1] = function;
|
temp[1] = function;
|
||||||
temp[2] = __ Int32Constant(arg_count);
|
temp[2] = __ Int32Constant(arg_count);
|
||||||
temp[3] = __ BytecodeOperandIdxInt32(kSlotOperandIndex);
|
temp[3] = __ BytecodeOperandIdxInt32(kSlotOperandIndex);
|
||||||
temp[4] = __ LoadFeedbackVector();
|
temp[4] = __ LoadFeedbackVector();
|
||||||
|
for (int i = 0; i < (arg_count + kReceiverOperandCount); ++i) {
|
||||||
int parameter_index = kReceiverParameterIndex;
|
Node* reg = __ BytecodeOperandReg(i + kReceiverOperandIndex);
|
||||||
if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
|
temp[kReceiverParameterIndex + i] = __ LoadRegister(reg);
|
||||||
// The first argument parameter (the receiver) is implied to be undefined.
|
|
||||||
Node* undefined_value =
|
|
||||||
__ HeapConstant(isolate_->factory()->undefined_value());
|
|
||||||
temp[parameter_index++] = undefined_value;
|
|
||||||
}
|
}
|
||||||
// The bytecode argument operands are copied into the remaining argument
|
temp[kReceiverParameterIndex + arg_count + kReceiverOperandCount] =
|
||||||
// parameters.
|
__ GetContext();
|
||||||
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();
|
|
||||||
|
|
||||||
Node* result = __ CallStubN(call_ic.descriptor(), 1,
|
Node* result = __ CallStubN(call_ic.descriptor(), 1,
|
||||||
arg_count + kBoilerplateParameterCount, &temp[0]);
|
arg_count + kBoilerplatParameterCount, &temp[0]);
|
||||||
__ SetAccumulator(result);
|
__ SetAccumulator(result);
|
||||||
__ Dispatch();
|
__ Dispatch();
|
||||||
}
|
}
|
||||||
@ -2405,46 +2375,40 @@ void InterpreterGenerator::DoJSCallN(InterpreterAssembler* assembler,
|
|||||||
// Call a JSfunction or Callable in |callable| with the |receiver| and
|
// Call a JSfunction or Callable in |callable| with the |receiver| and
|
||||||
// |arg_count| arguments in subsequent registers. Collect type feedback
|
// |arg_count| arguments in subsequent registers. Collect type feedback
|
||||||
// into |feedback_slot_id|
|
// into |feedback_slot_id|
|
||||||
void InterpreterGenerator::DoCallAnyReceiver(InterpreterAssembler* assembler) {
|
void InterpreterGenerator::DoCall(InterpreterAssembler* assembler) {
|
||||||
DoJSCall(assembler, ConvertReceiverMode::kAny, TailCallMode::kDisallow);
|
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) {
|
void InterpreterGenerator::DoCallProperty(InterpreterAssembler* assembler) {
|
||||||
DoJSCall(assembler, ConvertReceiverMode::kNotNullOrUndefined,
|
// Same as Call
|
||||||
TailCallMode::kDisallow);
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterGenerator::DoCallProperty0(InterpreterAssembler* assembler) {
|
void InterpreterGenerator::DoCallProperty0(InterpreterAssembler* assembler) {
|
||||||
DoJSCallN(assembler, 0, ConvertReceiverMode::kNotNullOrUndefined);
|
// Same as Call0
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterGenerator::DoCallProperty1(InterpreterAssembler* assembler) {
|
void InterpreterGenerator::DoCallProperty1(InterpreterAssembler* assembler) {
|
||||||
DoJSCallN(assembler, 1, ConvertReceiverMode::kNotNullOrUndefined);
|
// Same as Call1
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterGenerator::DoCallProperty2(InterpreterAssembler* assembler) {
|
void InterpreterGenerator::DoCallProperty2(InterpreterAssembler* assembler) {
|
||||||
DoJSCallN(assembler, 2, ConvertReceiverMode::kNotNullOrUndefined);
|
// Same as Call2
|
||||||
}
|
UNREACHABLE();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TailCall <callable> <receiver> <arg_count> <feedback_slot_id>
|
// TailCall <callable> <receiver> <arg_count> <feedback_slot_id>
|
||||||
@ -2453,7 +2417,7 @@ void InterpreterGenerator::DoCallUndefinedReceiver2(
|
|||||||
// |arg_count| arguments in subsequent registers. Collect type feedback
|
// |arg_count| arguments in subsequent registers. Collect type feedback
|
||||||
// into |feedback_slot_id|
|
// into |feedback_slot_id|
|
||||||
void InterpreterGenerator::DoTailCall(InterpreterAssembler* assembler) {
|
void InterpreterGenerator::DoTailCall(InterpreterAssembler* assembler) {
|
||||||
DoJSCall(assembler, ConvertReceiverMode::kAny, TailCallMode::kAllow);
|
DoJSCall(assembler, TailCallMode::kAllow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallRuntime <function_id> <first_arg> <arg_count>
|
// CallRuntime <function_id> <first_arg> <arg_count>
|
||||||
@ -2533,7 +2497,7 @@ void InterpreterGenerator::DoCallJSRuntime(InterpreterAssembler* assembler) {
|
|||||||
|
|
||||||
// Call the function.
|
// Call the function.
|
||||||
Node* result = __ CallJS(function, context, first_arg, args_count,
|
Node* result = __ CallJS(function, context, first_arg, args_count,
|
||||||
ConvertReceiverMode::kAny, TailCallMode::kDisallow);
|
TailCallMode::kDisallow);
|
||||||
__ SetAccumulator(result);
|
__ SetAccumulator(result);
|
||||||
__ Dispatch();
|
__ Dispatch();
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ Node* IntrinsicsGenerator::Call(Node* args_reg, Node* arg_count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node* result = __ CallJS(function, context, receiver_arg, target_args_count,
|
Node* result = __ CallJS(function, context, receiver_arg, target_args_count,
|
||||||
ConvertReceiverMode::kAny, TailCallMode::kDisallow);
|
TailCallMode::kDisallow);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +52,28 @@ void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) {
|
|||||||
bool SetupInterpreter::ReuseExistingHandler(Address* dispatch_table,
|
bool SetupInterpreter::ReuseExistingHandler(Address* dispatch_table,
|
||||||
Bytecode bytecode,
|
Bytecode bytecode,
|
||||||
OperandScale operand_scale) {
|
OperandScale operand_scale) {
|
||||||
// TODO(leszeks): reuse Lda[Immutable][Current]ContextSlot
|
size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale);
|
||||||
return false;
|
switch (bytecode) {
|
||||||
|
case Bytecode::kCallProperty:
|
||||||
|
case Bytecode::kCallProperty0:
|
||||||
|
case Bytecode::kCallProperty1:
|
||||||
|
case Bytecode::kCallProperty2: {
|
||||||
|
const int offset = static_cast<int>(Bytecode::kCallProperty) -
|
||||||
|
static_cast<int>(Bytecode::kCall);
|
||||||
|
STATIC_ASSERT(offset == static_cast<int>(Bytecode::kCallProperty0) -
|
||||||
|
static_cast<int>(Bytecode::kCall0));
|
||||||
|
STATIC_ASSERT(offset == static_cast<int>(Bytecode::kCallProperty1) -
|
||||||
|
static_cast<int>(Bytecode::kCall1));
|
||||||
|
STATIC_ASSERT(offset == static_cast<int>(Bytecode::kCallProperty2) -
|
||||||
|
static_cast<int>(Bytecode::kCall2));
|
||||||
|
CHECK_LT(offset, index);
|
||||||
|
dispatch_table[index] = dispatch_table[index - offset];
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -314,7 +314,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
a0, // argument count (not including receiver)
|
a0, // argument count (not including receiver)
|
||||||
@ -324,7 +324,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
a0, // argument count (not including receiver)
|
a0, // argument count (not including receiver)
|
||||||
@ -336,8 +336,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
a0, // argument count (not including receiver)
|
a0, // argument count (not including receiver)
|
||||||
a1, // the target to call verified to be Array function
|
a1, // the target to call verified to be Array function
|
||||||
|
@ -313,7 +313,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
a0, // argument count (not including receiver)
|
a0, // argument count (not including receiver)
|
||||||
@ -323,7 +323,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
a0, // argument count (not including receiver)
|
a0, // argument count (not including receiver)
|
||||||
@ -335,8 +335,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
a0, // argument count (not including receiver)
|
a0, // argument count (not including receiver)
|
||||||
a1, // the target to call verified to be Array function
|
a1, // the target to call verified to be Array function
|
||||||
|
@ -315,7 +315,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r3, // argument count (not including receiver)
|
r3, // argument count (not including receiver)
|
||||||
@ -325,7 +325,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r3, // argument count (not including receiver)
|
r3, // argument count (not including receiver)
|
||||||
@ -337,8 +337,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r3, // argument count (not including receiver)
|
r3, // argument count (not including receiver)
|
||||||
r4, // target to call checked to be Array function
|
r4, // target to call checked to be Array function
|
||||||
|
@ -299,7 +299,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r2, // argument count (not including receiver)
|
r2, // argument count (not including receiver)
|
||||||
@ -309,7 +309,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r2, // argument count (not including receiver)
|
r2, // argument count (not including receiver)
|
||||||
@ -321,8 +321,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
r2, // argument count (not including receiver)
|
r2, // argument count (not including receiver)
|
||||||
r3, // target to call checked to be Array function
|
r3, // target to call checked to be Array function
|
||||||
|
@ -316,7 +316,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
rax, // argument count (not including receiver)
|
rax, // argument count (not including receiver)
|
||||||
@ -326,7 +326,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
rax, // argument count (not including receiver)
|
rax, // argument count (not including receiver)
|
||||||
@ -338,8 +338,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
rax, // argument count (not including receiver)
|
rax, // argument count (not including receiver)
|
||||||
rdx, // target to the call. It is checked to be Array function.
|
rdx, // target to the call. It is checked to be Array function.
|
||||||
|
@ -330,7 +330,7 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
eax, // argument count (not including receiver)
|
eax, // argument count (not including receiver)
|
||||||
@ -340,7 +340,7 @@ void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
|
||||||
CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
eax, // argument count (not including receiver)
|
eax, // argument count (not including receiver)
|
||||||
@ -352,8 +352,8 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
|||||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterPushArgsThenConstructArrayDescriptor::
|
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
|
||||||
InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
|
CallInterfaceDescriptorData* data) {
|
||||||
Register registers[] = {
|
Register registers[] = {
|
||||||
eax, // argument count (not including receiver)
|
eax, // argument count (not including receiver)
|
||||||
edx, // target to the call. It is checked to be Array function.
|
edx, // target to the call. It is checked to be Array function.
|
||||||
|
@ -12,14 +12,16 @@ snippet: "
|
|||||||
function f() { return t(); }
|
function f() { return t(); }
|
||||||
f();
|
f();
|
||||||
"
|
"
|
||||||
frame size: 1
|
frame size: 2
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 10
|
bytecode array length: 14
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
/* 27 E> */ B(StackCheck),
|
/* 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),
|
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),
|
/* 44 S> */ B(Return),
|
||||||
]
|
]
|
||||||
constant pool: [
|
constant pool: [
|
||||||
@ -34,20 +36,22 @@ snippet: "
|
|||||||
function f() { return t(1, 2, 3); }
|
function f() { return t(1, 2, 3); }
|
||||||
f();
|
f();
|
||||||
"
|
"
|
||||||
frame size: 4
|
frame size: 5
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 24
|
bytecode array length: 27
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
/* 34 E> */ B(StackCheck),
|
/* 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(Star), R(0),
|
||||||
B(LdaSmi), I8(1),
|
B(LdaSmi), I8(1),
|
||||||
B(Star), R(1),
|
|
||||||
B(LdaSmi), I8(2),
|
|
||||||
B(Star), R(2),
|
B(Star), R(2),
|
||||||
B(LdaSmi), I8(3),
|
B(LdaSmi), I8(2),
|
||||||
B(Star), R(3),
|
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),
|
/* 58 S> */ B(Return),
|
||||||
]
|
]
|
||||||
constant pool: [
|
constant pool: [
|
||||||
|
@ -9,9 +9,9 @@ wrap: yes
|
|||||||
snippet: "
|
snippet: "
|
||||||
g = function(){}; eval(''); return g();
|
g = function(){}; eval(''); return g();
|
||||||
"
|
"
|
||||||
frame size: 9
|
frame size: 10
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 73
|
bytecode array length: 81
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(3),
|
B(CreateFunctionContext), U8(3),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -24,25 +24,29 @@ bytecodes: [
|
|||||||
/* 30 E> */ B(StackCheck),
|
/* 30 E> */ B(StackCheck),
|
||||||
/* 34 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
|
/* 34 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
|
||||||
/* 36 E> */ B(StaLookupSlotSloppy), U8(1),
|
/* 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(Star), R(1),
|
||||||
B(LdaConstant), U8(3),
|
B(LdaConstant), U8(3),
|
||||||
B(Star), R(2),
|
B(Star), R(3),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(6),
|
|
||||||
B(LdaSmi), I8(30),
|
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), I8(52),
|
B(LdaSmi), I8(30),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(Mov), R(1), R(3),
|
B(LdaSmi), I8(52),
|
||||||
B(Mov), R(2), R(4),
|
B(Star), R(9),
|
||||||
B(Mov), R(closure), R(5),
|
B(Mov), R(1), R(4),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6),
|
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),
|
B(Star), R(1),
|
||||||
/* 52 E> */ B(CallUndefinedReceiver1), R(1), R(2), U8(3),
|
/* 52 E> */ B(Call1), R(1), R(2), R(3), U8(3),
|
||||||
/* 62 S> */ B(LdaLookupGlobalSlot), U8(1), U8(9), U8(1),
|
/* 62 S> */ B(LdaUndefined),
|
||||||
|
B(Star), R(2),
|
||||||
|
/* 69 E> */ B(LdaLookupGlobalSlot), U8(1), U8(9), U8(1),
|
||||||
B(Star), R(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),
|
/* 74 S> */ B(Return),
|
||||||
]
|
]
|
||||||
constant pool: [
|
constant pool: [
|
||||||
|
@ -22,7 +22,7 @@ snippet: "
|
|||||||
"
|
"
|
||||||
frame size: 6
|
frame size: 6
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 34
|
bytecode array length: 33
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(Mov), R(closure), R(0),
|
B(Mov), R(closure), R(0),
|
||||||
/* 99 E> */ B(StackCheck),
|
/* 99 E> */ B(StackCheck),
|
||||||
@ -34,7 +34,7 @@ bytecodes: [
|
|||||||
B(Mov), R(this), R(3),
|
B(Mov), R(this), R(3),
|
||||||
B(CallRuntime), U16(Runtime::kLoadFromSuper), R(3), U8(3),
|
B(CallRuntime), U16(Runtime::kLoadFromSuper), R(3), U8(3),
|
||||||
B(Star), R(1),
|
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),
|
/* 126 E> */ B(AddSmi), I8(1), U8(8),
|
||||||
/* 131 S> */ B(Return),
|
/* 131 S> */ B(Return),
|
||||||
]
|
]
|
||||||
|
@ -75,16 +75,18 @@ handlers: [
|
|||||||
snippet: "
|
snippet: "
|
||||||
var a; (function() { a = 2; })(); return a;
|
var a; (function() { a = 2; })(); return a;
|
||||||
"
|
"
|
||||||
frame size: 2
|
frame size: 3
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 17
|
bytecode array length: 21
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(1),
|
B(CreateFunctionContext), U8(1),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
/* 30 E> */ B(StackCheck),
|
/* 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),
|
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),
|
/* 68 S> */ B(LdaCurrentContextSlot), U8(4),
|
||||||
/* 78 S> */ B(Return),
|
/* 78 S> */ B(Return),
|
||||||
]
|
]
|
||||||
@ -386,9 +388,9 @@ snippet: "
|
|||||||
var b = 100;
|
var b = 100;
|
||||||
return b
|
return b
|
||||||
"
|
"
|
||||||
frame size: 2
|
frame size: 3
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 787
|
bytecode array length: 791
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(254),
|
B(CreateFunctionContext), U8(254),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -899,9 +901,11 @@ bytecodes: [
|
|||||||
/* 3421 E> */ B(StaCurrentContextSlot), U8(254),
|
/* 3421 E> */ B(StaCurrentContextSlot), U8(254),
|
||||||
/* 3435 S> */ B(LdaZero),
|
/* 3435 S> */ B(LdaZero),
|
||||||
/* 3435 E> */ B(StaCurrentContextSlot), U8(255),
|
/* 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),
|
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 S> */ B(LdaSmi), I8(100),
|
||||||
/* 3454 E> */ B(Wide), B(StaCurrentContextSlot), U16(256),
|
/* 3454 E> */ B(Wide), B(StaCurrentContextSlot), U16(256),
|
||||||
/* 3459 S> */ B(Wide), B(LdaCurrentContextSlot), U16(256),
|
/* 3459 S> */ B(Wide), B(LdaCurrentContextSlot), U16(256),
|
||||||
|
@ -104,7 +104,7 @@ snippet: "
|
|||||||
"
|
"
|
||||||
frame size: 4
|
frame size: 4
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 27
|
bytecode array length: 31
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(LdaConstant), U8(0),
|
B(LdaConstant), U8(0),
|
||||||
B(Star), R(1),
|
B(Star), R(1),
|
||||||
@ -113,9 +113,11 @@ bytecodes: [
|
|||||||
B(Mov), R(closure), R(3),
|
B(Mov), R(closure), R(3),
|
||||||
B(CallRuntime), U16(Runtime::kDeclareGlobalsForInterpreter), R(1), U8(3),
|
B(CallRuntime), U16(Runtime::kDeclareGlobalsForInterpreter), R(1), U8(3),
|
||||||
/* 0 E> */ B(StackCheck),
|
/* 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),
|
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),
|
B(Star), R(0),
|
||||||
/* 20 S> */ B(Return),
|
/* 20 S> */ B(Return),
|
||||||
]
|
]
|
||||||
|
@ -9,9 +9,9 @@ wrap: yes
|
|||||||
snippet: "
|
snippet: "
|
||||||
return eval('1;');
|
return eval('1;');
|
||||||
"
|
"
|
||||||
frame size: 9
|
frame size: 10
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 58
|
bytecode array length: 62
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(3),
|
B(CreateFunctionContext), U8(3),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -22,22 +22,24 @@ bytecodes: [
|
|||||||
B(Ldar), R(new_target),
|
B(Ldar), R(new_target),
|
||||||
B(StaCurrentContextSlot), U8(5),
|
B(StaCurrentContextSlot), U8(5),
|
||||||
/* 30 E> */ B(StackCheck),
|
/* 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(Star), R(1),
|
||||||
B(LdaConstant), U8(1),
|
B(LdaConstant), U8(1),
|
||||||
B(Star), R(2),
|
B(Star), R(3),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(6),
|
|
||||||
B(LdaSmi), I8(30),
|
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), I8(41),
|
B(LdaSmi), I8(30),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(Mov), R(1), R(3),
|
B(LdaSmi), I8(41),
|
||||||
B(Mov), R(2), R(4),
|
B(Star), R(9),
|
||||||
B(Mov), R(closure), R(5),
|
B(Mov), R(1), R(4),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6),
|
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),
|
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),
|
/* 53 S> */ B(Return),
|
||||||
]
|
]
|
||||||
constant pool: [
|
constant pool: [
|
||||||
|
@ -27,14 +27,16 @@ handlers: [
|
|||||||
snippet: "
|
snippet: "
|
||||||
return (function(){ })()
|
return (function(){ })()
|
||||||
"
|
"
|
||||||
frame size: 1
|
frame size: 2
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 11
|
bytecode array length: 15
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
/* 30 E> */ B(StackCheck),
|
/* 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(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),
|
/* 59 S> */ B(Return),
|
||||||
]
|
]
|
||||||
constant pool: [
|
constant pool: [
|
||||||
@ -47,16 +49,18 @@ handlers: [
|
|||||||
snippet: "
|
snippet: "
|
||||||
return (function(x){ return x; })(1)
|
return (function(x){ return x; })(1)
|
||||||
"
|
"
|
||||||
frame size: 2
|
frame size: 3
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 16
|
bytecode array length: 20
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
/* 30 E> */ B(StackCheck),
|
/* 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(Star), R(0),
|
||||||
B(LdaSmi), I8(1),
|
B(LdaSmi), I8(1),
|
||||||
B(Star), R(1),
|
B(Star), R(2),
|
||||||
/* 67 E> */ B(CallUndefinedReceiver1), R(0), R(1), U8(2),
|
/* 67 E> */ B(Call1), R(0), R(1), R(2), U8(2),
|
||||||
/* 71 S> */ B(Return),
|
/* 71 S> */ B(Return),
|
||||||
]
|
]
|
||||||
constant pool: [
|
constant pool: [
|
||||||
|
@ -10,9 +10,9 @@ test function name: f
|
|||||||
snippet: "
|
snippet: "
|
||||||
eval('var x = 10;'); return x;
|
eval('var x = 10;'); return x;
|
||||||
"
|
"
|
||||||
frame size: 9
|
frame size: 10
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 62
|
bytecode array length: 66
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(3),
|
B(CreateFunctionContext), U8(3),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -23,22 +23,24 @@ bytecodes: [
|
|||||||
B(Ldar), R(new_target),
|
B(Ldar), R(new_target),
|
||||||
B(StaCurrentContextSlot), U8(5),
|
B(StaCurrentContextSlot), U8(5),
|
||||||
/* 10 E> */ B(StackCheck),
|
/* 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(Star), R(1),
|
||||||
B(LdaConstant), U8(1),
|
B(LdaConstant), U8(1),
|
||||||
B(Star), R(2),
|
B(Star), R(3),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(6),
|
|
||||||
B(LdaSmi), I8(10),
|
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), I8(14),
|
B(LdaSmi), I8(10),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(Mov), R(1), R(3),
|
B(LdaSmi), I8(14),
|
||||||
B(Mov), R(2), R(4),
|
B(Star), R(9),
|
||||||
B(Mov), R(closure), R(5),
|
B(Mov), R(1), R(4),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6),
|
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),
|
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),
|
/* 35 S> */ B(LdaLookupGlobalSlot), U8(2), U8(6), U8(1),
|
||||||
/* 45 S> */ B(Return),
|
/* 45 S> */ B(Return),
|
||||||
]
|
]
|
||||||
@ -54,9 +56,9 @@ handlers: [
|
|||||||
snippet: "
|
snippet: "
|
||||||
eval('var x = 10;'); return typeof x;
|
eval('var x = 10;'); return typeof x;
|
||||||
"
|
"
|
||||||
frame size: 9
|
frame size: 10
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 63
|
bytecode array length: 67
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(3),
|
B(CreateFunctionContext), U8(3),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -67,22 +69,24 @@ bytecodes: [
|
|||||||
B(Ldar), R(new_target),
|
B(Ldar), R(new_target),
|
||||||
B(StaCurrentContextSlot), U8(5),
|
B(StaCurrentContextSlot), U8(5),
|
||||||
/* 10 E> */ B(StackCheck),
|
/* 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(Star), R(1),
|
||||||
B(LdaConstant), U8(1),
|
B(LdaConstant), U8(1),
|
||||||
B(Star), R(2),
|
B(Star), R(3),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(6),
|
|
||||||
B(LdaSmi), I8(10),
|
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), I8(14),
|
B(LdaSmi), I8(10),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(Mov), R(1), R(3),
|
B(LdaSmi), I8(14),
|
||||||
B(Mov), R(2), R(4),
|
B(Star), R(9),
|
||||||
B(Mov), R(closure), R(5),
|
B(Mov), R(1), R(4),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6),
|
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),
|
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),
|
/* 35 S> */ B(LdaLookupGlobalSlotInsideTypeof), U8(2), U8(6), U8(1),
|
||||||
B(TypeOf),
|
B(TypeOf),
|
||||||
/* 52 S> */ B(Return),
|
/* 52 S> */ B(Return),
|
||||||
@ -99,9 +103,9 @@ handlers: [
|
|||||||
snippet: "
|
snippet: "
|
||||||
x = 20; return eval('');
|
x = 20; return eval('');
|
||||||
"
|
"
|
||||||
frame size: 9
|
frame size: 10
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 62
|
bytecode array length: 66
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(3),
|
B(CreateFunctionContext), U8(3),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -114,22 +118,24 @@ bytecodes: [
|
|||||||
/* 10 E> */ B(StackCheck),
|
/* 10 E> */ B(StackCheck),
|
||||||
/* 14 S> */ B(LdaSmi), I8(20),
|
/* 14 S> */ B(LdaSmi), I8(20),
|
||||||
/* 16 E> */ B(StaLookupSlotSloppy), U8(0),
|
/* 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(Star), R(1),
|
||||||
B(LdaConstant), U8(2),
|
B(LdaConstant), U8(2),
|
||||||
B(Star), R(2),
|
B(Star), R(3),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(6),
|
|
||||||
B(LdaSmi), I8(10),
|
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), I8(29),
|
B(LdaSmi), I8(10),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(Mov), R(1), R(3),
|
B(LdaSmi), I8(29),
|
||||||
B(Mov), R(2), R(4),
|
B(Star), R(9),
|
||||||
B(Mov), R(closure), R(5),
|
B(Mov), R(1), R(4),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6),
|
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),
|
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),
|
/* 39 S> */ B(Return),
|
||||||
]
|
]
|
||||||
constant pool: [
|
constant pool: [
|
||||||
@ -149,9 +155,9 @@ snippet: "
|
|||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
"
|
"
|
||||||
frame size: 9
|
frame size: 10
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 62
|
bytecode array length: 66
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(3),
|
B(CreateFunctionContext), U8(3),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -162,22 +168,24 @@ bytecodes: [
|
|||||||
B(Ldar), R(new_target),
|
B(Ldar), R(new_target),
|
||||||
B(StaCurrentContextSlot), U8(5),
|
B(StaCurrentContextSlot), U8(5),
|
||||||
/* 38 E> */ B(StackCheck),
|
/* 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(Star), R(1),
|
||||||
B(LdaConstant), U8(1),
|
B(LdaConstant), U8(1),
|
||||||
B(Star), R(2),
|
B(Star), R(3),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(6),
|
|
||||||
B(LdaSmi), I8(38),
|
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), I8(44),
|
B(LdaSmi), I8(38),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(Mov), R(1), R(3),
|
B(LdaSmi), I8(44),
|
||||||
B(Mov), R(2), R(4),
|
B(Star), R(9),
|
||||||
B(Mov), R(closure), R(5),
|
B(Mov), R(1), R(4),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6),
|
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),
|
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),
|
/* 66 S> */ B(LdaLookupContextSlot), U8(2), U8(6), U8(1),
|
||||||
/* 76 S> */ B(Return),
|
/* 76 S> */ B(Return),
|
||||||
]
|
]
|
||||||
@ -198,9 +206,9 @@ snippet: "
|
|||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
"
|
"
|
||||||
frame size: 9
|
frame size: 10
|
||||||
parameter count: 1
|
parameter count: 1
|
||||||
bytecode array length: 62
|
bytecode array length: 66
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(CreateFunctionContext), U8(3),
|
B(CreateFunctionContext), U8(3),
|
||||||
B(PushContext), R(0),
|
B(PushContext), R(0),
|
||||||
@ -211,22 +219,24 @@ bytecodes: [
|
|||||||
B(Ldar), R(new_target),
|
B(Ldar), R(new_target),
|
||||||
B(StaCurrentContextSlot), U8(5),
|
B(StaCurrentContextSlot), U8(5),
|
||||||
/* 34 E> */ B(StackCheck),
|
/* 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(Star), R(1),
|
||||||
B(LdaConstant), U8(1),
|
B(LdaConstant), U8(1),
|
||||||
B(Star), R(2),
|
B(Star), R(3),
|
||||||
B(LdaZero),
|
B(LdaZero),
|
||||||
B(Star), R(6),
|
|
||||||
B(LdaSmi), I8(34),
|
|
||||||
B(Star), R(7),
|
B(Star), R(7),
|
||||||
B(LdaSmi), I8(40),
|
B(LdaSmi), I8(34),
|
||||||
B(Star), R(8),
|
B(Star), R(8),
|
||||||
B(Mov), R(1), R(3),
|
B(LdaSmi), I8(40),
|
||||||
B(Mov), R(2), R(4),
|
B(Star), R(9),
|
||||||
B(Mov), R(closure), R(5),
|
B(Mov), R(1), R(4),
|
||||||
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(3), U8(6),
|
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),
|
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),
|
/* 62 S> */ B(LdaLookupGlobalSlot), U8(2), U8(6), U8(1),
|
||||||
/* 72 S> */ B(Return),
|
/* 72 S> */ B(Return),
|
||||||
]
|
]
|
||||||
|
@ -171,7 +171,7 @@ snippet: "
|
|||||||
"
|
"
|
||||||
frame size: 10
|
frame size: 10
|
||||||
parameter count: 2
|
parameter count: 2
|
||||||
bytecode array length: 205
|
bytecode array length: 213
|
||||||
bytecodes: [
|
bytecodes: [
|
||||||
B(Ldar), R(new_target),
|
B(Ldar), R(new_target),
|
||||||
B(JumpIfUndefined), U8(27),
|
B(JumpIfUndefined), U8(27),
|
||||||
@ -228,15 +228,17 @@ bytecodes: [
|
|||||||
/* 64 S> */ B(Return),
|
/* 64 S> */ B(Return),
|
||||||
B(Ldar), R(6),
|
B(Ldar), R(6),
|
||||||
/* 0 E> */ B(Throw),
|
/* 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(JumpIfNotHole), U8(11),
|
||||||
B(LdaConstant), U8(1),
|
B(LdaConstant), U8(1),
|
||||||
B(Star), R(5),
|
B(Star), R(6),
|
||||||
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1),
|
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(6), U8(1),
|
||||||
B(Star), R(4),
|
B(Star), R(4),
|
||||||
B(LdaSmi), I8(42),
|
B(LdaSmi), I8(42),
|
||||||
B(Star), R(5),
|
B(Star), R(6),
|
||||||
/* 32 E> */ B(CallUndefinedReceiver1), R(4), R(5), U8(2),
|
/* 32 E> */ B(Call1), R(4), R(5), R(6), U8(2),
|
||||||
B(Ldar), R(closure),
|
B(Ldar), R(closure),
|
||||||
B(CreateBlockContext), U8(2),
|
B(CreateBlockContext), U8(2),
|
||||||
B(PushContext), R(1),
|
B(PushContext), R(1),
|
||||||
@ -244,15 +246,17 @@ bytecodes: [
|
|||||||
B(StaCurrentContextSlot), U8(4),
|
B(StaCurrentContextSlot), U8(4),
|
||||||
/* 47 S> */ B(LdaUndefined),
|
/* 47 S> */ B(LdaUndefined),
|
||||||
/* 47 E> */ B(StaCurrentContextSlot), U8(4),
|
/* 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(JumpIfNotHole), U8(11),
|
||||||
B(LdaConstant), U8(1),
|
B(LdaConstant), U8(1),
|
||||||
B(Star), R(5),
|
B(Star), R(6),
|
||||||
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1),
|
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(6), U8(1),
|
||||||
B(Star), R(4),
|
B(Star), R(4),
|
||||||
B(LdaSmi), I8(42),
|
B(LdaSmi), I8(42),
|
||||||
B(Star), R(5),
|
B(Star), R(6),
|
||||||
/* 52 E> */ B(CallUndefinedReceiver1), R(4), R(5), U8(4),
|
/* 52 E> */ B(Call1), R(4), R(5), R(6), U8(4),
|
||||||
B(StaContextSlot), R(1), U8(6), U8(0),
|
B(StaContextSlot), R(1), U8(6), U8(0),
|
||||||
B(PopContext), R(1),
|
B(PopContext), R(1),
|
||||||
B(LdaCurrentContextSlot), U8(6),
|
B(LdaCurrentContextSlot), U8(6),
|
||||||
|
@ -1298,11 +1298,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) {
|
|||||||
.StoreAccumulatorInRegister(reg)
|
.StoreAccumulatorInRegister(reg)
|
||||||
.MoveRegister(builder.Receiver(), args[0]);
|
.MoveRegister(builder.Receiver(), args[0]);
|
||||||
|
|
||||||
if (tail_call_mode == TailCallMode::kAllow) {
|
builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode);
|
||||||
builder.TailCall(reg, args, call_slot_index);
|
|
||||||
} else {
|
|
||||||
builder.CallProperty(reg, args, call_slot_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Return();
|
builder.Return();
|
||||||
ast_factory.Internalize(isolate);
|
ast_factory.Internalize(isolate);
|
||||||
@ -1325,11 +1321,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) {
|
|||||||
builder.LoadNamedProperty(builder.Receiver(), name, slot_index)
|
builder.LoadNamedProperty(builder.Receiver(), name, slot_index)
|
||||||
.StoreAccumulatorInRegister(reg)
|
.StoreAccumulatorInRegister(reg)
|
||||||
.MoveRegister(builder.Receiver(), args[0]);
|
.MoveRegister(builder.Receiver(), args[0]);
|
||||||
if (tail_call_mode == TailCallMode::kAllow) {
|
builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode);
|
||||||
builder.TailCall(reg, args, call_slot_index);
|
|
||||||
} else {
|
|
||||||
builder.CallProperty(reg, args, call_slot_index);
|
|
||||||
}
|
|
||||||
builder.Return();
|
builder.Return();
|
||||||
ast_factory.Internalize(isolate);
|
ast_factory.Internalize(isolate);
|
||||||
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
|
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
|
||||||
@ -1361,11 +1353,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) {
|
|||||||
.LoadLiteral(Smi::FromInt(11))
|
.LoadLiteral(Smi::FromInt(11))
|
||||||
.StoreAccumulatorInRegister(args[2]);
|
.StoreAccumulatorInRegister(args[2]);
|
||||||
|
|
||||||
if (tail_call_mode == TailCallMode::kAllow) {
|
builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode);
|
||||||
builder.TailCall(reg, args, call_slot_index);
|
|
||||||
} else {
|
|
||||||
builder.CallProperty(reg, args, call_slot_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Return();
|
builder.Return();
|
||||||
|
|
||||||
@ -1414,11 +1402,7 @@ static void TestInterpreterCall(TailCallMode tail_call_mode) {
|
|||||||
.LoadLiteral(ast_factory.NewString(ast_factory.GetOneByteString("j")))
|
.LoadLiteral(ast_factory.NewString(ast_factory.GetOneByteString("j")))
|
||||||
.StoreAccumulatorInRegister(args[10]);
|
.StoreAccumulatorInRegister(args[10]);
|
||||||
|
|
||||||
if (tail_call_mode == TailCallMode::kAllow) {
|
builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode);
|
||||||
builder.TailCall(reg, args, call_slot_index);
|
|
||||||
} else {
|
|
||||||
builder.CallProperty(reg, args, call_slot_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Return();
|
builder.Return();
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
|||||||
Register reg(0);
|
Register reg(0);
|
||||||
Register other(reg.index() + 1);
|
Register other(reg.index() + 1);
|
||||||
Register wide(128);
|
Register wide(128);
|
||||||
RegisterList reg_list(0, 10);
|
RegisterList reg_list;
|
||||||
RegisterList empty, single(0, 1), pair(0, 2), triple(0, 3);
|
RegisterList single(0, 1), pair(0, 2), triple(0, 3);
|
||||||
|
|
||||||
// Emit argument creation operations.
|
// Emit argument creation operations.
|
||||||
builder.CreateArguments(CreateArgumentsType::kMappedArguments)
|
builder.CreateArguments(CreateArgumentsType::kMappedArguments)
|
||||||
@ -145,16 +145,16 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
|||||||
builder.CreateObjectLiteral(0, 0, 0, reg);
|
builder.CreateObjectLiteral(0, 0, 0, reg);
|
||||||
|
|
||||||
// Call operations.
|
// Call operations.
|
||||||
builder.CallAnyReceiver(reg, reg_list, 1)
|
builder.Call(reg, reg_list, 1, Call::GLOBAL_CALL)
|
||||||
.CallProperty(reg, reg_list, 1)
|
.Call(reg, single, 1, Call::GLOBAL_CALL)
|
||||||
.CallProperty(reg, single, 1)
|
.Call(reg, pair, 1, Call::GLOBAL_CALL)
|
||||||
.CallProperty(reg, pair, 1)
|
.Call(reg, triple, 1, Call::GLOBAL_CALL)
|
||||||
.CallProperty(reg, triple, 1)
|
.Call(reg, reg_list, 1, Call::NAMED_PROPERTY_CALL,
|
||||||
.CallUndefinedReceiver(reg, reg_list, 1)
|
TailCallMode::kDisallow)
|
||||||
.CallUndefinedReceiver(reg, empty, 1)
|
.Call(reg, single, 1, Call::NAMED_PROPERTY_CALL)
|
||||||
.CallUndefinedReceiver(reg, single, 1)
|
.Call(reg, pair, 1, Call::NAMED_PROPERTY_CALL)
|
||||||
.CallUndefinedReceiver(reg, pair, 1)
|
.Call(reg, triple, 1, Call::NAMED_PROPERTY_CALL)
|
||||||
.TailCall(reg, reg_list, 1)
|
.Call(reg, reg_list, 1, Call::GLOBAL_CALL, TailCallMode::kAllow)
|
||||||
.CallRuntime(Runtime::kIsArray, reg)
|
.CallRuntime(Runtime::kIsArray, reg)
|
||||||
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg_list, pair)
|
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg_list, pair)
|
||||||
.CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg_list)
|
.CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg_list)
|
||||||
|
@ -38,10 +38,10 @@ TEST(BytecodeDecoder, DecodeBytecodeAndOperands) {
|
|||||||
"LdaSmi.ExtraWide [-100000]"},
|
"LdaSmi.ExtraWide [-100000]"},
|
||||||
{{B(Star), R8(5)}, 2, 0, " Star r5"},
|
{{B(Star), R8(5)}, 2, 0, " Star r5"},
|
||||||
{{B(Wide), B(Star), R16(136)}, 4, 0, " Star.Wide r136"},
|
{{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,
|
10,
|
||||||
0,
|
0,
|
||||||
"CallAnyReceiver.Wide r134, r135-r144, [177]"},
|
"Call.Wide r134, r135-r144, [177]"},
|
||||||
{{B(ForInPrepare), R8(10), R8(11)},
|
{{B(ForInPrepare), R8(10), R8(11)},
|
||||||
3,
|
3,
|
||||||
0,
|
0,
|
||||||
|
@ -616,27 +616,25 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
|
TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
|
||||||
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
|
TailCallMode tail_call_modes[] = {TailCallMode::kDisallow,
|
||||||
if (Bytecodes::IsCallOrConstruct(bytecode) &&
|
TailCallMode::kAllow};
|
||||||
bytecode != Bytecode::kCallWithSpread) {
|
TRACED_FOREACH(TailCallMode, tail_call_mode, tail_call_modes) {
|
||||||
InterpreterAssemblerTestState state(this, bytecode);
|
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
|
||||||
InterpreterAssemblerForTest m(&state, bytecode);
|
if (Bytecodes::IsCallOrConstruct(bytecode)) {
|
||||||
ConvertReceiverMode receiver_mode = Bytecodes::GetReceiverMode(bytecode);
|
InterpreterAssemblerTestState state(this, bytecode);
|
||||||
TailCallMode tail_call_mode = (bytecode == Bytecode::kTailCall)
|
InterpreterAssemblerForTest m(&state, bytecode);
|
||||||
? TailCallMode::kAllow
|
Callable builtin = CodeFactory::InterpreterPushArgsAndCall(
|
||||||
: TailCallMode::kDisallow;
|
isolate(), tail_call_mode, InterpreterPushArgsMode::kOther);
|
||||||
|
Node* function = m.IntPtrConstant(0);
|
||||||
Callable builtin = CodeFactory::InterpreterPushArgsThenCall(
|
Node* first_arg = m.IntPtrConstant(1);
|
||||||
isolate(), receiver_mode, tail_call_mode,
|
Node* arg_count = m.Int32Constant(2);
|
||||||
InterpreterPushArgsMode::kOther);
|
Node* context = m.IntPtrConstant(3);
|
||||||
Node* function = m.IntPtrConstant(0);
|
Node* call_js =
|
||||||
Node* first_arg = m.IntPtrConstant(1);
|
m.CallJS(function, context, first_arg, arg_count, tail_call_mode);
|
||||||
Node* arg_count = m.Int32Constant(2);
|
EXPECT_THAT(call_js,
|
||||||
Node* context = m.IntPtrConstant(3);
|
IsCall(_, IsHeapConstant(builtin.code()), arg_count,
|
||||||
Node* call_js = m.CallJS(function, context, first_arg, arg_count,
|
first_arg, function, context, _, _));
|
||||||
receiver_mode, tail_call_mode);
|
}
|
||||||
EXPECT_THAT(call_js, IsCall(_, IsHeapConstant(builtin.code()), arg_count,
|
|
||||||
first_arg, function, context, _, _));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user