Revert of [Interpreter] Implements calls through CallICStub in the interpreter. (patchset #15 id:270001 of https://codereview.chromium.org/1688283003/ )

Reason for revert:
It is not a good idea to call CallICStub from the builtin. It might be sensitive to the frame structure. Constructing a internal frame might cause problems. It is much better to inline the code  related to the type feedback vector into the builtin.

Original issue's description:
> [Interpreter] Implements calls through CallICStub in the interpreter.
>
> Calls are implemented through CallICStub to collect type feedback. Adds
> a new builtin called InterpreterPushArgsAndCallIC that pushes the
> arguments onto stack and calls CallICStub.
>
> Also adds two new bytecodes CallIC and CallICWide to indicate calls have to
> go through CallICStub.
>
> MIPS port contributed by balazs.kilvady.
>
> BUG=v8:4280, v8:4680
> LOG=N
>
> Committed: https://crrev.com/20362a2214c11a0f2ea5141b6a79e09458939cec
> Cr-Commit-Position: refs/heads/master@{#34244}

TBR=rmcilroy@chromium.org,mvstanton@chromium.org,mstarzinger@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4280, v8:4680

Review URL: https://codereview.chromium.org/1731253003

Cr-Commit-Position: refs/heads/master@{#34252}
This commit is contained in:
mythria 2016-02-24 07:15:02 -08:00 committed by Commit bot
parent b38eabe845
commit eb358178f8
42 changed files with 278 additions and 1142 deletions

View File

@ -976,46 +976,6 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
__ b(gt, &loop_header);
}
static void Generate_InterpreterComputeLastArgumentAddress(
MacroAssembler* masm, Register num_args, Register start_address,
Register output_reg) {
__ add(output_reg, num_args, Operand(1)); // Add one for receiver.
__ mov(output_reg, Operand(output_reg, LSL, kPointerSizeLog2));
__ sub(output_reg, start_address, output_reg);
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallICImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
// ----------- S t a t e -------------
// -- r0 : the number of arguments (not including the receiver)
// -- r4 : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -- r1 : the target to call (can be any Object).
// -- r3 : feedback vector slot id
// -- r2 : type feedback vector
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Find the address of the last argument.
Generate_InterpreterComputeLastArgumentAddress(masm, r0, r4, r5);
// Push the arguments.
Generate_InterpreterPushArgs(masm, r4, r5, r6);
// Call via the CallIC stub.
CallICState call_ic_state(0, ConvertReceiverMode::kAny, tail_call_mode,
true);
CallICStub stub(masm->isolate(), call_ic_state);
// TODO(mythria): This should be replaced by a TailCallStub, when we
// update the code to find the target IC from jump instructions.
__ CallStub(&stub);
}
__ Ret();
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
@ -1029,7 +989,9 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
// -----------------------------------
// Find the address of the last argument.
Generate_InterpreterComputeLastArgumentAddress(masm, r0, r2, r3);
__ add(r3, r0, Operand(1)); // Add one for receiver.
__ mov(r3, Operand(r3, LSL, kPointerSizeLog2));
__ sub(r3, r2, r3);
// Push the arguments.
Generate_InterpreterPushArgs(masm, r2, r3, r4);
@ -1980,17 +1942,6 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
__ cmp(scratch1, Operand(0));
__ b(ne, &done);
// Drop possible internal frame pushed for calling CallICStub.
// TODO(mythria): when we tail call the CallICStub, remove this.
{
Label no_internal_callic_frame;
__ ldr(scratch3, MemOperand(fp, StandardFrameConstants::kMarkerOffset));
__ cmp(scratch3, Operand(Smi::FromInt(StackFrame::INTERNAL)));
__ b(ne, &no_internal_callic_frame);
__ ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ bind(&no_internal_callic_frame);
}
// Drop possible interpreter handler/stub frame.
{
Label no_interpreter_frame;

View File

@ -2067,6 +2067,8 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ cmp(r1, r5);
__ b(ne, miss);
__ mov(r0, Operand(arg_count()));
// Increment the call count for monomorphic function calls.
__ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3));
__ add(r2, r2, Operand(FixedArray::kHeaderSize + kPointerSize));
@ -2076,30 +2078,18 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ mov(r2, r4);
__ mov(r3, r1);
if (argc_in_register()) {
// Pass a default ArgumentCountKey::Any since the argc is only available
// in r0. We do not have the actual count here.
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
} else {
// arg_count() is expected in r0 if the arg_count() >= 2
// (ArgumentCountKey::MORE_THAN_ONE).
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate(MacroAssembler* masm) {
// r0 - number of arguments if argc_in_register() is true
// r1 - function
// r3 - slot id (Smi)
// r2 - vector
Label extra_checks_or_miss, call, call_function;
if (!argc_in_register()) {
int argc = arg_count();
__ mov(r0, Operand(argc));
}
int argc = arg_count();
ParameterCount actual(argc);
// The checks. First, does r1 match the recorded monomorphic target?
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
@ -2135,6 +2125,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ str(r3, FieldMemOperand(r2, 0));
__ bind(&call_function);
__ mov(r0, Operand(argc));
__ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(),
tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -2174,6 +2165,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
__ bind(&call);
__ mov(r0, Operand(argc));
__ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -2211,13 +2203,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
CreateWeakCellStub create_stub(masm->isolate());
__ SmiTag(r0);
__ Push(r0);
__ Push(r1);
__ CallStub(&create_stub);
__ Pop(r1);
__ Pop(r0);
__ SmiUntag(r0);
}
__ jmp(&call_function);
@ -2234,10 +2222,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm) {
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Store the number of arguments that is required later.
__ SmiTag(r0);
__ Push(r0);
// Push the receiver and the function and feedback info.
__ Push(r1, r2, r3);
@ -2246,10 +2230,6 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
// Move result to edi and exit the internal frame.
__ mov(r1, r0);
// Restore back the number of arguments to r0.
__ Pop(r0);
__ SmiUntag(r0);
}

View File

@ -443,18 +443,6 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallICDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r0, // argument count (not including receiver)
r4, // address of first argument
r1, // the target callable to be call
r3, // slot id
r2 // type feedback vector
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -1981,17 +1981,6 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
__ Cmp(scratch1, Operand(0));
__ B(ne, &done);
// Drop possible internal frame pushed for calling CallICStub.
// TODO(mythria): when we tail call the CallICStub, remove this.
{
Label no_internal_callic_frame;
__ Ldr(scratch3, MemOperand(fp, StandardFrameConstants::kMarkerOffset));
__ Cmp(scratch3, Operand(Smi::FromInt(StackFrame::INTERNAL)));
__ B(ne, &no_internal_callic_frame);
__ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ bind(&no_internal_callic_frame);
}
// Drop possible interpreter handler/stub frame.
{
Label no_interpreter_frame;
@ -2475,57 +2464,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register num_args,
Register start_addr) {
// Find the address of the last argument.
__ add(x5, num_args, Operand(1)); // Add one for receiver.
__ lsl(x5, x5, kPointerSizeLog2);
__ sub(x6, start_addr, x5);
// Push the arguments.
Label loop_header, loop_check;
__ Mov(x7, jssp);
__ Claim(x5, 1);
__ B(&loop_check);
__ Bind(&loop_header);
// TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
__ Ldr(x5, MemOperand(start_addr, -kPointerSize, PostIndex));
__ Str(x5, MemOperand(x7, -kPointerSize, PreIndex));
__ Bind(&loop_check);
__ Cmp(start_addr, x6);
__ B(gt, &loop_header);
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallICImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
// ----------- S t a t e -------------
// -- x0 : the number of arguments (not including the receiver)
// -- x4 : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -- x1 : the target to call (can be any Object).
// -- x3 : feedback vector slot id
// -- x2 : type feedback vector
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push arguments to stack. Clobbers x5-x7 registers.
Generate_InterpreterPushArgs(masm, x0, x4);
// Call via the CallIC stub.
CallICState call_ic_state(0, ConvertReceiverMode::kAny, tail_call_mode,
true);
CallICStub stub(masm->isolate(), call_ic_state);
// TODO(mythria): This should be replaced by a TailCallStub, when we
// update the code to find the target IC from jump instructions.
__ CallStub(&stub);
}
__ Ret();
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
@ -2538,8 +2476,23 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
// -- x1 : the target to call (can be any Object).
// -----------------------------------
// Push arguments to stack. Clobbers x5-x7 registers.
Generate_InterpreterPushArgs(masm, x0, x2);
// Find the address of the last argument.
__ add(x3, x0, Operand(1)); // Add one for receiver.
__ lsl(x3, x3, kPointerSizeLog2);
__ sub(x4, x2, x3);
// Push the arguments.
Label loop_header, loop_check;
__ Mov(x5, jssp);
__ Claim(x3, 1);
__ B(&loop_check);
__ Bind(&loop_header);
// TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
__ Ldr(x3, MemOperand(x2, -kPointerSize, PostIndex));
__ Str(x3, MemOperand(x5, -kPointerSize, PreIndex));
__ Bind(&loop_check);
__ Cmp(x2, x4);
__ B(gt, &loop_header);
// Call the target.
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,

View File

@ -2289,7 +2289,6 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
// x0 - number of arguments
// x1 - function
// x3 - slot id
// x2 - vector
@ -2304,6 +2303,8 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ Cmp(function, scratch);
__ B(ne, miss);
__ Mov(x0, Operand(arg_count()));
// Increment the call count for monomorphic function calls.
__ Add(feedback_vector, feedback_vector,
Operand::UntagSmiAndScale(index, kPointerSizeLog2));
@ -2318,31 +2319,20 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
Register new_target_arg = index;
__ Mov(allocation_site_arg, allocation_site);
__ Mov(new_target_arg, function);
if (argc_in_register()) {
// Pass a default ArgumentCountKey::Any since the argc is only available
// in r0. We do not have the actual count here.
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
} else {
// arg_count() is expected in r0 if the arg_count() >= 2
// (ArgumentCountKey::MORE_THAN_ONE).
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate(MacroAssembler* masm) {
ASM_LOCATION("CallICStub");
// x0 - number of arguments if argc_in_register() is true
// x1 - function
// x3 - slot id (Smi)
// x2 - vector
Label extra_checks_or_miss, call, call_function;
if (!argc_in_register()) {
__ Mov(x0, arg_count());
}
int argc = arg_count();
ParameterCount actual(argc);
Register function = x1;
Register feedback_vector = x2;
@ -2385,6 +2375,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ Str(index, FieldMemOperand(feedback_vector, 0));
__ Bind(&call_function);
__ Mov(x0, argc);
__ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(),
tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -2419,6 +2410,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize));
__ Bind(&call);
__ Mov(x0, argc);
__ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -2456,13 +2448,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
CreateWeakCellStub create_stub(masm->isolate());
__ SmiTag(x0);
__ Push(x0);
__ Push(function);
__ CallStub(&create_stub);
__ Pop(function);
__ Pop(x0);
__ SmiUntag(x0);
}
__ B(&call_function);
@ -2481,10 +2469,6 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::INTERNAL);
// Store number of arguments.
__ SmiTag(x0);
__ Push(x0);
// Push the receiver and the function and feedback info.
__ Push(x1, x2, x3);
@ -2493,10 +2477,6 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
// Move result to edi and exit the internal frame.
__ Mov(x1, x0);
// Restore number of arguments.
__ Pop(x0);
__ SmiUntag(x0);
}

