Also support smi in load-ICs.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 14 Nov 2013 16:37:36 +0000 (16:37 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 14 Nov 2013 16:37:36 +0000 (16:37 +0000)
BUG=
R=ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17756 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/stub-cache-arm.cc
src/ia32/stub-cache-ia32.cc
src/ic-inl.h
src/ic.cc
src/ic.h
src/objects.cc
src/objects.h
src/stub-cache.cc
src/stub-cache.h
src/x64/stub-cache-x64.cc

index a163c53..984c7d5 100644 (file)
@@ -3054,18 +3054,26 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
     GenerateNameCheck(name, this->name(), &miss);
   }
 
-  __ JumpIfSmi(receiver(), &miss);
+  Label number_case;
+  Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
+  __ JumpIfSmi(receiver(), smi_target);
+
   Register map_reg = scratch1();
 
   int receiver_count = receiver_maps->length();
   int number_of_handled_maps = 0;
   __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
   for (int current = 0; current < receiver_count; ++current) {
     Handle<Map> map = receiver_maps->at(current);
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
       __ mov(ip, Operand(receiver_maps->at(current)));
       __ cmp(map_reg, ip);
+      if (map.is_identical_to(heap_number_map)) {
+        ASSERT(!number_case.is_unused());
+        __ bind(&number_case);
+      }
       __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
     }
   }
index 66edf2e..61639a9 100644 (file)
@@ -3163,16 +3163,24 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
     GenerateNameCheck(name, this->name(), &miss);
   }
 
-  __ JumpIfSmi(receiver(), &miss);
+  Label number_case;
+  Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
+  __ JumpIfSmi(receiver(), smi_target);
+
   Register map_reg = scratch1();
   __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
   int receiver_count = receiver_maps->length();
   int number_of_handled_maps = 0;
+  Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
   for (int current = 0; current < receiver_count; ++current) {
     Handle<Map> map = receiver_maps->at(current);
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
       __ cmp(map_reg, map);
+      if (map.is_identical_to(heap_number_map)) {
+        ASSERT(!number_case.is_unused());
+        __ bind(&number_case);
+      }
       __ j(equal, handlers->at(current));
     }
   }
index c1c5c5e..d1c31c0 100644 (file)
@@ -113,8 +113,9 @@ InlineCacheHolderFlag IC::GetCodeCacheForObject(Object* object) {
 HeapObject* IC::GetCodeCacheHolder(Isolate* isolate,
                                  Object* object,
                                  InlineCacheHolderFlag holder) {
-  Object* map_owner =
-      holder == OWN_MAP ? object : object->GetPrototype(isolate);
+  if (object->IsSmi()) holder = PROTOTYPE_MAP;
+  Object* map_owner = holder == OWN_MAP
+      ? object : object->GetPrototype(isolate);
   return HeapObject::cast(map_owner);
 }
 
index 187023e..fa59e31 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -949,7 +949,7 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
 }
 
 
-bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
+bool IC::UpdatePolymorphicIC(Handle<Object> receiver,
                              Handle<String> name,
                              Handle<Code> code) {
   if (!code->is_handler()) return false;
@@ -958,7 +958,7 @@ bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
 
   int number_of_valid_maps;
   int handler_to_overwrite = -1;
-  Handle<Map> new_receiver_map(receiver->map());
+  Handle<Map> new_receiver_map(receiver->GetMarkerMap(isolate()));
 
   target()->FindAllMaps(&receiver_maps);
   int number_of_maps = receiver_maps.length();
@@ -1000,7 +1000,7 @@ bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
 }
 
 
