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

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

Issue 5716001: Add gyp target to build preparser as stand-alone library. (Closed)
Patch Set: Add type field for static windows build. 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
« no previous file with comments | « src/runtime.cc ('k') | src/v8natives.js » ('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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 count = 0; 264 int count = 0;
276 for (JavaScriptFrameIterator it; 265 for (JavaScriptFrameIterator it;
277 count < kSamplerFrameCount && !it.done(); 266 count < kSamplerFrameCount && !it.done();
278 it.Advance()) { 267 it.Advance()) {
279 JavaScriptFrame* frame = it.frame(); 268 JavaScriptFrame* frame = it.frame();
280 JSFunction* function = JSFunction::cast(frame->function()); 269 JSFunction* function = JSFunction::cast(frame->function());
281 270 int function_size = function->shared()->SourceSize();
282 // Adjust threshold each time we have processed 271 int threshold_size_factor;
283 // a certain number of ticks. 272 if (function_size > kSizeLimit) {
284 if (sampler_ticks_until_threshold_adjustment > 0) { 273 threshold_size_factor = sampler_threshold_size_factor;
285 sampler_ticks_until_threshold_adjustment--; 274 } else {
286 if (sampler_ticks_until_threshold_adjustment <= 0) { 275 threshold_size_factor = 1;
287 // If the threshold is not already at the minimum
288 // modify and reset the ticks until next adjustment.
289 if (sampler_threshold > kSamplerThresholdMin) {
290 sampler_threshold -= kSamplerThresholdDelta;
291 sampler_ticks_until_threshold_adjustment =
292 kSamplerTicksBetweenThresholdAdjustment;
293 }
294 }
295 } 276 }
296 277
278 int threshold = sampler_threshold * threshold_size_factor;
279 samples[count++] = function;
297 if (function->IsMarkedForLazyRecompilation()) { 280 if (function->IsMarkedForLazyRecompilation()) {
298 Code* unoptimized = function->shared()->code(); 281 Code* unoptimized = function->shared()->code();
299 int nesting = unoptimized->allow_osr_at_loop_nesting_level(); 282 int nesting = unoptimized->allow_osr_at_loop_nesting_level();
300 if (nesting == 0) AttemptOnStackReplacement(function); 283 if (nesting == 0) AttemptOnStackReplacement(function);
301 int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker); 284 int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker);
302 unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting); 285 unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting);
303 } 286 } else if (LookupSample(function) >= threshold) {
304 287 if (IsOptimizable(function)) {
305 // Do not record non-optimizable functions. 288 Optimize(function, false, 0);
306 if (!IsOptimizable(function)) continue; 289 CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function));
307 samples[count++] = function; 290 }
308
309 int function_size = function->shared()->SourceSize();
310 int threshold_size_factor = (function_size > kSizeLimit)
311 ? sampler_threshold_size_factor
312 : 1;
313
314 int threshold = sampler_threshold * threshold_size_factor;
315 int current_js_ratio = NoBarrier_Load(&js_ratio);
316
317 // Adjust threshold depending on the ratio of time spent
318 // in JS code.
319 if (current_js_ratio < 20) {
320 // If we spend less than 20% of the time in JS code,
321 // do not optimize.
322 continue;
323 } else if (current_js_ratio < 75) {
324 // Below 75% of time spent in JS code, only optimize very
325 // frequently used functions.
326 threshold *= 3;
327 }
328
329 if (LookupSample(function) >= threshold) {
330 Optimize(function, false, 0);
331 CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function));
332 } 291 }
333 } 292 }
334 293
335 // 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
336 // this as part of collecting them because this will interfere with 295 // this as part of collecting them because this will interfere with
337 // the sample lookup in case of recursive functions. 296 // the sample lookup in case of recursive functions.
338 for (int i = 0; i < count; i++) { 297 for (int i = 0; i < count; i++) {
339 AddSample(samples[i], kSamplerFrameWeight[i]); 298 AddSample(samples[i], kSamplerFrameWeight[i]);
340 } 299 }
341 } 300 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 void RuntimeProfiler::Setup() { 334 void RuntimeProfiler::Setup() {
376 ClearSampleBuffer(); 335 ClearSampleBuffer();
377 // 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
378 // the ticks for the runtime profiler. 337 // the ticks for the runtime profiler.
379 if (IsEnabled()) Logger::EnsureTickerStarted(); 338 if (IsEnabled()) Logger::EnsureTickerStarted();
380 } 339 }
381 340
382 341
383 void RuntimeProfiler::Reset() { 342 void RuntimeProfiler::Reset() {
384 sampler_threshold = kSamplerThresholdInit; 343 sampler_threshold = kSamplerThresholdInit;
385 sampler_ticks_until_threshold_adjustment =
386 kSamplerTicksBetweenThresholdAdjustment;
387 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; 344 sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit;
388 } 345 }
389 346
390 347
391 void RuntimeProfiler::TearDown() { 348 void RuntimeProfiler::TearDown() {
392 // Nothing to do. 349 // Nothing to do.
393 } 350 }
394 351
395 352
396 Object** RuntimeProfiler::SamplerWindowAddress() { 353 Object** RuntimeProfiler::SamplerWindowAddress() {
397 return sampler_window; 354 return sampler_window;
398 } 355 }
399 356
400 357
401 int RuntimeProfiler::SamplerWindowSize() { 358 int RuntimeProfiler::SamplerWindowSize() {
402 return kSamplerWindowSize; 359 return kSamplerWindowSize;
403 } 360 }
404 361
405 362
406 static void AddStateSample(SamplerState current_state) {
407 static const int kStateWindowSize = 128;
408 static SamplerState state_window[kStateWindowSize];
409 static int state_window_position = 0;
410 static int state_counts[2] = { kStateWindowSize, 0 };
411
412 SamplerState old_state = state_window[state_window_position];
413 state_counts[old_state]--;
414 state_window[state_window_position] = current_state;
415 state_counts[current_state]++;
416 ASSERT(IsPowerOf2(kStateWindowSize));
417 state_window_position = (state_window_position + 1) &
418 (kStateWindowSize - 1);
419 NoBarrier_Store(&js_ratio, state_counts[IN_JS_STATE] * 100 /
420 kStateWindowSize);
421 }
422
423
424 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() { 363 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() {
425 static const int kNonJSTicksThreshold = 100; 364 static const int kNonJSTicksThreshold = 100;
426 // We suspend the runtime profiler thread when not running 365 // We suspend the runtime profiler thread when not running
427 // JavaScript. If the CPU profiler is active we must not do this 366 // JavaScript. If the CPU profiler is active we must not do this
428 // because it samples both JavaScript and C++ code. 367 // because it samples both JavaScript and C++ code.
429 if (RuntimeProfiler::IsEnabled() && 368 if (RuntimeProfiler::IsEnabled() &&
430 !CpuProfiler::is_profiling() && 369 !CpuProfiler::is_profiling() &&
431 !(FLAG_prof && FLAG_prof_auto)) { 370 !(FLAG_prof && FLAG_prof_auto)) {
432 if (Top::IsInJSState()) { 371 if (Top::IsInJSState()) {
433 AddStateSample(IN_JS_STATE);
434 non_js_ticks_ = 0; 372 non_js_ticks_ = 0;
435 } else { 373 } else {
436 AddStateSample(IN_NON_JS_STATE);
437 if (non_js_ticks_ < kNonJSTicksThreshold) { 374 if (non_js_ticks_ < kNonJSTicksThreshold) {
438 ++non_js_ticks_; 375 ++non_js_ticks_;
439 } else { 376 } else {
440 if (Top::WaitForJSState()) return true; 377 if (Top::WaitForJSState()) return true;
441 } 378 }
442 } 379 }
443 } 380 }
444 return false; 381 return false;
445 } 382 }
446 383
447 384
448 } } // namespace v8::internal 385 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.cc ('k') | src/v8natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698