View File

@ -478,18 +478,6 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallICDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
x0, // argument count (not including receiver)
x4, // address of first argument
x1, // the target callable to be call
x3, // slot id
x2 // type feedback vector
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -3999,18 +3999,6 @@ Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode) {
return Handle<Code>::null();
}
Handle<Code> Builtins::InterpreterPushArgsAndCallIC(
TailCallMode tail_call_mode) {
switch (tail_call_mode) {
case TailCallMode::kDisallow:
return InterpreterPushArgsAndCallIC();
case TailCallMode::kAllow:
return InterpreterPushArgsAndTailCallIC();
}
UNREACHABLE();
return Handle<Code>::null();
}
namespace {
class RelocatableArguments

View File

@ -216,8 +216,6 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
\
V(InterpreterEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterExitTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterPushArgsAndCallIC, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterPushArgsAndTailCallIC, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterPushArgsAndCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterPushArgsAndTailCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(InterpreterPushArgsAndConstruct, BUILTIN, UNINITIALIZED, kNoExtraICState) \
@ -369,7 +367,6 @@ class Builtins {
TailCallMode tail_call_mode = TailCallMode::kDisallow);
Handle<Code> CallBoundFunction(TailCallMode tail_call_mode);
Handle<Code> InterpreterPushArgsAndCall(TailCallMode tail_call_mode);
Handle<Code> InterpreterPushArgsAndCallIC(TailCallMode tail_call_mode);
Code* builtin(Name name) {
// Code::cast cannot be used here since we access builtins
@ -585,16 +582,6 @@ class Builtins {
static void Generate_InterpreterEntryTrampoline(MacroAssembler* masm);
static void Generate_InterpreterExitTrampoline(MacroAssembler* masm);
static void Generate_InterpreterPushArgsAndCallIC(MacroAssembler* masm) {
return Generate_InterpreterPushArgsAndCallICImpl(masm,
TailCallMode::kDisallow);
}
static void Generate_InterpreterPushArgsAndTailCallIC(MacroAssembler* masm) {
return Generate_InterpreterPushArgsAndCallICImpl(masm,
TailCallMode::kAllow);
}
static void Generate_InterpreterPushArgsAndCallICImpl(
MacroAssembler* masm, TailCallMode tail_call_mode);
static void Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
return Generate_InterpreterPushArgsAndCallImpl(masm,
TailCallMode::kDisallow);

View File

@ -345,13 +345,6 @@ Callable CodeFactory::ConstructFunction(Isolate* isolate) {
ConstructTrampolineDescriptor(isolate));
}
// static
Callable CodeFactory::InterpreterPushArgsAndCallIC(
Isolate* isolate, TailCallMode tail_call_mode) {
return Callable(
isolate->builtins()->InterpreterPushArgsAndCallIC(tail_call_mode),
InterpreterPushArgsAndCallICDescriptor(isolate));
}
// static
Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
@ -361,6 +354,7 @@ Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
InterpreterPushArgsAndCallDescriptor(isolate));
}
// static
Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) {
return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(),

View File

@ -106,8 +106,6 @@ class CodeFactory final {
static Callable Construct(Isolate* isolate);
static Callable ConstructFunction(Isolate* isolate);
static Callable InterpreterPushArgsAndCallIC(Isolate* isolate,
TailCallMode tail_call_mode);
static Callable InterpreterPushArgsAndCall(Isolate* isolate,
TailCallMode tail_call_mode);
static Callable InterpreterPushArgsAndConstruct(Isolate* isolate);

View File

@ -973,13 +973,9 @@ class CallICStub: public PlatformCodeStub {
}
protected:
int arg_count() const {
DCHECK(!argc_in_register());
return state().argc();
}
int arg_count() const { return state().argc(); }
ConvertReceiverMode convert_mode() const { return state().convert_mode(); }
TailCallMode tail_call_mode() const { return state().tail_call_mode(); }
bool argc_in_register() const { return state().argc_in_register(); }
CallICState state() const {
return CallICState(static_cast<ExtraICState>(minor_key_));

View File

@ -501,7 +501,10 @@ Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
FeedbackVectorSlot slot = feedback_vector()->ToSlot(slot_id);
FeedbackVectorSlot slot;
if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
slot = feedback_vector()->ToSlot(slot_id);
}
return VectorSlotPair(feedback_vector(), slot);
}
@ -989,42 +992,6 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
return value;
}
void BytecodeGraphBuilder::BuildCallWithFeedbackSlot(
TailCallMode tail_call_mode) {
FrameStateBeforeAndAfter states(this);
// TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
// register has been loaded with null / undefined explicitly or we are sure it
// is not null / undefined.
ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
Node* callee =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
int slot_id = bytecode_iterator().GetIndexOperand(3);
VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
const Operator* call = javascript()->CallFunction(
arg_count + 1, feedback, receiver_hint, tail_call_mode);
Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
environment()->BindAccumulator(value, &states);
}
void BytecodeGraphBuilder::VisitCallIC() {
BuildCallWithFeedbackSlot(TailCallMode::kDisallow);
}
void BytecodeGraphBuilder::VisitCallICWide() {
BuildCallWithFeedbackSlot(TailCallMode::kDisallow);
}
void BytecodeGraphBuilder::VisitTailCallIC() {
BuildCallWithFeedbackSlot(TailCallMode::kAllow);
}
void BytecodeGraphBuilder::VisitTailCallICWide() {
BuildCallWithFeedbackSlot(TailCallMode::kAllow);
}
void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
FrameStateBeforeAndAfter states(this);
// TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
@ -1035,9 +1002,11 @@ void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
VectorSlotPair feedback =
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
const Operator* call = javascript()->CallFunction(
arg_count + 1, VectorSlotPair(), receiver_hint, tail_call_mode);
arg_count + 1, feedback, receiver_hint, tail_call_mode);
Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
environment()->BindAccumulator(value, &states);
}

View File

