Revision: 20426
Author:   [email protected]
Date:     Wed Apr  2 07:59:54 2014 UTC
Log:      Lazily initialize the target map list in IC.

This makes sure that we keep the target map list alive in the handle scope during IC computation.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/220923003
http://code.google.com/p/v8/source/detail?r=20426

Modified:
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/ic.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/ic.cc   Tue Apr  1 14:16:54 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc   Wed Apr  2 07:59:54 2014 UTC
@@ -121,7 +121,8 @@

 IC::IC(FrameDepth depth, Isolate* isolate)
     : isolate_(isolate),
-      target_set_(false) {
+      target_set_(false),
+      target_maps_set_(false) {
   // To improve the performance of the (much used) IC code, we unfold a few
// levels of the stack frame iteration code. This yields a ~35% speedup when // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
@@ -293,7 +294,7 @@
// If the IC is shared between multiple receivers (slow dictionary mode), then
   // the map cannot be deprecated and the stub invalidated.
   if (cache_holder == OWN_MAP) {
-    Map* old_map = target()->FindFirstMap();
+    Map* old_map = FirstTargetMap();
     if (old_map == *map) return true;
     if (old_map != NULL) {
       if (old_map->is_deprecated()) return true;
@@ -632,7 +633,7 @@
   TypeHandleList types;
   CodeHandleList handlers;

-  target()->FindAllTypes(&types);
+  TargetTypes(&types);
   int number_of_types = types.length();
   int deprecated_types = 0;
   int handler_to_overwrite = -1;
@@ -735,7 +736,7 @@
 void IC::CopyICToMegamorphicCache(Handle<String> name) {
   TypeHandleList types;
   CodeHandleList handlers;
-  target()->FindAllTypes(&types);
+  TargetTypes(&types);
   if (!target()->FindHandlers(&handlers, types.length())) return;
   for (int i = 0; i < types.length(); i++) {
     UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
@@ -1036,19 +1037,13 @@

   Handle<Map> receiver_map(receiver->map(), isolate());
   MapHandleList target_receiver_maps;
-  if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
- // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
-    // yet will do so and stay there.
-    return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
-  }
-
   if (target().is_identical_to(string_stub())) {
     target_receiver_maps.Add(isolate()->factory()->string_map());
   } else {
-    target()->FindAllMaps(&target_receiver_maps);
-    if (target_receiver_maps.length() == 0) {
- return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
-    }
+    TargetMaps(&target_receiver_maps);
+  }
+  if (target_receiver_maps.length() == 0) {
+    return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
   }

// The first time a receiver is seen that is a transitioned version of the
@@ -1435,23 +1430,14 @@
   }

   Handle<Map> receiver_map(receiver->map(), isolate());
-  if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
- // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
-    // yet will do so and stay there.
+  MapHandleList target_receiver_maps;
+  TargetMaps(&target_receiver_maps);
+  if (target_receiver_maps.length() == 0) {
Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode);
     store_mode = GetNonTransitioningStoreMode(store_mode);
     return isolate()->stub_cache()->ComputeKeyedStoreElement(
         monomorphic_map, strict_mode(), store_mode);
   }
-
-  MapHandleList target_receiver_maps;
-  target()->FindAllMaps(&target_receiver_maps);
-  if (target_receiver_maps.length() == 0) {
- // In the case that there is a non-map-specific IC is installed (e.g. keyed
-    // stores into properties in dictionary mode), then there will be not
-    // receiver maps in the target.
-    return generic_stub();
-  }

// There are several special cases where an IC that is MONOMORPHIC can still // transition to a different GetNonTransitioningStoreMode IC that handles a
@@ -2754,8 +2740,8 @@
   // Find or create the specialized stub to support the new set of types.
   Handle<Code> code;
   if (stub.IsMonomorphic()) {
-    Handle<Map> monomorphic_map(already_monomorphic
-                                ? target()->FindFirstMap()
+ Handle<Map> monomorphic_map(already_monomorphic && FirstTargetMap() != NULL
+                                ? FirstTargetMap()
                                 : HeapObject::cast(*object)->map());
code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub);
   } else {
=======================================
--- /branches/bleeding_edge/src/ic.h    Tue Apr  1 14:16:54 2014 UTC
+++ /branches/bleeding_edge/src/ic.h    Wed Apr  2 07:59:54 2014 UTC
@@ -252,6 +252,25 @@
   void set_extra_ic_state(ExtraICState state) {
     extra_ic_state_ = state;
   }
+
+  void TargetMaps(MapHandleList* list) {
+    FindTargetMaps();
+    for (int i = 0; i < target_maps_.length(); i++) {
+      list->Add(target_maps_.at(i));
+    }
+  }
+
+  void TargetTypes(TypeHandleList* list) {
+    FindTargetMaps();
+    for (int i = 0; i < target_maps_.length(); i++) {
+      list->Add(IC::MapToType<HeapType>(target_maps_.at(i), isolate_));
+    }
+  }
+
+  Map* FirstTargetMap() {
+    FindTargetMaps();
+    return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
+  }

  protected:
   void UpdateTarget() {
@@ -265,6 +284,17 @@
   inline ConstantPoolArray* constant_pool() const;
   inline ConstantPoolArray* raw_constant_pool() const;

+  void FindTargetMaps() {
+    if (target_maps_set_) return;
+    target_maps_set_ = true;
+    if (state_ == MONOMORPHIC) {
+      Map* map = target_->FindFirstMap();
+      if (map != NULL) target_maps_.Add(handle(map));
+    } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
+      target_->FindAllMaps(&target_maps_);
+    }
+  }
+
   // Frame pointer for the frame that uses (calls) the IC.
   Address fp_;

@@ -286,6 +316,8 @@
   bool target_set_;

   ExtraICState extra_ic_state_;
+  MapHandleList target_maps_;
+  bool target_maps_set_;

   DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
 };
=======================================
--- /branches/bleeding_edge/src/objects.cc      Tue Apr  1 11:30:31 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Wed Apr  2 07:59:54 2014 UTC
@@ -10538,21 +10538,6 @@
     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);
-  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(IC::MapToType<HeapType>(map, map->GetIsolate()));
-    }
-  }
-}


 Code* Code::FindFirstHandler() {
=======================================
--- /branches/bleeding_edge/src/objects.h       Tue Apr  1 11:30:31 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Wed Apr  2 07:59:54 2014 UTC
@@ -5407,7 +5407,6 @@
   // Find the first map in an IC stub.
   Map* FindFirstMap();
   void FindAllMaps(MapHandleList* maps);
-  void FindAllTypes(TypeHandleList* types);

   // Find the first handler in an IC stub.
   Code* FindFirstHandler();

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to