diff options
Diffstat (limited to 'deps/v8/src/runtime-profiler.cc')
-rw-r--r-- | deps/v8/src/runtime-profiler.cc | 263 |
1 files changed, 165 insertions, 98 deletions
diff --git a/deps/v8/src/runtime-profiler.cc b/deps/v8/src/runtime-profiler.cc index 2d4ee9c1a8..e17cbb1d6b 100644 --- a/deps/v8/src/runtime-profiler.cc +++ b/deps/v8/src/runtime-profiler.cc @@ -58,16 +58,18 @@ static void GetICCounts(SharedFunctionInfo* shared, int* ic_with_type_info_count, int* ic_generic_count, int* ic_total_count, int* type_info_percentage, int* generic_percentage) { - Code* shared_code = shared->code(); *ic_total_count = 0; *ic_generic_count = 0; *ic_with_type_info_count = 0; - Object* raw_info = shared_code->type_feedback_info(); - if (raw_info->IsTypeFeedbackInfo()) { - TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info); - *ic_with_type_info_count = info->ic_with_type_info_count(); - *ic_generic_count = info->ic_generic_count(); - *ic_total_count = info->ic_total_count(); + if (shared->code()->kind() == Code::FUNCTION) { + Code* shared_code = shared->code(); + Object* raw_info = shared_code->type_feedback_info(); + if (raw_info->IsTypeFeedbackInfo()) { + TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info); + *ic_with_type_info_count = info->ic_with_type_info_count(); + *ic_generic_count = info->ic_generic_count(); + *ic_total_count = info->ic_total_count(); + } } // Harvest vector-ics as well @@ -136,8 +138,160 @@ void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function, } } +void RuntimeProfiler::MaybeOptimizeFullCodegen(JSFunction* function, + int frame_count, + bool frame_optimized) { + SharedFunctionInfo* shared = function->shared(); + Code* shared_code = shared->code(); + if (shared_code->kind() != Code::FUNCTION) return; + if (function->IsInOptimizationQueue()) return; + + if (FLAG_always_osr) { + AttemptOnStackReplacement(function, Code::kMaxLoopNestingMarker); + // Fall through and do a normal optimized compile as well. + } else if (!frame_optimized && + (function->IsMarkedForOptimization() || + function->IsMarkedForConcurrentOptimization() || + function->IsOptimized())) { + // Attempt OSR if we are still running unoptimized code even though the + // the function has long been marked or even already been optimized. + int ticks = shared_code->profiler_ticks(); + int64_t allowance = + kOSRCodeSizeAllowanceBase + + static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTick; + if (shared_code->CodeSize() > allowance && + ticks < Code::ProfilerTicksField::kMax) { + shared_code->set_profiler_ticks(ticks + 1); + } else { + AttemptOnStackReplacement(function); + } + return; + } + + // Only record top-level code on top of the execution stack and + // avoid optimizing excessively large scripts since top-level code + // will be executed only once. + const int kMaxToplevelSourceSize = 10 * 1024; + if (shared->is_toplevel() && + (frame_count > 1 || shared->SourceSize() > kMaxToplevelSourceSize)) { + return; + } + + // Do not record non-optimizable functions. + if (shared->optimization_disabled()) { + if (shared->deopt_count() >= FLAG_max_opt_count) { + // If optimization was disabled due to many deoptimizations, + // then check if the function is hot and try to reenable optimization. + int ticks = shared_code->profiler_ticks(); + if (ticks >= kProfilerTicksBeforeReenablingOptimization) { + shared_code->set_profiler_ticks(0); + shared->TryReenableOptimization(); + } else { + shared_code->set_profiler_ticks(ticks + 1); + } + } + return; + } + if (function->IsOptimized()) return; + + int ticks = shared_code->profiler_ticks(); + + if (ticks >= kProfilerTicksBeforeOptimization) { + int typeinfo, generic, total, type_percentage, generic_percentage; + GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage, + &generic_percentage); + if (type_percentage >= FLAG_type_info_threshold && + generic_percentage <= FLAG_generic_ic_threshold) { + // If this particular function hasn't had any ICs patched for enough + // ticks, optimize it now. + Optimize(function, "hot and stable"); + } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { + Optimize(function, "not much type info but very hot"); + } else { + shared_code->set_profiler_ticks(ticks + 1); + if (FLAG_trace_opt_verbose) { + PrintF("[not yet optimizing "); + function->PrintName(); + PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, + type_percentage); + } + } + } else if (!any_ic_changed_ && + shared_code->instruction_size() < kMaxSizeEarlyOpt) { + // If no IC was patched since the last tick and this function is very + // small, optimistically optimize it now. + int typeinfo, generic, total, type_percentage, generic_percentage; + GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage, + &generic_percentage); + if (type_percentage >= FLAG_type_info_threshold && + generic_percentage <= FLAG_generic_ic_threshold) { + Optimize(function, "small function"); + } else { + shared_code->set_profiler_ticks(ticks + 1); + } + } else { + shared_code->set_profiler_ticks(ticks + 1); + } +} + +void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function, + bool frame_optimized) { + if (function->IsInOptimizationQueue()) return; -void RuntimeProfiler::OptimizeNow() { + SharedFunctionInfo* shared = function->shared(); + int ticks = shared->profiler_ticks(); + + // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller + // than kMaxToplevelSourceSize. + // TODO(rmcilroy): Consider whether we should optimize small functions when + // they are first seen on the stack (e.g., kMaxSizeEarlyOpt). + + if (!frame_optimized && (function->IsMarkedForOptimization() || + function->IsMarkedForConcurrentOptimization() || + function->IsOptimized())) { + // TODO(rmcilroy): Support OSR in these cases. + + return; + } + + // Do not optimize non-optimizable functions. + if (shared->optimization_disabled()) { + if (shared->deopt_count() >= FLAG_max_opt_count) { + // If optimization was disabled due to many deoptimizations, + // then check if the function is hot and try to reenable optimization. + if (ticks >= kProfilerTicksBeforeReenablingOptimization) { + shared->set_profiler_ticks(0); + shared->TryReenableOptimization(); + } + } + return; + } + + if (function->IsOptimized()) return; + + if (ticks >= kProfilerTicksBeforeOptimization) { + int typeinfo, generic, total, type_percentage, generic_percentage; + GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage, + &generic_percentage); + if (type_percentage >= FLAG_type_info_threshold && + generic_percentage <= FLAG_generic_ic_threshold) { + // If this particular function hasn't had any ICs patched for enough + // ticks, optimize it now. + Optimize(function, "hot and stable"); + } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { + Optimize(function, "not much type info but very hot"); + } else { + if (FLAG_trace_opt_verbose) { + PrintF("[not yet optimizing "); + function->PrintName(); + PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, + type_percentage); + } + } + } +} + +void RuntimeProfiler::MarkCandidatesForOptimization() { HandleScope scope(isolate_); if (!isolate_->use_crankshaft()) return; @@ -155,9 +309,6 @@ void RuntimeProfiler::OptimizeNow() { JavaScriptFrame* frame = it.frame(); JSFunction* function = frame->function(); - SharedFunctionInfo* shared = function->shared(); - Code* shared_code = shared->code(); - List<JSFunction*> functions(4); frame->GetFunctions(&functions); for (int i = functions.length(); --i >= 0; ) { @@ -168,94 +319,10 @@ void RuntimeProfiler::OptimizeNow() { } } - if (shared_code->kind() != Code::FUNCTION) continue; - if (function->IsInOptimizationQueue()) continue; - - if (FLAG_always_osr) { - AttemptOnStackReplacement(function, Code::kMaxLoopNestingMarker); - // Fall through and do a normal optimized compile as well. - } else if (!frame->is_optimized() && - (function->IsMarkedForOptimization() || - function->IsMarkedForConcurrentOptimization() || - function->IsOptimized())) { - // Attempt OSR if we are still running unoptimized code even though the - // the function has long been marked or even already been optimized. - int ticks = shared_code->profiler_ticks(); - int64_t allowance = - kOSRCodeSizeAllowanceBase + - static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTick; - if (shared_code->CodeSize() > allowance && - ticks < Code::ProfilerTicksField::kMax) { - shared_code->set_profiler_ticks(ticks + 1); - } else { - AttemptOnStackReplacement(function); - } - continue; - } - - // Only record top-level code on top of the execution stack and - // avoid optimizing excessively large scripts since top-level code - // will be executed only once. - const int kMaxToplevelSourceSize = 10 * 1024; - if (shared->is_toplevel() && - (frame_count > 1 || shared->SourceSize() > kMaxToplevelSourceSize)) { - continue; - } - - // Do not record non-optimizable functions. - if (shared->optimization_disabled()) { - if (shared->deopt_count() >= FLAG_max_opt_count) { - // If optimization was disabled due to many deoptimizations, - // then check if the function is hot and try to reenable optimization. - int ticks = shared_code->profiler_ticks(); - if (ticks >= kProfilerTicksBeforeReenablingOptimization) { - shared_code->set_profiler_ticks(0); - shared->TryReenableOptimization(); - } else { - shared_code->set_profiler_ticks(ticks + 1); - } - } - continue; - } - if (function->IsOptimized()) continue; - - int ticks = shared_code->profiler_ticks(); - - if (ticks >= kProfilerTicksBeforeOptimization) { - int typeinfo, generic, total, type_percentage, generic_percentage; - GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage, - &generic_percentage); - if (type_percentage >= FLAG_type_info_threshold && - generic_percentage <= FLAG_generic_ic_threshold) { - // If this particular function hasn't had any ICs patched for enough - // ticks, optimize it now. - Optimize(function, "hot and stable"); - } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { - Optimize(function, "not much type info but very hot"); - } else { - shared_code->set_profiler_ticks(ticks + 1); - if (FLAG_trace_opt_verbose) { - PrintF("[not yet optimizing "); - function->PrintName(); - PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, - type_percentage); - } - } - } else if (!any_ic_changed_ && - shared_code->instruction_size() < kMaxSizeEarlyOpt) { - // If no IC was patched since the last tick and this function is very - // small, optimistically optimize it now. - int typeinfo, generic, total, type_percentage, generic_percentage; - GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage, - &generic_percentage); - if (type_percentage >= FLAG_type_info_threshold && - generic_percentage <= FLAG_generic_ic_threshold) { - Optimize(function, "small function"); - } else { - shared_code->set_profiler_ticks(ticks + 1); - } + if (FLAG_ignition) { + MaybeOptimizeIgnition(function, frame->is_optimized()); } else { - shared_code->set_profiler_ticks(ticks + 1); + MaybeOptimizeFullCodegen(function, frame_count, frame->is_optimized()); } } any_ic_changed_ = false; |