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; }
const Register LoadDescriptor::NameRegister() { return r2; }
const Register LoadDescriptor::SlotRegister() { return r0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r4; }
const Register StoreDescriptor::ReceiverRegister() { return r1; }
const Register StoreDescriptor::NameRegister() { return r2; }
......
......@@ -31,9 +31,9 @@ const Register LoadDescriptor::ReceiverRegister() { return x1; }
const Register LoadDescriptor::NameRegister() { return x2; }
const Register LoadDescriptor::SlotRegister() { return x0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return x3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return x4; }
const Register StoreDescriptor::ReceiverRegister() { return x1; }
const Register StoreDescriptor::NameRegister() { return x2; }
......
......@@ -5715,12 +5715,38 @@ void CodeStubAssembler::HandleLoadICProtoHandler(
Bind(&array_handler);
{
Node* handler_length = SmiUntag(maybe_holder_cell);
Node* holder = EmitLoadICProtoArrayCheck(p, handler, handler_length,
handler_flags, miss);
var_holder->Bind(holder);
var_smi_handler->Bind(smi_handler);
Goto(if_smi_handler);
typedef LoadICProtoArrayDescriptor Descriptor;
LoadICProtoArrayStub stub(isolate());
Node* target = HeapConstant(stub.GetCode());
TailCallStub(Descriptor(isolate()), target, p->context,
Arg(Descriptor::kReceiver, p->receiver),
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 {
ParameterMode mode, Label* bailout);
void LoadIC(const LoadICParameters* p);
void LoadICProtoArray(const LoadICParameters* p, compiler::Node* handler);
void LoadGlobalIC(const LoadICParameters* p);
void KeyedLoadIC(const LoadICParameters* p);
void KeyedLoadICGeneric(const LoadICParameters* p);
......
......@@ -455,6 +455,21 @@ void LoadICStub::GenerateAssembly(CodeStubAssembler* assembler) const {
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(
CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
......
......@@ -121,6 +121,7 @@ class ObjectLiteral;
V(StringAdd) \
V(GetProperty) \
V(LoadIC) \
V(LoadICProtoArray) \
V(KeyedLoadICTF) \
V(StoreFastElement) \
V(StoreField) \
......@@ -2103,6 +2104,16 @@ class LoadICStub : public 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 {
public:
explicit LoadGlobalICStub(Isolate* isolate, const LoadGlobalICState& state)
......
......@@ -31,6 +31,7 @@ const Register LoadDescriptor::SlotRegister() { return eax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return edi; }
const Register StoreDescriptor::ReceiverRegister() { return edx; }
const Register StoreDescriptor::NameRegister() { return ecx; }
......
......@@ -217,7 +217,6 @@ void LoadWithVectorDescriptor::InitializePlatformIndependent(
machine_types);
}
void LoadWithVectorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
......@@ -225,6 +224,24 @@ void LoadWithVectorDescriptor::InitializePlatformSpecific(
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(
CallInterfaceDescriptorData* data) {
// kReceiver, kName, kValue, kSlot, kVector
......
......@@ -21,6 +21,7 @@ class PlatformInterfaceDescriptor;
V(ContextOnly) \
V(Load) \
V(LoadWithVector) \
V(LoadICProtoArray) \
V(LoadGlobal) \
V(LoadGlobalWithVector) \
V(Store) \
......@@ -389,6 +390,15 @@ class LoadWithVectorDescriptor : public LoadDescriptor {
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 {
public:
DEFINE_PARAMETERS(kSlot, kVector)
......
......@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return a1; }
const Register LoadDescriptor::NameRegister() { return a2; }
const Register LoadDescriptor::SlotRegister() { return a0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return a3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return t0; }
const Register StoreDescriptor::ReceiverRegister() { return a1; }
const Register StoreDescriptor::NameRegister() { return a2; }
......
......@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return a1; }
const Register LoadDescriptor::NameRegister() { return a2; }
const Register LoadDescriptor::SlotRegister() { return a0; }
const Register LoadWithVectorDescriptor::VectorRegister() { return a3; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return a4; }
const Register StoreDescriptor::ReceiverRegister() { return a1; }
const Register StoreDescriptor::NameRegister() { return a2; }
......
......@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return r4; }
const Register LoadDescriptor::NameRegister() { return r5; }
const Register LoadDescriptor::SlotRegister() { return r3; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r6; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r7; }
const Register StoreDescriptor::ReceiverRegister() { return r4; }
const Register StoreDescriptor::NameRegister() { return r5; }
......
......@@ -31,6 +31,8 @@ const Register LoadDescriptor::SlotRegister() { return r2; }
const Register LoadWithVectorDescriptor::VectorRegister() { return r5; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r6; }
const Register StoreDescriptor::ReceiverRegister() { return r3; }
const Register StoreDescriptor::NameRegister() { return r4; }
const Register StoreDescriptor::ValueRegister() { return r2; }
......
......@@ -29,9 +29,9 @@ const Register LoadDescriptor::ReceiverRegister() { return rdx; }
const Register LoadDescriptor::NameRegister() { return rcx; }
const Register LoadDescriptor::SlotRegister() { return rax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return rdi; }
const Register StoreDescriptor::ReceiverRegister() { return rdx; }
const Register StoreDescriptor::NameRegister() { return rcx; }
......
......@@ -31,6 +31,7 @@ const Register LoadDescriptor::SlotRegister() { return eax; }
const Register LoadWithVectorDescriptor::VectorRegister() { return ebx; }
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return edi; }
const Register StoreDescriptor::ReceiverRegister() { return edx; }
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