Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: src/runtime-profiler.cc

Issue 1969773002: [Interpreter] Clean up runtime-profiler logic for three tier pipeline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix test failure. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime-profiler.h ('k') | src/runtime/runtime-test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/runtime-profiler.h" 5 #include "src/runtime-profiler.h"
6 6
7 #include "src/assembler.h" 7 #include "src/assembler.h"
8 #include "src/ast/scopeinfo.h" 8 #include "src/ast/scopeinfo.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
11 #include "src/code-stubs.h" 11 #include "src/code-stubs.h"
12 #include "src/compilation-cache.h" 12 #include "src/compilation-cache.h"
13 #include "src/execution.h" 13 #include "src/execution.h"
14 #include "src/frames-inl.h" 14 #include "src/frames-inl.h"
15 #include "src/full-codegen/full-codegen.h" 15 #include "src/full-codegen/full-codegen.h"
16 #include "src/global-handles.h" 16 #include "src/global-handles.h"
17 17
18 namespace v8 { 18 namespace v8 {
19 namespace internal { 19 namespace internal {
20 20
21 21
22 // Number of times a function has to be seen on the stack before it is 22 // Number of times a function has to be seen on the stack before it is
23 // compiled for baseline.
24 static const int kProfilerTicksBeforeBaseline = 2;
25 // Number of times a function has to be seen on the stack before it is
23 // optimized. 26 // optimized.
24 static const int kProfilerTicksBeforeOptimization = 2; 27 static const int kProfilerTicksBeforeOptimization = 2;
25 // If the function optimization was disabled due to high deoptimization count, 28 // If the function optimization was disabled due to high deoptimization count,
26 // but the function is hot and has been seen on the stack this number of times, 29 // but the function is hot and has been seen on the stack this number of times,
27 // then we try to reenable optimization for this function. 30 // then we try to reenable optimization for this function.
28 static const int kProfilerTicksBeforeReenablingOptimization = 250; 31 static const int kProfilerTicksBeforeReenablingOptimization = 250;
29 // If a function does not have enough type info (according to 32 // If a function does not have enough type info (according to
30 // FLAG_type_info_threshold), but has seen a huge number of ticks, 33 // FLAG_type_info_threshold), but has seen a huge number of ticks,
31 // optimize it as it is. 34 // optimize it as it is.
32 static const int kTicksWhenNotEnoughTypeInfo = 100; 35 static const int kTicksWhenNotEnoughTypeInfo = 100;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 84
82 if (*ic_total_count > 0) { 85 if (*ic_total_count > 0) {
83 *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count; 86 *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count;
84 *generic_percentage = 100 * *ic_generic_count / *ic_total_count; 87 *generic_percentage = 100 * *ic_generic_count / *ic_total_count;
85 } else { 88 } else {
86 *type_info_percentage = 100; // Compared against lower bound. 89 *type_info_percentage = 100; // Compared against lower bound.
87 *generic_percentage = 0; // Compared against upper bound. 90 *generic_percentage = 0; // Compared against upper bound.
88 } 91 }
89 } 92 }
90 93
91 94 static void TraceRecompile(JSFunction* function, const char* reason,
92 void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) { 95 const char* type) {
93 if (FLAG_trace_opt && 96 if (FLAG_trace_opt &&
94 function->shared()->PassesFilter(FLAG_hydrogen_filter)) { 97 function->shared()->PassesFilter(FLAG_hydrogen_filter)) {
95 PrintF("[marking "); 98 PrintF("[marking ");
96 function->ShortPrint(); 99 function->ShortPrint();
97 PrintF(" for recompilation, reason: %s", reason); 100 PrintF(" for %s recompilation, reason: %s", type, reason);
98 if (FLAG_type_info_threshold > 0) { 101 if (FLAG_type_info_threshold > 0) {
99 int typeinfo, generic, total, type_percentage, generic_percentage; 102 int typeinfo, generic, total, type_percentage, generic_percentage;
100 GetICCounts(function->shared(), &typeinfo, &generic, &total, 103 GetICCounts(function->shared(), &typeinfo, &generic, &total,
101 &type_percentage, &generic_percentage); 104 &type_percentage, &generic_percentage);
102 PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, 105 PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total,
103 type_percentage); 106 type_percentage);
104 PrintF(", generic ICs: %d/%d (%d%%)", generic, total, generic_percentage); 107 PrintF(", generic ICs: %d/%d (%d%%)", generic, total, generic_percentage);
105 } 108 }
106 PrintF("]\n"); 109 PrintF("]\n");
107 } 110 }
108
109 if (function->shared()->HasBytecodeArray()) {
110 function->MarkForBaseline();
111 } else {
112 function->AttemptConcurrentOptimization();
113 }
114 } 111 }
115 112
113 void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) {
114 TraceRecompile(function, reason, "optimized");
115
116 // TODO(4280): Fix this to check function is compiled to baseline once we
117 // have a standard way to check that. For now, if baseline code doesn't have
118 // a bytecode array.
119 DCHECK(!function->shared()->HasBytecodeArray());
120 function->AttemptConcurrentOptimization();
121 }
122
123 void RuntimeProfiler::Baseline(JSFunction* function, const char* reason) {
124 TraceRecompile(function, reason, "baseline");
125
126 // TODO(4280): Fix this to check function is compiled for the interpreter
127 // once we have a standard way to check that. For now function will only
128 // have a bytecode array if compiled for the interpreter.
129 DCHECK(function->shared()->HasBytecodeArray());
130 function->MarkForBaseline();
131 }
116 132
117 void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function, 133 void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function,
118 int loop_nesting_levels) { 134 int loop_nesting_levels) {
119 SharedFunctionInfo* shared = function->shared(); 135 SharedFunctionInfo* shared = function->shared();
120 if (!FLAG_use_osr || function->shared()->IsBuiltin()) { 136 if (!FLAG_use_osr || function->shared()->IsBuiltin()) {
121 return; 137 return;
122 } 138 }
123 139
124 // If the code is not optimizable, don't try OSR. 140 // If the code is not optimizable, don't try OSR.
125 if (shared->optimization_disabled()) return; 141 if (shared->optimization_disabled()) return;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 generic_percentage <= FLAG_generic_ic_threshold) { 248 generic_percentage <= FLAG_generic_ic_threshold) {
233 Optimize(function, "small function"); 249 Optimize(function, "small function");
234 } else { 250 } else {
235 shared_code->set_profiler_ticks(ticks + 1); 251 shared_code->set_profiler_ticks(ticks + 1);
236 } 252 }
237 } else { 253 } else {
238 shared_code->set_profiler_ticks(ticks + 1); 254 shared_code->set_profiler_ticks(ticks + 1);
239 } 255 }
240 } 256 }
241 257
242 void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function, 258 void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function) {
243 bool frame_optimized) {
244 if (function->IsInOptimizationQueue()) return; 259 if (function->IsInOptimizationQueue()) return;
245 260
246 SharedFunctionInfo* shared = function->shared(); 261 SharedFunctionInfo* shared = function->shared();
247 int ticks = shared->profiler_ticks(); 262 int ticks = shared->profiler_ticks();
248 263
249 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller 264 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller
250 // than kMaxToplevelSourceSize. 265 // than kMaxToplevelSourceSize.
251 // TODO(rmcilroy): Consider whether we should optimize small functions when 266 // TODO(rmcilroy): Consider whether we should optimize small functions when
252 // they are first seen on the stack (e.g., kMaxSizeEarlyOpt). 267 // they are first seen on the stack (e.g., kMaxSizeEarlyOpt).
253 268
254 if (!frame_optimized && (function->IsMarkedForBaseline() || 269 if (function->IsMarkedForBaseline() || function->IsMarkedForOptimization() ||
255 function->IsMarkedForOptimization() || 270 function->IsMarkedForConcurrentOptimization() ||
256 function->IsMarkedForConcurrentOptimization() || 271 function->IsOptimized()) {
257 function->IsOptimized())) {
258 // TODO(rmcilroy): Support OSR in these cases. 272 // TODO(rmcilroy): Support OSR in these cases.
259
260 return; 273 return;
261 } 274 }
262 275
263 // Do not optimize non-optimizable functions. 276 if (shared->optimization_disabled() &&
264 if (shared->optimization_disabled()) { 277 shared->disable_optimization_reason() == kOptimizationDisabledForTest) {
265 if (shared->deopt_count() >= FLAG_max_opt_count) { 278 // Don't baseline functions which have been marked by NeverOptimizeFunction
266 // If optimization was disabled due to many deoptimizations, 279 // in a test.
267 // then check if the function is hot and try to reenable optimization.
268 if (ticks >= kProfilerTicksBeforeReenablingOptimization) {
269 shared->set_profiler_ticks(0);
270 shared->TryReenableOptimization();
271 }
272 }
273 return; 280 return;
274 } 281 }
275 282
276 if (function->IsOptimized()) return; 283 if (ticks >= kProfilerTicksBeforeBaseline) {
277 284 Baseline(function, "hot enough for baseline");
278 if (ticks >= kProfilerTicksBeforeOptimization) {
279 int typeinfo, generic, total, type_percentage, generic_percentage;
280 GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage,
281 &generic_percentage);
282 if (type_percentage >= FLAG_type_info_threshold &&
283 generic_percentage <= FLAG_generic_ic_threshold) {
284 // If this particular function hasn't had any ICs patched for enough
285 // ticks, optimize it now.
286 Optimize(function, "hot and stable");
287 } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
288 Optimize(function, "not much type info but very hot");
289 } else {
290 if (FLAG_trace_opt_verbose) {
291 PrintF("[not yet optimizing ");
292 function->PrintName();
293 PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total,
294 type_percentage);
295 }
296 }
297 } 285 }
298 } 286 }
299 287
300 void RuntimeProfiler::MarkCandidatesForOptimization() { 288 void RuntimeProfiler::MarkCandidatesForOptimization() {
301 HandleScope scope(isolate_); 289 HandleScope scope(isolate_);
302 290
303 if (!isolate_->use_crankshaft()) return; 291 if (!isolate_->use_crankshaft()) return;
304 292
305 DisallowHeapAllocation no_gc; 293 DisallowHeapAllocation no_gc;
306 294
(...skipping 12 matching lines...) Expand all
319 frame->GetFunctions(&functions); 307 frame->GetFunctions(&functions);
320 for (int i = functions.length(); --i >= 0; ) { 308 for (int i = functions.length(); --i >= 0; ) {
321 SharedFunctionInfo* shared_function_info = functions[i]->shared(); 309 SharedFunctionInfo* shared_function_info = functions[i]->shared();
322 int ticks = shared_function_info->profiler_ticks(); 310 int ticks = shared_function_info->profiler_ticks();
323 if (ticks < Smi::kMaxValue) { 311 if (ticks < Smi::kMaxValue) {
324 shared_function_info->set_profiler_ticks(ticks + 1); 312 shared_function_info->set_profiler_ticks(ticks + 1);
325 } 313 }
326 } 314 }
327 315
328 if (frame->is_interpreted()) { 316 if (frame->is_interpreted()) {
329 MaybeOptimizeIgnition(function, frame->is_optimized()); 317 DCHECK(!frame->is_optimized());
318 MaybeOptimizeIgnition(function);
330 } else { 319 } else {
331 MaybeOptimizeFullCodegen(function, frame_count, frame->is_optimized()); 320 MaybeOptimizeFullCodegen(function, frame_count, frame->is_optimized());
332 } 321 }
333 } 322 }
334 any_ic_changed_ = false; 323 any_ic_changed_ = false;
335 } 324 }
336 325
337 326
338 } // namespace internal 327 } // namespace internal
339 } // namespace v8 328 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime-profiler.h ('k') | src/runtime/runtime-test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698