summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime-profiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime-profiler.cc')
-rw-r--r--deps/v8/src/runtime-profiler.cc263
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;