Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index 4da83e859e3ddff3f2988c00f066ab63ddf58c04..3f5bff8386cce7166e7da63f437d6fd23649108e 100644 |
| --- a/src/heap.cc |
| +++ b/src/heap.cc |
| @@ -105,6 +105,7 @@ Heap::Heap() |
| gc_post_processing_depth_(0), |
| ms_count_(0), |
| gc_count_(0), |
| + scavenges_since_last_full_gc_(0), |
| unflattened_strings_length_(0), |
| #ifdef DEBUG |
| allocation_allowed_(true), |
| @@ -143,6 +144,10 @@ Heap::Heap() |
| number_idle_notifications_(0), |
| last_idle_notification_gc_count_(0), |
| last_idle_notification_gc_count_init_(false), |
| + idle_notification_will_schedule_next_gc_(false), |
| + mark_sweeps_since_idle_round_started_(0), |
| + ms_count_at_last_idle_notification_(0), |
| + gc_count_at_last_idle_gc_(0), |
| configured_(false), |
| chunks_queued_for_free_(NULL) { |
| // Allow build-time customization of the max semispace size. Building |
| @@ -822,6 +827,8 @@ void Heap::MarkCompact(GCTracer* tracer) { |
| isolate_->counters()->objs_since_last_full()->Set(0); |
| contexts_disposed_ = 0; |
| + |
| + scavenges_since_last_full_gc_ = 0; |
| } |
| @@ -1010,8 +1017,7 @@ void Heap::Scavenge() { |
| incremental_marking()->PrepareForScavenge(); |
| - old_pointer_space()->AdvanceSweeper(new_space_.Size()); |
| - old_data_space()->AdvanceSweeper(new_space_.Size()); |
| + AdvanceSweepers(new_space_.Size()); |
| // Flip the semispaces. After flipping, to space is empty, from space has |
| // live objects. |
| @@ -1099,6 +1105,8 @@ void Heap::Scavenge() { |
| LOG(isolate_, ResourceEvent("scavenge", "end")); |
| gc_state_ = NOT_IN_GC; |
| + |
| + scavenges_since_last_full_gc_++; |
| } |
| @@ -4460,7 +4468,75 @@ void Heap::EnsureHeapIsIterable() { |
| } |
| -bool Heap::IdleNotification() { |
| +bool Heap::IdleNotification(int hint) { |
| + if (!FLAG_incremental_marking) { |
| + return hint < 1000 ? true : IdleGlobalGC(); |
| + } |
| + |
| + // By doing small chunks of GC work in each IdleNotification, |
| + // perform a round of incremental GCs and after that wait until |
| + // the mutator creates enough garbage to justify a new round. |
| + // An incremental GC progresses as follows: |
| + // 1. many incremental marking steps, |
| + // 2. one old space mark-sweep-compact, |
| + // 3. many lazy sweep steps. |
| + // Use mark-sweep-compact events to count incremental GCs in a round. |
| + |
| + if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { |
| + if (EnoughGarbageSinceLastIdleRound()) { |
| + StartIdleRound(); |
| + } else { |
| + return true; |
| + } |
| + } |
| + |
| + int new_mark_sweeps = ms_count_ - ms_count_at_last_idle_notification_; |
| + mark_sweeps_since_idle_round_started_ += new_mark_sweeps; |
| + ms_count_at_last_idle_notification_ = ms_count_; |
| + |
| + if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { |
|
Erik Corry
2011/11/22 12:29:26
This test is also included in WorthStartingGCWhenI
ulan
2011/11/23 16:18:06
Removed the test from WorthStartingGCWhenIdle.
|
| + FinishIdleRound(); |
| + return true; |
|
Erik Corry
2011/11/22 12:29:26
If sweeping is not complete we should not return h
ulan
2011/11/23 16:18:06
Moved the sweeping steps up.
|
| + } |
| + |
| + 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() && !AdvanceSweepers(step_size)) { |
| + return false; |
| + } |
| + 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_) { |
|
Erik Corry
2011/11/22 12:29:26
It would be nice with a comment that explained the
ulan
2011/11/23 16:18:06
Done.
|
| + isolate_->compilation_cache()->Clear(); |
| + uncommit = true; |
| + } |
| + CollectAllGarbage(kNoGCFlags); |
| + gc_count_at_last_idle_gc_ = gc_count_; |
| + if (uncommit) { |
| + new_space_.Shrink(); |
| + UncommitFromSpace(); |
| + } |
| + } |
| + return false; |
| +} |
| + |
| + |
| +bool Heap::IdleGlobalGC() { |
| static const int kIdlesBeforeScavenge = 4; |
| static const int kIdlesBeforeMarkSweep = 7; |
| static const int kIdlesBeforeMarkCompact = 8; |