Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index bd8db3e01af8bda046cff075238be2c522597304..cc01fc399724919f842f8dc033acebf2cd14948a 100644 |
--- 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()) { |
@@ -1920,6 +1937,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; |
@@ -1943,6 +1962,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, |
@@ -1981,6 +2008,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); |
} |