Index: src/heap/memory-reducer.cc |
diff --git a/src/heap/memory-reducer.cc b/src/heap/memory-reducer.cc |
index 13aa09daa5fddb932a991fe77b0805d614defcbf..8e144c6caa6c4df103ef4191f25ec2ddba9fb406 100644 |
--- a/src/heap/memory-reducer.cc |
+++ b/src/heap/memory-reducer.cc |
@@ -24,15 +24,19 @@ MemoryReducer::TimerTask::TimerTask(MemoryReducer* memory_reducer) |
void MemoryReducer::TimerTask::RunInternal() { |
Hannes Payer (out of office)
2015/10/28 14:58:08
Can we leave a comment somewhere mentioning under
ulan
2015/10/29 12:39:24
Done.
|
+ const double kJsCallsPerMsThreshold = 0.25; |
Heap* heap = memory_reducer_->heap(); |
Event event; |
double time_ms = heap->MonotonicallyIncreasingTimeInMs(); |
heap->tracer()->SampleAllocation(time_ms, heap->NewSpaceAllocationCounter(), |
heap->OldGenerationAllocationCounter()); |
+ double js_call_rate = memory_reducer_->SampleAndGetJsCallsPerMs(time_ms); |
+ bool is_idle = |
+ js_call_rate < kJsCallsPerMsThreshold && heap->HasLowAllocationRate(); |
event.type = kTimer; |
event.time_ms = time_ms; |
event.should_start_incremental_gc = |
- heap->HasLowAllocationRate() || heap->ShouldOptimizeForMemoryUsage(); |
+ is_idle || heap->ShouldOptimizeForMemoryUsage(); |
event.can_start_incremental_gc = |
heap->incremental_marking()->IsStopped() && |
heap->incremental_marking()->CanBeActivated(); |
@@ -40,6 +44,16 @@ void MemoryReducer::TimerTask::RunInternal() { |
} |
+double MemoryReducer::SampleAndGetJsCallsPerMs(double time_ms) { |
+ unsigned int counter = heap()->isolate()->js_calls_from_api_counter(); |
+ unsigned int call_delta = counter - js_calls_counter_; |
+ double time_delta_ms = time_ms - js_calls_sample_time_ms_; |
+ js_calls_counter_ = counter; |
+ js_calls_sample_time_ms_ = time_ms; |
+ return time_delta_ms > 0 ? call_delta / time_delta_ms : 0; |
+} |
+ |
+ |
void MemoryReducer::NotifyTimer(const Event& event) { |
DCHECK_EQ(kTimer, event.type); |
DCHECK_EQ(kWait, state_.action); |
@@ -70,7 +84,7 @@ void MemoryReducer::NotifyTimer(const Event& event) { |
"Memory reducer: finalize incremental marking"); |
} |
// Re-schedule the timer. |
- ScheduleTimer(state_.next_gc_start_ms - event.time_ms); |
+ ScheduleTimer(event.time_ms, state_.next_gc_start_ms - event.time_ms); |
if (FLAG_trace_gc_verbose) { |
PrintIsolate(heap()->isolate(), "Memory reducer: waiting for %.f ms\n", |
state_.next_gc_start_ms - event.time_ms); |
@@ -85,7 +99,7 @@ void MemoryReducer::NotifyMarkCompact(const Event& event) { |
state_ = Step(state_, event); |
if (old_action != kWait && state_.action == kWait) { |
// If we are transitioning to the WAIT state, start the timer. |
- ScheduleTimer(state_.next_gc_start_ms - event.time_ms); |
+ ScheduleTimer(event.time_ms, state_.next_gc_start_ms - event.time_ms); |
} |
if (old_action == kRun) { |
if (FLAG_trace_gc_verbose) { |
@@ -103,7 +117,7 @@ void MemoryReducer::NotifyContextDisposed(const Event& event) { |
state_ = Step(state_, event); |
if (old_action != kWait && state_.action == kWait) { |
// If we are transitioning to the WAIT state, start the timer. |
- ScheduleTimer(state_.next_gc_start_ms - event.time_ms); |
+ ScheduleTimer(event.time_ms, state_.next_gc_start_ms - event.time_ms); |
} |
} |
@@ -172,8 +186,10 @@ MemoryReducer::State MemoryReducer::Step(const State& state, |
} |
-void MemoryReducer::ScheduleTimer(double delay_ms) { |
+void MemoryReducer::ScheduleTimer(double time_ms, double delay_ms) { |
DCHECK(delay_ms > 0); |
+ // Record the time and the js call counter. |
+ SampleAndGetJsCallsPerMs(time_ms); |
// Leave some room for precision error in task scheduler. |
const double kSlackMs = 100; |
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate()); |