Turn Load/StoreGlobal into a handler.

BUG=
R=ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17550 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-11-07 10:17:13 +00:00
parent e7ef18110d
commit 442e77d536
8 changed files with 90 additions and 140 deletions

View File

@ -3020,10 +3020,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
bool is_dont_delete) { bool is_dont_delete) {
Label success, miss; Label success, miss;
__ CheckMap( HandlerFrontendHeader(object, receiver(), global, name, &miss);
receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK);
HandlerFrontendHeader(
object, receiver(), Handle<JSObject>::cast(global), name, &miss);
// Get the value from the cell. // Get the value from the cell.
__ mov(r3, Operand(cell)); __ mov(r3, Operand(cell));
@ -3045,7 +3042,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
__ Ret(); __ Ret();
// Return the generated code. // Return the generated code.
return GetICCode(kind(), Code::NORMAL, name); return GetCode(kind(), Code::NORMAL, name);
} }

View File

@ -553,51 +553,6 @@ class FastNewBlockContextStub : public PlatformCodeStub {
int MinorKey() { return slots_; } int MinorKey() { return slots_; }
}; };
class StoreGlobalStub : public HydrogenCodeStub {
public:
StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) {
bit_field_ = StrictModeBits::encode(strict_mode) |
IsConstantBits::encode(is_constant);
}
virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor);
virtual Code::Kind GetCodeKind() const { return Code::STORE_IC; }
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
virtual Code::ExtraICState GetExtraICState() { return bit_field_; }
bool is_constant() {
return IsConstantBits::decode(bit_field_);
}
void set_is_constant(bool value) {
bit_field_ = IsConstantBits::update(bit_field_, value);
}
Representation representation() {
return Representation::FromKind(RepresentationBits::decode(bit_field_));
}
void set_representation(Representation r) {
bit_field_ = RepresentationBits::update(bit_field_, r.kind());
}
private:
virtual int NotMissMinorKey() { return GetExtraICState(); }
Major MajorKey() { return StoreGlobal; }
class StrictModeBits: public BitField<StrictModeFlag, 0, 1> {};
class IsConstantBits: public BitField<bool, 1, 1> {};
class RepresentationBits: public BitField<Representation::Kind, 2, 8> {};
int bit_field_;
DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub);
};
class FastCloneShallowArrayStub : public HydrogenCodeStub { class FastCloneShallowArrayStub : public HydrogenCodeStub {
public: public:
// Maximum length of copied elements array. // Maximum length of copied elements array.
@ -899,7 +854,6 @@ class HICStub: public HydrogenCodeStub {
virtual InlineCacheState GetICState() { return MONOMORPHIC; } virtual InlineCacheState GetICState() { return MONOMORPHIC; }
protected: protected:
HICStub() { }
class KindBits: public BitField<Code::Kind, 0, 4> {}; class KindBits: public BitField<Code::Kind, 0, 4> {};
virtual Code::Kind kind() const = 0; virtual Code::Kind kind() const = 0;
}; };
@ -909,16 +863,12 @@ class HandlerStub: public HICStub {
public: public:
virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
virtual int GetStubFlags() { return kind(); } virtual int GetStubFlags() { return kind(); }
protected:
HandlerStub() : HICStub() { }
}; };
class LoadFieldStub: public HandlerStub { class LoadFieldStub: public HandlerStub {
public: public:
LoadFieldStub(bool inobject, int index, Representation representation) LoadFieldStub(bool inobject, int index, Representation representation) {
: HandlerStub() {
Initialize(Code::LOAD_IC, inobject, index, representation); Initialize(Code::LOAD_IC, inobject, index, representation);
} }
@ -980,6 +930,63 @@ class LoadFieldStub: public HandlerStub {
}; };
class StoreGlobalStub : public HandlerStub {
public:
StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) {
bit_field_ = StrictModeBits::encode(strict_mode) |
IsConstantBits::encode(is_constant);
}
Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
Map* receiver_map,
PropertyCell* cell) {
Handle<Code> code = CodeStub::GetCodeCopyFromTemplate(isolate);
// Replace the placeholder cell and global object map with the actual global
// cell and receiver map.
Map* cell_map = isolate->heap()->global_property_cell_map();
code->ReplaceNthObject(1, cell_map, cell);
code->ReplaceNthObject(1, isolate->heap()->meta_map(), receiver_map);
return code;
}
virtual Code::Kind kind() const { return Code::STORE_IC; }
virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor);
virtual Code::ExtraICState GetExtraICState() { return bit_field_; }
bool is_constant() {
return IsConstantBits::decode(bit_field_);
}
void set_is_constant(bool value) {
bit_field_ = IsConstantBits::update(bit_field_, value);
}
Representation representation() {
return Representation::FromKind(RepresentationBits::decode(bit_field_));
}
void set_representation(Representation r) {
bit_field_ = RepresentationBits::update(bit_field_, r.kind());
}
private:
virtual int NotMissMinorKey() { return GetExtraICState(); }
Major MajorKey() { return StoreGlobal; }
class StrictModeBits: public BitField<StrictModeFlag, 0, 1> {};
class IsConstantBits: public BitField<bool, 1, 1> {};
class RepresentationBits: public BitField<Representation::Kind, 2, 8> {};
int bit_field_;
DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub);
};
class KeyedLoadFieldStub: public LoadFieldStub { class KeyedLoadFieldStub: public LoadFieldStub {
public: public:
KeyedLoadFieldStub(bool inobject, int index, Representation representation) KeyedLoadFieldStub(bool inobject, int index, Representation representation)

View File

@ -3125,9 +3125,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
bool is_dont_delete) { bool is_dont_delete) {
Label success, miss; Label success, miss;
__ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); HandlerFrontendHeader(object, receiver(), global, name, &miss);
HandlerFrontendHeader(
object, receiver(), Handle<JSObject>::cast(global), name, &miss);
// Get the value from the cell. // Get the value from the cell.
if (Serializer::enabled()) { if (Serializer::enabled()) {
__ mov(eax, Immediate(cell)); __ mov(eax, Immediate(cell));
@ -3154,7 +3152,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
__ ret(0); __ ret(0);
// Return the generated code. // Return the generated code.
return GetICCode(kind(), Code::NORMAL, name); return GetCode(kind(), Code::NORMAL, name);
} }

View File

@ -768,12 +768,13 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// Bail out if we didn't find a result. // Bail out if we didn't find a result.
if (!lookup->IsProperty() || !lookup->IsCacheable()) return; if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
// Compute the number of arguments. if (state() == UNINITIALIZED) {
Handle<Code> code; set_target(*pre_monomorphic_stub());
code = state() == UNINITIALIZED TRACE_IC("CallIC", name);
? pre_monomorphic_stub() return;
: ComputeMonomorphicStub(lookup, object, name); }
Handle<Code> code = ComputeMonomorphicStub(lookup, object, name);
// If there's no appropriate stub we simply avoid updating the caches. // If there's no appropriate stub we simply avoid updating the caches.
// TODO(verwaest): Install a slow fallback in this case to avoid not learning, // TODO(verwaest): Install a slow fallback in this case to avoid not learning,
// and deopting Crankshaft code. // and deopting Crankshaft code.
@ -954,7 +955,6 @@ bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
Handle<String> name, Handle<String> name,
Handle<Code> code) { Handle<Code> code) {
if (!code->is_handler()) return false; if (!code->is_handler()) return false;
MapHandleList receiver_maps; MapHandleList receiver_maps;
CodeHandleList handlers; CodeHandleList handlers;
@ -1133,7 +1133,9 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
// This is the first time we execute this inline cache. // This is the first time we execute this inline cache.
// Set the target to the pre monomorphic stub to delay // Set the target to the pre monomorphic stub to delay
// setting the monomorphic state. // setting the monomorphic state.
code = pre_monomorphic_stub(); set_target(*pre_monomorphic_stub());
TRACE_IC("LoadIC", name);
return;
} else if (!lookup->IsCacheable()) { } else if (!lookup->IsCacheable()) {
// Bail out if the result is not cacheable. // Bail out if the result is not cacheable.
code = slow_stub(); code = slow_stub();
@ -1175,8 +1177,9 @@ Handle<Code> IC::ComputeHandler(LookupResult* lookup,
if (!code.is_null()) return code; if (!code.is_null()) return code;
code = CompileHandler(lookup, receiver, name, value); code = CompileHandler(lookup, receiver, name, value);
ASSERT(code->is_handler());
if (code->is_handler() && code->type() != Code::NORMAL) { if (code->type() != Code::NORMAL) {
HeapObject::UpdateMapCodeCache(receiver, name, code); HeapObject::UpdateMapCodeCache(receiver, name, code);
} }
@ -1215,9 +1218,11 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
Handle<PropertyCell> cell( Handle<PropertyCell> cell(
global->GetPropertyCell(lookup), isolate()); global->GetPropertyCell(lookup), isolate());
// TODO(verwaest): Turn into a handler. Handle<Code> code = compiler.CompileLoadGlobal(
return isolate()->stub_cache()->ComputeLoadGlobal( receiver, global, cell, name, lookup->IsDontDelete());
name, receiver, global, cell, lookup->IsDontDelete()); // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
HeapObject::UpdateMapCodeCache(receiver, name, code);
return code;
} }
// There is only one shared stub for loading normalized // There is only one shared stub for loading normalized
// properties. It does not traverse the prototype chain, so the // properties. It does not traverse the prototype chain, so the
@ -1632,11 +1637,15 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
// from the property cell. So the property must be directly on the // from the property cell. So the property must be directly on the
// global object. // global object.
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
Handle<PropertyCell> cell( Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
global->GetPropertyCell(lookup), isolate()); Handle<Type> union_type = PropertyCell::UpdatedType(cell, value);
// TODO(verwaest): Turn into a handler. StoreGlobalStub stub(strict_mode(), union_type->IsConstant());
return isolate()->stub_cache()->ComputeStoreGlobal(
name, global, cell, value, strict_mode()); Handle<Code> code = stub.GetCodeCopyFromTemplate(
isolate(), receiver->map(), *cell);
// TODO(verwaest): Move caching of these NORMAL stubs outside as well.
HeapObject::UpdateMapCodeCache(receiver, name, code);
return code;
} }
ASSERT(holder.is_identical_to(receiver)); ASSERT(holder.is_identical_to(receiver));
return strict_mode() == kStrictMode return strict_mode() == kStrictMode

