From: mvstanton@chromium.org Date: Thu, 7 Aug 2014 08:52:00 +0000 (+0000) Subject: CallIC must update type feedback info correctly. X-Git-Tag: upstream/4.7.83~7751 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=76c87c1cf2361894ad76f5fc7a89534bb5ffe891;p=platform%2Fupstream%2Fv8.git CallIC must update type feedback info correctly. 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 --- diff --git a/src/ic-inl.h b/src/ic-inl.h index 4a3edbe..ad0078e 100644 --- a/src/ic-inl.h +++ b/src/ic-inl.h @@ -168,6 +168,20 @@ Handle 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_ diff --git a/src/ic.cc b/src/ic.cc index 9007e93..90d77f2 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 stub) { if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic && stub->CanBeWeakStub()) { @@ -1949,6 +1966,8 @@ bool CallIC::DoCustomHandler(Handle 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 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 receiver, Handle function, Handle vector, @@ -2010,6 +2037,9 @@ void CallIC::HandleMiss(Handle receiver, TRACE_IC("CallIC", name); vector->set(slot->value(), *function); } + + Object* new_feedback = vector->get(slot->value()); + UpdateTypeFeedbackInfo(feedback, new_feedback); } diff --git a/src/ic.h b/src/ic.h index 606da14..72cc3f6 100644 --- 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; };