-void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver,
+void IC::UpdateMonomorphicIC(Handle<Object> receiver,
                              Handle<Code> handler,
                              Handle<String> name) {
   if (!handler->is_handler()) return set_target(*handler);
@@ -1038,43 +1038,36 @@ bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
 void IC::PatchCache(Handle<Object> object,
                     Handle<String> name,
                     Handle<Code> code) {
-  // TODO(verwaest): Handle smi here as well.
-  if (!object->IsHeapObject()) return;
-
-  Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
   switch (state()) {
     case UNINITIALIZED:
     case PREMONOMORPHIC:
     case MONOMORPHIC_PROTOTYPE_FAILURE:
-      UpdateMonomorphicIC(receiver, code, name);
+      UpdateMonomorphicIC(object, code, name);
       break;
-    case MONOMORPHIC:
+    case MONOMORPHIC: {
       // For now, call stubs are allowed to rewrite to the same stub. This
       // happens e.g., when the field does not contain a function.
       ASSERT(target()->is_call_stub() ||
              target()->is_keyed_call_stub() ||
              !target().is_identical_to(code));
-      if (!target()->is_keyed_stub()) {
-        bool is_same_handler = false;
-        Code* old_handler = target()->FindFirstHandler();
-        is_same_handler = old_handler == *code;
-
-        if (is_same_handler &&
-            IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
-          UpdateMonomorphicIC(receiver, code, name);
-          break;
-        }
+      Code* old_handler = target()->FindFirstHandler();
+      if (old_handler == *code &&
+          IsTransitionedMapOfMonomorphicTarget(
+              object->GetMarkerMap(isolate()))) {
+        UpdateMonomorphicIC(object, code, name);
+        break;
       }
       // Fall through.
+    }
     case POLYMORPHIC:
       if (!target()->is_keyed_stub()) {
-        if (UpdatePolymorphicIC(receiver, name, code)) break;
+        if (UpdatePolymorphicIC(object, name, code)) break;
         CopyICToMegamorphicCache(name);
       }
       set_target(*megamorphic_stub());
       // Fall through.
     case MEGAMORPHIC:
-      UpdateMegamorphicCache(receiver->map(), *name, *code);
+      UpdateMegamorphicCache(object->GetMarkerMap(isolate()), *name, *code);
       break;
     case DEBUG_STUB:
       break;
index 819cb4b..33252e8 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -193,11 +193,11 @@ class IC {
     UNREACHABLE();
     return Handle<Code>::null();
   }
-  void UpdateMonomorphicIC(Handle<HeapObject> receiver,
+  void UpdateMonomorphicIC(Handle<Object> receiver,
                            Handle<Code> handler,
                            Handle<String> name);
 
-  bool UpdatePolymorphicIC(Handle<HeapObject> receiver,
+  bool UpdatePolymorphicIC(Handle<Object> receiver,
                            Handle<String> name,
                            Handle<Code> code);
 
index 8308146..651ad6f 100644 (file)
@@ -1028,6 +1028,12 @@ Object* Object::GetPrototype(Isolate* isolate) {
 }
 
 
+Map* Object::GetMarkerMap(Isolate* isolate) {
+  if (IsSmi()) return isolate->heap()->heap_number_map();
+  return HeapObject::cast(this)->map();
+}
+
+
 Object* Object::GetHash() {
   // The object is either a number, a name, an odd-ball,
   // a real JS object, or a Harmony proxy.
index 85627b7..6fe18fa 100644 (file)
@@ -1494,6 +1494,7 @@ class Object : public MaybeObject {
 
   // Return the object's prototype (might be Heap::null_value()).
   Object* GetPrototype(Isolate* isolate);
+  Map* GetMarkerMap(Isolate* isolate);
 
   // Returns the permanent hash code associated with this object. May return
   // undefined if not yet created.
index 9dc89c2..b3d93f3 100644 (file)
@@ -134,7 +134,7 @@ Handle<Code> StubCache::FindHandler(Handle<Name> name,
 
 
 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
-                                             Handle<HeapObject> object,
+                                             Handle<Object> object,
                                              Handle<Code> handler,
                                              StrictModeFlag strict_mode) {
   Code::Kind kind = handler->handler_kind();
@@ -148,7 +148,7 @@ Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
       name, stub_holder_map, kind, strict_mode, cache_holder);
   if (!ic.is_null()) return ic;
 
-  Handle<Map> map(object->map());
+  Handle<Map> map(object->GetMarkerMap(isolate()));
   if (kind == Code::LOAD_IC) {
     LoadStubCompiler ic_compiler(isolate(), cache_holder);
     ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
@@ -1181,6 +1181,17 @@ Register StoreStubCompiler::HandlerFrontendHeader(
 }
 
 
+bool BaseLoadStoreStubCompiler::HasHeapNumberMap(MapHandleList* receiver_maps) {
+  for (int i = 0; i < receiver_maps->length(); ++i) {
+    Handle<Map> map = receiver_maps->at(i);
+    if (map.is_identical_to(isolate()->factory()->heap_number_map())) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object,
                                                     Register object_reg,
                                                     Handle<JSObject> holder,
index 2f78fde..1daffff 100644 (file)
@@ -93,7 +93,7 @@ class StubCache {
                            StrictModeFlag strict_mode = kNonStrictMode);
 
   Handle<Code> ComputeMonomorphicIC(Handle<Name> name,
-                                    Handle<HeapObject> receiver,
+                                    Handle<Object> receiver,
                                     Handle<Code> handler,
                                     StrictModeFlag strict_mode);
 
@@ -608,6 +608,8 @@ class BaseLoadStoreStubCompiler: public StubCompiler {
 
   void InitializeRegisters();
 
+  bool HasHeapNumberMap(MapHandleList* receiver_maps);
+
   Code::Kind kind_;
   InlineCacheHolderFlag cache_holder_;
   Register* registers_;
index b4222bc..3a1a179 100644 (file)
@@ -3071,17 +3071,25 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
     GenerateNameCheck(name, this->name(), &miss);
   }
 
-  __ JumpIfSmi(receiver(), &miss);
+  Label number_case;
+  Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
+  __ JumpIfSmi(receiver(), smi_target);
+
   Register map_reg = scratch1();
   __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
   int receiver_count = receiver_maps->length();
   int number_of_handled_maps = 0;
+  Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
   for (int current = 0; current < receiver_count; ++current) {
     Handle<Map> map = receiver_maps->at(current);
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
       // Check map and tail call if there's a match
       __ Cmp(map_reg, receiver_maps->at(current));
+      if (map.is_identical_to(heap_number_map)) {
+        ASSERT(!number_case.is_unused());
+        __ bind(&number_case);
+      }
       __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
     }
   }