@ -124,7 +124,6 @@ class BytecodeGraphBuilder {
void BuildLdaLookupSlot(TypeofMode typeof_mode);
void BuildStaLookupSlot(LanguageMode language_mode);
void BuildCall(TailCallMode tail_call_mode);
void BuildCallWithFeedbackSlot(TailCallMode tail_call_mode);
void BuildCallJSRuntime();
void BuildCallRuntime();
void BuildCallRuntimeForPair();

View File

@ -559,58 +559,6 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
__ j(greater, &loop_header, Label::kNear);
}
static void Generate_InterpreterComputeLastArgumentAddress(MacroAssembler* masm,
Register r) {
// Find the address of the last argument.
// ----------- S t a t e -------------
// input: eax : Number of arguments.
// input: ebx : Address of the first argument.
// output: Register |r|: Address of the last argument.
// -----------------------------------
__ mov(r, eax);
__ add(r, Immediate(1)); // Add one for receiver.
__ shl(r, kPointerSizeLog2);
__ neg(r);
__ add(r, ebx);
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallICImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
// ----------- S t a t e -------------
// -- eax : the number of arguments (not including the receiver)
// -- ebx : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -- edi : the target to call (can be any Object).
// -- edx : feedback slot id.
// -- ecx : type feedback vector.
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Store type feedback vector on the stack since we ran out of registers.
__ Push(ecx);
// computes the address of last argument in ecx.
// ecx = ebx - (eax + 1) * kPointerSize.
Generate_InterpreterComputeLastArgumentAddress(masm, ecx);
Generate_InterpreterPushArgs(masm, ecx);
// Restore feedback vector to ebx from the stack. It was pushed
// before the arguments were pushed, so compute the correct offset.
__ mov(ebx, Operand(esp, eax, times_pointer_size, 1 * kPointerSize));
// Call via the CallIC stub.
CallICState call_ic_state(0, ConvertReceiverMode::kAny, tail_call_mode,
true);
CallICStub stub(masm->isolate(), call_ic_state);
// TODO(mythria): This should be replaced by a TailCallStub, when we
// update the code to find the target IC from jump instructions.
__ CallStub(&stub);
}
__ Ret();
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
@ -626,9 +574,13 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
// Pop return address to allow tail-call after pushing arguments.
__ Pop(edx);
// computes the address of last argument in ecx.
// ecx = ebx - (eax + 1) * kPointerSize.
Generate_InterpreterComputeLastArgumentAddress(masm, ecx);
// Find the address of the last argument.
__ mov(ecx, eax);
__ add(ecx, Immediate(1)); // Add one for receiver.
__ shl(ecx, kPointerSizeLog2);
__ neg(ecx);
__ add(ecx, ebx);
Generate_InterpreterPushArgs(masm, ecx);
// Call the target.
@ -638,6 +590,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
RelocInfo::CODE_TARGET);
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
@ -649,24 +602,27 @@ void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// they are to be pushed onto the stack.
// -----------------------------------
// Save number of arguments on the stack below where arguments are going
// to be pushed.
__ mov(ecx, eax);
__ neg(ecx);
__ mov(Operand(esp, ecx, times_pointer_size, -kPointerSize), eax);
__ mov(eax, ecx);
// Pop return address to allow tail-call after pushing arguments.
__ Pop(ecx);
// Push edi in the slot meant for receiver. We need an extra register so
// store edi temporarily on the stack.
__ Push(edi);
// Find the address of the last argument.
__ mov(edi, eax);
__ neg(edi);
__ shl(edi, kPointerSizeLog2);
__ add(edi, ebx);
__ shl(eax, kPointerSizeLog2);
__ add(eax, ebx);
Generate_InterpreterPushArgs(masm, edi);
// Push padding for receiver.
__ Push(Immediate(0));
// Restore number of arguments from slot on stack. edi was pushed at
// the slot meant for receiver.
__ mov(edi, Operand(esp, eax, times_pointer_size, 0));
Generate_InterpreterPushArgs(masm, eax);
// Restore number of arguments from slot on stack.
__ mov(eax, Operand(esp, -kPointerSize));
// Re-push return address.
__ Push(ecx);
@ -1917,17 +1873,6 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
__ cmp(scratch1, Immediate(0));
__ j(not_equal, &done, Label::kNear);
// Drop possible internal frame pushed for calling CallICStub.
// TODO(mythria): when we tail call the CallICStub, remove this.
{
Label no_internal_callic_frame;
__ cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset),
Immediate(Smi::FromInt(StackFrame::INTERNAL)));
__ j(not_equal, &no_internal_callic_frame, Label::kNear);
__ mov(ebp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
__ bind(&no_internal_callic_frame);
}
// Drop possible interpreter handler/stub frame.
{
Label no_interpreter_frame;

View File

@ -1624,11 +1624,11 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
// edi - function
// edx - slot id
// ebx - vector
// eax - number of arguments - if argc_in_register() is true.
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
__ cmp(edi, ecx);
__ j(not_equal, miss);
__ mov(eax, arg_count());
// Reload ecx.
__ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize));
@ -1640,17 +1640,9 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ mov(ebx, ecx);
__ mov(edx, edi);
if (argc_in_register()) {
// Pass a default ArgumentCountKey::Any since the argc is only available
// in eax. We do not have the actual count here.
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
} else {
// arg_count() is expected in rax if the arg_count() >= 2
// (ArgumentCountKey::MORE_THAN_ONE).
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
// Unreachable.
}
@ -1659,13 +1651,10 @@ void CallICStub::Generate(MacroAssembler* masm) {
// edi - function
// edx - slot id
// ebx - vector
// eax - number of arguments - if argc_in_register() is true.
Isolate* isolate = masm->isolate();
Label extra_checks_or_miss, call, call_function;
if (!argc_in_register()) {
int argc = arg_count();
__ Set(eax, argc);
}
int argc = arg_count();
ParameterCount actual(argc);
// The checks. First, does edi match the recorded monomorphic target?
__ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
@ -1698,6 +1687,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement)));
__ bind(&call_function);
__ Set(eax, argc);
__ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(),
tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -1737,6 +1727,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
__ bind(&call);
__ Set(eax, argc);
__ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -1773,15 +1764,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
CreateWeakCellStub create_stub(isolate);
__ SmiTag(eax);
__ push(eax);
__ push(edi);
__ CallStub(&create_stub);
__ pop(edi);
__ pop(eax);
__ SmiUntag(eax);
}
__ jmp(&call_function);
@ -1801,9 +1786,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::INTERNAL);
// Store eax since we need it later.
__ SmiTag(eax);
__ push(eax);
// Push the function and feedback info.
__ push(edi);
__ push(ebx);
@ -1814,10 +1796,6 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
// Move result to edi and exit the internal frame.
__ mov(edi, eax);
// Restore eax.
__ pop(eax);
__ SmiUntag(eax);
}

View File

@ -433,18 +433,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallICDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
eax, // argument count (not including receiver)
ebx, // address of first argument
edi, // the target callable to be call
edx, // feedback vector slot id
ecx // type feedback vector
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -26,11 +26,10 @@ class CallICState final BASE_EMBEDDED {
explicit CallICState(ExtraICState extra_ic_state)
: bit_field_(extra_ic_state) {}
CallICState(int argc, ConvertReceiverMode convert_mode,
TailCallMode tail_call_mode, bool is_argc_in_reg = false)
TailCallMode tail_call_mode)
: bit_field_(ArgcBits::encode(argc) |
ConvertModeBits::encode(convert_mode) |
TailCallModeBits::encode(tail_call_mode) |
ArgcInRegBits::encode(is_argc_in_reg)) {}
TailCallModeBits::encode(tail_call_mode)) {}
ExtraICState GetExtraICState() const { return bit_field_; }
@ -45,13 +44,11 @@ class CallICState final BASE_EMBEDDED {
TailCallMode tail_call_mode() const {
return TailCallModeBits::decode(bit_field_);
}
bool argc_in_register() { return ArgcInRegBits::decode(bit_field_); }
private:
typedef BitField<int, 0, Code::kArgumentsBits> ArgcBits;
typedef BitField<ConvertReceiverMode, ArgcBits::kNext, 2> ConvertModeBits;
typedef BitField<TailCallMode, ConvertModeBits::kNext, 1> TailCallModeBits;
typedef BitField<bool, TailCallModeBits::kNext, 1> ArgcInRegBits;
int const bit_field_;
};

View File

