| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 68bc30f3fe248c0c9506e7dca7c77fcf890b97df..78694dcb5628c5adfe8de1d839cb00febcdba3cb 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -296,58 +296,44 @@ Failure* 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;
|
| +}
|
| +
|
| +
|
| void IC::PostPatching(Address address, Code* target, Code* old_target) {
|
| - if (FLAG_type_info_threshold > 0) {
|
| - if (old_target->is_inline_cache_stub() &&
|
| - target->is_inline_cache_stub()) {
|
| - State old_state = old_target->ic_state();
|
| - State new_state = target->ic_state();
|
| - bool was_uninitialized =
|
| - old_state == UNINITIALIZED || old_state == PREMONOMORPHIC;
|
| - bool is_uninitialized =
|
| - new_state == UNINITIALIZED || new_state == PREMONOMORPHIC;
|
| - int delta = 0;
|
| - if (was_uninitialized && !is_uninitialized) {
|
| - delta = 1;
|
| - } else if (!was_uninitialized && is_uninitialized) {
|
| - delta = -1;
|
| - }
|
| - if (delta != 0) {
|
| - Code* host = target->GetHeap()->isolate()->
|
| - inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
|
| - // Not all Code objects have TypeFeedbackInfo.
|
| - if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
|
| - TypeFeedbackInfo* info =
|
| - TypeFeedbackInfo::cast(host->type_feedback_info());
|
| - info->set_ic_with_typeinfo_count(
|
| - info->ic_with_typeinfo_count() + delta);
|
| - }
|
| - }
|
| + if (FLAG_type_info_threshold == 0 && !FLAG_watch_ic_patching) {
|
| + return;
|
| + }
|
| + Code* host = target->GetHeap()->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()) {
|
| + int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
|
| + target->ic_state());
|
| + // Not all Code objects have TypeFeedbackInfo.
|
| + if (delta != 0 && host->type_feedback_info()->IsTypeFeedbackInfo()) {
|
| + TypeFeedbackInfo* info =
|
| + TypeFeedbackInfo::cast(host->type_feedback_info());
|
| + info->set_ic_with_type_info_count(
|
| + info->ic_with_type_info_count() + delta);
|
| }
|
| }
|
| if (FLAG_watch_ic_patching) {
|
| + host->set_profiler_ticks(0);
|
| Isolate::Current()->runtime_profiler()->NotifyICChanged();
|
| - // We do not want to optimize until the ICs have settled down,
|
| - // so when they are patched, we postpone optimization for the
|
| - // current function and the functions above it on the stack that
|
| - // might want to inline this one.
|
| - StackFrameIterator it;
|
| - if (it.done()) return;
|
| - it.Advance();
|
| - static const int kStackFramesToMark = Compiler::kMaxInliningLevels - 1;
|
| - for (int i = 0; i < kStackFramesToMark; ++i) {
|
| - if (it.done()) return;
|
| - StackFrame* raw_frame = it.frame();
|
| - if (raw_frame->is_java_script()) {
|
| - JSFunction* function =
|
| - JSFunction::cast(JavaScriptFrame::cast(raw_frame)->function());
|
| - if (function->IsOptimized()) continue;
|
| - SharedFunctionInfo* shared = function->shared();
|
| - shared->set_profiler_ticks(0);
|
| - }
|
| - it.Advance();
|
| - }
|
| }
|
| + // TODO(2029): When an optimized function is patched, it would
|
| + // be nice to propagate the corresponding type information to its
|
| + // unoptimized version for the benefit of later inlining.
|
| }
|
|
|
|
|
|
|