View File

@ -10543,7 +10543,7 @@ Map* Code::FindFirstMap() {
void Code::ReplaceNthObject(int n, void Code::ReplaceNthObject(int n,
Map* match_map, Map* match_map,
Object* replace_with) { Object* replace_with) {
ASSERT(is_inline_cache_stub()); ASSERT(is_inline_cache_stub() || is_handler());
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
for (RelocIterator it(this, mask); !it.done(); it.next()) { for (RelocIterator it(this, mask); !it.done(); it.next()) {

View File

@ -202,22 +202,6 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
} }
Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name,
Handle<JSObject> receiver,
Handle<GlobalObject> holder,
Handle<PropertyCell> cell,
bool is_dont_delete) {
Handle<Code> stub = FindIC(name, receiver, Code::LOAD_IC);
if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_);
Handle<Code> ic =
compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
HeapObject::UpdateMapCodeCache(receiver, name, ic);
return ic;
}
Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
Handle<Name> name = Handle<Name> name =
@ -262,35 +246,6 @@ Handle<Code> StubCache::ComputeKeyedStoreElement(
} }
Handle<Code> StubCache::ComputeStoreGlobal(Handle<Name> name,
Handle<GlobalObject> receiver,
Handle<PropertyCell> cell,
Handle<Object> value,
StrictModeFlag strict_mode) {
Handle<Type> union_type = PropertyCell::UpdatedType(cell, value);
bool is_constant = union_type->IsConstant();
StoreGlobalStub stub(strict_mode, is_constant);
Handle<Code> code = FindIC(
name, Handle<JSObject>::cast(receiver),
Code::STORE_IC, stub.GetExtraICState());
if (!code.is_null()) return code;
// Replace the placeholder cell and global object map with the actual global
// cell and receiver map.
Handle<Map> meta_map(isolate_->heap()->meta_map());
Handle<Object> receiver_map(receiver->map(), isolate_);
code = stub.GetCodeCopyFromTemplate(isolate_);
code->ReplaceNthObject(1, *meta_map, *receiver_map);
Handle<Map> cell_map(isolate_->heap()->global_property_cell_map());
code->ReplaceNthObject(1, *cell_map, *cell);
HeapObject::UpdateMapCodeCache(receiver, name, code);
return code;
}
#define CALL_LOGGER_TAG(kind, type) \ #define CALL_LOGGER_TAG(kind, type) \
(kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
@ -1596,7 +1551,6 @@ Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind,
Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind,
Code::StubType type, Code::StubType type,
Handle<Name> name) { Handle<Name> name) {
ASSERT(type != Code::NORMAL);
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
Code::HANDLER, MONOMORPHIC, extra_state(), type, kind); Code::HANDLER, MONOMORPHIC, extra_state(), type, kind);
Handle<Code> code = GetCodeWithFlags(flags, name); Handle<Code> code = GetCodeWithFlags(flags, name);