@ -78,7 +78,6 @@ class PlatformInterfaceDescriptor;
V(GrowArrayElements) \
V(InterpreterDispatch) \
V(InterpreterPushArgsAndCall) \
V(InterpreterPushArgsAndCallIC) \
V(InterpreterPushArgsAndConstruct) \
V(InterpreterCEntry)
@ -758,18 +757,13 @@ class InterpreterDispatchDescriptor : public CallInterfaceDescriptor {
static const int kContextParameter = 5;
};
class InterpreterPushArgsAndCallICDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(InterpreterPushArgsAndCallICDescriptor,
CallInterfaceDescriptor)
};
class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(InterpreterPushArgsAndCallDescriptor,
CallInterfaceDescriptor)
};
class InterpreterPushArgsAndConstructDescriptor
: public CallInterfaceDescriptor {
public:

View File

@ -1059,10 +1059,12 @@ void BytecodeArrayBuilder::EnsureReturn(FunctionLiteral* literal) {
}
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CallIC(
Register callable, Register receiver_args, size_t receiver_args_count,
int feedback_slot, TailCallMode tail_call_mode) {
Bytecode bytecode = BytecodeForCallIC(tail_call_mode);
BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
Register receiver_args,
size_t receiver_args_count,
int feedback_slot,
TailCallMode tail_call_mode) {
Bytecode bytecode = BytecodeForCall(tail_call_mode);
if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) &&
FitsInIdx8Operand(receiver_args_count) &&
FitsInIdx8Operand(feedback_slot)) {
@ -1083,26 +1085,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallIC(
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
Register receiver_args,
size_t receiver_args_count,
TailCallMode tail_call_mode) {
Bytecode bytecode = BytecodeForCall(tail_call_mode);
if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) &&
FitsInIdx8Operand(receiver_args_count)) {
Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(),
static_cast<uint8_t>(receiver_args_count));
} else if (FitsInReg16Operand(callable) &&
FitsInReg16Operand(receiver_args) &&
FitsInIdx16Operand(receiver_args_count)) {
bytecode = BytecodeForWideOperands(bytecode);
Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(),
static_cast<uint16_t>(receiver_args_count));
} else {
UNIMPLEMENTED();
}
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
Register first_arg,
size_t arg_count) {
@ -1444,10 +1426,6 @@ Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) {
// static
Bytecode BytecodeArrayBuilder::BytecodeForWideOperands(Bytecode bytecode) {
switch (bytecode) {
case Bytecode::kCallIC:
return Bytecode::kCallICWide;
case Bytecode::kTailCallIC:
return Bytecode::kTailCallICWide;
case Bytecode::kCall:
return Bytecode::kCallWide;
case Bytecode::kTailCall:
@ -1591,19 +1569,6 @@ Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) {
return static_cast<Bytecode>(-1);
}
// static
Bytecode BytecodeArrayBuilder::BytecodeForCallIC(TailCallMode tail_call_mode) {
switch (tail_call_mode) {
case TailCallMode::kDisallow:
return Bytecode::kCallIC;
case TailCallMode::kAllow:
return Bytecode::kTailCallIC;
default:
UNREACHABLE();
}
return static_cast<Bytecode>(-1);
}
// static
Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
switch (tail_call_mode) {

View File

@ -163,28 +163,18 @@ class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover {
// <receiver_args + receiver_arg_count - 1>.
BytecodeArrayBuilder& Call(
Register callable, Register receiver_args, size_t receiver_arg_count,
TailCallMode tail_call_mode = TailCallMode::kDisallow);
int feedback_slot, TailCallMode tail_call_mode = TailCallMode::kDisallow);
BytecodeArrayBuilder& TailCall(Register callable, Register receiver_args,
size_t receiver_arg_count) {
return Call(callable, receiver_args, receiver_arg_count,
size_t receiver_arg_count, int feedback_slot) {
return Call(callable, receiver_args, receiver_arg_count, feedback_slot,
TailCallMode::kAllow);
}
// Call a JS function. The JSFunction or Callable to be called should be in
// |callable|, the receiver should be in |receiver_args| and all subsequent
// arguments should be in registers <receiver_args + 1> to
// <receiver_args + receiver_arg_count - 1>.
// Call through CallICStub to get Typefeedback.
BytecodeArrayBuilder& CallIC(Register callable, Register receiver_args,
size_t receiver_arg_count, int feedback_slot,
TailCallMode tail_call_mode);
// Call the new operator. The accumulator holds the |new_target|.
// The |constructor| is in a register followed by |arg_count|
// consecutive arguments starting at |first_arg| for the constuctor
// invocation.
BytecodeArrayBuilder& New(Register constructor, Register first_arg,
size_t arg_count);
@ -297,7 +287,6 @@ class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover {
static Bytecode BytecodeForCreateArguments(CreateArgumentsType type);
static Bytecode BytecodeForDelete(LanguageMode language_mode);
static Bytecode BytecodeForCall(TailCallMode tail_call_mode);
static Bytecode BytecodeForCallIC(TailCallMode tail_call_mode);
static bool FitsInIdx8Operand(int value);
static bool FitsInIdx8Operand(size_t value);

View File

@ -2457,15 +2457,9 @@ void BytecodeGenerator::VisitCall(Call* expr) {
}
builder()->SetExpressionPosition(expr);
if (expr->CallFeedbackICSlot().IsInvalid()) {
builder()->Call(callee, receiver, 1 + args->length(),
expr->tail_call_mode());
} else {
DCHECK(call_type != Call::POSSIBLY_EVAL_CALL);
builder()->CallIC(callee, receiver, 1 + args->length(),
feedback_index(expr->CallFeedbackICSlot()),
expr->tail_call_mode());
}
builder()->Call(callee, receiver, 1 + args->length(),
feedback_index(expr->CallFeedbackICSlot()),
expr->tail_call_mode());
execution_result()->SetResultInAccumulator();
}

View File

@ -278,10 +278,8 @@ bool Bytecodes::IsJump(Bytecode bytecode) {
// static
bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
bytecode == Bytecode::kNew || bytecode == Bytecode::kCallIC ||
bytecode == Bytecode::kCallWide ||
bytecode == Bytecode::kTailCallWide ||
bytecode == Bytecode::kNewWide || bytecode == Bytecode::kCallICWide;
bytecode == Bytecode::kNew || bytecode == Bytecode::kCallWide ||
bytecode == Bytecode::kTailCallWide || bytecode == Bytecode::kNewWide;
}
// static

View File

@ -169,20 +169,14 @@ namespace interpreter {
V(DeletePropertySloppy, OperandType::kReg8) \
\
/* Call operations */ \
V(CallIC, OperandType::kReg8, OperandType::kReg8, OperandType::kRegCount8, \
V(Call, OperandType::kReg8, OperandType::kReg8, OperandType::kRegCount8, \
OperandType::kIdx8) \
V(CallICWide, OperandType::kReg16, OperandType::kReg16, \
OperandType::kRegCount16, OperandType::kIdx16) \
V(TailCallIC, OperandType::kReg8, OperandType::kReg8, \
OperandType::kRegCount8, OperandType::kIdx8) \
V(TailCallICWide, OperandType::kReg16, OperandType::kReg16, \
OperandType::kRegCount16, OperandType::kIdx16) \
V(Call, OperandType::kReg8, OperandType::kReg8, OperandType::kRegCount8) \
V(CallWide, OperandType::kReg16, OperandType::kReg16, \
OperandType::kRegCount16) \
V(TailCall, OperandType::kReg8, OperandType::kReg8, OperandType::kRegCount8) \
OperandType::kRegCount16, OperandType::kIdx16) \
V(TailCall, OperandType::kReg8, OperandType::kReg8, OperandType::kRegCount8, \
OperandType::kIdx8) \
V(TailCallWide, OperandType::kReg16, OperandType::kReg16, \
OperandType::kRegCount16) \
OperandType::kRegCount16, OperandType::kIdx16) \
V(CallRuntime, OperandType::kIdx16, OperandType::kMaybeReg8, \
OperandType::kRegCount8) \
V(CallRuntimeWide, OperandType::kIdx16, OperandType::kMaybeReg16, \

View File

@ -345,19 +345,6 @@ Node* InterpreterAssembler::CallJS(Node* function, Node* context,
first_arg, function);
}
Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context,
Node* first_arg, Node* arg_count,
Node* slot_id,
Node* type_feedback_vector,
TailCallMode tail_call_mode) {
Callable callable =
CodeFactory::InterpreterPushArgsAndCallIC(isolate(), tail_call_mode);
Node* code_target = HeapConstant(callable.code());
return CallStub(callable.descriptor(), code_target, context, arg_count,
first_arg, function, slot_id, type_feedback_vector);
}
Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
Node* new_target, Node* first_arg,
Node* arg_count) {

View File

@ -87,18 +87,6 @@ class InterpreterAssembler : public compiler::CodeStubAssembler {
compiler::Node* first_arg, compiler::Node* arg_count,
TailCallMode tail_call_mode);
// Call JSFunction or Callable |function| with |arg_count|
// arguments (not including receiver) and the first argument
// located at |first_arg| with feedback slot id |slot_id| and
// type feedback vector |type_feedback_vector|.
compiler::Node* CallJSWithFeedback(compiler::Node* function,
compiler::Node* context,
compiler::Node* first_arg,
compiler::Node* arg_count,
compiler::Node* slot_id,
compiler::Node* type_feedback_vector,
TailCallMode tail_call_mode);
// Call constructor |constructor| with |arg_count| arguments (not
// including receiver) and the first argument located at
// |first_arg|. The |new_target| is the same as the

View File

@ -934,58 +934,6 @@ void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) {
DoDelete(Runtime::kDeleteProperty_Sloppy, assembler);
}
void Interpreter::DoJSCallWithFeedback(InterpreterAssembler* assembler,
TailCallMode tail_call_mode) {
Node* function_reg = __ BytecodeOperandReg(0);
Node* function = __ LoadRegister(function_reg);
Node* receiver_reg = __ BytecodeOperandReg(1);
Node* receiver_arg = __ RegisterLocation(receiver_reg);
Node* receiver_args_count = __ BytecodeOperandCount(2);
Node* receiver_count = __ Int32Constant(1);
Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
Node* slot_id_raw = __ BytecodeOperandIdx(3);
Node* slot_id = __ SmiTag(slot_id_raw);
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* context = __ GetContext();
Node* result =
__ CallJSWithFeedback(function, context, receiver_arg, args_count,
slot_id, type_feedback_vector, tail_call_mode);
__ SetAccumulator(result);
__ Dispatch();
}
// Call <callable> <receiver> <arg_count>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers.
void Interpreter::DoCallIC(InterpreterAssembler* assembler) {
DoJSCallWithFeedback(assembler, TailCallMode::kDisallow);
}
// CallWide <callable> <receiver> <arg_count>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers.
void Interpreter::DoCallICWide(InterpreterAssembler* assembler) {
DoJSCallWithFeedback(assembler, TailCallMode::kDisallow);
}
// Call <callable> <receiver> <arg_count>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers.
void Interpreter::DoTailCallIC(InterpreterAssembler* assembler) {
DoJSCallWithFeedback(assembler, TailCallMode::kAllow);
}
// CallWide <callable> <receiver> <arg_count>
//
// Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers.
void Interpreter::DoTailCallICWide(InterpreterAssembler* assembler) {
DoJSCallWithFeedback(assembler, TailCallMode::kAllow);
}
void Interpreter::DoJSCall(InterpreterAssembler* assembler,
TailCallMode tail_call_mode) {
Node* function_reg = __ BytecodeOperandReg(0);
@ -996,6 +944,7 @@ void Interpreter::DoJSCall(InterpreterAssembler* assembler,
Node* receiver_count = __ Int32Constant(1);
Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
Node* context = __ GetContext();
// TODO(rmcilroy): Use the call type feedback slot to call via CallStub.
Node* result =
__ CallJS(function, context, receiver_arg, args_count, tail_call_mode);
__ SetAccumulator(result);

View File

@ -94,10 +94,6 @@ class Interpreter {
// Generates code to perform a JS call.
void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);
// Generates code to perform a JS call with feedback.
void DoJSCallWithFeedback(InterpreterAssembler* assembler,
TailCallMode tail_call_mode);
// Generates code to perform a runtime call.
void DoCallRuntimeCommon(InterpreterAssembler* assembler);

View File

@ -961,58 +961,6 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
__ Jump(ra);
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register limit, Register scratch) {
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ lw(scratch, MemOperand(index));
__ Addu(index, index, Operand(-kPointerSize));
__ push(scratch);
__ bind(&loop_check);
__ Branch(&loop_header, gt, index, Operand(limit));
}
static void Generate_InterpreterComputeLastArgumentAddress(
MacroAssembler* masm, Register num_args, Register start_address,
Register output_reg) {
__ Addu(output_reg, num_args, Operand(1)); // Add one for receiver.
__ sll(output_reg, output_reg, kPointerSizeLog2);
__ Subu(output_reg, start_address, output_reg);
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallICImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
// ----------- S t a t e -------------
// -- a0 : the number of arguments (not including the receiver)
// -- t0 : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -- a1 : the target to call (can be any Object).
// -- a3 : feedback vector slot id
// -- a2 : type feedback vector
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Computes the address of last argument in t1.
Generate_InterpreterComputeLastArgumentAddress(masm, a0, t0, t1);
// Push the arguments.
Generate_InterpreterPushArgs(masm, t0, t1, at);
// Call via the CallIC stub.
CallICState call_ic_state(0, ConvertReceiverMode::kAny, tail_call_mode,
true);
CallICStub stub(masm->isolate(), call_ic_state);
// TODO(mythria): This should be replaced by a TailCallStub, when we
// update the code to find the target IC from jump instructions.
__ CallStub(&stub);
}
__ Ret();
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
@ -1025,11 +973,20 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
// -- a1 : the target to call (can be any Object).
// -----------------------------------
// Computes the address of last argument in a3.
Generate_InterpreterComputeLastArgumentAddress(masm, a0, a2, a3);
// Find the address of the last argument.
__ Addu(a3, a0, Operand(1)); // Add one for receiver.
__ sll(a3, a3, kPointerSizeLog2);
__ Subu(a3, a2, Operand(a3));
// Push the arguments.
Generate_InterpreterPushArgs(masm, a2, a3, at);
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ lw(t0, MemOperand(a2));
__ Addu(a2, a2, Operand(-kPointerSize));
__ push(t0);
__ bind(&loop_check);
__ Branch(&loop_header, gt, a2, Operand(a3));
// Call the target.
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
@ -1037,6 +994,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
RelocInfo::CODE_TARGET);
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
@ -2011,17 +1969,6 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
__ lb(scratch1, MemOperand(at));
__ Branch(&done, ne, scratch1, Operand(zero_reg));
// Drop possible internal frame pushed for calling CallICStub.
// TODO(mythria): when we tail call the CallICStub, remove this.
{
Label no_internal_callic_frame;
__ lw(scratch3, MemOperand(fp, StandardFrameConstants::kMarkerOffset));
__ Branch(&no_internal_callic_frame, ne, scratch3,
Operand(Smi::FromInt(StackFrame::INTERNAL)));
__ lw(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ bind(&no_internal_callic_frame);
}
// Drop possible interpreter handler/stub frame.
{
Label no_interpreter_frame;

View File

@ -2181,7 +2181,6 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
// a0 - number of arguments - if argc_in_register() is true.
// a1 - function
// a3 - slot id
// a2 - vector
@ -2189,6 +2188,8 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, at);
__ Branch(miss, ne, a1, Operand(at));
__ li(a0, Operand(arg_count()));
// Increment the call count for monomorphic function calls.
__ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize);
__ lw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize));
@ -2197,32 +2198,20 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ mov(a2, t0);
__ mov(a3, a1);
if (argc_in_register()) {
// Pass a default ArgumentCountKey::Any since the argc is only available
// in a0. We do not have the actual count here.
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
} else {
// arg_count() is expected in a0 if the arg_count() >= 2
// (ArgumentCountKey::MORE_THAN_ONE).
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate(MacroAssembler* masm) {
// a0 - number of arguments - if argc_in_register() is true.
// a1 - function
// a3 - slot id (Smi)
// a2 - vector
Label extra_checks_or_miss, call, call_function;
if (!argc_in_register()) {
int argc = arg_count();
__ li(a0, argc);
}
int argc = arg_count();
ParameterCount actual(argc);
// The checks. First, does a1 match the recorded monomorphic target?
// The checks. First, does r1 match the recorded monomorphic target?
__ Lsa(t0, a2, a3, kPointerSizeLog2 - kSmiTagSize);
__ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize));
@ -2256,7 +2245,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ bind(&call_function);
__ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(),
tail_call_mode()),
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg));
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg),
USE_DELAY_SLOT);
__ li(a0, Operand(argc)); // In delay slot.
__ bind(&extra_checks_or_miss);
Label uninitialized, miss, not_allocation_site;
@ -2293,7 +2284,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ bind(&call);
__ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()),
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg));
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg),
USE_DELAY_SLOT);
__ li(a0, Operand(argc)); // In delay slot.
__ bind(&uninitialized);
@ -2327,11 +2320,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
CreateWeakCellStub create_stub(masm->isolate());
__ SmiTag(a0);
__ Push(a0, a1);
__ Push(a1);
__ CallStub(&create_stub);
__ Pop(a0, a1);
__ SmiUntag(a0);
__ Pop(a1);
}
__ Branch(&call_function);
@ -2348,19 +2339,14 @@ void CallICStub::Generate(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::INTERNAL);
__ SmiTag(a0);
// Push number of arguments, receiver, function and feedback info.
__ Push(a0, a1, a2, a3);
// Push the receiver and the function and feedback info.
__ Push(a1, a2, a3);
// Call the entry.
__ CallRuntime(Runtime::kCallIC_Miss);
// Move result to a1 and exit the internal frame.
__ mov(a1, v0);
// Restore a0.
__ Pop(a0);
__ SmiUntag(a0);
}

