Refactor CallICStub to use a different stub for each customization.

This gives us much more room to customize on different functions, by
using MajorKey to differentiate them.

R=verwaest@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21564 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1084ead1
......@@ -3066,13 +3066,18 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
}
void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// r1 - function
// r2 - feedback vector
// r3 - slot id
Label miss;
int argc = state_.arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, r2);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4);
__ cmp(r1, r4);
__ b(ne, miss);
__ b(ne, &miss);
__ mov(r0, Operand(arg_count()));
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
......@@ -3081,24 +3086,9 @@ void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
__ AssertUndefinedOrAllocationSite(r2, r4);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
// r1 - function
// r2 - feedback vector
// r3 - slot id
Label miss;
if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
Generate_MonomorphicArray(masm, &miss);
} else {
// So far there is only one customer for our custom feedback scheme.
UNREACHABLE();
}
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Customization_Miss);
// The slow case, we need this no matter what to complete a call after a miss.
CallFunctionNoFeedback(masm,
......@@ -3122,11 +3112,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, r2);
if (state_.stub_type() != CallIC::DEFAULT) {
Generate_CustomFeedbackCall(masm);
return;
}
// The checks. First, does r1 match the recorded monomorphic target?
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
__ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
......@@ -3174,7 +3159,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
// We are here because tracing is on or we are going monomorphic.
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Miss);
// the slow case
__ bind(&slow_start);
......@@ -3189,7 +3174,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
}
void CallICStub::GenerateMiss(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
// Get the receiver of the function from the stack; 1 ~ return address.
__ ldr(r4, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize));
......@@ -3200,7 +3185,7 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
__ Push(r4, r1, r2, r3);
// Call the entry.
ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
ExternalReference miss = ExternalReference(IC_Utility(id),
masm->isolate());
__ CallExternalReference(miss, 4);
......
......@@ -3360,18 +3360,20 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
}
void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// x1 - function
// x2 - feedback vector
// x3 - slot id
Label miss;
Register function = x1;
Register feedback_vector = x2;
Register index = x3;
Register scratch = x4;
EmitLoadTypeFeedbackVector(masm, feedback_vector);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, scratch);
__ Cmp(function, scratch);
__ B(ne, miss);
__ B(ne, &miss);
Register allocation_site = feedback_vector;
__ Mov(x0, Operand(arg_count()));
......@@ -3384,24 +3386,9 @@ void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
__ AssertUndefinedOrAllocationSite(allocation_site, scratch);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
// x1 - function
// x2 - feedback vector
// x3 - slot id
Label miss;
if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
Generate_MonomorphicArray(masm, &miss);
} else {
// So far there is only one customer for our custom feedback scheme.
UNREACHABLE();
}
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Customization_Miss);
// The slow case, we need this no matter what to complete a call after a miss.
CallFunctionNoFeedback(masm,
......@@ -3431,11 +3418,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, feedback_vector);
if (state_.stub_type() != CallIC::DEFAULT) {
Generate_CustomFeedbackCall(masm);
return;
}
// The checks. First, does x1 match the recorded monomorphic target?
__ Add(x4, feedback_vector,
Operand::UntagSmiAndScale(index, kPointerSizeLog2));
......@@ -3487,7 +3469,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
// We are here because tracing is on or we are going monomorphic.
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Miss);
// the slow case
__ bind(&slow_start);
......@@ -3501,7 +3483,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
}
void CallICStub::GenerateMiss(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
ASM_LOCATION("CallICStub[Miss]");
// Get the receiver of the function from the stack; 1 ~ return address.
......@@ -3514,7 +3496,7 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
__ Push(x4, x1, x2, x3);
// Call the entry.
ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
ExternalReference miss = ExternalReference(IC_Utility(id),
masm->isolate());
__ CallExternalReference(miss, 4);
......
......@@ -470,6 +470,12 @@ Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) {
}
void CallIC_ArrayStub::PrintState(StringStream* stream) {
state_.Print(stream);
stream->Add(" (Array)");
}
void CallICStub::PrintState(StringStream* stream) {
state_.Print(stream);
}
......
......@@ -30,6 +30,7 @@ namespace internal {
V(CompareNilIC) \
V(MathPow) \
V(CallIC) \
V(CallIC_Array) \
V(FunctionPrototype) \
V(RecordWrite) \
V(StoreBufferOverflow) \
......@@ -819,15 +820,26 @@ class CallICStub: public PlatformCodeStub {
virtual int MinorKey() { return GetExtraICState(); }
virtual void PrintState(StringStream* stream) V8_FINAL V8_OVERRIDE;
private:
virtual CodeStub::Major MajorKey() { return CallIC; }
// Code generation helpers.
void GenerateMiss(MacroAssembler* masm);
void Generate_CustomFeedbackCall(MacroAssembler* masm);
void Generate_MonomorphicArray(MacroAssembler* masm, Label* miss);
void GenerateMiss(MacroAssembler* masm, IC::UtilityId id);
const CallIC::State state_;
};
class CallIC_ArrayStub: public CallICStub {
public:
CallIC_ArrayStub(Isolate* isolate, const CallIC::State& state_in)
: CallICStub(isolate, state_in) {}
virtual void Generate(MacroAssembler* masm);
protected:
virtual void PrintState(StringStream* stream) V8_FINAL V8_OVERRIDE;
CallIC::State state_;
virtual CodeStub::Major MajorKey() { return CallIC_Array; }
};
......
......@@ -2470,13 +2470,18 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
}
void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// edi - function
// ebx - feedback vector
// edx - slot id
Label miss;
int argc = state_.arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, ebx);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
__ cmp(edi, ecx);
__ j(not_equal, miss);
__ j(not_equal, &miss);
__ mov(eax, arg_count());
__ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
......@@ -2485,24 +2490,9 @@ void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
__ AssertUndefinedOrAllocationSite(ebx);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
// edi - function
// ebx - feedback vector
// edx - slot id
Label miss;
if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
Generate_MonomorphicArray(masm, &miss);
} else {
// So far there is only one customer for our custom feedback scheme.
UNREACHABLE();
}
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Customization_Miss);
// The slow case, we need this no matter what to complete a call after a miss.
CallFunctionNoFeedback(masm,
......@@ -2527,11 +2517,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, ebx);
if (state_.stub_type() != CallIC::DEFAULT) {
Generate_CustomFeedbackCall(masm);
return;
}
// The checks. First, does edi match the recorded monomorphic target?
__ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize));
......@@ -2582,7 +2567,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
// We are here because tracing is on or we are going monomorphic.
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Miss);
// the slow case
__ bind(&slow_start);
......@@ -2600,7 +2585,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
}
void CallICStub::GenerateMiss(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
// Get the receiver of the function from the stack; 1 ~ return address.
__ mov(ecx, Operand(esp, (state_.arg_count() + 1) * kPointerSize));
......@@ -2614,7 +2599,7 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
__ push(edx);
// Call the entry.
ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
ExternalReference miss = ExternalReference(IC_Utility(id),
masm->isolate());
__ CallExternalReference(miss, 4);
......
......@@ -501,14 +501,6 @@ void CallIC::Clear(Isolate* isolate,
Code* target,
ConstantPoolArray* constant_pool) {
// Currently, CallIC doesn't have state changes.
if (target->ic_state() != v8::internal::MONOMORPHIC) return;
CallIC::State existing_state(target->extra_ic_state());
// Monomorphic array stubs don't need to be cleared because
// 1) the stub doesn't store information that should be cleared, and
// 2) the AllocationSite stored in the type feedback vector is immune
// from gc type feedback clearing.
ASSERT(existing_state.stub_type() == MONOMORPHIC_ARRAY);
}
......@@ -1351,7 +1343,7 @@ void CallIC::State::Print(StringStream* stream) const {
Handle<Code> CallIC::initialize_stub(Isolate* isolate,
int argc,
CallType call_type) {
CallICStub stub(isolate, State::DefaultCallState(argc, call_type));
CallICStub stub(isolate, State(argc, call_type));
Handle<Code> code = stub.GetCode();
return code;
}
......@@ -1825,16 +1817,14 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
CallIC::State::State(ExtraICState extra_ic_state)
: argc_(ArgcBits::decode(extra_ic_state)),
call_type_(CallTypeBits::decode(extra_ic_state)),
stub_type_(StubTypeBits::decode(extra_ic_state)) {
call_type_(CallTypeBits::decode(extra_ic_state)) {
}
ExtraICState CallIC::State::GetExtraICState() const {
ExtraICState extra_ic_state =
ArgcBits::encode(argc_) |
CallTypeBits::encode(call_type_) |
StubTypeBits::encode(stub_type_);
CallTypeBits::encode(call_type_);
return extra_ic_state;
}
......@@ -1853,8 +1843,7 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver,
// Alter the slot.
Handle<AllocationSite> new_site = isolate()->factory()->NewAllocationSite();
vector->set(slot->value(), *new_site);
State new_state = state.ToMonomorphicArrayCallState();
CallICStub stub(isolate(), new_state);
CallIC_ArrayStub stub(isolate(), state);
set_target(*stub.GetCode());
Handle<String> name;
if (array_function->shared()->name()->IsString()) {
......@@ -1869,6 +1858,23 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver,
}
void CallIC::PatchMegamorphic(Handle<FixedArray> vector,
Handle<Smi> slot) {
State state(target()->extra_ic_state());
// We are going generic.
vector->set(slot->value(),
*TypeFeedbackInfo::MegamorphicSentinel(isolate()),
SKIP_WRITE_BARRIER);
CallICStub stub(isolate(), state);
Handle<Code> code = stub.GetCode();
set_target(*code);
TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
}
void CallIC::HandleMiss(Handle<Object> receiver,
Handle<Object> function,
Handle<FixedArray> vector,
......@@ -1876,23 +1882,12 @@ void CallIC::HandleMiss(Handle<Object> receiver,
State state(target()->extra_ic_state());
Object* feedback = vector->get(slot->value());
if (feedback->IsJSFunction() || !function->IsJSFunction() ||
state.stub_type() != DEFAULT) {
if (feedback->IsJSFunction() || !function->IsJSFunction()) {
// We are going generic.
vector->set(slot->value(),
*TypeFeedbackInfo::MegamorphicSentinel(isolate()),
SKIP_WRITE_BARRIER);
State new_state = state.ToGenericState();
if (new_state != state) {
// Only happens when the array ic goes generic.
ASSERT(state.stub_type() == MONOMORPHIC_ARRAY &&
FLAG_use_ic);
CallICStub stub(isolate(), new_state);
Handle<Code> code = stub.GetCode();
set_target(*code);
}
TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
} else {
// If we came here feedback must be the uninitialized sentinel,
......@@ -1934,6 +1929,19 @@ RUNTIME_FUNCTION(CallIC_Miss) {
}
RUNTIME_FUNCTION(CallIC_Customization_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
// A miss on a custom call ic always results in going megamorphic.
CallIC ic(isolate);
Handle<Object> function = args.at<Object>(1);
Handle<FixedArray> vector = args.at<FixedArray>(2);
Handle<Smi> slot = args.at<Smi>(3);
ic.PatchMegamorphic(vector, slot);
return *function;
}
// Used from ic-<arch>.cc.
RUNTIME_FUNCTION(LoadIC_Miss) {
HandleScope scope(isolate);
......
......@@ -20,6 +20,7 @@ const int kMaxKeyedPolymorphism = 4;
ICU(LoadIC_Miss) \
ICU(KeyedLoadIC_Miss) \
ICU(CallIC_Miss) \
ICU(CallIC_Customization_Miss) \
ICU(StoreIC_Miss) \
ICU(StoreIC_ArrayLength) \
ICU(StoreIC_Slow) \
......@@ -333,34 +334,16 @@ class IC_Utility {
class CallIC: public IC {
public:
enum CallType { METHOD, FUNCTION };
enum StubType { DEFAULT, MONOMORPHIC_ARRAY };
class State V8_FINAL BASE_EMBEDDED {
public:
explicit State(ExtraICState extra_ic_state);
static State MonomorphicArrayCallState(int argc, CallType call_type) {
return State(argc, call_type, MONOMORPHIC_ARRAY);
State(int argc, CallType call_type)
: argc_(argc), call_type_(call_type) {
}
static State DefaultCallState(int argc, CallType call_type) {
return State(argc, call_type, DEFAULT);
}
// Transition from the current state to another.
State ToGenericState() const {
return DefaultCallState(arg_count(), call_type());
}
State ToMonomorphicArrayCallState() const {
return MonomorphicArrayCallState(arg_count(), call_type());
}
InlineCacheState GetICState() const {
return stub_type_ == CallIC::DEFAULT
? ::v8::internal::GENERIC
: ::v8::internal::MONOMORPHIC;
}
InlineCacheState GetICState() const { return ::v8::internal::GENERIC; }
ExtraICState GetExtraICState() const;
......@@ -369,43 +352,25 @@ class CallIC: public IC {
int arg_count() const { return argc_; }
CallType call_type() const { return call_type_; }
StubType stub_type() const { return stub_type_; }
bool CallAsMethod() const { return call_type_ == METHOD; }
void Print(StringStream* stream) const;
bool operator==(const State& other_state) const {
return (argc_ == other_state.argc_ &&
call_type_ == other_state.call_type_ &&
stub_type_ == other_state.stub_type_);
}
bool operator!=(const State& other_state) const {
return !(*this == other_state);
}
private:
State(int argc, CallType call_type, StubType stub_type)
: argc_(argc),
call_type_(call_type),
stub_type_(stub_type) {
}
class ArgcBits: public BitField<int, 0, Code::kArgumentsBits> {};
class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {};
class StubTypeBits:
public BitField<StubType, Code::kArgumentsBits + 1, 1> {}; // NOLINT
const int argc_;
const CallType call_type_;
const StubType stub_type_;
};
explicit CallIC(Isolate* isolate)
: IC(EXTRA_CALL_FRAME, isolate) {
}
void PatchMegamorphic(Handle<FixedArray> vector, Handle<Smi> slot);
void HandleMiss(Handle<Object> receiver,
Handle<Object> function,
Handle<FixedArray> vector,
......@@ -416,7 +381,7 @@ class CallIC: public IC {
Handle<Object> function,
Handle<FixedArray> vector,
Handle<Smi> slot,
const State& new_state);
const State& state);
// Code generator routines.
static Handle<Code> initialize_stub(Isolate* isolate,
......
......@@ -3227,12 +3227,15 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
}
void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// a1 - function
// a2 - feedback vector
// a3 - slot id
Label miss;
EmitLoadTypeFeedbackVector(masm, a2);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, at);
__ Branch(miss, ne, a1, Operand(at));
__ Branch(&miss, ne, a1, Operand(at));
__ li(a0, Operand(arg_count()));
__ sll(at, a3, kPointerSizeLog2 - kSmiTagSize);
......@@ -3242,24 +3245,9 @@ void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
__ AssertUndefinedOrAllocationSite(a2, at);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
// a1 - function
// a2 - feedback vector
// a3 - slot id
Label miss;
if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
Generate_MonomorphicArray(masm, &miss);
} else {
// So far there is only one customer for our custom feedback scheme.
UNREACHABLE();
}
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Customization_Miss);
// The slow case, we need this no matter what to complete a call after a miss.
CallFunctionNoFeedback(masm,
......@@ -3283,11 +3271,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, a2);
if (state_.stub_type() != CallIC::DEFAULT) {
Generate_CustomFeedbackCall(masm);
return;
}
// The checks. First, does r1 match the recorded monomorphic target?
__ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
__ Addu(t0, a2, Operand(t0));
......@@ -3336,7 +3319,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
// We are here because tracing is on or we are going monomorphic.
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Miss);
// the slow case
__ bind(&slow_start);
......@@ -3351,7 +3334,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
}
void CallICStub::GenerateMiss(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
// Get the receiver of the function from the stack; 1 ~ return address.
__ lw(t0, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize));
......@@ -3362,7 +3345,7 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
__ Push(t0, a1, a2, a3);
// Call the entry.
ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
ExternalReference miss = ExternalReference(IC_Utility(id),
masm->isolate());
__ CallExternalReference(miss, 4);
......
......@@ -2364,13 +2364,19 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
}
void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// rdi - function
// rbx - feedback vector
// rdx - slot id (as integer)
Label miss;
int argc = state_.arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, rbx);
__ SmiToInteger32(rdx, rdx);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx);
__ cmpq(rdi, rcx);
__ j(not_equal, miss);
__ j(not_equal, &miss);
__ movq(rax, Immediate(arg_count()));
__ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size,
......@@ -2380,26 +2386,9 @@ void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
__ AssertUndefinedOrAllocationSite(rbx);
ArrayConstructorStub stub(masm->isolate(), arg_count());
__ TailCallStub(&stub);
}
void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
// rdi - function
// rbx - feedback vector
// rdx - slot id
Label miss;
__ SmiToInteger32(rdx, rdx);
if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
Generate_MonomorphicArray(masm, &miss);
} else {
// So far there is only one customer for our custom feedback scheme.
UNREACHABLE();
}
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Customization_Miss);
// The slow case, we need this no matter what to complete a call after a miss.
CallFunctionNoFeedback(masm,
......@@ -2426,11 +2415,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, rbx);
if (state_.stub_type() != CallIC::DEFAULT) {
Generate_CustomFeedbackCall(masm);
return;
}
// The checks. First, does rdi match the recorded monomorphic target?
__ SmiToInteger32(rdx, rdx);
__ cmpq(rdi, FieldOperand(rbx, rdx, times_pointer_size,
......@@ -2482,7 +2466,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
// We are here because tracing is on or we are going monomorphic.
__ bind(&miss);
GenerateMiss(masm);
GenerateMiss(masm, IC::kCallIC_Miss);
// the slow case
__ bind(&slow_start);
......@@ -2498,7 +2482,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
}
void CallICStub::GenerateMiss(MacroAssembler* masm) {
void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
// Get the receiver of the function from the stack; 1 ~ return address.
__ movp(rcx, Operand(rsp, (state_.arg_count() + 1) * kPointerSize));
......@@ -2513,7 +2497,7 @@ void CallICStub::GenerateMiss(MacroAssembler* masm) {
__ Push(rdx);
// Call the entry.
ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
ExternalReference miss = ExternalReference(IC_Utility(id),
masm->isolate());
__ CallExternalReference(miss, 4);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment