Convert PatchCache (and related methods) to use types rather than objects/maps.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 18 Nov 2013 17:18:14 +0000 (17:18 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 18 Nov 2013 17:18:14 +0000 (17:18 +0000)
R=rossberg@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17847 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/list.h
src/objects.cc
src/objects.h
src/stub-cache.cc
src/stub-cache.h
src/x64/stub-cache-x64.cc

index 9f3e0790ea53a7b68b8ac71bb943a14925d67564..2e3a0f8a3e4744294be395792901f5eaff001c4d 100644 (file)
@@ -3051,7 +3051,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
 
 
 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
-    MapHandleList* receiver_maps,
+    TypeHandleList* types,
     CodeHandleList* handlers,
     Handle<Name> name,
     Code::StubType type,
@@ -3063,22 +3063,22 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
   }
 
   Label number_case;
-  Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
+  Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
   __ JumpIfSmi(receiver(), smi_target);
 
   Register map_reg = scratch1();
 
-  int receiver_count = receiver_maps->length();
+  int receiver_count = types->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);
+    Handle<Type> type = types->at(current);
+    Handle<Map> map = IC::TypeToMap(*type, isolate());
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
-      __ mov(ip, Operand(receiver_maps->at(current)));
+      __ mov(ip, Operand(map));
       __ cmp(map_reg, ip);
-      if (map.is_identical_to(heap_number_map)) {
+      if (type->Is(Type::Number())) {
         ASSERT(!number_case.is_unused());
         __ bind(&number_case);
       }
index 40144208f67926866105d8e668ac75a17196175e..a3be0a777739e071980b4b57e73138768573f38e 100644 (file)
@@ -3156,7 +3156,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
 
 
 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
-    MapHandleList* receiver_maps,
+    TypeHandleList* types,
     CodeHandleList* handlers,
     Handle<Name> name,
     Code::StubType type,
@@ -3168,20 +3168,20 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
   }
 
   Label number_case;
-  Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
+  Label* smi_target = IncludesNumberType(types) ? &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 receiver_count = types->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);
+    Handle<Type> type = types->at(current);
+    Handle<Map> map = IC::TypeToMap(*type, isolate());
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
       __ cmp(map_reg, map);
-      if (map.is_identical_to(heap_number_map)) {
+      if (type->Is(Type::Number())) {
         ASSERT(!number_case.is_unused());
         __ bind(&number_case);
       }
index d1c31c0c8f3227e4afab1771daeed4ed7a803033..bd45c3e99d8a19a7778a6ef7439f4e4b18944ad9 100644 (file)
@@ -120,6 +120,39 @@ HeapObject* IC::GetCodeCacheHolder(Isolate* isolate,
 }
 
 
+InlineCacheHolderFlag IC::GetCodeCacheFlag(Type* type) {
+  if (type->Is(Type::Boolean()) ||
+      type->Is(Type::Number()) ||
+      type->Is(Type::String()) ||
+      type->Is(Type::Symbol())) {
+    return PROTOTYPE_MAP;
+  }
+  return OWN_MAP;
+}
+
+
+Handle<Map> IC::GetCodeCacheHolder(InlineCacheHolderFlag flag,
+                                   Type* type,
+                                   Isolate* isolate) {
+  if (flag == PROTOTYPE_MAP) {
+    Context* context = isolate->context()->native_context();
+    JSFunction* constructor;
+    if (type->Is(Type::Boolean())) {
+      constructor = context->boolean_function();
+    } else if (type->Is(Type::Number())) {
+      constructor = context->number_function();
+    } else if (type->Is(Type::String())) {
+      constructor = context->string_function();
+    } else {
+      ASSERT(type->Is(Type::Symbol()));
+      constructor = context->symbol_function();
+    }
+    return handle(JSObject::cast(constructor->instance_prototype())->map());
+  }
+  return type->AsClass();
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_IC_INL_H_
index 2f225323404f23b9471b6e7df1fdbff936e18559..9b304057ade037d471539297de6c3c4762d9bc73 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -783,7 +783,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
       : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())),
                          isolate());
 
-  PatchCache(cache_object, name, code);
+  PatchCache(handle(Type::CurrentOf(cache_object), isolate()), name, code);
   TRACE_IC("CallIC", name);
 }
 
@@ -967,79 +967,94 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
 }
 
 
-bool IC::UpdatePolymorphicIC(Handle<Object> receiver,
+bool IC::UpdatePolymorphicIC(Handle<Type> type,
                              Handle<String> name,
                              Handle<Code> code) {
   if (!code->is_handler()) return false;
-  MapHandleList receiver_maps;
+  TypeHandleList types;
   CodeHandleList handlers;
 
-  int number_of_valid_maps;
+  int number_of_valid_types;
   int handler_to_overwrite = -1;
-  Handle<Map> new_receiver_map(receiver->GetMarkerMap(isolate()));
-
-  target()->FindAllMaps(&receiver_maps);
-  int number_of_maps = receiver_maps.length();
-  number_of_valid_maps = number_of_maps;
-
-  for (int i = 0; i < number_of_maps; i++) {
-    Handle<Map> map = receiver_maps.at(i);
-    // Filter out deprecated maps to ensure its instances get migrated.
-    if (map->is_deprecated()) {
-      number_of_valid_maps--;
-    // If the receiver map is already in the polymorphic IC, this indicates
+
+  target()->FindAllTypes(&types);
+  int number_of_types = types.length();
+  number_of_valid_types = number_of_types;
+
+  for (int i = 0; i < number_of_types; i++) {
+    Handle<Type> current_type = types.at(i);
+    // Filter out deprecated maps to ensure their instances get migrated.
+    if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
+      number_of_valid_types--;
+    // If the receiver type is already in the polymorphic IC, this indicates
     // there was a prototoype chain failure. In that case, just overwrite the
     // handler.
-    } else if (map.is_identical_to(new_receiver_map)) {
-      number_of_valid_maps--;
+    } else if (type->Is(current_type)) {
+      ASSERT(handler_to_overwrite == -1);
+      number_of_valid_types--;
       handler_to_overwrite = i;
     }
   }
 
-  if (number_of_valid_maps >= 4) return false;
-  if (number_of_maps == 0) return false;
+  if (number_of_valid_types >= 4) return false;
+  if (number_of_types == 0) return false;
+  if (!target()->FindHandlers(&handlers, types.length())) return false;
 
-  if (!target()->FindHandlers(&handlers, receiver_maps.length())) {
-    return false;
-  }
-
-  number_of_valid_maps++;
+  number_of_valid_types++;
   if (handler_to_overwrite >= 0) {
     handlers.Set(handler_to_overwrite, code);
   } else {
-    receiver_maps.Add(new_receiver_map);
+    types.Add(type);
     handlers.Add(code);
   }
 
   Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
-      &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode());
+      &types, &handlers, number_of_valid_types, name, strict_mode());
   set_target(*ic);
   return true;
 }
 
 
-void IC::UpdateMonomorphicIC(Handle<Object> receiver,
+Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) {
+  if (type->Is(Type::Number())) return isolate->factory()->heap_number_map();
+  if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map();
+  ASSERT(type->IsClass());
+  return type->AsClass();
+}
+
+
+Type* IC::MapToType(Handle<Map> map) {
+  if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number();
+  // The only oddballs that can be recorded in ICs are booleans.
+  if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean();
+  return Type::Class(map);
+}
+
+
+void IC::UpdateMonomorphicIC(Handle<Type> type,
                              Handle<Code> handler,
                              Handle<String> name) {
   if (!handler->is_handler()) return set_target(*handler);
   Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
-      name, receiver, handler, strict_mode());
+      name, type, handler, strict_mode());
   set_target(*ic);
 }
 
 
 void IC::CopyICToMegamorphicCache(Handle<String> name) {
-  MapHandleList receiver_maps;
+  TypeHandleList types;
   CodeHandleList handlers;
-  target()->FindAllMaps(&receiver_maps);
-  if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
-  for (int i = 0; i < receiver_maps.length(); i++) {
-    UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
+  target()->FindAllTypes(&types);
+  if (!target()->FindHandlers(&handlers, types.length())) return;
+  for (int i = 0; i < types.length(); i++) {
+    UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
   }
 }
 
 
-bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
+bool IC::IsTransitionOfMonomorphicTarget(Type* type) {
+  if (!type->IsClass()) return false;
+  Map* receiver_map = *type->AsClass();
   Map* current_map = target()->FindFirstMap();
   ElementsKind receiver_elements_kind = receiver_map->elements_kind();
   bool more_general_transition =
@@ -1053,14 +1068,14 @@ bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
 }
 
 
-void IC::PatchCache(Handle<Object> object,
+void IC::PatchCache(Handle<Type> type,
                     Handle<String> name,
                     Handle<Code> code) {
   switch (state()) {
     case UNINITIALIZED:
     case PREMONOMORPHIC:
     case MONOMORPHIC_PROTOTYPE_FAILURE:
-      UpdateMonomorphicIC(object, code, name);
+      UpdateMonomorphicIC(type, code, name);
       break;
     case MONOMORPHIC: {
       // For now, call stubs are allowed to rewrite to the same stub. This
@@ -1069,23 +1084,21 @@ void IC::PatchCache(Handle<Object> object,
              target()->is_keyed_call_stub() ||
              !target().is_identical_to(code));
       Code* old_handler = target()->FindFirstHandler();
-      if (old_handler == *code &&
-          IsTransitionedMapOfMonomorphicTarget(
-              object->GetMarkerMap(isolate()))) {
-        UpdateMonomorphicIC(object, code, name);
+      if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) {
+        UpdateMonomorphicIC(type, code, name);
         break;
       }
       // Fall through.
     }
     case POLYMORPHIC:
       if (!target()->is_keyed_stub()) {
-        if (UpdatePolymorphicIC(object, name, code)) break;
+        if (UpdatePolymorphicIC(type, name, code)) break;
         CopyICToMegamorphicCache(name);
       }
       set_target(*megamorphic_stub());
       // Fall through.
     case MEGAMORPHIC:
-      UpdateMegamorphicCache(object->GetMarkerMap(isolate()), *name, *code);
+      UpdateMegamorphicCache(*type, *name, *code);
       break;
     case DEBUG_STUB:
       break;
@@ -1135,14 +1148,15 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
     code = ComputeHandler(lookup, object, name);
   }
 
-  PatchCache(object, name, code);
+  PatchCache(handle(Type::CurrentOf(object), isolate()), name, code);
   TRACE_IC("LoadIC", name);
 }
 
 
-void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
+void IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) {
   // Cache code holding map should be consistent with
   // GenerateMonomorphicCacheProbe.
+  Map* map = *TypeToMap(type, isolate());
   isolate()->stub_cache()->Set(name, map, code);
 }
 
@@ -1598,7 +1612,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
 
   Handle<Code> code = ComputeHandler(lookup, receiver, name, value);
 
-  PatchCache(receiver, name, code);
+  PatchCache(handle(Type::CurrentOf(receiver), isolate()), name, code);
   TRACE_IC("StoreIC", name);
 }
 
@@ -1744,7 +1758,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
       transitioned_receiver_map =
           ComputeTransitionedMap(receiver, store_mode);
     }
-    if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) {
+    if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) {
       // Element family is the same, use the "worst" case map.
       store_mode = GetNonTransitioningStoreMode(store_mode);
       return isolate()->stub_cache()->ComputeKeyedStoreElement(
index 3f5a25658b79dc29d82c96235dd37d749c29ab8c..7113b0b5121918a6b3d04694b422e67c0a63fe79 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -148,11 +148,24 @@ class IC {
                                                Object* object,
                                                InlineCacheHolderFlag holder);
 
+  static inline InlineCacheHolderFlag GetCodeCacheFlag(Type* type);
+  static inline Handle<Map> GetCodeCacheHolder(InlineCacheHolderFlag flag,
+                                               Type* type,
+                                               Isolate* isolate);
+
   static bool IsCleared(Code* code) {
     InlineCacheState state = code->ic_state();
     return state == UNINITIALIZED || state == PREMONOMORPHIC;
   }
 
+  // Utility functions to convert maps to types and back. There are two special
+  // cases:
+  // - The heap_number_map is used as a marker which includes heap numbers as
+  //   well as smis.
+  // - The oddball map is only used for booleans.
+  static Handle<Map> TypeToMap(Type* type, Isolate* isolate);
+  static Type* MapToType(Handle<Map> type);
+
  protected:
   // Get the call-site target; used for determining the state.
   Handle<Code> target() const { return target_; }
@@ -204,20 +217,22 @@ class IC {
     UNREACHABLE();
     return Handle<Code>::null();
   }
-  void UpdateMonomorphicIC(Handle<Object> receiver,
+
+  void UpdateMonomorphicIC(Handle<Type> type,
                            Handle<Code> handler,
                            Handle<String> name);
 
-  bool UpdatePolymorphicIC(Handle<Object> receiver,
+  bool UpdatePolymorphicIC(Handle<Type> type,
                            Handle<String> name,
                            Handle<Code> code);
 
+  virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code);
+
   void CopyICToMegamorphicCache(Handle<String> name);
-  bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map);
-  void PatchCache(Handle<Object> object,
+  bool IsTransitionOfMonomorphicTarget(Type* type);
+  void PatchCache(Handle<Type> type,
                   Handle<String> name,
                   Handle<Code> code);
-  virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code);
   virtual Code::Kind kind() const {
     UNREACHABLE();
     return Code::STUB;
@@ -512,7 +527,7 @@ class KeyedLoadIC: public LoadIC {
     return isolate()->builtins()->KeyedLoadIC_Slow();
   }
 
-  virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
+  virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
 
  private:
   // Stub accessors.
@@ -693,7 +708,7 @@ class KeyedStoreIC: public StoreIC {
  protected:
   virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
 
-  virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
+  virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
 
   virtual Handle<Code> pre_monomorphic_stub() {
     return pre_monomorphic_stub(isolate(), strict_mode());
index 41666deb2678f47520ef64fc63691cf3676669a2..ea67b8b0c6ce487b70ef031411975bebdf8b49ab 100644 (file)
@@ -197,11 +197,13 @@ class List {
 };
 
 class Map;
+class Type;
 class Code;
 template<typename T> class Handle;
 typedef List<Map*> MapList;
 typedef List<Code*> CodeList;
 typedef List<Handle<Map> > MapHandleList;
+typedef List<Handle<Type> > TypeHandleList;
 typedef List<Handle<Code> > CodeHandleList;
 
 // Perform binary search for an element in an already sorted
index 2212e575ebc704d2c3e813c954b90945fe2648ed..6cb5e212026de06051e8d83d9000964d4e3a7ba5 100644 (file)
@@ -10550,7 +10550,23 @@ void Code::FindAllMaps(MapHandleList* maps) {
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
     RelocInfo* info = it.rinfo();
     Object* object = info->target_object();
-    if (object->IsMap()) maps->Add(Handle<Map>(Map::cast(object)));
+    if (object->IsMap()) maps->Add(handle(Map::cast(object)));
+  }
+}
+
+
+void Code::FindAllTypes(TypeHandleList* types) {
+  ASSERT(is_inline_cache_stub());
+  DisallowHeapAllocation no_allocation;
+  int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+  Isolate* isolate = GetIsolate();
+  for (RelocIterator it(this, mask); !it.done(); it.next()) {
+    RelocInfo* info = it.rinfo();
+    Object* object = info->target_object();
+    if (object->IsMap()) {
+      Handle<Map> map(Map::cast(object));
+      types->Add(handle(IC::MapToType(map), isolate));
+    }
   }
 }
 
index 1a2187f1239028d02a1cbed1a6efb15dffe28b02..d44ae28053de6cce777caf8129c8fa84f07d0254 100644 (file)
@@ -5238,6 +5238,7 @@ class Code: public HeapObject {
   // Find the first map in an IC stub.
   Map* FindFirstMap();
   void FindAllMaps(MapHandleList* maps);
+  void FindAllTypes(TypeHandleList* types);
   void ReplaceFirstMap(Map* replace);
 
   // Find the first handler in an IC stub.
index af1f3a12a28ca72543b1468bd38836f7e4b19f4a..f9918ed62ef46c1286f743f37584527b3a3f7349 100644 (file)
@@ -134,37 +134,40 @@ Handle<Code> StubCache::FindHandler(Handle<Name> name,
 
 
 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
-                                             Handle<Object> object,
+                                             Handle<Type> type,
                                              Handle<Code> handler,
                                              StrictModeFlag strict_mode) {
   Code::Kind kind = handler->handler_kind();
-  // Use the same cache holder for the IC as for the handler.
-  InlineCacheHolderFlag cache_holder =
-      Code::ExtractCacheHolderFromFlags(handler->flags());
-  Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
-      isolate(), *object, cache_holder));
-  Handle<Map> stub_holder_map(stub_holder->map());
-  Handle<Code> ic = FindIC(
-      name, stub_holder_map, kind, strict_mode, cache_holder);
-  if (!ic.is_null()) return ic;
+  InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
+
+  Handle<Map> stub_holder;
+  Handle<Code> ic;
+  // There are multiple string maps that all use the same prototype. That
+  // prototype cannot hold multiple handlers, one for each of the string maps,
+  // for a single name. Hence, turn off caching of the IC.
+  bool can_be_cached = !type->Is(Type::String());
+  if (can_be_cached) {
+    stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
+    ic = FindIC(name, stub_holder, kind, strict_mode, flag);
+    if (!ic.is_null()) return ic;
+  }
 
-  Handle<Map> map(object->GetMarkerMap(isolate()));
   if (kind == Code::LOAD_IC) {
-    LoadStubCompiler ic_compiler(isolate(), cache_holder);
-    ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
+    LoadStubCompiler ic_compiler(isolate(), flag);
+    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
   } else if (kind == Code::KEYED_LOAD_IC) {
-    KeyedLoadStubCompiler ic_compiler(isolate(), cache_holder);
-    ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
+    KeyedLoadStubCompiler ic_compiler(isolate(), flag);
+    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
   } else if (kind == Code::STORE_IC) {
     StoreStubCompiler ic_compiler(isolate(), strict_mode);
-    ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
+    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
   } else {
     ASSERT(kind == Code::KEYED_STORE_IC);
     KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE);
-    ic = ic_compiler.CompileMonomorphicIC(map, handler, name);
+    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
   }
 
-  HeapObject::UpdateMapCodeCache(stub_holder, name, ic);
+  if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
   return ic;
 }
 
@@ -584,6 +587,7 @@ Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
 }
 
 
+// TODO(verwaest): Change this method so it takes in a TypeHandleList.
 Handle<Code> StubCache::ComputeLoadElementPolymorphic(
     MapHandleList* receiver_maps) {
   Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
@@ -592,12 +596,15 @@ Handle<Code> StubCache::ComputeLoadElementPolymorphic(
   Handle<Object> probe = cache->Lookup(receiver_maps, flags);
   if (probe->IsCode()) return Handle<Code>::cast(probe);
 
+  TypeHandleList types(receiver_maps->length());
+  for (int i = 0; i < receiver_maps->length(); i++) {
+    types.Add(handle(Type::Class(receiver_maps->at(i)), isolate()));
+  }
   CodeHandleList handlers(receiver_maps->length());
   KeyedLoadStubCompiler compiler(isolate_);
   compiler.CompileElementHandlers(receiver_maps, &handlers);
   Handle<Code> code = compiler.CompilePolymorphicIC(
-      receiver_maps, &handlers, factory()->empty_string(),
-      Code::NORMAL, ELEMENT);
+      &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT);
 
   isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
 
@@ -606,24 +613,24 @@ Handle<Code> StubCache::ComputeLoadElementPolymorphic(
 }
 
 
-Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps,
+Handle<Code> StubCache::ComputePolymorphicIC(TypeHandleList* types,
                                              CodeHandleList* handlers,
-                                             int number_of_valid_maps,
+                                             int number_of_valid_types,
                                              Handle<Name> name,
                                              StrictModeFlag strict_mode) {
   Handle<Code> handler = handlers->at(0);
   Code::Kind kind = handler->handler_kind();
-  Code::StubType type = number_of_valid_maps == 1 ? handler->type()
-                                                  : Code::NORMAL;
+  Code::StubType type = number_of_valid_types == 1 ? handler->type()
+                                                   : Code::NORMAL;
   if (kind == Code::LOAD_IC) {
     LoadStubCompiler ic_compiler(isolate_);
     return ic_compiler.CompilePolymorphicIC(
-        receiver_maps, handlers, name, type, PROPERTY);
+        types, handlers, name, type, PROPERTY);
   } else {
     ASSERT(kind == Code::STORE_IC);
     StoreStubCompiler ic_compiler(isolate_, strict_mode);
     return ic_compiler.CompilePolymorphicIC(
-        receiver_maps, handlers, name, type, PROPERTY);
+        types, handlers, name, type, PROPERTY);
   }
 }
 
@@ -1181,12 +1188,9 @@ 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;
-    }
+bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) {
+  for (int i = 0; i < types->length(); ++i) {
+    if (types->at(i)->Is(Type::Number())) return true;
   }
   return false;
 }
@@ -1353,15 +1357,15 @@ void LoadStubCompiler::GenerateLoadPostInterceptor(
 
 
 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
-    Handle<Map> receiver_map,
+    Handle<Type> type,
     Handle<Code> handler,
     Handle<Name> name) {
-  MapHandleList receiver_maps(1);
-  receiver_maps.Add(receiver_map);
+  TypeHandleList types(1);
   CodeHandleList handlers(1);
+  types.Add(type);
   handlers.Add(handler);
-  Code::StubType type = handler->type();
-  return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY);
+  Code::StubType stub_type = handler->type();
+  return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY);
 }
 
 
index 1daffff4a957961d5c9f63f6f92e8e3d893f2b99..adfa44a3ef01a8e4ff794bffb66a1c9d57986450 100644 (file)
@@ -93,7 +93,7 @@ class StubCache {
                            StrictModeFlag strict_mode = kNonStrictMode);
 
   Handle<Code> ComputeMonomorphicIC(Handle<Name> name,
-                                    Handle<Object> receiver,
+                                    Handle<Type> type,
                                     Handle<Code> handler,
                                     StrictModeFlag strict_mode);
 
