Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index e6dd2a9657c7f81a7d5c186ad618d7f957eac8bc..0169df038dc3e1802d0ed1b9a979c5d3c3a17656 100644 |
| --- a/src/heap.cc |
| +++ b/src/heap.cc |
| @@ -4821,11 +4821,53 @@ void Heap::EnsureHeapIsIterable() { |
| } |
| +void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { |
|
ulan
2012/03/16 13:37:23
This function is extracted from lines 4876-4894 of
|
| + // This flag prevents incremental marking from requesting GC via stack guard |
| + idle_notification_will_schedule_next_gc_ = true; |
| + incremental_marking()->Step(step_size); |
| + idle_notification_will_schedule_next_gc_ = false; |
| + |
| + if (incremental_marking()->IsComplete()) { |
| + bool uncommit = false; |
| + if (gc_count_at_last_idle_gc_ == gc_count_) { |
| + // No GC since the last full GC, the mutator is probably not active. |
| + isolate_->compilation_cache()->Clear(); |
| + uncommit = true; |
| + } |
| + CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); |
| + gc_count_at_last_idle_gc_ = gc_count_; |
| + if (uncommit) { |
| + new_space_.Shrink(); |
| + UncommitFromSpace(); |
| + } |
| + } |
| +} |
| + |
| + |
| bool Heap::IdleNotification(int hint) { |
| - if (hint >= 1000) return IdleGlobalGC(); |
| - if (contexts_disposed_ > 0 || !FLAG_incremental_marking || |
| + intptr_t size_factor = Min(Max(hint, 30), 1000) / 10; |
| + // The size factor is in range [3..100]. |
| + intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold; |
| + |
| + if (contexts_disposed_ > 0) { |
| + if (hint > TimeMarkSweepWouldTakeInMs() && !FLAG_expose_gc) { |
| + HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| + CollectAllGarbage(kReduceMemoryFootprintMask, |
| + "idle notification: contexts disposed"); |
| + } else { |
| + AdvanceIdleIncrementalMarking(step_size); |
| + contexts_disposed_ = 0; |
| + } |
| + // Make sure that we have no pending context disposals. |
| + // Take into account that we might have decided to delay full collection |
| + // because incremental marking is in progress. |
| + ASSERT((contexts_disposed_ == 0) || !incremental_marking()->IsStopped()); |
| + return false; |
| + } |
| + |
| + if (hint >= 1000 || !FLAG_incremental_marking || |
|
ulan
2012/03/16 13:37:23
Once this CL lands into Chromium without memory re
|
| FLAG_expose_gc || Serializer::enabled()) { |
| - return true; |
| + return IdleGlobalGC(); |
| } |
| // By doing small chunks of GC work in each IdleNotification, |
| @@ -4837,9 +4879,6 @@ bool Heap::IdleNotification(int hint) { |
| // 3. many lazy sweep steps. |
| // Use mark-sweep-compact events to count incremental GCs in a round. |
| - intptr_t size_factor = Min(Max(hint, 30), 1000) / 10; |
| - // The size factor is in range [3..100]. |
| - intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold; |
| if (incremental_marking()->IsStopped()) { |
| if (!IsSweepingComplete() && |
| @@ -4866,32 +4905,14 @@ bool Heap::IdleNotification(int hint) { |
| } |
| if (incremental_marking()->IsStopped()) { |
| - if (hint < 1000 && !WorthStartingGCWhenIdle()) { |
| + if (!WorthStartingGCWhenIdle()) { |
| FinishIdleRound(); |
| return true; |
| } |
| incremental_marking()->Start(); |
| } |
| - // This flag prevents incremental marking from requesting GC via stack guard |
| - idle_notification_will_schedule_next_gc_ = true; |
| - incremental_marking()->Step(step_size); |
| - idle_notification_will_schedule_next_gc_ = false; |
| - |
| - if (incremental_marking()->IsComplete()) { |
| - bool uncommit = false; |
| - if (gc_count_at_last_idle_gc_ == gc_count_) { |
| - // No GC since the last full GC, the mutator is probably not active. |
| - isolate_->compilation_cache()->Clear(); |
| - uncommit = true; |
| - } |
| - CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); |
| - gc_count_at_last_idle_gc_ = gc_count_; |
| - if (uncommit) { |
| - new_space_.Shrink(); |
| - UncommitFromSpace(); |
| - } |
| - } |
| + AdvanceIdleIncrementalMarking(step_size); |
| return false; |
| } |
| @@ -4924,13 +4945,7 @@ bool Heap::IdleGlobalGC() { |
| } |
| if (number_idle_notifications_ == kIdlesBeforeScavenge) { |
| - if (contexts_disposed_ > 0) { |
| - HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| - CollectAllGarbage(kReduceMemoryFootprintMask, |
| - "idle notification: contexts disposed"); |
| - } else { |
| - CollectGarbage(NEW_SPACE, "idle notification"); |
| - } |
| + CollectGarbage(NEW_SPACE, "idle notification"); |
| new_space_.Shrink(); |
| last_idle_notification_gc_count_ = gc_count_; |
| } else if (number_idle_notifications_ == kIdlesBeforeMarkSweep) { |
| @@ -4949,23 +4964,6 @@ bool Heap::IdleGlobalGC() { |
| last_idle_notification_gc_count_ = gc_count_; |
| number_idle_notifications_ = 0; |
| finished = true; |
| - } else if (contexts_disposed_ > 0) { |
| - if (FLAG_expose_gc) { |
| - contexts_disposed_ = 0; |
| - } else { |
| - HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| - CollectAllGarbage(kReduceMemoryFootprintMask, |
| - "idle notification: contexts disposed"); |
| - last_idle_notification_gc_count_ = gc_count_; |
| - } |
| - // If this is the first idle notification, we reset the |
| - // notification count to avoid letting idle notifications for |
| - // context disposal garbage collections start a potentially too |
| - // aggressive idle GC cycle. |
| - if (number_idle_notifications_ <= 1) { |
| - number_idle_notifications_ = 0; |
| - uncommit = false; |
| - } |
| } else if (number_idle_notifications_ > kIdlesBeforeMarkCompact) { |
| // If we have received more than kIdlesBeforeMarkCompact idle |
| // notifications we do not perform any cleanup because we don't |
| @@ -4973,11 +4971,6 @@ bool Heap::IdleGlobalGC() { |
| finished = true; |
| } |
| - // Make sure that we have no pending context disposals and |
| - // conditionally uncommit from space. |
| - // Take into account that we might have decided to delay full collection |
| - // because incremental marking is in progress. |
| - ASSERT((contexts_disposed_ == 0) || !incremental_marking()->IsStopped()); |
| if (uncommit) UncommitFromSpace(); |
| return finished; |