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
parent 2c615439
...@@ -168,6 +168,20 @@ Handle<Map> IC::GetICCacheHolder(HeapType* type, Isolate* isolate, ...@@ -168,6 +168,20 @@ Handle<Map> IC::GetICCacheHolder(HeapType* type, Isolate* isolate,
return TypeToMap(type, 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 } } // namespace v8::internal
#endif // V8_IC_INL_H_ #endif // V8_IC_INL_H_
...@@ -370,23 +370,20 @@ static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state, ...@@ -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) { void IC::OnTypeFeedbackChanged(Isolate* isolate, Address address,
Isolate* isolate = target->GetHeap()->isolate(); State old_state, State new_state,
bool target_remains_ic_stub) {
Code* host = isolate-> Code* host = isolate->
inner_pointer_to_code_cache()->GetCacheEntry(address)->code; inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
if (host->kind() != Code::FUNCTION) return; if (host->kind() != Code::FUNCTION) return;
if (FLAG_type_info_threshold > 0 && old_target->is_inline_cache_stub() && if (FLAG_type_info_threshold > 0 && target_remains_ic_stub &&
target->is_inline_cache_stub() &&
// Call ICs don't have interesting state changes from this point
// of view.
target->kind() != Code::CALL_IC &&
// Not all Code objects have TypeFeedbackInfo. // Not all Code objects have TypeFeedbackInfo.
host->type_feedback_info()->IsTypeFeedbackInfo()) { host->type_feedback_info()->IsTypeFeedbackInfo()) {
int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic. int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic.
int generic_delta = 0; // "Generic" here includes megamorphic. int generic_delta = 0; // "Generic" here includes megamorphic.
ComputeTypeInfoCountDelta(old_target->ic_state(), target->ic_state(), ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
&polymorphic_delta, &generic_delta); &generic_delta);
TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
info->change_ic_with_type_info_count(polymorphic_delta); info->change_ic_with_type_info_count(polymorphic_delta);
info->change_ic_generic_count(generic_delta); info->change_ic_generic_count(generic_delta);
...@@ -404,6 +401,26 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) { ...@@ -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) { void IC::RegisterWeakMapDependency(Handle<Code> stub) {
if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic && if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic &&
stub->CanBeWeakStub()) { stub->CanBeWeakStub()) {
...@@ -1949,6 +1966,8 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver, ...@@ -1949,6 +1966,8 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver,
} }
TRACE_IC("CallIC (Array call)", name); TRACE_IC("CallIC (Array call)", name);
Object* new_feedback = vector->get(slot->value());
UpdateTypeFeedbackInfo(feedback, new_feedback);
return true; return true;
} }
return false; return false;
...@@ -1972,6 +1991,14 @@ void CallIC::PatchMegamorphic(Handle<FixedArray> vector, ...@@ -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, void CallIC::HandleMiss(Handle<Object> receiver,
Handle<Object> function, Handle<Object> function,
Handle<FixedArray> vector, Handle<FixedArray> vector,
...@@ -2010,6 +2037,9 @@ void CallIC::HandleMiss(Handle<Object> receiver, ...@@ -2010,6 +2037,9 @@ void CallIC::HandleMiss(Handle<Object> receiver,
TRACE_IC("CallIC", name); TRACE_IC("CallIC", name);
vector->set(slot->value(), *function); vector->set(slot->value(), *function);
} }
Object* new_feedback = vector->get(slot->value());
UpdateTypeFeedbackInfo(feedback, new_feedback);
} }
......
...@@ -175,6 +175,9 @@ class IC { ...@@ -175,6 +175,9 @@ class IC {
static inline void SetTargetAtAddress(Address address, static inline void SetTargetAtAddress(Address address,
Code* target, Code* target,
ConstantPoolArray* constant_pool); 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); static void PostPatching(Address address, Code* target, Code* old_target);
// Compute the handler either by compiling or by retrieving a cached version. // Compute the handler either by compiling or by retrieving a cached version.
...@@ -377,6 +380,10 @@ class CallIC: public IC { ...@@ -377,6 +380,10 @@ class CallIC: public IC {
static void Clear(Isolate* isolate, Address address, Code* target, static void Clear(Isolate* isolate, Address address, Code* target,
ConstantPoolArray* constant_pool); ConstantPoolArray* constant_pool);
private:
void UpdateTypeFeedbackInfo(Object* old_feedback, Object* new_feedback);
inline IC::State FeedbackObjectToState(Object* feedback) const;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment