CallIC must update type feedback info correctly.
authormvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Aug 2014 08:52:00 +0000 (08:52 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Aug 2014 08:52:00 +0000 (08:52 +0000)
CallIC, as the first of vector-based ICs didn't update the ic with type
count counter and the generic count counter correctly. This CL fixes
that.

BUG=
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/445943002

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

src/ic-inl.h
src/ic.cc
src/ic.h

index 4a3edbe..ad0078e 100644 (file)
@@ -168,6 +168,20 @@ Handle<Map> IC::GetICCacheHolder(HeapType* type, Isolate* isolate,
   return TypeToMap(type, isolate);
 }
 
+
+IC::State CallIC::FeedbackObjectToState(Object* feedback) const {
+  IC::State state = UNINITIALIZED;
+
+  if (feedback == *TypeFeedbackInfo::MegamorphicSentinel(isolate())) {
+    state = GENERIC;
+  } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
+    state = MONOMORPHIC;
+  } else {
+    CHECK(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate()));
+  }
+
+  return state;
+}
 } }  // namespace v8::internal
 
 #endif  // V8_IC_INL_H_
index 9007e93..90d77f2 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -370,23 +370,20 @@ static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state,
 }
 
 
-void IC::PostPatching(Address address, Code* target, Code* old_target) {
-  Isolate* isolate = target->GetHeap()->isolate();
+void IC::OnTypeFeedbackChanged(Isolate* isolate, Address address,
+                               State old_state, State new_state,
+                               bool target_remains_ic_stub) {
   Code* host = isolate->
       inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
   if (host->kind() != Code::FUNCTION) return;
 
-  if (FLAG_type_info_threshold > 0 && old_target->is_inline_cache_stub() &&
-      target->is_inline_cache_stub() &&
-      // Call ICs don't have interesting state changes from this point
-      // of view.
-      target->kind() != Code::CALL_IC &&
+  if (FLAG_type_info_threshold > 0 && target_remains_ic_stub &&
       // Not all Code objects have TypeFeedbackInfo.
       host->type_feedback_info()->IsTypeFeedbackInfo()) {
     int polymorphic_delta = 0;  // "Polymorphic" here includes monomorphic.
     int generic_delta = 0;      // "Generic" here includes megamorphic.
-    ComputeTypeInfoCountDelta(old_target->ic_state(), target->ic_state(),
-                              &polymorphic_delta, &generic_delta);
+    ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
+                              &generic_delta);
     TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
     info->change_ic_with_type_info_count(polymorphic_delta);
     info->change_ic_generic_count(generic_delta);
@@ -404,6 +401,26 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
 }
 
 
+void IC::PostPatching(Address address, Code* target, Code* old_target) {
+  // Type vector based ICs update these statistics at a different time because
+  // they don't always patch on state change.
+  if (target->kind() == Code::CALL_IC) return;
+
+  Isolate* isolate = target->GetHeap()->isolate();
+  State old_state = UNINITIALIZED;
+  State new_state = UNINITIALIZED;
+  bool target_remains_ic_stub = false;
+  if (old_target->is_inline_cache_stub() && target->is_inline_cache_stub()) {
+    old_state = old_target->ic_state();
+    new_state = target->ic_state();
+    target_remains_ic_stub = true;
+  }
+
+  OnTypeFeedbackChanged(isolate, address, old_state, new_state,
+                        target_remains_ic_stub);
+}
+
+
 void IC::RegisterWeakMapDependency(Handle<Code> stub) {
   if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic &&
       stub->CanBeWeakStub()) {
@@ -1949,6 +1966,8 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver,
     }
 
     TRACE_IC("CallIC (Array call)", name);
+    Object* new_feedback = vector->get(slot->value());
+    UpdateTypeFeedbackInfo(feedback, new_feedback);
     return true;
   }
   return false;
@@ -1972,6 +1991,14 @@ void CallIC::PatchMegamorphic(Handle<FixedArray> vector,
 }
 
 
+void CallIC::UpdateTypeFeedbackInfo(Object* old_feedback,
+                                    Object* new_feedback) {
+  IC::State old_state = FeedbackObjectToState(old_feedback);
+  IC::State new_state = FeedbackObjectToState(new_feedback);
+  OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
+}
+
+
 void CallIC::HandleMiss(Handle<Object> receiver,
                         Handle<Object> function,
                         Handle<FixedArray> vector,
@@ -2010,6 +2037,9 @@ void CallIC::HandleMiss(Handle<Object> receiver,
     TRACE_IC("CallIC", name);
     vector->set(slot->value(), *function);
   }
+
+  Object* new_feedback = vector->get(slot->value());
+  UpdateTypeFeedbackInfo(feedback, new_feedback);
 }
 
 
index 606da14..72cc3f6 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -175,6 +175,9 @@ class IC {
   static inline void SetTargetAtAddress(Address address,
                                         Code* target,
                                         ConstantPoolArray* constant_pool);
+  static void OnTypeFeedbackChanged(Isolate* isolate, Address address,
+                                    State old_state, State new_state,
+                                    bool target_remains_ic_stub);
   static void PostPatching(Address address, Code* target, Code* old_target);
 
   // Compute the handler either by compiling or by retrieving a cached version.
@@ -377,6 +380,10 @@ class CallIC: public IC {
 
   static void Clear(Isolate* isolate, Address address, Code* target,
                     ConstantPoolArray* constant_pool);
+
+ private:
+  void UpdateTypeFeedbackInfo(Object* old_feedback, Object* new_feedback);
+  inline IC::State FeedbackObjectToState(Object* feedback) const;
 };