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

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

Issue 5633009: Collect only optimizable function samples.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years 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 | Annotate | Revision Log
« src/compiler.cc ('K') | « src/compiler.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 Handle<Object> function_; // Weak handle. 66 Handle<Object> function_; // Weak handle.
67 int64_t start_; 67 int64_t start_;
68 }; 68 };
69 69
70 70
71 // Optimization sampler constants. 71 // Optimization sampler constants.
72 static const int kSamplerFrameCount = 2; 72 static const int kSamplerFrameCount = 2;
73 static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 }; 73 static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 };
74 static const int kSamplerWindowSize = 16; 74 static const int kSamplerWindowSize = 16;
75 75
76 static const int kSamplerTicksDelta = 32; 76 static const int kSamplerTicksDelta = 32;
Kasper Lund 2010/12/08 14:54:15 kSamplerTicksBetweenThresholdAdjustment.
77 77
78 static const int kSamplerThresholdInit = 3; 78 static const int kSamplerThresholdInit = 3;
79 static const int kSamplerThresholdMin = 1; 79 static const int kSamplerThresholdMin = 1;
80 static const int kSamplerThresholdDelta = 1; 80 static const int kSamplerThresholdDelta = 1;
81 81
82 static const int kSamplerThresholdSizeFactorInit = 3; 82 static const int kSamplerThresholdSizeFactorInit = 3;
83 static const int kSamplerThresholdSizeFactorMin = 1; 83 static const int kSamplerThresholdSizeFactorMin = 1;
84 static const int kSamplerThresholdSizeFactorDelta = 1; 84 static const int kSamplerThresholdSizeFactorDelta = 1;
85 85
86 static const int kSizeLimit = 1500; 86 static const int kSizeLimit = 1500;
87 87
88 static int sampler_threshold = kSamplerThresholdInit; 88 static int sampler_threshold = kSamplerThresholdInit;
89 static int sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; 89 static int sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit;
90 90
91 static const int kStateWindowSize = 128;
92 static bool state_window[kStateWindowSize];
Kasper Lund 2010/12/08 14:54:15 To me the name is of this is somewhat weird. If it
93 static int state_window_position = 0;
94 static int in_JS_state = 0;
Kasper Lund 2010/12/08 14:54:15 static int state_counts[2] = { 0, } and then use s
95 static int not_in_JS_state = 0;
96
97 static int sampler_ticks = kSamplerTicksDelta;
Kasper Lund 2010/12/08 14:54:15 This name doesn't really relay much information. I
91 98
92 // The JSFunctions in the sampler window are not GC safe. Old-space 99 // The JSFunctions in the sampler window are not GC safe. Old-space
93 // pointers are not cleared during mark-sweep collection and therefore 100 // pointers are not cleared during mark-sweep collection and therefore
94 // the window might contain stale pointers. The window is updated on 101 // the window might contain stale pointers. The window is updated on
95 // scavenges and (parts of it) cleared on mark-sweep and 102 // scavenges and (parts of it) cleared on mark-sweep and
96 // mark-sweep-compact. 103 // mark-sweep-compact.
97 static Object* sampler_window[kSamplerWindowSize] = { NULL, }; 104 static Object* sampler_window[kSamplerWindowSize] = { NULL, };
98 static int sampler_window_position = 0; 105 static int sampler_window_position = 0;
99 static int sampler_window_weight[kSamplerWindowSize] = { 0, }; 106 static int sampler_window_weight[kSamplerWindowSize] = { 0, };
100 107
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 int delay = current->Delay(); 257 int delay = current->Delay();
251 if (IsOptimizable(*function)) { 258 if (IsOptimizable(*function)) {
252 Optimize(*function, true, delay); 259 Optimize(*function, true, delay);
253 } 260 }
254 } 261 }
255 delete current; 262 delete current;
256 current = next; 263 current = next;
257 } 264 }
258 optimize_soon_list = NULL; 265 optimize_soon_list = NULL;
259 266
267 float js_ratio = in_JS_state / static_cast<float>(
Kasper Lund 2010/12/08 14:54:15 Maybe comment on what this ratio means or change t
268 in_JS_state + not_in_JS_state);
269
260 // Run through the JavaScript frames and collect them. If we already 270 // Run through the JavaScript frames and collect them. If we already
261 // have a sample of the function, we mark it for optimizations 271 // have a sample of the function, we mark it for optimizations
262 // (eagerly or lazily). 272 // (eagerly or lazily).
263 JSFunction* samples[kSamplerFrameCount]; 273 JSFunction* samples[kSamplerFrameCount];
264 int count = 0; 274 int count = 0;
265 for (JavaScriptFrameIterator it; 275 for (JavaScriptFrameIterator it;
266 count < kSamplerFrameCount && !it.done(); 276 count < kSamplerFrameCount && !it.done();
267 it.Advance()) { 277 it.Advance()) {
268 JavaScriptFrame* frame = it.frame(); 278 JavaScriptFrame* frame = it.frame();
269 JSFunction* function = JSFunction::cast(frame->function()); 279 JSFunction* function = JSFunction::cast(frame->function());
280
281 if (sampler_ticks > 0) {
Kasper Lund 2010/12/08 14:54:15 Add a comment that explains what this does.
282 sampler_ticks--;
283 if (sampler_ticks == 0) {
284 if (sampler_threshold > kSamplerThresholdMin) {
285 sampler_threshold -= kSamplerThresholdDelta;
286 }
287 sampler_ticks = kSamplerTicksDelta;
288 }
289 }
290
291 if (!IsOptimizable(function) && !function->IsMarkedForLazyRecompilation()) {
Kasper Lund 2010/12/08 14:54:15 Please explain what you're trying to filter out he
292 continue;
293 }
294
295 samples[count++] = function;
296
270 int function_size = function->shared()->SourceSize(); 297 int function_size = function->shared()->SourceSize();
271 int threshold_size_factor; 298 int threshold_size_factor;
272 if (function_size > kSizeLimit) { 299 threshold_size_factor = (function_size > kSizeLimit)
Kasper Lund 2010/12/08 14:54:15 Why not initialize threshold_size_factor directly
273 threshold_size_factor = sampler_threshold_size_factor; 300 ? sampler_threshold_size_factor
274 } else { 301 : 1;
275 threshold_size_factor = 1; 302
303 int threshold = sampler_threshold * threshold_size_factor;
304
305 if (js_ratio < .2) {
fschneider 2010/12/08 14:33:33 These constants need some comments about the ratio
Kasper Lund 2010/12/08 14:54:15 0.2, 0.5, 0.75. I agree that you should explain th
306 threshold = kStateWindowSize;
307 } else if (js_ratio < .5) {
308 threshold *= 3;
309 } else if (js_ratio < .75) {
310 threshold *= 2;
276 } 311 }
277 312
278 int threshold = sampler_threshold * threshold_size_factor;
279 samples[count++] = function;
280 if (function->IsMarkedForLazyRecompilation()) { 313 if (function->IsMarkedForLazyRecompilation()) {
281 Code* unoptimized = function->shared()->code(); 314 Code* unoptimized = function->shared()->code();
282 int nesting = unoptimized->allow_osr_at_loop_nesting_level(); 315 int nesting = unoptimized->allow_osr_at_loop_nesting_level();
283 if (nesting == 0) AttemptOnStackReplacement(function); 316 if (nesting == 0) AttemptOnStackReplacement(function);
284 int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker); 317 int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker);
285 unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting); 318 unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting);
286 } else if (LookupSample(function) >= threshold) { 319 } else if (LookupSample(function) >= threshold) {
287 if (IsOptimizable(function)) { 320 Optimize(function, false, 0);
288 Optimize(function, false, 0); 321 CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function));
289 CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function));
290 }
291 } 322 }
292 } 323 }
293 324
294 // Add the collected functions as samples. It's important not to do 325 // Add the collected functions as samples. It's important not to do
295 // this as part of collecting them because this will interfere with 326 // this as part of collecting them because this will interfere with
296 // the sample lookup in case of recursive functions. 327 // the sample lookup in case of recursive functions.
297 for (int i = 0; i < count; i++) { 328 for (int i = 0; i < count; i++) {
298 AddSample(samples[i], kSamplerFrameWeight[i]); 329 AddSample(samples[i], kSamplerFrameWeight[i]);
299 } 330 }
300 } 331 }
(...skipping 24 matching lines...) Expand all
325 } 356 }
326 } 357 }
327 358
328 359
329 bool IsEqual(void* first, void* second) { 360 bool IsEqual(void* first, void* second) {
330 return first == second; 361 return first == second;
331 } 362 }
332 363
333 364
334 void RuntimeProfiler::Setup() { 365 void RuntimeProfiler::Setup() {
366 for (int i = 0; i < kStateWindowSize; i++) {
367 state_window[i] = false;
368 }
369 in_JS_state = 0;
370 not_in_JS_state = kStateWindowSize;
335 ClearSampleBuffer(); 371 ClearSampleBuffer();
336 // If the ticker hasn't already started, make sure to do so to get 372 // If the ticker hasn't already started, make sure to do so to get
337 // the ticks for the runtime profiler. 373 // the ticks for the runtime profiler.
338 if (IsEnabled()) Logger::EnsureTickerStarted(); 374 if (IsEnabled()) Logger::EnsureTickerStarted();
339 } 375 }
340 376
341 377
342 void RuntimeProfiler::Reset() { 378 void RuntimeProfiler::Reset() {
343 sampler_threshold = kSamplerThresholdInit; 379 sampler_threshold = kSamplerThresholdInit;
380 sampler_ticks = kSamplerTicksDelta;
344 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; 381 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit;
345 } 382 }
346 383
347 384
348 void RuntimeProfiler::TearDown() { 385 void RuntimeProfiler::TearDown() {
349 // Nothing to do. 386 // Nothing to do.
350 } 387 }
351 388
352 389
353 Object** RuntimeProfiler::SamplerWindowAddress() { 390 Object** RuntimeProfiler::SamplerWindowAddress() {
354 return sampler_window; 391 return sampler_window;
355 } 392 }
356 393
357 394
358 int RuntimeProfiler::SamplerWindowSize() { 395 int RuntimeProfiler::SamplerWindowSize() {
359 return kSamplerWindowSize; 396 return kSamplerWindowSize;
360 } 397 }
361 398
362 399
400 void AddStateSample(bool in_js_state) {
Kasper Lund 2010/12/08 14:54:15 Use enum SampleState for the parameter.
Kasper Lund 2010/12/08 14:54:15 Make this function static.
401 if (state_window[state_window_position]) {
Kasper Lund 2010/12/08 14:54:15 state_counts[state_window[state_window_position]]-
402 in_JS_state--;
fschneider 2010/12/08 14:33:33 is_js_state vs in_JS_state: These variable names a
403 } else {
404 not_in_JS_state--;
405 }
406 state_window[state_window_position] = in_js_state;
407 if (in_js_state) {
Kasper Lund 2010/12/08 14:54:15 state_counts[state]++; No branches.
408 in_JS_state++;
409 } else {
410 not_in_JS_state++;
411 }
412 state_window_position = (state_window_position + 1) &
Kasper Lund 2010/12/08 14:54:15 ASSERT(IsPowerOf2(kStateWindowSize));
413 (kStateWindowSize - 1);
414 }
415
416
363 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() { 417 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() {
364 static const int kNonJSTicksThreshold = 100; 418 static const int kNonJSTicksThreshold = 100;
365 // We suspend the runtime profiler thread when not running 419 // We suspend the runtime profiler thread when not running
366 // JavaScript. If the CPU profiler is active we must not do this 420 // JavaScript. If the CPU profiler is active we must not do this
367 // because it samples both JavaScript and C++ code. 421 // because it samples both JavaScript and C++ code.
368 if (RuntimeProfiler::IsEnabled() && 422 if (RuntimeProfiler::IsEnabled() &&
369 !CpuProfiler::is_profiling() && 423 !CpuProfiler::is_profiling() &&
370 !(FLAG_prof && FLAG_prof_auto)) { 424 !(FLAG_prof && FLAG_prof_auto)) {
371 if (Top::IsInJSState()) { 425 if (Top::IsInJSState()) {
426 AddStateSample(true);
372 non_js_ticks_ = 0; 427 non_js_ticks_ = 0;
373 } else { 428 } else {
429 AddStateSample(false);
374 if (non_js_ticks_ < kNonJSTicksThreshold) { 430 if (non_js_ticks_ < kNonJSTicksThreshold) {
375 ++non_js_ticks_; 431 ++non_js_ticks_;
376 } else { 432 } else {
377 if (Top::WaitForJSState()) return true; 433 if (Top::WaitForJSState()) return true;
378 } 434 }
379 } 435 }
380 } 436 }
381 return false; 437 return false;
382 } 438 }
383 439
384 440
385 } } // namespace v8::internal 441 } } // namespace v8::internal
OLDNEW
« src/compiler.cc ('K') | « src/compiler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698