View File

@ -428,18 +428,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallICDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // argument count (not including receiver)
t0, // address of first argument
a1, // the target callable to be call
a3, // feedback vector slot id
a2 // type feedback vector
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -1077,58 +1077,6 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
__ Jump(ra);
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register limit, Register scratch) {
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ ld(scratch, MemOperand(index));
__ Daddu(index, index, Operand(-kPointerSize));
__ push(scratch);
__ bind(&loop_check);
__ Branch(&loop_header, gt, index, Operand(limit));
}
static void Generate_InterpreterComputeLastArgumentAddress(
MacroAssembler* masm, Register num_args, Register start_address,
Register output_reg) {
__ Daddu(output_reg, num_args, Operand(1)); // Add one for receiver.
__ dsll(output_reg, output_reg, kPointerSizeLog2);
__ Dsubu(output_reg, start_address, output_reg);
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallICImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
// ----------- S t a t e -------------
// -- a0 : the number of arguments (not including the receiver)
// -- a4 : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -- a1 : the target to call (can be any Object).
// -- a3 : feedback vector slot id
// -- a2 : type feedback vector
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Computes the address of last argument in a5.
Generate_InterpreterComputeLastArgumentAddress(masm, a0, a4, a5);
// Push the arguments.
Generate_InterpreterPushArgs(masm, a4, a5, at);
// Call via the CallIC stub.
CallICState call_ic_state(0, ConvertReceiverMode::kAny, tail_call_mode,
true);
CallICStub stub(masm->isolate(), call_ic_state);
// TODO(mythria): This should be replaced by a TailCallStub, when we
// update the code to find the target IC from jump instructions.
__ CallStub(&stub);
}
__ Ret();
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
@ -1141,11 +1089,20 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
// -- a1 : the target to call (can be any Object).
// -----------------------------------
// Computes the address of last argument in a3.
Generate_InterpreterComputeLastArgumentAddress(masm, a0, a2, a3);
// Find the address of the last argument.
__ Daddu(a3, a0, Operand(1)); // Add one for receiver.
__ dsll(a3, a3, kPointerSizeLog2);
__ Dsubu(a3, a2, Operand(a3));
// Push the arguments.
Generate_InterpreterPushArgs(masm, a2, a3, at);
Label loop_header, loop_check;
__ Branch(&loop_check);
__ bind(&loop_header);
__ ld(t0, MemOperand(a2));
__ Daddu(a2, a2, Operand(-kPointerSize));
__ push(t0);
__ bind(&loop_check);
__ Branch(&loop_header, gt, a2, Operand(a3));
// Call the target.
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
@ -2131,17 +2088,6 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
__ lb(scratch1, MemOperand(at));
__ Branch(&done, ne, scratch1, Operand(zero_reg));
// Drop possible internal frame pushed for calling CallICStub.
// TODO(mythria): when we tail call the CallICStub, remove this.
{
Label no_internal_callic_frame;
__ ld(scratch3, MemOperand(fp, StandardFrameConstants::kMarkerOffset));
__ Branch(&no_internal_callic_frame, ne, scratch3,
Operand(Smi::FromInt(StackFrame::INTERNAL)));
__ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ bind(&no_internal_callic_frame);
}
// Drop possible interpreter handler/stub frame.
{
Label no_interpreter_frame;

View File

@ -2224,7 +2224,6 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
// a0 - number of arguments - if argc_in_register() is true.
// a1 - function
// a3 - slot id
// a2 - vector
@ -2232,42 +2231,32 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, at);
__ Branch(miss, ne, a1, Operand(at));
__ li(a0, Operand(arg_count()));
// Increment the call count for monomorphic function calls.
__ dsrl(a5, a3, kSmiShiftSize + 1 - kPointerSizeLog2);
__ Daddu(a3, a2, Operand(a5));
__ ld(a5, FieldMemOperand(a3, FixedArray::kHeaderSize + kPointerSize));
__ Daddu(a5, a5, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement)));
__ sd(a5, FieldMemOperand(a3, FixedArray::kHeaderSize + kPointerSize));
__ dsrl(t0, a3, 32 - kPointerSizeLog2);
__ Daddu(a3, a2, Operand(t0));
__ ld(t0, FieldMemOperand(a3, FixedArray::kHeaderSize + kPointerSize));
__ Daddu(t0, t0, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement)));
__ sd(t0, FieldMemOperand(a3, FixedArray::kHeaderSize + kPointerSize));
__ mov(a2, a4);
__ mov(a3, a1);
if (argc_in_register()) {
// Pass a default ArgumentCountKey::Any since the argc is only available
// in a0. We do not have the actual count here.
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
} else {
// arg_count() is expected in a0 if the arg_count() >= 2
// (ArgumentCountKey::MORE_THAN_ONE).
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate(MacroAssembler* masm) {
// a0 - number of arguments - if argc_in_register() is true.
// a1 - function
// a3 - slot id (Smi)
// a2 - vector
Label extra_checks_or_miss, call, call_function;
if (!argc_in_register()) {
int argc = arg_count();
__ li(a0, argc);
}
int argc = arg_count();
ParameterCount actual(argc);
// The checks. First, does a1 match the recorded monomorphic target?
__ dsrl(a4, a3, kSmiShiftSize + 1 - kPointerSizeLog2);
// The checks. First, does r1 match the recorded monomorphic target?
__ dsrl(a4, a3, 32 - kPointerSizeLog2);
__ Daddu(a4, a2, Operand(a4));
__ ld(a4, FieldMemOperand(a4, FixedArray::kHeaderSize));
@ -2302,7 +2291,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ bind(&call_function);
__ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(),
tail_call_mode()),
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg));
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg),
USE_DELAY_SLOT);
__ li(a0, Operand(argc)); // In delay slot.
__ bind(&extra_checks_or_miss);
Label uninitialized, miss, not_allocation_site;
@ -2340,7 +2331,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ bind(&call);
__ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()),
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg));
RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg),
USE_DELAY_SLOT);
__ li(a0, Operand(argc)); // In delay slot.
__ bind(&uninitialized);
@ -2375,11 +2368,9 @@ void CallICStub::Generate(MacroAssembler* masm) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
CreateWeakCellStub create_stub(masm->isolate());
__ SmiTag(a0);
__ Push(a0, a1);
__ Push(a1);
__ CallStub(&create_stub);
__ Pop(a0, a1);
__ SmiUntag(a0);
__ Pop(a1);
}
__ Branch(&call_function);
@ -2396,19 +2387,14 @@ void CallICStub::Generate(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::INTERNAL);
__ SmiTag(a0);
// Push number of arguments, receiver, function and feedback info.
__ Push(a0, a1, a2, a3);
// Push the receiver and the function and feedback info.
__ Push(a1, a2, a3);
// Call the entry.
__ CallRuntime(Runtime::kCallIC_Miss);
// Move result to a1 and exit the internal frame.
__ mov(a1, v0);
// Restore a0.
__ Pop(a0);
__ SmiUntag(a0);
}

