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(
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(
HValue* object, HValue* value, FieldIndex index,
Representation representation, bool transition_to_field) {
......
......@@ -1929,6 +1929,11 @@ void StoreGlobalStub::GenerateAssembly(
}
}
void LoadFieldStub::GenerateAssembly(
compiler::CodeAssemblerState* state) const {
AccessorAssembler::GenerateLoadField(state);
}
void KeyedLoadSloppyArgumentsStub::GenerateAssembly(
compiler::CodeAssemblerState* state) const {
typedef CodeStubAssembler::Label Label;
......
......@@ -64,10 +64,6 @@ class Node;
/* used universally */ \
V(CallICTrampoline) \
/* --- 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 */ \
/* because they are either used only by */ \
/* FCG/Crankshaft or are deprecated */ \
......@@ -125,6 +121,7 @@ class Node;
V(StoreInterceptor) \
V(LoadApiGetter) \
V(LoadIndexedInterceptor) \
V(LoadField) \
V(GrowArrayElements) \
/* These are only called from FGC and */ \
/* can be removed when we use ignition */ \
......@@ -1167,28 +1164,16 @@ class HandlerStub : public HydrogenCodeStub {
DEFINE_CODE_STUB_BASE(HandlerStub, HydrogenCodeStub);
};
class LoadFieldStub: public HandlerStub {
class LoadFieldStub : public TurboFanCodeStub {
public:
LoadFieldStub(Isolate* isolate, FieldIndex index) : HandlerStub(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);
}
explicit LoadFieldStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
protected:
Code::Kind kind() const override { return Code::LOAD_IC; }
Code::Kind GetCodeKind() const override { return Code::HANDLER; }
ExtraICState GetExtraICState() const override { return GetCodeKind(); }
private:
class LoadFieldByIndexBits : public BitField<int, 0, 13> {};
// TODO(ishell): The stub uses only kReceiver parameter.
DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
DEFINE_HANDLER_CODE_STUB(LoadField, HandlerStub);
DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadField);
DEFINE_TURBOFAN_CODE_STUB(LoadField, TurboFanCodeStub);
};
class KeyedLoadSloppyArgumentsStub : public TurboFanCodeStub {
......
......@@ -18,6 +18,7 @@ using compiler::Node;
#define ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(V) \
V(LoadIC) \
V(LoadField) \
V(LoadICTrampoline) \
V(KeyedLoadICTF) \
V(KeyedLoadICTrampolineTF) \
......
......@@ -1654,6 +1654,20 @@ void AccessorAssemblerImpl::GenerateLoadICProtoArray(
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) {
typedef LoadGlobalICStub::Descriptor Descriptor;
......
......@@ -30,6 +30,7 @@ class AccessorAssembler {
compiler::CodeAssemblerState* state);
static void GenerateKeyedLoadICMegamorphic(
compiler::CodeAssemblerState* state);
static void GenerateLoadField(compiler::CodeAssemblerState* state);
static void GenerateStoreIC(compiler::CodeAssemblerState* state);
static void GenerateStoreICTrampoline(compiler::CodeAssemblerState* state);
static void GenerateKeyedStoreICTF(compiler::CodeAssemblerState* state,
......
......@@ -389,8 +389,11 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
UNREACHABLE();
case LookupIterator::DATA: {
DCHECK_EQ(DATA, it->property_details().type());
__ Move(receiver(), reg);
LoadFieldStub stub(isolate(), it->GetFieldIndex());
__ Move(LoadFieldDescriptor::ReceiverRegister(), reg);
Handle<Object> smi_handler =
LoadIC::SimpleFieldLoad(isolate(), it->GetFieldIndex());
__ Move(LoadFieldDescriptor::SmiHandlerRegister(), smi_handler);
LoadFieldStub stub(isolate());
GenerateTailCall(masm(), stub.GetCode());
break;
}
......
......@@ -883,9 +883,9 @@ void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
}
}
Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH);
return LoadHandler::LoadField(isolate(), index);
Handle<Object> LoadIC::SimpleFieldLoad(Isolate* isolate, FieldIndex index) {
TRACE_HANDLER_STATS(isolate, LoadIC_LoadFieldDH);
return LoadHandler::LoadField(isolate, index);
}
namespace {
......@@ -1310,7 +1310,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (receiver->IsString() &&
Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset);
return SimpleFieldLoad(index);
return SimpleFieldLoad(isolate(), index);
}
if (receiver->IsStringWrapper() &&
......@@ -1348,7 +1348,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
&object_offset)) {
FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map);
return SimpleFieldLoad(index);
return SimpleFieldLoad(isolate(), index);
}
if (IsCompatibleReceiver(lookup, map)) {
......@@ -1419,7 +1419,7 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
// -------------- Fields --------------
if (lookup->property_details().type() == DATA) {
FieldIndex field = lookup->GetFieldIndex();
Handle<Object> smi_handler = SimpleFieldLoad(field);
Handle<Object> smi_handler = SimpleFieldLoad(isolate(), field);
if (receiver_is_holder) {
return smi_handler;
}
......
......@@ -312,7 +312,7 @@ class LoadIC : public IC {
private:
// 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
// by given Smi-handler that encoded a load from the holder.
......@@ -325,6 +325,7 @@ class LoadIC : public IC {
Handle<Object> LoadNonExistent(Handle<Map> receiver_map, Handle<Name> name);
friend class IC;
friend class NamedLoadHandlerCompiler;
};
class LoadGlobalIC : public LoadIC {
......
......@@ -90,6 +90,21 @@ void LoadDescriptor::InitializePlatformSpecific(
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(
CallInterfaceDescriptorData* data) {
// kName, kSlot
......@@ -237,6 +252,19 @@ void MathPowIntegerDescriptor::InitializePlatformSpecific(
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(
CallInterfaceDescriptorData* data) {
// kReceiver, kName, kSlot, kVector
......
......@@ -21,6 +21,7 @@ class PlatformInterfaceDescriptor;
V(ContextOnly) \
V(Load) \
V(LoadWithVector) \
V(LoadField) \
V(LoadICProtoArray) \
V(LoadGlobal) \
V(LoadGlobalWithVector) \
......@@ -308,6 +309,18 @@ class LoadDescriptor : public CallInterfaceDescriptor {
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 {
public:
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