Use a trampoline stub to load the type feedback vector for CallICs.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#26290}
This commit is contained in:
mvstanton 2015-01-27 03:23:51 -08:00 committed by Commit bot
parent 7f9b2fa699
commit 2a567faa3e
18 changed files with 188 additions and 26 deletions

View File

@ -2604,12 +2604,11 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// r1 - function
// r3 - slot id
// r2 - vector
Label miss;
int argc = arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, r2);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4);
__ cmp(r1, r4);
__ b(ne, &miss);
@ -2644,6 +2643,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
void CallICStub::Generate(MacroAssembler* masm) {
// r1 - function
// r3 - slot id (Smi)
// r2 - vector
const int with_types_offset =
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
const int generic_offset =
@ -2654,8 +2654,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
int argc = arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, r2);
// The checks. First, does r1 match the recorded monomorphic target?
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
__ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
@ -4252,6 +4250,20 @@ void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
}
void CallICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, r2);
CallICStub stub(isolate(), state());
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, r2);
CallIC_ArrayStub stub(isolate(), state());
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
ProfileEntryHookStub stub(masm->isolate());

View File

@ -3007,8 +3007,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = CallIC::initialize_stub(
isolate(), arg_count, call_type);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
// Don't assign a type feedback id to the IC, since type feedback is provided

View File

@ -125,6 +125,16 @@ void CallFunctionWithFeedbackDescriptor::Initialize(
}
void CallFunctionWithFeedbackAndVectorDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
Register registers[] = {cp, r1, r3, r2};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
Representation::Tagged()};
data->Initialize(arraysize(registers), registers, representations);
}
void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
// r0 : number of arguments
// r1 : the function to call

View File

@ -2983,14 +2983,13 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// x1 - function
// x3 - slot id
// x2 - vector
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);
@ -3029,6 +3028,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
// x1 - function
// x3 - slot id (Smi)
// x2 - vector
const int with_types_offset =
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
const int generic_offset =
@ -3044,8 +3044,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
Register index = x3;
Register type = x4;
EmitLoadTypeFeedbackVector(masm, feedback_vector);
// The checks. First, does x1 match the recorded monomorphic target?
__ Add(x4, feedback_vector,
Operand::UntagSmiAndScale(index, kPointerSizeLog2));
@ -4374,6 +4372,20 @@ void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
}
void CallICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, x2);
CallICStub stub(isolate(), state());
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, x2);
CallIC_ArrayStub stub(isolate(), state());
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
// The entry hook is a "BumpSystemStackPointer" instruction (sub), followed by
// a "Push lr" instruction, followed by a call.
static const unsigned int kProfileEntryHookCallSize =

View File

@ -2695,8 +2695,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = CallIC::initialize_stub(
isolate(), arg_count, call_type);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot()));
__ Peek(x1, (arg_count + 1) * kXRegSize);
// Don't assign a type feedback id to the IC, since type feedback is provided

View File

@ -152,6 +152,16 @@ void CallFunctionWithFeedbackDescriptor::Initialize(
}
void CallFunctionWithFeedbackAndVectorDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
Register registers[] = {cp, x1, x3, x2};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
Representation::Tagged()};
data->Initialize(arraysize(registers), registers, representations);
}
void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
// x0 : number of arguments
// x1 : the function to call

View File