View File

@ -428,18 +428,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallICDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // argument count (not including receiver)
a4, // address of first argument
a1, // the target callable to be call
a3, // feedback vector slot id
a2 // type feedback vector
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -639,38 +639,6 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallICImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
// ----------- S t a t e -------------
// -- rax : the number of arguments (not including the receiver)
// -- rbx : the address of the first argument to be pushed. Subsequent
// arguments should be consecutive above this, in the same order as
// they are to be pushed onto the stack.
// -- rdi : the target to call (can be any Object).
// -- rdx : Feedback vector slot-id.
// -- r9 : type feedback vector. // TODO(mythria): move to rbx to match
// CallICStub expectation.
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
Generate_InterpreterPushArgs(masm, true);
__ Move(rbx, r9);
// Call via the CallIC stub.
CallICState call_ic_state(0, ConvertReceiverMode::kAny, tail_call_mode,
true);
CallICStub stub(masm->isolate(), call_ic_state);
// TODO(mythria): This should be replaced by a TailCallStub, when we
// update the code to find the target IC from jump instructions.
__ CallStub(&stub);
}
__ Ret();
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
@ -694,6 +662,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
RelocInfo::CODE_TARGET);
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
@ -2104,17 +2073,6 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
__ cmpb(Operand(kScratchRegister, 0), Immediate(0));
__ j(not_equal, &done);
// Drop possible internal frame pushed for calling CallICStub.
// TODO(mythria): when we tail call the CallICStub, remove this.
{
Label no_internal_callic_frame;
__ Cmp(Operand(rbp, StandardFrameConstants::kMarkerOffset),
Smi::FromInt(StackFrame::INTERNAL));
__ j(not_equal, &no_internal_callic_frame, Label::kNear);
__ movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
__ bind(&no_internal_callic_frame);
}
// Drop possible interpreter handler/stub frame.
{
Label no_interpreter_frame;

View File

@ -1500,12 +1500,13 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
// rdi - function
// rdx - slot id
// rbx - vector
// rax - number of arguments if argc_in_register() is true.
// rcx - allocation site (loaded from vector[slot]).
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r8);
__ cmpp(rdi, r8);
__ j(not_equal, miss);
__ movp(rax, Immediate(arg_count()));
// Increment the call count for monomorphic function calls.
__ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size,
FixedArray::kHeaderSize + kPointerSize),
@ -1513,17 +1514,8 @@ void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
__ movp(rbx, rcx);
__ movp(rdx, rdi);
if (argc_in_register()) {
// Pass a default ArgumentCountKey::Any since the argc is only available
// in rax. We do not have the actual count here.
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
} else {
// arg_count() is expected in rax if the arg_count() >= 2
// (ArgumentCountKey::MORE_THAN_ONE).
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
@ -1532,14 +1524,12 @@ void CallICStub::Generate(MacroAssembler* masm) {
// -- rdi - function
// -- rdx - slot id
// -- rbx - vector
// -- rax - number of arguments if argc_in_register() is true.
// -----------------------------------
Isolate* isolate = masm->isolate();
Label extra_checks_or_miss, call, call_function;
if (!argc_in_register()) {
int argc = arg_count();
__ Set(rax, argc);
}
int argc = arg_count();
StackArgumentsAccessor args(rsp, argc);
ParameterCount actual(argc);
// The checks. First, does rdi match the recorded monomorphic target?
__ SmiToInteger32(rdx, rdx);
@ -1573,6 +1563,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
Smi::FromInt(CallICNexus::kCallCountIncrement));
__ bind(&call_function);
__ Set(rax, argc);
__ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(),
tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -1611,6 +1602,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
TypeFeedbackVector::MegamorphicSentinel(isolate));
__ bind(&call);
__ Set(rax, argc);
__ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()),
RelocInfo::CODE_TARGET);
@ -1648,16 +1640,10 @@ void CallICStub::Generate(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::INTERNAL);
CreateWeakCellStub create_stub(isolate);
__ Integer32ToSmi(rax, rax);
__ Push(rax);
__ Integer32ToSmi(rdx, rdx);
__ Push(rdi);
__ CallStub(&create_stub);
__ Pop(rdi);
__ Pop(rax);
__ SmiToInteger32(rax, rax);
}
__ jmp(&call_function);
@ -1677,10 +1663,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::INTERNAL);
// Store the number of arguments to be used later.
__ Integer32ToSmi(rax, rax);
__ Push(rax);
// Push the receiver and the function and feedback info.
__ Push(rdi);
__ Push(rbx);
@ -1692,10 +1674,6 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
// Move result to edi and exit the internal frame.
__ movp(rdi, rax);
// rdi, rbx, rdx are arguments to CallIC_Miss. They will be popped by
// Runtime_CallIC_Miss.
__ Pop(rax);
__ SmiToInteger32(rax, rax);
}

View File

@ -415,19 +415,6 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallICDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
rax, // argument count (not including receiver)
rbx, // address of first argument
rdi, // the target callable to be call
rdx, // slot id
r9, // type feedback vector // TODO(mythria): move to rbx to match
// CallICStub.
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -563,18 +563,6 @@
'test-run-jsexceptions/ThrowMessagePosition': [FAIL],
'test-api/TryCatchMixedNesting': [FAIL],
# TODO(4680): Related to lack of code-ageing in interpreter.
'test-heap/Regress169209': [FAIL],
# TODO(4680): Related to lack of code-ageing and/or lack of compilation cache
# in interpreter.
'test-heap/CompilationCacheCachingBehavior': [FAIL],
# TODO(4680): Use CallConstructStub for new operator.
'test-heap/IncrementalMarkingPreservesMonomorphicConstructor': [FAIL],
'test-heap/IncrementalMarkingClearsMonomorphicConstructor': [FAIL],
'test-heap/WeakFunctionInConstructor': [FAIL],
# TODO(rmcilroy,4680): Test assert errors.
'test-cpu-profiler/CodeEvents': [FAIL],
'test-cpu-profiler/TickEvents': [FAIL],
@ -599,8 +587,17 @@
'test-profile-generator/LineNumber': [FAIL],
'test-profile-generator/ProfileNodeScriptId': [FAIL],
'test-profile-generator/RecordStackTraceAtStartProfiling': [FAIL],
'test-feedback-vector/VectorCallICStates': [FAIL],
'test-compiler/FeedbackVectorPreservedAcrossRecompiles': [FAIL],
'test-api/PromiseRejectCallback': [FAIL],
'test-api/SetJitCodeEventHandler': [FAIL],
'test-heap/WeakFunctionInConstructor': [FAIL],
'test-heap/Regress169209': [FAIL],
'test-heap/IncrementalMarkingClearsMonomorphicConstructor': [FAIL],
'test-heap/IncrementalMarkingPreservesMonomorphicConstructor': [FAIL],
'test-heap/IncrementalMarkingPreservesMonomorphicCallIC': [FAIL],
'test-heap/CompilationCacheCachingBehavior': [FAIL],
'test-heap/CellsInOptimizedCodeAreWeak': [FAIL],
'test-run-inlining/InlineTwice': [FAIL],
'test-serialize/SerializeInternalReference': [FAIL, ['arch == arm or arch == arm64', PASS]],
}], # ignition == True

View File