@@ -173,7 +173,7 @@ class StubCache {
                                               KeyedAccessStoreMode store_mode,
                                               StrictModeFlag strict_mode);
 
-  Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps,
+  Handle<Code> ComputePolymorphicIC(TypeHandleList* types,
                                     CodeHandleList* handlers,
                                     int number_of_valid_maps,
                                     Handle<Name> name,
@@ -532,11 +532,11 @@ class BaseLoadStoreStubCompiler: public StubCompiler {
   }
   virtual ~BaseLoadStoreStubCompiler() { }
 
-  Handle<Code> CompileMonomorphicIC(Handle<Map> receiver_map,
+  Handle<Code> CompileMonomorphicIC(Handle<Type> type,
                                     Handle<Code> handler,
                                     Handle<Name> name);
 
-  Handle<Code> CompilePolymorphicIC(MapHandleList* receiver_maps,
+  Handle<Code> CompilePolymorphicIC(TypeHandleList* types,
                                     CodeHandleList* handlers,
                                     Handle<Name> name,
                                     Code::StubType type,
@@ -608,7 +608,7 @@ class BaseLoadStoreStubCompiler: public StubCompiler {
 
   void InitializeRegisters();
 
-  bool HasHeapNumberMap(MapHandleList* receiver_maps);
+  bool IncludesNumberType(TypeHandleList* types);
 
   Code::Kind kind_;
   InlineCacheHolderFlag cache_holder_;
index 431bf471071aefa7d51e9591fe16dffa506928ab..a1e8f211161e9c42cbfeffa0f9d9d3eb9818bcae 100644 (file)
@@ -3068,7 +3068,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
 
 
 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
-    MapHandleList* receiver_maps,
+    TypeHandleList* types,
     CodeHandleList* handlers,
     Handle<Name> name,
     Code::StubType type,
@@ -3080,21 +3080,21 @@ Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
   }
 
   Label number_case;
-  Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
+  Label* smi_target = IncludesNumberType(types) ? &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 receiver_count = types->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);
+    Handle<Type> type = types->at(current);
+    Handle<Map> map = IC::TypeToMap(*type, isolate());
     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)) {
+      __ Cmp(map_reg, map);
+      if (type->Is(Type::Number())) {
         ASSERT(!number_case.is_unused());
         __ bind(&number_case);
       }