Commit 815eca57 authored by ishell's avatar ishell Committed by Commit bot

[ic] Extract load IC proto array handlers handling to a separate stub.

This is to fix the performance regression by avoiding creation of a frame
in LoadIC dispatcher caused by complicated logic of CSA::EmitLoadICProtoArrayCheck().

BUG=v8:5561, chromium:660795

Review-Url: https://codereview.chromium.org/2496333002
Cr-Commit-Position: refs/heads/master@{#40986}
parent fa567a49
...@@ -31,9 +31,9 @@ const Register LoadDescriptor::ReceiverRegister() { return r1; } ...@@ -31,9 +31,9 @@ const Register LoadDescriptor::ReceiverRegister() { return r1; }
const Register LoadDescriptor::NameRegister() { return r2; } const Register LoadDescriptor::NameRegister() { return r2; }
const Register LoadDescriptor::SlotRegister() { return r0; } const Register LoadDescriptor::SlotRegister() { return r0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r3; } const Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r4; }
const Register StoreDescriptor::ReceiverRegister() { return r1; } const Register StoreDescriptor::ReceiverRegister() { return r1; }
const Register StoreDescriptor::NameRegister() { return r2; } const Register StoreDescriptor::NameRegister() { return r2; }
......
...@@ -31,9 +31,9 @@ const Register LoadDescriptor::ReceiverRegister() { return x1; } ...@@ -31,9 +31,9 @@ const Register LoadDescriptor::ReceiverRegister() { return x1; }
const Register LoadDescriptor::NameRegister() { return x2; } const Register LoadDescriptor::NameRegister() { return x2; }
const Register LoadDescriptor::SlotRegister() { return x0; } const Register LoadDescriptor::SlotRegister() { return x0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return x3; } const Register LoadWithVectorDescriptor::VectorRegister() { return x3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return x4; }
const Register StoreDescriptor::ReceiverRegister() { return x1; } const Register StoreDescriptor::ReceiverRegister() { return x1; }
const Register StoreDescriptor::NameRegister() { return x2; } const Register StoreDescriptor::NameRegister() { return x2; }
......
...@@ -5715,12 +5715,38 @@ void CodeStubAssembler::HandleLoadICProtoHandler( ...@@ -5715,12 +5715,38 @@ void CodeStubAssembler::HandleLoadICProtoHandler(
Bind(&array_handler); Bind(&array_handler);
{ {
Node* handler_length = SmiUntag(maybe_holder_cell); typedef LoadICProtoArrayDescriptor Descriptor;
Node* holder = EmitLoadICProtoArrayCheck(p, handler, handler_length, LoadICProtoArrayStub stub(isolate());
handler_flags, miss); Node* target = HeapConstant(stub.GetCode());
var_holder->Bind(holder); TailCallStub(Descriptor(isolate()), target, p->context,
var_smi_handler->Bind(smi_handler); Arg(Descriptor::kReceiver, p->receiver),
Goto(if_smi_handler); Arg(Descriptor::kName, p->name),
Arg(Descriptor::kSlot, p->slot),
Arg(Descriptor::kVector, p->vector),
Arg(Descriptor::kHandler, handler));
}
}
void CodeStubAssembler::LoadICProtoArray(const LoadICParameters* p,
Node* handler) {
Label miss(this);
CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(handler)));
CSA_ASSERT(this, IsFixedArrayMap(LoadMap(handler)));
Node* smi_handler = LoadObjectField(handler, LoadHandler::kSmiHandlerOffset);
Node* handler_flags = SmiUntag(smi_handler);
Node* handler_length = LoadAndUntagFixedArrayBaseLength(handler);
Node* holder = EmitLoadICProtoArrayCheck(p, handler, handler_length,
handler_flags, &miss);
HandleLoadICSmiHandlerCase(p, holder, smi_handler, &miss, kOnlyProperties);
Bind(&miss);
{
TailCallRuntime(Runtime::kLoadIC_Miss, p->context, p->receiver, p->name,
p->slot, p->vector);
} }
} }
......
...@@ -999,6 +999,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -999,6 +999,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
ParameterMode mode, Label* bailout); ParameterMode mode, Label* bailout);
void LoadIC(const LoadICParameters* p); void LoadIC(const LoadICParameters* p);
void LoadICProtoArray(const LoadICParameters* p, compiler::Node* handler);
void LoadGlobalIC(const LoadICParameters* p); void LoadGlobalIC(const LoadICParameters* p);
void KeyedLoadIC(const LoadICParameters* p); void KeyedLoadIC(const LoadICParameters* p);
void KeyedLoadICGeneric(const LoadICParameters* p); void KeyedLoadICGeneric(const LoadICParameters* p);
......
...@@ -455,6 +455,21 @@ void LoadICStub::GenerateAssembly(CodeStubAssembler* assembler) const { ...@@ -455,6 +455,21 @@ void LoadICStub::GenerateAssembly(CodeStubAssembler* assembler) const {
assembler->LoadIC(&p); assembler->LoadIC(&p);
} }
void LoadICProtoArrayStub::GenerateAssembly(
CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
Node* receiver = assembler->Parameter(Descriptor::kReceiver);
Node* name = assembler->Parameter(Descriptor::kName);
Node* slot = assembler->Parameter(Descriptor::kSlot);
Node* vector = assembler->Parameter(Descriptor::kVector);
Node* handler = assembler->Parameter(Descriptor::kHandler);
Node* context = assembler->Parameter(Descriptor::kContext);
CodeStubAssembler::LoadICParameters p(context, receiver, name, slot, vector);
assembler->LoadICProtoArray(&p, handler);
}
void LoadGlobalICTrampolineStub::GenerateAssembly( void LoadGlobalICTrampolineStub::GenerateAssembly(
CodeStubAssembler* assembler) const { CodeStubAssembler* assembler) const {
typedef compiler::Node Node; typedef compiler::Node Node;
......
...@@ -121,6 +121,7 @@ class ObjectLiteral; ...@@ -121,6 +121,7 @@ class ObjectLiteral;
V(StringAdd) \ V(StringAdd) \
V(GetProperty) \ V(GetProperty) \
V(LoadIC) \ V(LoadIC) \
V(LoadICProtoArray) \
V(KeyedLoadICTF) \ V(KeyedLoadICTF) \
V(StoreFastElement) \ V(StoreFastElement) \
V(StoreField) \ V(StoreField) \
...@@ -2103,6 +2104,16 @@ class LoadICStub : public TurboFanCodeStub { ...@@ -2103,6 +2104,16 @@ class LoadICStub : public TurboFanCodeStub {
DEFINE_CODE_STUB(LoadIC, TurboFanCodeStub); DEFINE_CODE_STUB(LoadIC, TurboFanCodeStub);
}; };
class LoadICProtoArrayStub : public TurboFanCodeStub {
public:
explicit LoadICProtoArrayStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
void GenerateAssembly(CodeStubAssembler* assembler) const override;
DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadICProtoArray);
DEFINE_CODE_STUB(LoadICProtoArray, TurboFanCodeStub);
};
class LoadGlobalICStub : public TurboFanCodeStub { class LoadGlobalICStub : public TurboFanCodeStub {
public: public:
explicit LoadGlobalICStub(Isolate* isolate, const LoadGlobalICState& state) explicit LoadGlobalICStub(Isolate* isolate, const LoadGlobalICState& state)
......
...@@ -31,6 +31,7 @@ const Register LoadDescriptor::SlotRegister() { return eax; } ...@@ -31,6 +31,7 @@ const Register LoadDescriptor::SlotRegister() { return eax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; } const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return edi; }
const Register StoreDescriptor::ReceiverRegister() { return edx; } const Register StoreDescriptor::ReceiverRegister() { return edx; }
const Register StoreDescriptor::NameRegister() { return ecx; } const Register StoreDescriptor::NameRegister() { return ecx; }
......
...@@ -217,7 +217,6 @@ void LoadWithVectorDescriptor::InitializePlatformIndependent( ...@@ -217,7 +217,6 @@ void LoadWithVectorDescriptor::InitializePlatformIndependent(
machine_types); machine_types);
} }
void LoadWithVectorDescriptor::InitializePlatformSpecific( void LoadWithVectorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(), Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
...@@ -225,6 +224,24 @@ void LoadWithVectorDescriptor::InitializePlatformSpecific( ...@@ -225,6 +224,24 @@ void LoadWithVectorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void LoadICProtoArrayDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kReceiver, kName, kSlot, kVector, kHandler
MachineType machine_types[] = {
MachineType::AnyTagged(), MachineType::AnyTagged(),
MachineType::TaggedSigned(), MachineType::AnyTagged(),
MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void LoadICProtoArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
VectorRegister(), HandlerRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void StoreWithVectorDescriptor::InitializePlatformIndependent( void StoreWithVectorDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// kReceiver, kName, kValue, kSlot, kVector // kReceiver, kName, kValue, kSlot, kVector
......
...@@ -21,6 +21,7 @@ class PlatformInterfaceDescriptor; ...@@ -21,6 +21,7 @@ class PlatformInterfaceDescriptor;
V(ContextOnly) \ V(ContextOnly) \
V(Load) \ V(Load) \
V(LoadWithVector) \ V(LoadWithVector) \
V(LoadICProtoArray) \
V(LoadGlobal) \ V(LoadGlobal) \
V(LoadGlobalWithVector) \ V(LoadGlobalWithVector) \
V(Store) \ V(Store) \
...@@ -389,6 +390,15 @@ class LoadWithVectorDescriptor : public LoadDescriptor { ...@@ -389,6 +390,15 @@ class LoadWithVectorDescriptor : public LoadDescriptor {
static const Register VectorRegister(); static const Register VectorRegister();
}; };
class LoadICProtoArrayDescriptor : public LoadWithVectorDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector, kHandler)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadICProtoArrayDescriptor,
LoadWithVectorDescriptor)
static const Register HandlerRegister();
};
class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor { class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
public: public:
DEFINE_PARAMETERS(kSlot, kVector) DEFINE_PARAMETERS(kSlot, kVector)
......
...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return a1; } ...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return a1; }
const Register LoadDescriptor::NameRegister() { return a2; } const Register LoadDescriptor::NameRegister() { return a2; }
const Register LoadDescriptor::SlotRegister() { return a0; } const Register LoadDescriptor::SlotRegister() { return a0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return a3; } const Register LoadWithVectorDescriptor::VectorRegister() { return a3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return t0; }
const Register StoreDescriptor::ReceiverRegister() { return a1; } const Register StoreDescriptor::ReceiverRegister() { return a1; }
const Register StoreDescriptor::NameRegister() { return a2; } const Register StoreDescriptor::NameRegister() { return a2; }
......
...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return a1; } ...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return a1; }
const Register LoadDescriptor::NameRegister() { return a2; } const Register LoadDescriptor::NameRegister() { return a2; }
const Register LoadDescriptor::SlotRegister() { return a0; } const Register LoadDescriptor::SlotRegister() { return a0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return a3; } const Register LoadWithVectorDescriptor::VectorRegister() { return a3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return a4; }
const Register StoreDescriptor::ReceiverRegister() { return a1; } const Register StoreDescriptor::ReceiverRegister() { return a1; }
const Register StoreDescriptor::NameRegister() { return a2; } const Register StoreDescriptor::NameRegister() { return a2; }
......
...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return r4; } ...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return r4; }
const Register LoadDescriptor::NameRegister() { return r5; } const Register LoadDescriptor::NameRegister() { return r5; }
const Register LoadDescriptor::SlotRegister() { return r3; } const Register LoadDescriptor::SlotRegister() { return r3; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r6; } const Register LoadWithVectorDescriptor::VectorRegister() { return r6; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r7; }
const Register StoreDescriptor::ReceiverRegister() { return r4; } const Register StoreDescriptor::ReceiverRegister() { return r4; }
const Register StoreDescriptor::NameRegister() { return r5; } const Register StoreDescriptor::NameRegister() { return r5; }
......
...@@ -31,6 +31,8 @@ const Register LoadDescriptor::SlotRegister() { return r2; } ...@@ -31,6 +31,8 @@ const Register LoadDescriptor::SlotRegister() { return r2; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r5; } const Register LoadWithVectorDescriptor::VectorRegister() { return r5; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r6; }
const Register StoreDescriptor::ReceiverRegister() { return r3; } const Register StoreDescriptor::ReceiverRegister() { return r3; }
const Register StoreDescriptor::NameRegister() { return r4; } const Register StoreDescriptor::NameRegister() { return r4; }
const Register StoreDescriptor::ValueRegister() { return r2; } const Register StoreDescriptor::ValueRegister() { return r2; }
......
...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return rdx; } ...@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return rdx; }
const Register LoadDescriptor::NameRegister() { return rcx; } const Register LoadDescriptor::NameRegister() { return rcx; }
const Register LoadDescriptor::SlotRegister() { return rax; } const Register LoadDescriptor::SlotRegister() { return rax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; } const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return rdi; }
const Register StoreDescriptor::ReceiverRegister() { return rdx; } const Register StoreDescriptor::ReceiverRegister() { return rdx; }
const Register StoreDescriptor::NameRegister() { return rcx; } const Register StoreDescriptor::NameRegister() { return rcx; }
......
...@@ -31,6 +31,7 @@ const Register LoadDescriptor::SlotRegister() { return eax; } ...@@ -31,6 +31,7 @@ const Register LoadDescriptor::SlotRegister() { return eax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; } const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return edi; }
const Register StoreDescriptor::ReceiverRegister() { return edx; } const Register StoreDescriptor::ReceiverRegister() { return edx; }
const Register StoreDescriptor::NameRegister() { return ecx; } const Register StoreDescriptor::NameRegister() { return ecx; }
......
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