Reviewers: Hannes Payer,

Message:
Hi Hannes, here is the issue we discussed.

Description:
Vector ICs: Stop iterating the heap to clear keyed store ics.

When vector based stores are on, we don't need to do this anymore.

BUG=

Please review this at https://codereview.chromium.org/1314433004/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+58, -17 lines):
  M src/heap/heap.h
  M src/heap/heap.cc
  M src/objects.cc
  M src/objects-printer.cc
  M src/type-feedback-vector.h
  M src/type-feedback-vector.cc


Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index ec3837cfbec09c4ce8f52b2e9a7530d8203863c4..531c170c140007f3a4869a3114461ac7771a7074 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -477,16 +477,26 @@ const char* Heap::GetSpaceName(int idx) {
 }


-void Heap::ClearAllICsByKind(Code::Kind kind) {
-  // TODO(mvstanton): Do not iterate the heap.
-  HeapObjectIterator it(code_space());
-
-  for (Object* object = it.Next(); object != NULL; object = it.Next()) {
-    Code* code = Code::cast(object);
-    Code::Kind current_kind = code->kind();
-    if (current_kind == Code::FUNCTION ||
-        current_kind == Code::OPTIMIZED_FUNCTION) {
-      code->ClearInlineCaches(kind);
+void Heap::ClearAllKeyedStoreICs() {
+  if (FLAG_vector_stores) {
+    SharedFunctionInfo::Iterator iterator(isolate_);
+    SharedFunctionInfo* shared;
+    while ((shared = iterator.Next())) {
+      TypeFeedbackVector* vector = shared->feedback_vector();
+      vector->ClearKeyedStoreICs(shared);
+    }
+  } else {
+ // TODO(mvstanton): Remove this branch when FLAG_vector_stores is turned on
+    // permanently.
+    HeapObjectIterator it(code_space());
+
+    for (Object* object = it.Next(); object != NULL; object = it.Next()) {
+      Code* code = Code::cast(object);
+      Code::Kind current_kind = code->kind();
+      if (current_kind == Code::FUNCTION ||
+          current_kind == Code::OPTIMIZED_FUNCTION) {
+        code->ClearInlineCaches(Code::KEYED_STORE_IC);
+      }
     }
   }
 }
Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index 5c825e77804ad06cd30b1f3ae3ae6b4d562bcd86..0433bf7ecc8e0132cb5693a910547c24a0927b92 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -853,8 +853,8 @@ class Heap {
   // Clear the Instanceof cache (used when a prototype changes).
   inline void ClearInstanceofCache();

-  // Iterates the whole code space to clear all ICs of the given kind.
-  void ClearAllICsByKind(Code::Kind kind);
+  // Iterates the whole code space to clear all keyed store ICs.
+  void ClearAllKeyedStoreICs();

// FreeSpace objects have a null map after deserialization. Update the map.
   void RepairFreeListsAfterDeserialization();
Index: src/objects-printer.cc
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index de8aa444d45d7eeecf0c8ec843a2534abd9b9f56..538864418776ad8492e755f38dd728e86c6b6f93 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -572,10 +572,17 @@ void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) { // NOLINT
         KeyedLoadICNexus nexus(this, slot);
         os << " KEYED_LOAD_IC "
            << Code::ICState2String(nexus.StateFromFeedback());
-      } else {
-        DCHECK(kind == Code::CALL_IC);
+      } else if (kind == Code::CALL_IC) {
         CallICNexus nexus(this, slot);
os << " CALL_IC " << Code::ICState2String(nexus.StateFromFeedback());
+      } else if (kind == Code::STORE_IC) {
+        StoreICNexus nexus(this, slot);
+ os << " STORE_IC " << Code::ICState2String(nexus.StateFromFeedback());
+      } else {
+        DCHECK(kind == Code::KEYED_STORE_IC);
+        KeyedStoreICNexus nexus(this, slot);
+        os << " KEYED_STORE_IC "
+           << Code::ICState2String(nexus.StateFromFeedback());
       }

       os << "\n  [" << GetIndex(slot) << "]: " << Brief(Get(slot));
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 4572af446d984a8aca197d02baff4a75a3164079..ac0774f4ba7ba0da020dd2eaf547bdd23817825d 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4763,7 +4763,7 @@ void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) {
   dictionary->set_requires_slow_elements();
   // TODO(verwaest): Remove this hack.
   if (map()->is_prototype_map()) {
-    GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
+    GetHeap()->ClearAllKeyedStoreICs();
   }
 }

@@ -12106,7 +12106,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object, // If the prototype chain didn't previously have element callbacks, then
     // KeyedStoreICs need to be cleared to ensure any that involve this
     // map go generic.
-    object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
+    object->GetHeap()->ClearAllKeyedStoreICs();
   }

   heap->ClearInstanceofCache();
@@ -14520,7 +14520,7 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key,
   if (key > kRequiresSlowElementsLimit) {
     if (used_as_prototype) {
       // TODO(verwaest): Remove this hack.
-      GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
+      GetHeap()->ClearAllKeyedStoreICs();
     }
     set_requires_slow_elements();
     return;
Index: src/type-feedback-vector.cc
diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc
index 6aa4712682733538345657ecf2bc190201a99336..25b3565708c3df98e9da26efbac037f08bec76b5 100644
--- a/src/type-feedback-vector.cc
+++ b/src/type-feedback-vector.cc
@@ -223,6 +223,28 @@ void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared,
 }


+void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) {
+  Heap* heap = GetIsolate()->heap();
+
+  int slots = ICSlots();
+  Code* host = shared->code();
+  Object* uninitialized_sentinel =
+      TypeFeedbackVector::RawUninitializedSentinel(heap);
+  for (int i = 0; i < slots; i++) {
+    FeedbackVectorICSlot slot(i);
+    Object* obj = Get(slot);
+    if (obj != uninitialized_sentinel) {
+      Code::Kind kind = GetKind(slot);
+      if (kind == Code::KEYED_STORE_IC) {
+        DCHECK(FLAG_vector_stores);
+        KeyedStoreICNexus nexus(this, slot);
+        nexus.Clear(host);
+      }
+    }
+  }
+}
+
+
 // static
Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector());
Index: src/type-feedback-vector.h
diff --git a/src/type-feedback-vector.h b/src/type-feedback-vector.h
index 6a7d6663ae9e08a536246dfe55ba4b7306754679..72b92048182644ea7af7d0805325ecbb1f234c42 100644
--- a/src/type-feedback-vector.h
+++ b/src/type-feedback-vector.h
@@ -213,6 +213,8 @@ class TypeFeedbackVector : public FixedArray {
     ClearICSlotsImpl(shared, false);
   }

+  void ClearKeyedStoreICs(SharedFunctionInfo* shared);
+
   // The object that indicates an uninitialized cache.
   static inline Handle<Object> UninitializedSentinel(Isolate* isolate);



--
--
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