Commit 6236060c authored by danno's avatar danno Committed by Commit bot

[stubs] Port LoadFieldStub to TF

LoadFieldStub is the last Crankshaft/Hydrogen stub that stands in the way
of being able to run --ignition-staging --turbo without any Crankshaft support,
even for ICs/stubs.

Review-Url: https://codereview.chromium.org/2595343002
Cr-Commit-Position: refs/heads/master@{#41939}
parent c42bbec9
...@@ -396,18 +396,6 @@ HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField( ...@@ -396,18 +396,6 @@ HLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField(
return Add<HLoadNamedField>(object, nullptr, access); return Add<HLoadNamedField>(object, nullptr, access);
} }
template<>
HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
return BuildLoadNamedField(GetParameter(Descriptor::kReceiver),
casted_stub()->index());
}
Handle<Code> LoadFieldStub::GenerateCode() {
return DoGenerateCode(this);
}
void CodeStubGraphBuilderBase::BuildStoreNamedField( void CodeStubGraphBuilderBase::BuildStoreNamedField(
HValue* object, HValue* value, FieldIndex index, HValue* object, HValue* value, FieldIndex index,
Representation representation, bool transition_to_field) { Representation representation, bool transition_to_field) {
......
...@@ -1929,6 +1929,11 @@ void StoreGlobalStub::GenerateAssembly( ...@@ -1929,6 +1929,11 @@ void StoreGlobalStub::GenerateAssembly(
} }
} }
void LoadFieldStub::GenerateAssembly(
compiler::CodeAssemblerState* state) const {
AccessorAssembler::GenerateLoadField(state);
}
void KeyedLoadSloppyArgumentsStub::GenerateAssembly( void KeyedLoadSloppyArgumentsStub::GenerateAssembly(
compiler::CodeAssemblerState* state) const { compiler::CodeAssemblerState* state) const {
typedef CodeStubAssembler::Label Label; typedef CodeStubAssembler::Label Label;
......
...@@ -64,10 +64,6 @@ class Node; ...@@ -64,10 +64,6 @@ class Node;
/* used universally */ \ /* used universally */ \
V(CallICTrampoline) \ V(CallICTrampoline) \
/* --- HydrogenCodeStubs --- */ \ /* --- HydrogenCodeStubs --- */ \
/* These will be ported/eliminated */ \
/* as part of the new IC system, ask */ \
/* ishell before doing anything */ \
V(LoadField) \
/* These should never be ported to TF */ \ /* These should never be ported to TF */ \
/* because they are either used only by */ \ /* because they are either used only by */ \
/* FCG/Crankshaft or are deprecated */ \ /* FCG/Crankshaft or are deprecated */ \
...@@ -125,6 +121,7 @@ class Node; ...@@ -125,6 +121,7 @@ class Node;
V(StoreInterceptor) \ V(StoreInterceptor) \
V(LoadApiGetter) \ V(LoadApiGetter) \
V(LoadIndexedInterceptor) \ V(LoadIndexedInterceptor) \
V(LoadField) \
V(GrowArrayElements) \ V(GrowArrayElements) \
/* These are only called from FGC and */ \ /* These are only called from FGC and */ \
/* can be removed when we use ignition */ \ /* can be removed when we use ignition */ \
...@@ -1167,28 +1164,16 @@ class HandlerStub : public HydrogenCodeStub { ...@@ -1167,28 +1164,16 @@ class HandlerStub : public HydrogenCodeStub {
DEFINE_CODE_STUB_BASE(HandlerStub, HydrogenCodeStub); DEFINE_CODE_STUB_BASE(HandlerStub, HydrogenCodeStub);
}; };
class LoadFieldStub : public TurboFanCodeStub {
class LoadFieldStub: public HandlerStub {
public: public:
LoadFieldStub(Isolate* isolate, FieldIndex index) : HandlerStub(isolate) { explicit LoadFieldStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
int property_index_key = index.GetFieldAccessStubKey();
set_sub_minor_key(LoadFieldByIndexBits::encode(property_index_key));
}
FieldIndex index() const {
int property_index_key = LoadFieldByIndexBits::decode(sub_minor_key());
return FieldIndex::FromFieldAccessStubKey(property_index_key);
}
protected: Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Code::Kind kind() const override { return Code::LOAD_IC; } ExtraICState GetExtraICState() const override { return GetCodeKind(); }
private: private:
class LoadFieldByIndexBits : public BitField<int, 0, 13> {}; DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadField);
DEFINE_TURBOFAN_CODE_STUB(LoadField, TurboFanCodeStub);
// TODO(ishell): The stub uses only kReceiver parameter.
DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
DEFINE_HANDLER_CODE_STUB(LoadField, HandlerStub);
}; };
class KeyedLoadSloppyArgumentsStub : public TurboFanCodeStub { class KeyedLoadSloppyArgumentsStub : public TurboFanCodeStub {
......
...@@ -18,6 +18,7 @@ using compiler::Node; ...@@ -18,6 +18,7 @@ using compiler::Node;
#define ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(V) \ #define ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(V) \
V(LoadIC) \ V(LoadIC) \
V(LoadField) \
V(LoadICTrampoline) \ V(LoadICTrampoline) \
V(KeyedLoadICTF) \ V(KeyedLoadICTF) \
V(KeyedLoadICTrampolineTF) \ V(KeyedLoadICTrampolineTF) \
......
...@@ -1654,6 +1654,20 @@ void AccessorAssemblerImpl::GenerateLoadICProtoArray( ...@@ -1654,6 +1654,20 @@ void AccessorAssemblerImpl::GenerateLoadICProtoArray(
LoadICProtoArray(&p, handler, throw_reference_error_if_nonexistent); LoadICProtoArray(&p, handler, throw_reference_error_if_nonexistent);
} }
void AccessorAssemblerImpl::GenerateLoadField() {
typedef LoadFieldStub::Descriptor Descriptor;
Node* receiver = Parameter(Descriptor::kReceiver);
Node* name = nullptr;
Node* slot = nullptr;
Node* vector = nullptr;
Node* context = Parameter(Descriptor::kContext);
LoadICParameters p(context, receiver, name, slot, vector);
HandleLoadICSmiHandlerCase(&p, receiver, Parameter(Descriptor::kSmiHandler),
nullptr, kOnlyProperties);
}
void AccessorAssemblerImpl::GenerateLoadGlobalIC(TypeofMode typeof_mode) { void AccessorAssemblerImpl::GenerateLoadGlobalIC(TypeofMode typeof_mode) {
typedef LoadGlobalICStub::Descriptor Descriptor; typedef LoadGlobalICStub::Descriptor Descriptor;
......
...@@ -30,6 +30,7 @@ class AccessorAssembler { ...@@ -30,6 +30,7 @@ class AccessorAssembler {
compiler::CodeAssemblerState* state); compiler::CodeAssemblerState* state);
static void GenerateKeyedLoadICMegamorphic( static void GenerateKeyedLoadICMegamorphic(
compiler::CodeAssemblerState* state); compiler::CodeAssemblerState* state);
static void GenerateLoadField(compiler::CodeAssemblerState* state);
static void GenerateStoreIC(compiler::CodeAssemblerState* state); static void GenerateStoreIC(compiler::CodeAssemblerState* state);
static void GenerateStoreICTrampoline(compiler::CodeAssemblerState* state); static void GenerateStoreICTrampoline(compiler::CodeAssemblerState* state);
static void GenerateKeyedStoreICTF(compiler::CodeAssemblerState* state, static void GenerateKeyedStoreICTF(compiler::CodeAssemblerState* state,
......
...@@ -389,8 +389,11 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( ...@@ -389,8 +389,11 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
UNREACHABLE(); UNREACHABLE();
case LookupIterator::DATA: { case LookupIterator::DATA: {
DCHECK_EQ(DATA, it->property_details().type()); DCHECK_EQ(DATA, it->property_details().type());
__ Move(receiver(), reg); __ Move(LoadFieldDescriptor::ReceiverRegister(), reg);
LoadFieldStub stub(isolate(), it->GetFieldIndex()); Handle<Object> smi_handler =
LoadIC::SimpleFieldLoad(isolate(), it->GetFieldIndex());
__ Move(LoadFieldDescriptor::SmiHandlerRegister(), smi_handler);
LoadFieldStub stub(isolate());
GenerateTailCall(masm(), stub.GetCode()); GenerateTailCall(masm(), stub.GetCode());
break; break;
} }
......
...@@ -883,9 +883,9 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { ...@@ -883,9 +883,9 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
} }
} }
Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) { Handle<Object> LoadIC::SimpleFieldLoad(Isolate* isolate, FieldIndex index) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH); TRACE_HANDLER_STATS(isolate, LoadIC_LoadFieldDH);
return LoadHandler::LoadField(isolate(), index); return LoadHandler::LoadField(isolate, index);
} }
namespace { namespace {
...@@ -1310,7 +1310,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { ...@@ -1310,7 +1310,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (receiver->IsString() && if (receiver->IsString() &&
Name::Equals(isolate()->factory()->length_string(), lookup->name())) { Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset);
return SimpleFieldLoad(index); return SimpleFieldLoad(isolate(), index);
} }
if (receiver->IsStringWrapper() && if (receiver->IsStringWrapper() &&
...@@ -1348,7 +1348,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { ...@@ -1348,7 +1348,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(), if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
&object_offset)) { &object_offset)) {
FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map);
return SimpleFieldLoad(index); return SimpleFieldLoad(isolate(), index);
} }
if (IsCompatibleReceiver(lookup, map)) { if (IsCompatibleReceiver(lookup, map)) {
...@@ -1419,7 +1419,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { ...@@ -1419,7 +1419,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
// -------------- Fields -------------- // -------------- Fields --------------
if (lookup->property_details().type() == DATA) { if (lookup->property_details().type() == DATA) {
FieldIndex field = lookup->GetFieldIndex(); FieldIndex field = lookup->GetFieldIndex();
Handle<Object> smi_handler = SimpleFieldLoad(field); Handle<Object> smi_handler = SimpleFieldLoad(isolate(), field);
if (receiver_is_holder) { if (receiver_is_holder) {
return smi_handler; return smi_handler;
} }
......
...@@ -312,7 +312,7 @@ class LoadIC : public IC { ...@@ -312,7 +312,7 @@ class LoadIC : public IC {
private: private:
// Creates a data handler that represents a load of a field by given index. // Creates a data handler that represents a load of a field by given index.
Handle<Object> SimpleFieldLoad(FieldIndex index); static Handle<Object> SimpleFieldLoad(Isolate* isolate, FieldIndex index);
// Creates a data handler that represents a prototype chain check followed // Creates a data handler that represents a prototype chain check followed
// by given Smi-handler that encoded a load from the holder. // by given Smi-handler that encoded a load from the holder.
...@@ -325,6 +325,7 @@ class LoadIC : public IC { ...@@ -325,6 +325,7 @@ class LoadIC : public IC {
Handle<Object> LoadNonExistent(Handle<Map> receiver_map, Handle<Name> name); Handle<Object> LoadNonExistent(Handle<Map> receiver_map, Handle<Name> name);
friend class IC; friend class IC;
friend class NamedLoadHandlerCompiler;
}; };
class LoadGlobalIC : public LoadIC { class LoadGlobalIC : public LoadIC {
......
...@@ -90,6 +90,21 @@ void LoadDescriptor::InitializePlatformSpecific( ...@@ -90,6 +90,21 @@ void LoadDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void LoadFieldDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kReceiver, kSmiHandler
MachineType machine_types[] = {MachineType::AnyTagged(),
MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void LoadFieldDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {ReceiverRegister(), SmiHandlerRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void LoadGlobalDescriptor::InitializePlatformIndependent( void LoadGlobalDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// kName, kSlot // kName, kSlot
...@@ -237,6 +252,19 @@ void MathPowIntegerDescriptor::InitializePlatformSpecific( ...@@ -237,6 +252,19 @@ void MathPowIntegerDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
const Register LoadFieldDescriptor::ReceiverRegister() {
// Reuse the register from the LoadDescriptor, since given the
// LoadFieldDescriptor's usage, it doesn't matter exactly which registers are
// used to pass parameters in.
return LoadDescriptor::ReceiverRegister();
}
const Register LoadFieldDescriptor::SmiHandlerRegister() {
// Reuse the register from the LoadDescriptor, since given the
// LoadFieldDescriptor's usage, it doesn't matter exactly which registers are
// used to pass parameters in.
return LoadDescriptor::NameRegister();
}
void LoadWithVectorDescriptor::InitializePlatformIndependent( void LoadWithVectorDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// kReceiver, kName, kSlot, kVector // kReceiver, kName, 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(LoadField) \
V(LoadICProtoArray) \ V(LoadICProtoArray) \
V(LoadGlobal) \ V(LoadGlobal) \
V(LoadGlobalWithVector) \ V(LoadGlobalWithVector) \
...@@ -308,6 +309,18 @@ class LoadDescriptor : public CallInterfaceDescriptor { ...@@ -308,6 +309,18 @@ class LoadDescriptor : public CallInterfaceDescriptor {
static const Register SlotRegister(); static const Register SlotRegister();
}; };
// LoadFieldDescriptor is used by the shared handler that loads a field from an
// object based on the smi-encoded field description.
class LoadFieldDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kSmiHandler)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadFieldDescriptor,
CallInterfaceDescriptor)
static const Register ReceiverRegister();
static const Register SmiHandlerRegister();
};
class LoadGlobalDescriptor : public CallInterfaceDescriptor { class LoadGlobalDescriptor : public CallInterfaceDescriptor {
public: public:
DEFINE_PARAMETERS(kName, kSlot) DEFINE_PARAMETERS(kName, kSlot)
......
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