@ -48,6 +48,23 @@ Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) {
}
// static
Callable CodeFactory::CallIC(Isolate* isolate, int argc,
CallICState::CallType call_type) {
return Callable(CallIC::initialize_stub(isolate, argc, call_type),
CallFunctionWithFeedbackDescriptor(isolate));
}
// static
Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc,
CallICState::CallType call_type) {
return Callable(
CallIC::initialize_stub_in_optimized_code(isolate, argc, call_type),
CallFunctionWithFeedbackAndVectorDescriptor(isolate));
}
// static
Callable CodeFactory::StoreIC(Isolate* isolate, StrictMode mode) {
return Callable(StoreIC::initialize_stub(isolate, mode),

View File

@ -36,6 +36,10 @@ class CodeFactory FINAL {
static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode);
static Callable KeyedLoadIC(Isolate* isolate);
static Callable KeyedLoadICInOptimizedCode(Isolate* isolate);
static Callable CallIC(Isolate* isolate, int argc,
CallICState::CallType call_type);
static Callable CallICInOptimizedCode(Isolate* isolate, int argc,
CallICState::CallType call_type);
static Callable StoreIC(Isolate* isolate, StrictMode mode);
static Callable KeyedStoreIC(Isolate* isolate, StrictMode mode);

View File

@ -39,6 +39,8 @@ namespace internal {
V(JSEntry) \
V(KeyedLoadICTrampoline) \
V(LoadICTrampoline) \
V(CallICTrampoline) \
V(CallIC_ArrayTrampoline) \
V(LoadIndexedInterceptor) \
V(LoadIndexedString) \
V(MathPow) \
@ -829,7 +831,7 @@ class CallICStub: public PlatformCodeStub {
private:
void PrintState(std::ostream& os) const OVERRIDE; // NOLINT
DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedbackAndVector);
DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub);
};
@ -1938,6 +1940,41 @@ class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
};
class CallICTrampolineStub : public PlatformCodeStub {
public:
CallICTrampolineStub(Isolate* isolate, const CallICState& state)
: PlatformCodeStub(isolate) {
minor_key_ = state.GetExtraICState();
}
Code::Kind GetCodeKind() const OVERRIDE { return Code::CALL_IC; }
InlineCacheState GetICState() const FINAL { return DEFAULT; }
ExtraICState GetExtraICState() const FINAL {
return static_cast<ExtraICState>(minor_key_);
}
protected:
CallICState state() const {
return CallICState(static_cast<ExtraICState>(minor_key_));
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
DEFINE_PLATFORM_CODE_STUB(CallICTrampoline, PlatformCodeStub);
};
class CallIC_ArrayTrampolineStub : public CallICTrampolineStub {
public:
CallIC_ArrayTrampolineStub(Isolate* isolate, const CallICState& state)
: CallICTrampolineStub(isolate, state) {}
private:
DEFINE_PLATFORM_CODE_STUB(CallIC_ArrayTrampoline, CallICTrampolineStub);
};
class MegamorphicLoadStub : public HydrogenCodeStub {
public:
MegamorphicLoadStub(Isolate* isolate, const LoadICState& state)

View File

@ -2192,12 +2192,11 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// edi - function
// edx - slot id
// ebx - vector
Label miss;
int argc = arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, ebx);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
__ cmp(edi, ecx);
__ j(not_equal, &miss);
@ -2233,6 +2232,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
void CallICStub::Generate(MacroAssembler* masm) {
// edi - function
// edx - slot id
// ebx - vector
Isolate* isolate = masm->isolate();
const int with_types_offset =
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
@ -2244,8 +2244,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
int argc = arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, ebx);
// The checks. First, does edi match the recorded monomorphic target?
__ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize));
@ -4337,6 +4335,20 @@ void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
}
void CallICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, ebx);
CallICStub stub(isolate(), state());
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
}
void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, ebx);
CallIC_ArrayStub stub(isolate(), state());
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
}
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
ProfileEntryHookStub stub(masm->isolate());

View File

@ -2905,8 +2905,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = CallIC::initialize_stub(
isolate(), arg_count, call_type);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot())));
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
// Don't assign a type feedback id to the IC, since type feedback is provided

View File

@ -128,6 +128,16 @@ void CallFunctionWithFeedbackDescriptor::Initialize(
}
void CallFunctionWithFeedbackAndVectorDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
Register registers[] = {esi, edi, edx, ebx};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
Representation::Tagged()};
data->Initialize(arraysize(registers), registers, representations);
}
void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
// eax : number of arguments
// ebx : feedback vector

View File

