Turn Load/StoreGlobal into a handler.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Nov 2013 10:17:13 +0000 (10:17 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Nov 2013 10:17:13 +0000 (10:17 +0000)
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
src/code-stubs.h
src/ia32/stub-cache-ia32.cc
src/ic.cc
src/objects.cc
src/stub-cache.cc
src/stub-cache.h
src/x64/stub-cache-x64.cc

index 923011f..a7ddc8e 100644 (file)
@@ -3020,10 +3020,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
     bool is_dont_delete) {
   Label success, miss;
 
-  __ CheckMap(
-      receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK);
-  HandlerFrontendHeader(
-      object, receiver(), Handle<JSObject>::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<Code> LoadStubCompiler::CompileLoadGlobal(
   __ Ret();
 
   // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, name);
+  return GetCode(kind(), Code::NORMAL, name);
 }
 
 
index 80d99d8..3dc32e8 100644 (file)
@@ -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<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 {
  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<Code::Kind, 0, 4> {};
   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<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 {
  public:
   KeyedLoadFieldStub(bool inobject, int index, Representation representation)
index 0648833..23e2398 100644 (file)
@@ -3125,9 +3125,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
     bool is_dont_delete) {
   Label success, miss;
 
-  __ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK);
-  HandlerFrontendHeader(
-      object, receiver(), Handle<JSObject>::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<Code> LoadStubCompiler::CompileLoadGlobal(
   __ ret(0);
 
   // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, name);
+  return GetCode(kind(), Code::NORMAL, name);
 }
 
 
index 193ec16..dafb6d3 100644 (file)
--- 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;
-  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> 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<HeapObject> receiver,
                              Handle<String> name,
                              Handle<Code> 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<Code> 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<Code> LoadIC::CompileHandler(LookupResult* lookup,
         Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
         Handle<PropertyCell> cell(
             global->GetPropertyCell(lookup), isolate());
-        // TODO(verwaest): Turn into a handler.
-        return isolate()->stub_cache()->ComputeLoadGlobal(
-            name, receiver, global, cell, lookup->IsDontDelete());
+        Handle<Code> 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<Code> StoreIC::CompileHandler(LookupResult* lookup,
         // from the property cell. So the property must be directly on the
         // global object.
         Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
-        Handle<PropertyCell> cell(
-            global->GetPropertyCell(lookup), isolate());
-        // TODO(verwaest): Turn into a handler.
-        return isolate()->stub_cache()->ComputeStoreGlobal(
-            name, global, cell, value, strict_mode());
+        Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
+        Handle<Type> union_type = PropertyCell::UpdatedType(cell, value);
+        StoreGlobalStub stub(strict_mode(), union_type->IsConstant());
+
+        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));
       return strict_mode() == kStrictMode
index 6ed25f6..489f3f5 100644 (file)
@@ -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()) {
index 1ec00d4..8ab4e26 100644 (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) {
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
   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) \
     (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,
                                                 Code::StubType type,
                                                 Handle<Name> name) {
-  ASSERT(type != Code::NORMAL);
   Code::Flags flags = Code::ComputeFlags(
       Code::HANDLER, MONOMORPHIC, extra_state(), type, kind);
   Handle<Code> code = GetCodeWithFlags(flags, name);
index 42685b2..4642339 100644 (file)
@@ -105,12 +105,6 @@ class StubCache {
   Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
                                       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,
@@ -140,12 +134,6 @@ class StubCache {
                                            Handle<JSObject> object,
                                            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> ComputeKeyedStoreElement(Handle<Map> receiver_map,
index f5339ca..499ccdf 100644 (file)
@@ -3036,10 +3036,7 @@ Handle<Code> 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<Map>(object->map()), &miss, DO_SMI_CHECK);
-  HandlerFrontendHeader(
-      object, receiver(), Handle<JSObject>::cast(global), name, &miss);
+  HandlerFrontendHeader(object, receiver(), global, name, &miss);
 
   // Get the value from the cell.
   __ Move(rbx, cell);
@@ -3063,7 +3060,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
   __ ret(0);
 
   // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, name);
+  return GetCode(kind(), Code::NORMAL, name);
 }