From 442e77d536ef587467b5fc6ae5c8a95567f52db7 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Thu, 7 Nov 2013 10:17:13 +0000 Subject: [PATCH] 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 --- src/arm/stub-cache-arm.cc | 7 +-- src/code-stubs.h | 109 +++++++++++++++++++----------------- src/ia32/stub-cache-ia32.cc | 6 +- src/ic.cc | 41 ++++++++------ src/objects.cc | 2 +- src/stub-cache.cc | 46 --------------- src/stub-cache.h | 12 ---- src/x64/stub-cache-x64.cc | 7 +-- 8 files changed, 90 insertions(+), 140 deletions(-) diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 923011fe08..a7ddc8e532 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -3020,10 +3020,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( bool is_dont_delete) { Label success, miss; - __ CheckMap( - receiver(), scratch1(), Handle(object->map()), &miss, DO_SMI_CHECK); - HandlerFrontendHeader( - object, receiver(), Handle::cast(global), name, &miss); + HandlerFrontendHeader(object, receiver(), global, name, &miss); // Get the value from the cell. __ mov(r3, Operand(cell)); @@ -3045,7 +3042,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( __ Ret(); // Return the generated code. - return GetICCode(kind(), Code::NORMAL, name); + return GetCode(kind(), Code::NORMAL, name); } diff --git a/src/code-stubs.h b/src/code-stubs.h index 80d99d8b68..3dc32e8913 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -553,51 +553,6 @@ class FastNewBlockContextStub : public PlatformCodeStub { 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 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 {}; - class IsConstantBits: public BitField {}; - class RepresentationBits: public BitField {}; - - int bit_field_; - - DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub); -}; - - class FastCloneShallowArrayStub : public HydrogenCodeStub { public: // Maximum length of copied elements array. @@ -899,7 +854,6 @@ class HICStub: public HydrogenCodeStub { virtual InlineCacheState GetICState() { return MONOMORPHIC; } protected: - HICStub() { } class KindBits: public BitField {}; virtual Code::Kind kind() const = 0; }; @@ -909,16 +863,12 @@ class HandlerStub: public HICStub { public: virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } virtual int GetStubFlags() { return kind(); } - - protected: - HandlerStub() : HICStub() { } }; class LoadFieldStub: public HandlerStub { public: - LoadFieldStub(bool inobject, int index, Representation representation) - : HandlerStub() { + LoadFieldStub(bool inobject, int index, Representation 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 GetCodeCopyFromTemplate(Isolate* isolate, + Map* receiver_map, + PropertyCell* cell) { + Handle 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 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 {}; + class IsConstantBits: public BitField {}; + class RepresentationBits: public BitField {}; + + int bit_field_; + + DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub); +}; + + class KeyedLoadFieldStub: public LoadFieldStub { public: KeyedLoadFieldStub(bool inobject, int index, Representation representation) diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 0648833dc7..23e2398b34 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -3125,9 +3125,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( bool is_dont_delete) { Label success, miss; - __ CheckMap(receiver(), Handle(object->map()), &miss, DO_SMI_CHECK); - HandlerFrontendHeader( - object, receiver(), Handle::cast(global), name, &miss); + HandlerFrontendHeader(object, receiver(), global, name, &miss); // Get the value from the cell. if (Serializer::enabled()) { __ mov(eax, Immediate(cell)); @@ -3154,7 +3152,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( __ ret(0); // Return the generated code. - return GetICCode(kind(), Code::NORMAL, name); + return GetCode(kind(), Code::NORMAL, name); } diff --git a/src/ic.cc b/src/ic.cc index 193ec1603e..dafb6d3321 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -768,12 +768,13 @@ void CallICBase::UpdateCaches(LookupResult* lookup, // Bail out if we didn't find a result. if (!lookup->IsProperty() || !lookup->IsCacheable()) return; - // Compute the number of arguments. - Handle code; - code = state() == UNINITIALIZED - ? pre_monomorphic_stub() - : ComputeMonomorphicStub(lookup, object, name); + if (state() == UNINITIALIZED) { + set_target(*pre_monomorphic_stub()); + TRACE_IC("CallIC", name); + return; + } + Handle code = ComputeMonomorphicStub(lookup, object, name); // 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, // and deopting Crankshaft code. @@ -954,7 +955,6 @@ bool IC::UpdatePolymorphicIC(Handle receiver, Handle name, Handle code) { if (!code->is_handler()) return false; - MapHandleList receiver_maps; CodeHandleList handlers; @@ -1133,7 +1133,9 @@ void LoadIC::UpdateCaches(LookupResult* lookup, // This is the first time we execute this inline cache. // Set the target to the pre monomorphic stub to delay // setting the monomorphic state. - code = pre_monomorphic_stub(); + set_target(*pre_monomorphic_stub()); + TRACE_IC("LoadIC", name); + return; } else if (!lookup->IsCacheable()) { // Bail out if the result is not cacheable. code = slow_stub(); @@ -1175,8 +1177,9 @@ Handle IC::ComputeHandler(LookupResult* lookup, if (!code.is_null()) return code; 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); } @@ -1215,9 +1218,11 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, Handle global = Handle::cast(holder); Handle cell( global->GetPropertyCell(lookup), isolate()); - // TODO(verwaest): Turn into a handler. - return isolate()->stub_cache()->ComputeLoadGlobal( - name, receiver, global, cell, lookup->IsDontDelete()); + Handle code = compiler.CompileLoadGlobal( + receiver, global, cell, name, 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 // properties. It does not traverse the prototype chain, so the @@ -1632,11 +1637,15 @@ Handle StoreIC::CompileHandler(LookupResult* lookup, // from the property cell. So the property must be directly on the // global object. Handle global = Handle::cast(receiver); - Handle cell( - global->GetPropertyCell(lookup), isolate()); - // TODO(verwaest): Turn into a handler. - return isolate()->stub_cache()->ComputeStoreGlobal( - name, global, cell, value, strict_mode()); + Handle cell(global->GetPropertyCell(lookup), isolate()); + Handle union_type = PropertyCell::UpdatedType(cell, value); + StoreGlobalStub stub(strict_mode(), union_type->IsConstant()); + + Handle 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)); return strict_mode() == kStrictMode diff --git a/src/objects.cc b/src/objects.cc index 6ed25f6e9f..489f3f5ac7 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -10543,7 +10543,7 @@ Map* Code::FindFirstMap() { void Code::ReplaceNthObject(int n, Map* match_map, Object* replace_with) { - ASSERT(is_inline_cache_stub()); + ASSERT(is_inline_cache_stub() || is_handler()); DisallowHeapAllocation no_allocation; int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); for (RelocIterator it(this, mask); !it.done(); it.next()) { diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 1ec00d49bb..8ab4e262c8 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -202,22 +202,6 @@ Handle StubCache::ComputeLoadNonexistent(Handle name, } -Handle StubCache::ComputeLoadGlobal(Handle name, - Handle receiver, - Handle holder, - Handle cell, - bool is_dont_delete) { - Handle stub = FindIC(name, receiver, Code::LOAD_IC); - if (!stub.is_null()) return stub; - - LoadStubCompiler compiler(isolate_); - Handle ic = - compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); - HeapObject::UpdateMapCodeCache(receiver, name, ic); - return ic; -} - - Handle StubCache::ComputeKeyedLoadElement(Handle receiver_map) { Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); Handle name = @@ -262,35 +246,6 @@ Handle StubCache::ComputeKeyedStoreElement( } -Handle StubCache::ComputeStoreGlobal(Handle name, - Handle receiver, - Handle cell, - Handle value, - StrictModeFlag strict_mode) { - Handle union_type = PropertyCell::UpdatedType(cell, value); - bool is_constant = union_type->IsConstant(); - StoreGlobalStub stub(strict_mode, is_constant); - - Handle code = FindIC( - name, Handle::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 meta_map(isolate_->heap()->meta_map()); - Handle receiver_map(receiver->map(), isolate_); - code = stub.GetCodeCopyFromTemplate(isolate_); - code->ReplaceNthObject(1, *meta_map, *receiver_map); - Handle 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) \ (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) @@ -1596,7 +1551,6 @@ Handle BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind, Handle BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, Code::StubType type, Handle name) { - ASSERT(type != Code::NORMAL); Code::Flags flags = Code::ComputeFlags( Code::HANDLER, MONOMORPHIC, extra_state(), type, kind); Handle code = GetCodeWithFlags(flags, name); diff --git a/src/stub-cache.h b/src/stub-cache.h index 42685b2059..4642339b36 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -105,12 +105,6 @@ class StubCache { Handle ComputeLoadNonexistent(Handle name, Handle object); - Handle ComputeLoadGlobal(Handle name, - Handle object, - Handle holder, - Handle cell, - bool is_dont_delete); - // --- Handle ComputeKeyedLoadField(Handle name, @@ -140,12 +134,6 @@ class StubCache { Handle object, Handle holder); - Handle ComputeStoreGlobal(Handle name, - Handle object, - Handle cell, - Handle value, - StrictModeFlag strict_mode); - Handle ComputeKeyedLoadElement(Handle receiver_map); Handle ComputeKeyedStoreElement(Handle receiver_map, diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index f5339ca387..499ccdf24c 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -3036,10 +3036,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( // TODO(verwaest): Directly store to rax. Currently we cannot do this, since // rax is used as receiver(), which we would otherwise clobber before a // potential miss. - - __ CheckMap(receiver(), Handle(object->map()), &miss, DO_SMI_CHECK); - HandlerFrontendHeader( - object, receiver(), Handle::cast(global), name, &miss); + HandlerFrontendHeader(object, receiver(), global, name, &miss); // Get the value from the cell. __ Move(rbx, cell); @@ -3063,7 +3060,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( __ ret(0); // Return the generated code. - return GetICCode(kind(), Code::NORMAL, name); + return GetCode(kind(), Code::NORMAL, name); }