@ -136,9 +136,6 @@ class BytecodeGraphTester {
compilation_info.MarkAsDeoptimizationEnabled();
compiler::Pipeline pipeline(&compilation_info);
Handle<Code> code = pipeline.GenerateCode();
// We do not actually record weak dependencies between objects and
// code objects. We just clear the dependencies for now.
compilation_info.dependencies()->Commit(compilation_info.code());
function->ReplaceCode(*code);
return function;

View File

@ -1512,7 +1512,7 @@ TEST(PropertyCall) {
B(Star), R(1), //
B(LoadIC), R(1), U8(0), U8(vector->GetIndex(slot2)), //
B(Star), R(0), //
B(CallIC), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)), //
B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)), //
B(Return), //
},
1,
@ -1531,7 +1531,7 @@ TEST(PropertyCall) {
B(Star), R(2), //
B(Ldar), A(3, 4), //
B(Star), R(3), //
B(CallIC), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)), //
B(Call), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)), //
B(Return) //
},
1,
@ -1553,7 +1553,7 @@ TEST(PropertyCall) {
B(Star), R(2), //
B(Ldar), A(2, 3), //
B(Star), R(3), //
B(CallIC), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)), //
B(Call), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)), //
B(Return), //
},
1,
@ -1577,7 +1577,7 @@ TEST(PropertyCall) {
B(Star), R(1), //
B(LoadICWide), R(1), U16(0), U16(wide_idx + 4), //
B(Star), R(0), //
B(CallICWide), R16(0), R16(1), U16(1), U16(wide_idx + 2), //
B(CallWide), R16(0), R16(1), U16(1), U16(wide_idx + 2), //
B(Return), //
},
1,
@ -1826,13 +1826,13 @@ TEST(CallGlobal) {
1,
15,
{
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), //
B(Star), R(0), //
B(CallIC), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)), //
B(Return) //
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), //
B(Star), R(0), //
B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)), //
B(Return) //
},
1,
{"t"}},
@ -1841,19 +1841,19 @@ TEST(CallGlobal) {
1,
27,
{
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), //
B(Star), R(0), //
B(LdaSmi8), U8(1), //
B(Star), R(2), //
B(LdaSmi8), U8(2), //
B(Star), R(3), //
B(LdaSmi8), U8(3), //
B(Star), R(4), //
B(CallIC), R(0), R(1), U8(4), U8(vector->GetIndex(slot1)), //
B(Return) //
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(LdaGlobal), U8(0), U8(vector->GetIndex(slot2)), //
B(Star), R(0), //
B(LdaSmi8), U8(1), //
B(Star), R(2), //
B(LdaSmi8), U8(2), //
B(Star), R(3), //
B(LdaSmi8), U8(3), //
B(Star), R(4), //
B(Call), R(0), R(1), U8(4), U8(vector->GetIndex(slot1)), //
B(Return) //
},
1,
{"t"}},
@ -2300,7 +2300,7 @@ TEST(DeclareGlobals) {
B(Star), R(2), //
B(LdaGlobal), U8(1), U8(load_vector->GetIndex(load_slot_1)), //
B(Star), R(1), //
B(CallIC), R(1), R(2), U8(1), //
B(Call), R(1), R(2), U8(1), //
/* */ U8(load_vector->GetIndex(call_slot_1)), //
B(Star), R(0), //
B(Return) //
@ -3774,13 +3774,13 @@ TEST(FunctionLiterals) {
1,
15,
{
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(0), //
B(CallIC), R(0), R(1), U8(1), U8(vector->GetIndex(slot)), //
B(Return) //
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(0), //
B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot)), //
B(Return) //
},
1,
{InstanceType::SHARED_FUNCTION_INFO_TYPE}},
@ -3789,15 +3789,15 @@ TEST(FunctionLiterals) {
1,
19,
{
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(0), //
B(LdaSmi8), U8(1), //
B(Star), R(2), //
B(CallIC), R(0), R(1), U8(2), U8(vector->GetIndex(slot)), //
B(Return) //
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(0), //
B(LdaSmi8), U8(1), //
B(Star), R(2), //
B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot)), //
B(Return) //
},
1,
{InstanceType::SHARED_FUNCTION_INFO_TYPE}},
@ -3861,7 +3861,7 @@ TEST(RegExpLiterals) {
B(Star), R(0), //
B(LdaConstant), U8(2), //
B(Star), R(2), //
B(CallIC), R(0), R(1), U8(2), U8(vector->GetIndex(slot1)), //
B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot1)), //
B(Return), //
},
3,
@ -5036,17 +5036,17 @@ TEST(ContextVariables) {
1,
25,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), //
/* */ R(closure), U8(1), //
B(PushContext), R(0), //
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(2), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(1), //
B(CallIC), R(1), R(2), U8(1), U8(vector->GetIndex(slot)), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Return), //
B(CallRuntime), U16(Runtime::kNewFunctionContext), //
/* */ R(closure), U8(1), //
B(PushContext), R(0), //
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(2), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(1), U8(vector->GetIndex(slot)), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Return), //
},
1,
{InstanceType::SHARED_FUNCTION_INFO_TYPE}},
@ -5087,7 +5087,7 @@ TEST(ContextVariables) {
"return b",
3 * kPointerSize,
1,
1041,
1042,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
/* */ U8(1), //
@ -5104,9 +5104,9 @@ TEST(ContextVariables) {
B(StaContextSlot), R(context), U8(wide_slot++)), //
B(LdaUndefined), //
B(Star), R(2), //
B(LdaGlobal), U8(0), U8(1), //
B(LdaGlobal), U8(0), U8(1), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(1), //
B(Call), R(1), R(2), U8(1), U8(0), //
B(LdaSmi8), U8(100), //
B(StaContextSlotWide), R(context), U16(256), //
B(LdaContextSlotWide), R(context), U16(256), //
@ -6324,13 +6324,13 @@ DISABLED_TEST(ForOf) {
B(LdaConstant), U8(1), //
B(KeyedLoadIC), R(5), U8(vector->GetIndex(slot2)), //
B(Star), R(4), //
B(CallIC), R(4), R(5), U8(1), U8(vector->GetIndex(slot1)), //
B(Call), R(4), R(5), U8(1), U8(vector->GetIndex(slot1)), //
B(Star), R(1), //
B(Ldar), R(1), //
B(Star), R(6), //
B(LoadIC), R(6), U8(2), U8(vector->GetIndex(slot4)), //
B(Star), R(5), //
B(CallIC), R(5), R(6), U8(1), U8(vector->GetIndex(slot3)), //
B(Call), R(5), R(6), U8(1), U8(vector->GetIndex(slot3)), //
B(Star), R(2), //
B(Star), R(4), //
B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(4), U8(1), //
@ -6373,13 +6373,13 @@ DISABLED_TEST(ForOf) {
B(LdaConstant), U8(1), //
B(KeyedLoadIC), R(6), U8(vector->GetIndex(slot2)), //
B(Star), R(5), //
B(CallIC), R(5), R(6), U8(1), U8(vector->GetIndex(slot1)), //
B(Call), R(5), R(6), U8(1), U8(vector->GetIndex(slot1)), //
B(Star), R(1), //
B(Ldar), R(1), //
B(Star), R(7), //
B(LoadIC), R(7), U8(2), U8(vector->GetIndex(slot4)), //
B(Star), R(6), //
B(CallIC), R(6), R(7), U8(1), U8(vector->GetIndex(slot3)), //
B(Call), R(6), R(7), U8(1), U8(vector->GetIndex(slot3)), //
B(Star), R(2), //
B(Star), R(5), //
B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(5), U8(1), //
@ -6424,13 +6424,13 @@ DISABLED_TEST(ForOf) {
B(LdaConstant), U8(1), //
B(KeyedLoadIC), R(5), U8(vector->GetIndex(slot2)), //
B(Star), R(4), //
B(CallIC), R(4), R(5), U8(1), U8(vector->GetIndex(slot1)), //
B(Call), R(4), R(5), U8(1), U8(vector->GetIndex(slot1)), //
B(Star), R(1), //
B(Ldar), R(1), //
B(Star), R(6), //
B(LoadIC), R(6), U8(2), U8(vector->GetIndex(slot4)), //
B(Star), R(5), //
B(CallIC), R(5), R(6), U8(1), U8(vector->GetIndex(slot3)), //
B(Call), R(5), R(6), U8(1), U8(vector->GetIndex(slot3)), //
B(Star), R(2), //
B(Star), R(4), //
B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(4), U8(1), //
@ -6486,13 +6486,13 @@ DISABLED_TEST(ForOf) {
B(LdaConstant), U8(2), //
B(KeyedLoadIC), R(4), U8(vector->GetIndex(slot2)), //
B(Star), R(3), //
B(CallIC), R(3), R(4), U8(1), U8(vector->GetIndex(slot1)), //
B(Call), R(3), R(4), U8(1), U8(vector->GetIndex(slot1)), //
B(Star), R(0), //
B(Ldar), R(0), //
B(Star), R(5), //
B(LoadIC), R(5), U8(3), U8(vector->GetIndex(slot4)), //
B(Star), R(4), //
B(CallIC), R(4), R(5), U8(1), U8(vector->GetIndex(slot3)), //
B(Call), R(4), R(5), U8(1), U8(vector->GetIndex(slot3)), //
B(Star), R(1), //
B(Star), R(3), //
B(CallRuntime), U16(Runtime::kInlineIsJSReceiver), R(3), U8(1), //
@ -7440,7 +7440,7 @@ TEST(Eval) {
{"return eval('1;');",
9 * kPointerSize,
1,
64,
65,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
/* */ U8(1), //
@ -7468,7 +7468,7 @@ TEST(Eval) {
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
/* */ U8(5), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(2), //
B(Call), R(1), R(2), U8(2), U8(0), //
B(Return), //
},
2,
@ -7498,7 +7498,7 @@ TEST(LookupSlot) {
{"eval('var x = 10;'); return x;",
9 * kPointerSize,
1,
66,
67,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
/* */ U8(1), //
@ -7526,7 +7526,7 @@ TEST(LookupSlot) {
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
U8(5), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(2), //
B(Call), R(1), R(2), U8(2), U8(0), //
B(LdaLookupSlot), U8(2), //
B(Return), //
},
@ -7535,7 +7535,7 @@ TEST(LookupSlot) {
{"eval('var x = 10;'); return typeof x;",
9 * kPointerSize,
1,
67,
68,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
/* */ U8(1), //
@ -7563,7 +7563,7 @@ TEST(LookupSlot) {
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
/* */ U8(5), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(2), //
B(Call), R(1), R(2), U8(2), U8(0), //
B(LdaLookupSlotInsideTypeof), U8(2), //
B(TypeOf), //
B(Return), //
@ -7573,7 +7573,7 @@ TEST(LookupSlot) {
{"x = 20; return eval('');",
9 * kPointerSize,
1,
68,
69,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
U8(1), //
@ -7603,7 +7603,7 @@ TEST(LookupSlot) {
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
/* */ U8(5), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(2), //
B(Call), R(1), R(2), U8(2), U8(0), //
B(Return), //
},
3,
@ -7641,7 +7641,7 @@ TEST(CallLookupSlot) {
{"g = function(){}; eval(''); return g();",
9 * kPointerSize,
1,
84,
85,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
/* */ U8(1), //
@ -7671,12 +7671,12 @@ TEST(CallLookupSlot) {
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
U8(5), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(2), //
B(Call), R(1), R(2), U8(2), U8(0), //
B(LdaConstant), U8(1), //
B(Star), R(3), //
B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlotForCall), //
R(3), U8(1), R(1), //
B(CallIC), R(1), R(2), U8(1), U8(vector->GetIndex(slot2)), //
B(Call), R(1), R(2), U8(1), U8(vector->GetIndex(slot2)), //
B(Return), //
},
4,
@ -9069,7 +9069,7 @@ TEST(ClassDeclarations) {
B(Star), R(6), //
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), //
B(Star), R(3), //
B(LoadIC), R(3), U8(1), U8(1), //
B(LoadIC), R(3), U8(1), U8(1), //
B(Star), R(4), //
B(CallRuntime), U16(Runtime::kFinalizeClassDefinition), R(3), U8(2), //
B(Star), R(0), //
@ -9096,113 +9096,6 @@ TEST(ClassDeclarations) {
}
}
TEST(TailCall) {
bool old_tailcall_flag = FLAG_harmony_tailcalls;
FLAG_harmony_tailcalls = true;
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int new_target = Register::new_target().index();
// clang-format off
ExpectedSnippet<const char*> snippets[] = {
{"function g() { throw new Error('foo'); };"
"var eval = g;"
"function f() {"
" 'use strict';"
" return eval('g()');"
"}",
9 * kPointerSize,
1,
63,
{
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
U8(1), //
B(PushContext), R(0), //
B(Ldar), THIS(1), //
B(StaContextSlot), R(context), U8(4), //
B(CreateUnmappedArguments), //
B(StaContextSlot), R(context), U8(5), //
B(Ldar), R(new_target), //
B(StaContextSlot), R(context), U8(6), //
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(2), //
B(LdaGlobal), U8(0), U8(1), //
B(Star), R(1), //
B(LdaConstant), U8(1), //
B(Star), R(3), //
B(Mov), R(1), R(4), //
B(Mov), R(3), R(5), //
B(Mov), R(closure), R(6), //
B(LdaSmi8), U8(1), //
B(Star), R(7), //
B(LdaSmi8), U8(64), //
B(Star), R(8), //
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
U8(5), //
B(Star), R(1), //
B(TailCall), R(1), R(2), U8(2), //
B(Return), //
},
2,
{"eval",
"g()"}}
};
// clang-format on
for (size_t i = 0; i < arraysize(snippets); i++) {
Handle<BytecodeArray> bytecode_array =
helper.MakeBytecodeForFunction(snippets[i].code_snippet);
CheckBytecodeArrayEqual(snippets[i], bytecode_array);
}
FLAG_harmony_tailcalls = old_tailcall_flag;
}
TEST(TailCallIC) {
bool old_tailcall_flag = FLAG_harmony_tailcalls;
FLAG_harmony_tailcalls = true;
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
// clang-format off
ExpectedSnippet<const char*> snippets[] = {
{"function g() { return 0; };"
"function f() {"
" 'use strict';"
" return g();"
"}",
2 * kPointerSize,
1,
15,
{
B(StackCheck), //
B(LdaUndefined), //
B(Star), R(1), //
B(LdaGlobal), U8(0), U8(3), //
B(Star), R(0), //
B(TailCallIC), R(0), R(1), U8(1), U8(1), //
B(Return),
},
1,
{"g"}}
};
// clang-format on
for (size_t i = 0; i < arraysize(snippets); i++) {
Handle<BytecodeArray> bytecode_array =
helper.MakeBytecodeForFunction(snippets[i].code_snippet);
CheckBytecodeArrayEqual(snippets[i], bytecode_array);
}
FLAG_harmony_tailcalls = old_tailcall_flag;
}
// TODO(oth): Add tests for super keyword.
} // namespace interpreter

View File

@ -928,8 +928,7 @@ TEST(InterpreterStoreKeyedProperty) {
CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
}
static void TestInterpreterCall(TailCallMode tail_call_mode,
bool has_feedback_slot) {
static void TestInterpreterCall(TailCallMode tail_call_mode) {
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
i::Factory* factory = isolate->factory();
@ -937,15 +936,10 @@ static void TestInterpreterCall(TailCallMode tail_call_mode,
i::FeedbackVectorSpec feedback_spec(&zone);
i::FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
i::FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot();
Handle<i::TypeFeedbackVector> vector =
i::NewTypeFeedbackVector(isolate, &feedback_spec);
int slot_index = vector->GetIndex(slot);
int call_slot_index = -1;
if (has_feedback_slot) {
call_slot_index = vector->GetIndex(call_slot);
}
Handle<i::String> name = factory->NewStringFromAsciiChecked("func");
name = factory->string_table()->LookupString(isolate, name);
@ -955,16 +949,9 @@ static void TestInterpreterCall(TailCallMode tail_call_mode,
BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
0, 1);
builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
.StoreAccumulatorInRegister(Register(0));
if (has_feedback_slot) {
builder.CallIC(Register(0), builder.Parameter(0), 1, call_slot_index,
tail_call_mode);
} else {
builder.Call(Register(0), builder.Parameter(0), 1, tail_call_mode);
}
builder.Return();
.StoreAccumulatorInRegister(Register(0))
.Call(Register(0), builder.Parameter(0), 1, 0, tail_call_mode)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
@ -981,14 +968,9 @@ static void TestInterpreterCall(TailCallMode tail_call_mode,
BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
0, 1);
builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
.StoreAccumulatorInRegister(Register(0));
if (has_feedback_slot) {
builder.CallIC(Register(0), builder.Parameter(0), 1, call_slot_index,
tail_call_mode);
} else {
builder.Call(Register(0), builder.Parameter(0), 1, tail_call_mode);
}
builder.Return();
.StoreAccumulatorInRegister(Register(0))
.Call(Register(0), builder.Parameter(0), 1, 0, tail_call_mode)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
@ -1014,17 +996,9 @@ static void TestInterpreterCall(TailCallMode tail_call_mode,
.LoadLiteral(Smi::FromInt(51))
.StoreAccumulatorInRegister(Register(2))
.LoadLiteral(Smi::FromInt(11))
.StoreAccumulatorInRegister(Register(3));
if (has_feedback_slot) {
builder.CallIC(Register(0), Register(1), 3, call_slot_index,
tail_call_mode);
} else {
builder.Call(Register(0), Register(1), 3, tail_call_mode);
}
builder.Return();
.StoreAccumulatorInRegister(Register(3))
.Call(Register(0), Register(1), 3, 0, tail_call_mode)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
@ -1065,17 +1039,9 @@ static void TestInterpreterCall(TailCallMode tail_call_mode,
.LoadLiteral(factory->NewStringFromAsciiChecked("i"))
.StoreAccumulatorInRegister(Register(10))
.LoadLiteral(factory->NewStringFromAsciiChecked("j"))
.StoreAccumulatorInRegister(Register(11));
if (has_feedback_slot) {
builder.CallIC(Register(0), Register(1), 11, call_slot_index,
tail_call_mode);
} else {
builder.Call(Register(0), Register(1), 11, tail_call_mode);
}
builder.Return();
.StoreAccumulatorInRegister(Register(11))
.Call(Register(0), Register(1), 11, 0, tail_call_mode)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
@ -1095,13 +1061,9 @@ static void TestInterpreterCall(TailCallMode tail_call_mode,
}
}
TEST(InterpreterCall) { TestInterpreterCall(TailCallMode::kDisallow, false); }
TEST(InterpreterCall) { TestInterpreterCall(TailCallMode::kDisallow); }
TEST(InterpreterTailCall) { TestInterpreterCall(TailCallMode::kAllow, false); }
TEST(InterpreterCallIC) { TestInterpreterCall(TailCallMode::kDisallow, true); }
TEST(InterpreterTailCallIC) { TestInterpreterCall(TailCallMode::kAllow, true); }
TEST(InterpreterTailCall) { TestInterpreterCall(TailCallMode::kAllow); }
static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder& builder,
Register reg, int value,

View File

@ -918,12 +918,6 @@
'unicodelctest-no-optimization': [SKIP],
}], # ignition == True and (arch == arm or arch == arm64)
['ignition == True and arch == x64', {
# TODO(mythria,4680): Stack call size exceeds limit.
# Try to tail call CallICStub from PushArgsAndCallIC builtin.
'regress/regress-353551': [FAIL],
}], # ignition == True and arch == x64
##############################################################################
['gcov_coverage', {
# Tests taking too long.

View File

@ -94,14 +94,10 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.CreateObjectLiteral(factory->NewFixedArray(1), 0, 0);
// Call operations.
builder.Call(reg, other, 1)
.Call(reg, wide, 1)
.TailCall(reg, other, 1)
.TailCall(reg, wide, 1)
.CallIC(reg, other, 1, 0, TailCallMode::kDisallow)
.CallIC(reg, other, 1, 0, TailCallMode::kAllow)
.CallIC(reg, wide, 1, 0, TailCallMode::kDisallow)
.CallIC(reg, wide, 1, 0, TailCallMode::kAllow)
builder.Call(reg, other, 1, 0)
.Call(reg, wide, 1, 0)
.TailCall(reg, other, 1, 0)
.TailCall(reg, wide, 1, 0)
.CallRuntime(Runtime::kIsArray, reg, 1)
.CallRuntime(Runtime::kIsArray, wide, 1)
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg, 1, other)