View File

@ -105,12 +105,6 @@ class StubCache {
Handle<Code> ComputeLoadNonexistent(Handle<Name> name, Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
Handle<JSObject> object); Handle<JSObject> object);
Handle<Code> ComputeLoadGlobal(Handle<Name> name,
Handle<JSObject> object,
Handle<GlobalObject> holder,
Handle<PropertyCell> cell,
bool is_dont_delete);
// --- // ---
Handle<Code> ComputeKeyedLoadField(Handle<Name> name, Handle<Code> ComputeKeyedLoadField(Handle<Name> name,
@ -140,12 +134,6 @@ class StubCache {
Handle<JSObject> object, Handle<JSObject> object,
Handle<JSObject> holder); Handle<JSObject> holder);
Handle<Code> ComputeStoreGlobal(Handle<Name> name,
Handle<GlobalObject> object,
Handle<PropertyCell> cell,
Handle<Object> value,
StrictModeFlag strict_mode);
Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map); Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map);
Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map, Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map,

View File

@ -3036,10 +3036,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
// TODO(verwaest): Directly store to rax. Currently we cannot do this, since // TODO(verwaest): Directly store to rax. Currently we cannot do this, since
// rax is used as receiver(), which we would otherwise clobber before a // rax is used as receiver(), which we would otherwise clobber before a
// potential miss. // potential miss.
HandlerFrontendHeader(object, receiver(), global, name, &miss);
__ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK);
HandlerFrontendHeader(
object, receiver(), Handle<JSObject>::cast(global), name, &miss);
// Get the value from the cell. // Get the value from the cell.
__ Move(rbx, cell); __ Move(rbx, cell);
@ -3063,7 +3060,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
__ ret(0); __ ret(0);
// Return the generated code. // Return the generated code.
return GetICCode(kind(), Code::NORMAL, name); return GetCode(kind(), Code::NORMAL, name);
} }