@ -1591,6 +1591,14 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
Handle<Code> CallIC::initialize_stub(Isolate* isolate, int argc,
CallICState::CallType call_type) {
CallICTrampolineStub stub(isolate, CallICState(argc, call_type));
Handle<Code> code = stub.GetCode();
return code;
}
Handle<Code> CallIC::initialize_stub_in_optimized_code(
Isolate* isolate, int argc, CallICState::CallType call_type) {
CallICStub stub(isolate, CallICState(argc, call_type));
Handle<Code> code = stub.GetCode();
return code;
@ -2136,7 +2144,7 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
CallICNexus* nexus = casted_nexus<CallICNexus>();
nexus->ConfigureMonomorphicArray();
CallIC_ArrayStub stub(isolate(), callic_state);
CallIC_ArrayTrampolineStub stub(isolate(), callic_state);
set_target(*stub.GetCode());
Handle<String> name;
if (array_function->shared()->name()->IsString()) {
@ -2159,7 +2167,7 @@ void CallIC::PatchMegamorphic(Handle<Object> function) {
CallICNexus* nexus = casted_nexus<CallICNexus>();
nexus->ConfigureGeneric();
CallICStub stub(isolate(), callic_state);
CallICTrampolineStub stub(isolate(), callic_state);
Handle<Code> code = stub.GetCode();
set_target(*code);

View File

@ -355,6 +355,8 @@ class CallIC : public IC {
// Code generator routines.
static Handle<Code> initialize_stub(Isolate* isolate, int argc,
CallICState::CallType call_type);
static Handle<Code> initialize_stub_in_optimized_code(
Isolate* isolate, int argc, CallICState::CallType call_type);
static void Clear(Isolate* isolate, Code* host, CallICNexus* nexus);
};

View File

@ -30,6 +30,7 @@ class PlatformInterfaceDescriptor;
V(CreateAllocationSite) \
V(CallFunction) \
V(CallFunctionWithFeedback) \
V(CallFunctionWithFeedbackAndVector) \
V(CallConstruct) \
V(RegExpConstructResult) \
V(TransitionElementsKind) \
@ -330,6 +331,14 @@ class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor {
};
class CallFunctionWithFeedbackAndVectorDescriptor
: public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(CallFunctionWithFeedbackAndVectorDescriptor,
CallInterfaceDescriptor)
};
class CallConstructDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)

View File

@ -2059,11 +2059,11 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
// rdi - function
// rdx - slot id (as integer)
// rbx - vector
Label miss;
int argc = arg_count();
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, rbx);
__ SmiToInteger32(rdx, rdx);
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx);
@ -2100,6 +2100,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
void CallICStub::Generate(MacroAssembler* masm) {
// rdi - function
// rdx - slot id
// rbx - vector
Isolate* isolate = masm->isolate();
const int with_types_offset =
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
@ -2112,8 +2113,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
StackArgumentsAccessor args(rsp, argc);
ParameterCount actual(argc);
EmitLoadTypeFeedbackVector(masm, rbx);
// The checks. First, does rdi match the recorded monomorphic target?
__ SmiToInteger32(rdx, rdx);
__ cmpp(rdi, FieldOperand(rbx, rdx, times_pointer_size,
@ -4266,6 +4265,20 @@ void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
}
void CallICTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, rbx);
CallICStub stub(isolate(), state());
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
}
void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) {
EmitLoadTypeFeedbackVector(masm, rbx);
CallIC_ArrayStub stub(isolate(), state());
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
}
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
ProfileEntryHookStub stub(masm->isolate());

View File

@ -2906,8 +2906,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = CallIC::initialize_stub(
isolate(), arg_count, call_type);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot()));
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
// Don't assign a type feedback id to the IC, since type feedback is provided

View File

@ -128,6 +128,16 @@ void CallFunctionWithFeedbackDescriptor::Initialize(
}
void CallFunctionWithFeedbackAndVectorDescriptor::Initialize(
CallInterfaceDescriptorData* data) {
Register registers[] = {rsi, rdi, rdx, rbx};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
Representation::Tagged()};
data->Initialize(arraysize(registers), registers, representations);
}
void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
// rax : number of arguments
// rbx : feedback vector