Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index 67ee043e0b1168d49e5fef8914fc9535cc575600..3ef8005f8588d5f8aecb523ffd437b424a066582 100644 |
| --- a/src/heap.cc |
| +++ b/src/heap.cc |
| @@ -4230,7 +4230,10 @@ void Heap::MakeHeapIterable() { |
| void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { |
| incremental_marking()->Step(step_size, |
| IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| +} |
| + |
| +void Heap::FinalizeIdleIncrementalMarking() { |
| if (incremental_marking()->IsComplete()) { |
| bool uncommit = false; |
| if (gc_count_at_last_idle_gc_ == gc_count_) { |
| @@ -4250,37 +4253,45 @@ void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { |
| } |
| -bool Heap::IdleNotification(int hint) { |
| +bool Heap::IdleNotification(int idle_time_in_ms) { |
| // If incremental marking is off, we do not perform idle notification. |
| if (!FLAG_incremental_marking) return true; |
| // Hints greater than this value indicate that |
| // the embedder is requesting a lot of GC work. |
| const int kMaxHint = 1000; |
| + // TODO(hpayer): remove min hint |
| const int kMinHintForIncrementalMarking = 10; |
| // Minimal hint that allows to do full GC. |
| const int kMinHintForFullGC = 100; |
| - intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; |
| + // TODO(hpayer, ernstm): use previous time measurements to calculate |
| + // proper size_factor |
| + intptr_t size_factor = Min(Max(idle_time_in_ms, 20), kMaxHint) / 4; |
| // The size factor is in range [5..250]. The numbers here are chosen from |
| // experiments. If you changes them, make sure to test with |
| // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.* |
| intptr_t step_size = |
| size_factor * IncrementalMarking::kAllocatedThreshold; |
| - isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(hint); |
| + isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( |
| + idle_time_in_ms); |
| HistogramTimerScope idle_notification_scope( |
| isolate_->counters()->gc_idle_notification()); |
| if (contexts_disposed_ > 0) { |
| contexts_disposed_ = 0; |
| int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); |
| - if (hint >= mark_sweep_time && !FLAG_expose_gc && |
| + if (idle_time_in_ms >= mark_sweep_time && !FLAG_expose_gc && |
| incremental_marking()->IsStopped()) { |
| HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| CollectAllGarbage(kReduceMemoryFootprintMask, |
| "idle notification: contexts disposed"); |
| } else { |
| AdvanceIdleIncrementalMarking(step_size); |
|
Hannes Payer (out of office)
2014/07/30 12:52:08
AdvanceIdleIncrementalMarking does not necessarily
|
| + int elapsed_time = tracer_.last_incremental_marking_step_duration(); |
| + if (idle_time_in_ms - elapsed_time > kMinHintForIncrementalMarking) { |
| + FinalizeIdleIncrementalMarking(); |
| + } |
| } |
| // After context disposal there is likely a lot of garbage remaining, reset |
| @@ -4315,17 +4326,21 @@ bool Heap::IdleNotification(int hint) { |
| // the code space. |
| // TODO(ulan): Once we enable code compaction for incremental marking, |
| // we can get rid of this special case and always start incremental marking. |
| - if (remaining_mark_sweeps <= 2 && hint >= kMinHintForFullGC) { |
| + if (remaining_mark_sweeps <= 2 && idle_time_in_ms >= kMinHintForFullGC) { |
| CollectAllGarbage(kReduceMemoryFootprintMask, |
| "idle notification: finalize idle round"); |
| mark_sweeps_since_idle_round_started_++; |
| - } else if (hint > kMinHintForIncrementalMarking) { |
| + } else if (idle_time_in_ms > kMinHintForIncrementalMarking) { |
| incremental_marking()->Start(); |
| } |
| } |
| if (!incremental_marking()->IsStopped() && |
| - hint > kMinHintForIncrementalMarking) { |
| + idle_time_in_ms > kMinHintForIncrementalMarking) { |
| AdvanceIdleIncrementalMarking(step_size); |
| + int elapsed_time = tracer_.last_incremental_marking_step_duration(); |
| + if (idle_time_in_ms - elapsed_time > kMinHintForIncrementalMarking) { |
| + FinalizeIdleIncrementalMarking(); |
| + } |
| } |
| if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { |
| @@ -4333,9 +4348,9 @@ bool Heap::IdleNotification(int hint) { |
| return true; |
| } |
| - // If the IdleNotifcation is called with a large hint we will wait for |
| - // the sweepter threads here. |
| - if (hint >= kMinHintForFullGC && |
| + // If the IdleNotifcation is called with a large idle_time_in_ms we will wait |
| + // for the sweepter threads here. |
| + if (idle_time_in_ms >= kMinHintForFullGC && |
| mark_compact_collector()->sweeping_in_progress()) { |
| mark_compact_collector()->EnsureSweepingCompleted(); |
| } |