| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index bbfb2dd781283d5d03b43d3710401fa0e8779d05..ba744d9d53a562e5e306e0f962151a7033cd2def 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -328,13 +328,39 @@ MaybeHandle<Object> IC::ReferenceError(const char* type, Handle<String> name) {
|
| }
|
|
|
|
|
| -static int ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state) {
|
| - bool was_uninitialized =
|
| - old_state == UNINITIALIZED || old_state == PREMONOMORPHIC;
|
| - bool is_uninitialized =
|
| - new_state == UNINITIALIZED || new_state == PREMONOMORPHIC;
|
| - return (was_uninitialized && !is_uninitialized) ? 1 :
|
| - (!was_uninitialized && is_uninitialized) ? -1 : 0;
|
| +static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state,
|
| + int* polymorphic_delta,
|
| + int* generic_delta) {
|
| + switch (old_state) {
|
| + case UNINITIALIZED:
|
| + case PREMONOMORPHIC:
|
| + if (new_state == UNINITIALIZED || new_state == PREMONOMORPHIC) break;
|
| + if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) {
|
| + *polymorphic_delta = 1;
|
| + } else if (new_state == MEGAMORPHIC || new_state == GENERIC) {
|
| + *generic_delta = 1;
|
| + }
|
| + break;
|
| + case MONOMORPHIC:
|
| + case POLYMORPHIC:
|
| + if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) break;
|
| + *polymorphic_delta = -1;
|
| + if (new_state == MEGAMORPHIC || new_state == GENERIC) {
|
| + *generic_delta = 1;
|
| + }
|
| + break;
|
| + case MEGAMORPHIC:
|
| + case GENERIC:
|
| + if (new_state == MEGAMORPHIC || new_state == GENERIC) break;
|
| + *generic_delta = -1;
|
| + if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) {
|
| + *polymorphic_delta = 1;
|
| + }
|
| + break;
|
| + case PROTOTYPE_FAILURE:
|
| + case DEBUG_STUB:
|
| + UNREACHABLE();
|
| + }
|
| }
|
|
|
|
|
| @@ -344,21 +370,20 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
|
| 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()) {
|
| - int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
|
| - target->ic_state());
|
| - // Call ICs don't have interesting state changes from this point
|
| - // of view.
|
| - DCHECK(target->kind() != Code::CALL_IC || delta == 0);
|
| -
|
| - // Not all Code objects have TypeFeedbackInfo.
|
| - if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
|
| - TypeFeedbackInfo* info =
|
| - TypeFeedbackInfo::cast(host->type_feedback_info());
|
| - info->change_ic_with_type_info_count(delta);
|
| - }
|
| + 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 &&
|
| + // 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);
|
| + TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
|
| + info->change_ic_with_type_info_count(polymorphic_delta);
|
| + info->change_ic_generic_count(generic_delta);
|
| }
|
| if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
|
| TypeFeedbackInfo* info =
|
|
|