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

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

Issue 5862002: Version 3.0.2. (Closed)
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
« ChangeLog ('K') | « src/runtime.cc ('k') | src/scanner.h » ('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 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 private: 61 private:
62 void Destroy(); 62 void Destroy();
63 static void WeakCallback(v8::Persistent<v8::Value> object, void* data); 63 static void WeakCallback(v8::Persistent<v8::Value> object, void* data);
64 64
65 PendingListNode* next_; 65 PendingListNode* next_;
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 enum SamplerState {
72 IN_NON_JS_STATE = 0,
73 IN_JS_STATE = 1
74 };
75
76
77 // Optimization sampler constants. 71 // Optimization sampler constants.
78 static const int kSamplerFrameCount = 2; 72 static const int kSamplerFrameCount = 2;
79 static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 }; 73 static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 };
80 static const int kSamplerWindowSize = 16; 74 static const int kSamplerWindowSize = 16;
81 75
82 static const int kSamplerTicksBetweenThresholdAdjustment = 32; 76 static const int kSamplerTicksDelta = 32;
83 77
84 static const int kSamplerThresholdInit = 3; 78 static const int kSamplerThresholdInit = 3;
85 static const int kSamplerThresholdMin = 1; 79 static const int kSamplerThresholdMin = 1;
86 static const int kSamplerThresholdDelta = 1; 80 static const int kSamplerThresholdDelta = 1;
87 81
88 static const int kSamplerThresholdSizeFactorInit = 3; 82 static const int kSamplerThresholdSizeFactorInit = 3;
89 static const int kSamplerThresholdSizeFactorMin = 1; 83 static const int kSamplerThresholdSizeFactorMin = 1;
90 static const int kSamplerThresholdSizeFactorDelta = 1; 84 static const int kSamplerThresholdSizeFactorDelta = 1;
91 85
92 static const int kSizeLimit = 1500; 86 static const int kSizeLimit = 1500;
93 87
94 static int sampler_threshold = kSamplerThresholdInit; 88 static int sampler_threshold = kSamplerThresholdInit;
95 static int sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; 89 static int sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit;
96 90
97 static int sampler_ticks_until_threshold_adjustment =
98 kSamplerTicksBetweenThresholdAdjustment;
99
100 // The ratio of ticks spent in JS code in percent.
101 static Atomic32 js_ratio;
102 91
103 // The JSFunctions in the sampler window are not GC safe. Old-space 92 // The JSFunctions in the sampler window are not GC safe. Old-space
104 // pointers are not cleared during mark-sweep collection and therefore 93 // pointers are not cleared during mark-sweep collection and therefore
105 // the window might contain stale pointers. The window is updated on 94 // the window might contain stale pointers. The window is updated on
106 // scavenges and (parts of it) cleared on mark-sweep and 95 // scavenges and (parts of it) cleared on mark-sweep and
107 // mark-sweep-compact. 96 // mark-sweep-compact.
108 static Object* sampler_window[kSamplerWindowSize] = { NULL, }; 97 static Object* sampler_window[kSamplerWindowSize] = { NULL, };
109 static int sampler_window_position = 0; 98 static int sampler_window_position = 0;
110 static int sampler_window_weight[kSamplerWindowSize] = { 0, }; 99 static int sampler_window_weight[kSamplerWindowSize] = { 0, };
111 100
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 254 }
266 delete current; 255 delete current;
267 current = next; 256 current = next;
268 } 257 }
269 optimize_soon_list = NULL; 258 optimize_soon_list = NULL;
270 259
271 // Run through the JavaScript frames and collect them. If we already 260 // Run through the JavaScript frames and collect them. If we already
272 // have a sample of the function, we mark it for optimizations 261 // have a sample of the function, we mark it for optimizations
273 // (eagerly or lazily). 262 // (eagerly or lazily).
274 JSFunction* samples[kSamplerFrameCount]; 263 JSFunction* samples[kSamplerFrameCount];
275 int sample_count = 0; 264 int count = 0;
276 int frame_count = 0;
277 for (JavaScriptFrameIterator it; 265 for (JavaScriptFrameIterator it;
278 frame_count++ < kSamplerFrameCount && !it.done(); 266 count < kSamplerFrameCount && !it.done();
279 it.Advance()) { 267 it.Advance()) {
280 JavaScriptFrame* frame = it.frame(); 268 JavaScriptFrame* frame = it.frame();
281 JSFunction* function = JSFunction::cast(frame->function()); 269 JSFunction* function = JSFunction::cast(frame->function());
282 270 int function_size = function->shared()->SourceSize();
283 // Adjust threshold each time we have processed 271 int threshold_size_factor;
284 // a certain number of ticks. 272 if (function_size > kSizeLimit) {
285 if (sampler_ticks_until_threshold_adjustment > 0) { 273 threshold_size_factor = sampler_threshold_size_factor;
286 sampler_ticks_until_threshold_adjustment--; 274 } else {
287 if (sampler_ticks_until_threshold_adjustment <= 0) { 275 threshold_size_factor = 1;
288 // If the threshold is not already at the minimum
289 // modify and reset the ticks until next adjustment.
290 if (sampler_threshold > kSamplerThresholdMin) {
291 sampler_threshold -= kSamplerThresholdDelta;
292 sampler_ticks_until_threshold_adjustment =
293 kSamplerTicksBetweenThresholdAdjustment;
294 }
295 }
296 } 276 }
297 277
278 int threshold = sampler_threshold * threshold_size_factor;
279 samples[count++] = function;
298 if (function->IsMarkedForLazyRecompilation()) { 280 if (function->IsMarkedForLazyRecompilation()) {
299 Code* unoptimized = function->shared()->code(); 281 Code* unoptimized = function->shared()->code();
300 int nesting = unoptimized->allow_osr_at_loop_nesting_level(); 282 int nesting = unoptimized->allow_osr_at_loop_nesting_level();
301 if (nesting == 0) AttemptOnStackReplacement(function); 283 if (nesting == 0) AttemptOnStackReplacement(function);
302 int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker); 284 int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker);
303 unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting); 285 unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting);
304 } 286 } else if (LookupSample(function) >= threshold) {
305 287 if (IsOptimizable(function)) {
306 // Do not record non-optimizable functions. 288 Optimize(function, false, 0);
307 if (!IsOptimizable(function)) continue; 289 CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function));
308 samples[sample_count++] = function; 290 }
309
310 int function_size = function->shared()->SourceSize();
311 int threshold_size_factor = (function_size > kSizeLimit)
312 ? sampler_threshold_size_factor
313 : 1;
314
315 int threshold = sampler_threshold * threshold_size_factor;
316 int current_js_ratio = NoBarrier_Load(&js_ratio);
317
318 // Adjust threshold depending on the ratio of time spent
319 // in JS code.
320 if (current_js_ratio < 20) {
321 // If we spend less than 20% of the time in JS code,
322 // do not optimize.
323 continue;
324 } else if (current_js_ratio < 75) {
325 // Below 75% of time spent in JS code, only optimize very
326 // frequently used functions.
327 threshold *= 3;
328 }
329
330 if (LookupSample(function) >= threshold) {
331 Optimize(function, false, 0);
332 CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function));
333 } 291 }
334 } 292 }
335 293
336 // Add the collected functions as samples. It's important not to do 294 // Add the collected functions as samples. It's important not to do
337 // this as part of collecting them because this will interfere with 295 // this as part of collecting them because this will interfere with
338 // the sample lookup in case of recursive functions. 296 // the sample lookup in case of recursive functions.
339 for (int i = 0; i < sample_count; i++) { 297 for (int i = 0; i < count; i++) {
340 AddSample(samples[i], kSamplerFrameWeight[i]); 298 AddSample(samples[i], kSamplerFrameWeight[i]);
341 } 299 }
342 } 300 }
343 301
344 302
345 void RuntimeProfiler::OptimizeSoon(JSFunction* function) { 303 void RuntimeProfiler::OptimizeSoon(JSFunction* function) {
346 if (!IsOptimizable(function)) return; 304 if (!IsOptimizable(function)) return;
347 PendingListNode* node = new PendingListNode(function); 305 PendingListNode* node = new PendingListNode(function);
348 node->set_next(optimize_soon_list); 306 node->set_next(optimize_soon_list);
349 optimize_soon_list = node; 307 optimize_soon_list = node;
350 } 308 }
351 309
352 310
353 static void UpdateStateRatio(SamplerState current_state) {
354 static const int kStateWindowSize = 128;
355 static SamplerState state_window[kStateWindowSize];
356 static int state_window_position = 0;
357 static int state_counts[2] = { kStateWindowSize, 0 };
358
359 SamplerState old_state = state_window[state_window_position];
360 state_counts[old_state]--;
361 state_window[state_window_position] = current_state;
362 state_counts[current_state]++;
363 ASSERT(IsPowerOf2(kStateWindowSize));
364 state_window_position = (state_window_position + 1) &
365 (kStateWindowSize - 1);
366 NoBarrier_Store(&js_ratio, state_counts[IN_JS_STATE] * 100 /
367 kStateWindowSize);
368 }
369
370
371 void RuntimeProfiler::NotifyTick() { 311 void RuntimeProfiler::NotifyTick() {
372 // Record state sample.
373 SamplerState state = Top::IsInJSState()
374 ? IN_JS_STATE
375 : IN_NON_JS_STATE;
376 UpdateStateRatio(state);
377 StackGuard::RequestRuntimeProfilerTick(); 312 StackGuard::RequestRuntimeProfilerTick();
378 } 313 }
379 314
380 315
381 void RuntimeProfiler::MarkCompactPrologue(bool is_compacting) { 316 void RuntimeProfiler::MarkCompactPrologue(bool is_compacting) {
382 if (is_compacting) { 317 if (is_compacting) {
383 // Clear all samples before mark-sweep-compact because every 318 // Clear all samples before mark-sweep-compact because every
384 // function might move. 319 // function might move.
385 ClearSampleBuffer(); 320 ClearSampleBuffer();
386 } else { 321 } else {
(...skipping 12 matching lines...) Expand all
399 void RuntimeProfiler::Setup() { 334 void RuntimeProfiler::Setup() {
400 ClearSampleBuffer(); 335 ClearSampleBuffer();
401 // If the ticker hasn't already started, make sure to do so to get 336 // If the ticker hasn't already started, make sure to do so to get
402 // the ticks for the runtime profiler. 337 // the ticks for the runtime profiler.
403 if (IsEnabled()) Logger::EnsureTickerStarted(); 338 if (IsEnabled()) Logger::EnsureTickerStarted();
404 } 339 }
405 340
406 341
407 void RuntimeProfiler::Reset() { 342 void RuntimeProfiler::Reset() {
408 sampler_threshold = kSamplerThresholdInit; 343 sampler_threshold = kSamplerThresholdInit;
409 sampler_ticks_until_threshold_adjustment =
410 kSamplerTicksBetweenThresholdAdjustment;
411 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; 344 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit;
412 } 345 }
413 346
414 347
415 void RuntimeProfiler::TearDown() { 348 void RuntimeProfiler::TearDown() {
416 // Nothing to do. 349 // Nothing to do.
417 } 350 }
418 351
419 352
420 Object** RuntimeProfiler::SamplerWindowAddress() { 353 Object** RuntimeProfiler::SamplerWindowAddress() {
(...skipping 22 matching lines...) Expand all
443 } else { 376 } else {
444 if (Top::WaitForJSState()) return true; 377 if (Top::WaitForJSState()) return true;
445 } 378 }
446 } 379 }
447 } 380 }
448 return false; 381 return false;
449 } 382 }
450 383
451 384
452 } } // namespace v8::internal 385 } } // namespace v8::internal
OLDNEW
« ChangeLog ('K') | « src/runtime.cc ('k') | src/scanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698