Index: src/runtime-profiler.cc |
=================================================================== |
--- src/runtime-profiler.cc (revision 5946) |
+++ src/runtime-profiler.cc (working copy) |
@@ -88,7 +88,14 @@ |
static int sampler_threshold = kSamplerThresholdInit; |
static int sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; |
+static const int kStateWindowSize = 128; |
+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
|
+static int state_window_position = 0; |
+static int in_JS_state = 0; |
Kasper Lund
2010/12/08 14:54:15
static int state_counts[2] = { 0, } and then use s
|
+static int not_in_JS_state = 0; |
+static int sampler_ticks = kSamplerTicksDelta; |
Kasper Lund
2010/12/08 14:54:15
This name doesn't really relay much information. I
|
+ |
// The JSFunctions in the sampler window are not GC safe. Old-space |
// pointers are not cleared during mark-sweep collection and therefore |
// the window might contain stale pointers. The window is updated on |
@@ -257,6 +264,9 @@ |
} |
optimize_soon_list = NULL; |
+ 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
|
+ in_JS_state + not_in_JS_state); |
+ |
// Run through the JavaScript frames and collect them. If we already |
// have a sample of the function, we mark it for optimizations |
// (eagerly or lazily). |
@@ -267,16 +277,39 @@ |
it.Advance()) { |
JavaScriptFrame* frame = it.frame(); |
JSFunction* function = JSFunction::cast(frame->function()); |
+ |
+ if (sampler_ticks > 0) { |
Kasper Lund
2010/12/08 14:54:15
Add a comment that explains what this does.
|
+ sampler_ticks--; |
+ if (sampler_ticks == 0) { |
+ if (sampler_threshold > kSamplerThresholdMin) { |
+ sampler_threshold -= kSamplerThresholdDelta; |
+ } |
+ sampler_ticks = kSamplerTicksDelta; |
+ } |
+ } |
+ |
+ if (!IsOptimizable(function) && !function->IsMarkedForLazyRecompilation()) { |
Kasper Lund
2010/12/08 14:54:15
Please explain what you're trying to filter out he
|
+ continue; |
+ } |
+ |
+ samples[count++] = function; |
+ |
int function_size = function->shared()->SourceSize(); |
int threshold_size_factor; |
- if (function_size > kSizeLimit) { |
- threshold_size_factor = sampler_threshold_size_factor; |
- } else { |
- threshold_size_factor = 1; |
+ threshold_size_factor = (function_size > kSizeLimit) |
Kasper Lund
2010/12/08 14:54:15
Why not initialize threshold_size_factor directly
|
+ ? sampler_threshold_size_factor |
+ : 1; |
+ |
+ int threshold = sampler_threshold * threshold_size_factor; |
+ |
+ 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
|
+ threshold = kStateWindowSize; |
+ } else if (js_ratio < .5) { |
+ threshold *= 3; |
+ } else if (js_ratio < .75) { |
+ threshold *= 2; |
} |
- int threshold = sampler_threshold * threshold_size_factor; |
- samples[count++] = function; |
if (function->IsMarkedForLazyRecompilation()) { |
Code* unoptimized = function->shared()->code(); |
int nesting = unoptimized->allow_osr_at_loop_nesting_level(); |
@@ -284,10 +317,8 @@ |
int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker); |
unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting); |
} else if (LookupSample(function) >= threshold) { |
- if (IsOptimizable(function)) { |
- Optimize(function, false, 0); |
- CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function)); |
- } |
+ Optimize(function, false, 0); |
+ CompilationCache::MarkForEagerOptimizing(Handle<JSFunction>(function)); |
} |
} |
@@ -332,6 +363,11 @@ |
void RuntimeProfiler::Setup() { |
+ for (int i = 0; i < kStateWindowSize; i++) { |
+ state_window[i] = false; |
+ } |
+ in_JS_state = 0; |
+ not_in_JS_state = kStateWindowSize; |
ClearSampleBuffer(); |
// If the ticker hasn't already started, make sure to do so to get |
// the ticks for the runtime profiler. |
@@ -341,6 +377,7 @@ |
void RuntimeProfiler::Reset() { |
sampler_threshold = kSamplerThresholdInit; |
+ sampler_ticks = kSamplerTicksDelta; |
sampler_threshold_size_factor = kSamplerThresholdSizeFactorInit; |
} |
@@ -360,6 +397,23 @@ |
} |
+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.
|
+ if (state_window[state_window_position]) { |
Kasper Lund
2010/12/08 14:54:15
state_counts[state_window[state_window_position]]-
|
+ in_JS_state--; |
fschneider
2010/12/08 14:33:33
is_js_state vs in_JS_state: These variable names a
|
+ } else { |
+ not_in_JS_state--; |
+ } |
+ state_window[state_window_position] = in_js_state; |
+ if (in_js_state) { |
Kasper Lund
2010/12/08 14:54:15
state_counts[state]++; No branches.
|
+ in_JS_state++; |
+ } else { |
+ not_in_JS_state++; |
+ } |
+ state_window_position = (state_window_position + 1) & |
Kasper Lund
2010/12/08 14:54:15
ASSERT(IsPowerOf2(kStateWindowSize));
|
+ (kStateWindowSize - 1); |
+} |
+ |
+ |
bool RuntimeProfilerRateLimiter::SuspendIfNecessary() { |
static const int kNonJSTicksThreshold = 100; |
// We suspend the runtime profiler thread when not running |
@@ -369,8 +423,10 @@ |
!CpuProfiler::is_profiling() && |
!(FLAG_prof && FLAG_prof_auto)) { |
if (Top::IsInJSState()) { |
+ AddStateSample(true); |
non_js_ticks_ = 0; |
} else { |
+ AddStateSample(false); |
if (non_js_ticks_ < kNonJSTicksThreshold) { |
++non_js_ticks_; |
} else { |