Commit 51dded6e authored by verwaest@chromium.org's avatar verwaest@chromium.org

Turn the load field code stub into a hydrogen code stub.

Review URL: https://chromiumcodereview.appspot.com/14847004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14526 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f78f5831
......@@ -74,6 +74,28 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
}
void LoadFieldStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->stack_parameter_count_ = NULL;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1 };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->stack_parameter_count_ = NULL;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
......@@ -3777,12 +3799,6 @@ Register InstanceofStub::left() { return r0; }
Register InstanceofStub::right() { return r1; }
void LoadFieldStub::Generate(MacroAssembler* masm) {
StubCompiler::DoGenerateFastPropertyLoad(masm, r0, reg_, inobject_, index_);
__ Ret();
}
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
// The displacement is the offset of the last parameter (if any)
// relative to the frame pointer.
......
......@@ -1309,9 +1309,17 @@ void BaseLoadStubCompiler::NonexistentHandlerFrontend(
void BaseLoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
PropertyIndex index) {
GenerateFastPropertyLoad(masm(), r0, reg, holder, index);
__ Ret();
PropertyIndex field) {
if (!reg.is(receiver())) __ mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
LoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
} else {
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
}
}
......
......@@ -240,7 +240,8 @@ Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(Isolate* isolate) {
GetCodeKind(),
GetICState(),
GetExtraICState(),
GetStubType(), -1);
GetStubType(),
GetStubFlags());
Handle<Code> new_object = factory->NewCode(
desc, flags, masm.CodeObject(), NeedsImmovableCode());
return new_object;
......@@ -410,6 +411,36 @@ Handle<Code> KeyedLoadFastElementStub::GenerateCode() {
}
template<>
HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
Representation representation = casted_stub()->representation();
HInstruction* load = AddInstruction(new(zone()) HLoadNamedField(
GetParameter(0), casted_stub()->is_inobject(),
representation, casted_stub()->offset()));
return load;
}
Handle<Code> LoadFieldStub::GenerateCode() {
return DoGenerateCode(this);
}
template<>
HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() {
Representation representation = casted_stub()->representation();
HInstruction* load = AddInstruction(new(zone()) HLoadNamedField(
GetParameter(0), casted_stub()->is_inobject(),
representation, casted_stub()->offset()));
return load;
}
Handle<Code> KeyedLoadFieldStub::GenerateCode() {
return DoGenerateCode(this);
}
template <>
HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() {
BuildUncheckedMonomorphicElementAccess(
......
......@@ -87,7 +87,8 @@ namespace internal {
V(ArrayConstructor) \
V(ProfileEntryHook) \
/* IC Handler stubs */ \
V(LoadField)
V(LoadField) \
V(KeyedLoadField)
// List of code stubs only used on ARM platforms.
#ifdef V8_TARGET_ARCH_ARM
......@@ -185,6 +186,12 @@ class CodeStub BASE_EMBEDDED {
virtual Code::ExtraICState GetExtraICState() {
return Code::kNoExtraICState;
}
virtual Code::StubType GetStubType() {
return Code::NORMAL;
}
virtual int GetStubFlags() {
return -1;
}
protected:
static bool CanUseFPRegisters();
......@@ -192,9 +199,6 @@ class CodeStub BASE_EMBEDDED {
// Generates the assembler code for the stub.
virtual Handle<Code> GenerateCode() = 0;
virtual Code::StubType GetStubType() {
return Code::NORMAL;
}
// Returns whether the code generated for this stub needs to be allocated as
// a fixed (non-moveable) code object.
......@@ -253,7 +257,6 @@ class PlatformCodeStub : public CodeStub {
virtual Handle<Code> GenerateCode();
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
virtual int GetStubFlags() { return -1; }
protected:
// Generates the assembler code for the stub.
......@@ -754,42 +757,95 @@ class StoreArrayLengthStub: public StoreICStub {
};
class HandlerStub: public ICStub {
class HICStub: public HydrogenCodeStub {
public:
virtual Code::Kind GetCodeKind() const { return kind(); }
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
protected:
HICStub() : HydrogenCodeStub(CODE_STUB_IS_NOT_MISS) { }
class KindBits: public BitField<Code::Kind, 0, 4> {};
virtual Code::Kind kind() const = 0;
};
class HandlerStub: public HICStub {
public:
explicit HandlerStub(Code::Kind kind) : ICStub(kind) { }
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
virtual int GetStubFlags() { return kind(); }
protected:
HandlerStub() : HICStub() { }
};
class LoadFieldStub: public HandlerStub {
public:
LoadFieldStub(Register reg, bool inobject, int index)
: HandlerStub(Code::LOAD_IC),
reg_(reg),
inobject_(inobject),
index_(index) { }
virtual void Generate(MacroAssembler* masm);
LoadFieldStub(bool inobject, int index) : HandlerStub() {
Initialize(Code::LOAD_IC, inobject, index);
}
virtual Handle<Code> GenerateCode();
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor);
Representation representation() {
return Representation::Tagged();
}
virtual Code::Kind kind() const {
return KindBits::decode(bit_field_);
}
bool is_inobject() {
return InobjectBits::decode(bit_field_);
}
int offset() {
int index = IndexBits::decode(bit_field_);
int offset = index * kPointerSize;
if (is_inobject()) return offset;
return FixedArray::kHeaderSize + offset;
}
protected:
virtual Code::StubType GetStubType() { return Code::FIELD; }
protected:
LoadFieldStub() : HandlerStub() { }
void Initialize(Code::Kind kind, bool inobject, int index) {
bit_field_ = KindBits::encode(kind)
| InobjectBits::encode(inobject)
| IndexBits::encode(index);
}
private:
STATIC_ASSERT(KindBits::kSize == 4);
class RegisterBits: public BitField<int, 4, 6> {};
class InobjectBits: public BitField<bool, 10, 1> {};
class IndexBits: public BitField<int, 11, 11> {};
class InobjectBits: public BitField<bool, 4, 1> {};
class IndexBits: public BitField<int, 5, 11> {};
virtual CodeStub::Major MajorKey() { return LoadField; }
virtual int MinorKey() {
return KindBits::encode(kind())
| RegisterBits::encode(reg_.code())
| InobjectBits::encode(inobject_)
| IndexBits::encode(index_);
virtual int NotMissMinorKey() { return bit_field_; }
int bit_field_;
};
class KeyedLoadFieldStub: public LoadFieldStub {
public:
KeyedLoadFieldStub(bool inobject, int index) : LoadFieldStub() {
Initialize(Code::KEYED_LOAD_IC, inobject, index);
}
Register reg_;
bool inobject_;
int index_;
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor);
virtual Handle<Code> GenerateCode();
private:
virtual CodeStub::Major MajorKey() { return KeyedLoadField; }
};
......
......@@ -144,7 +144,8 @@ Code::Flags CompilationInfo::flags() const {
return Code::ComputeFlags(code_stub()->GetCodeKind(),
code_stub()->GetICState(),
code_stub()->GetExtraICState(),
Code::NORMAL, -1);
code_stub()->GetStubType(),
code_stub()->GetStubFlags());
} else {
return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
}
......
......@@ -80,6 +80,28 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
}
void LoadFieldStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->stack_parameter_count_ = NULL;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->stack_parameter_count_ = NULL;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
......@@ -3299,12 +3321,6 @@ void StoreArrayLengthStub::Generate(MacroAssembler* masm) {
}
void LoadFieldStub::Generate(MacroAssembler* masm) {
StubCompiler::DoGenerateFastPropertyLoad(masm, eax, reg_, inobject_, index_);
__ ret(0);
}
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
// The key is in edx and the parameter count is in eax.
......
......@@ -1236,10 +1236,17 @@ void BaseLoadStubCompiler::NonexistentHandlerFrontend(
void BaseLoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
PropertyIndex index) {
// Get the value from the properties.
GenerateFastPropertyLoad(masm(), eax, reg, holder, index);
__ ret(0);
PropertyIndex field) {
if (!reg.is(receiver())) __ mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
LoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
} else {
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
}
}
......
......@@ -223,8 +223,7 @@ Handle<Code> StubCache::ComputeLoadField(Handle<Name> name,
Handle<JSObject> holder,
PropertyIndex field) {
if (receiver.is_identical_to(holder)) {
LoadFieldStub stub(LoadStubCompiler::receiver(),
field.is_inobject(holder),
LoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
return stub.GetCode(isolate());
}
......@@ -339,9 +338,8 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
Handle<JSObject> holder,
PropertyIndex field) {
if (receiver.is_identical_to(holder)) {
LoadFieldStub stub(KeyedLoadStubCompiler::receiver(),
field.is_inobject(holder),
field.translate(holder));
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
return stub.GetCode(isolate());
}
......@@ -1504,8 +1502,7 @@ Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
GenerateLoadField(reg, holder, field);
__ bind(&miss);
TailCallBuiltin(masm(), MissBuiltin(kind()));
......@@ -1590,10 +1587,7 @@ void BaseLoadStubCompiler::GenerateLoadPostInterceptor(
if (lookup->IsField()) {
PropertyIndex field = lookup->GetFieldIndex();
if (interceptor_holder.is_identical_to(holder)) {
LoadFieldStub stub(interceptor_reg,
field.is_inobject(holder),
field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
GenerateLoadField(interceptor_reg, holder, field);
} else {
// We found FIELD property in prototype chain of interceptor's holder.
// Retrieve a field from field's holder.
......
......@@ -75,6 +75,28 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
}
void LoadFieldStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->stack_parameter_count_ = NULL;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx };
descriptor->register_param_count_ = 1;
descriptor->register_params_ = registers;
descriptor->stack_parameter_count_ = NULL;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
......@@ -2392,12 +2414,6 @@ void StoreArrayLengthStub::Generate(MacroAssembler* masm) {
}
void LoadFieldStub::Generate(MacroAssembler* masm) {
StubCompiler::DoGenerateFastPropertyLoad(masm, rax, reg_, inobject_, index_);
__ ret(0);
}
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
// The key is in rdx and the parameter count is in rax.
......
......@@ -1196,10 +1196,17 @@ void BaseLoadStubCompiler::NonexistentHandlerFrontend(
void BaseLoadStubCompiler::GenerateLoadField(Register reg,
Handle<JSObject> holder,
PropertyIndex index) {
// Get the value from the properties.
GenerateFastPropertyLoad(masm(), rax, reg, holder, index);
__ ret(0);
PropertyIndex field) {
if (!reg.is(receiver())) __ movq(receiver(), reg);
if (kind() == Code::LOAD_IC) {
LoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
} else {
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder));
GenerateTailCall(masm(), stub.GetCode(isolate()));
}
}
......
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