Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(300)

Unified Diff: src/heap.cc

Issue 8519002: Start incremental marking on idle notification. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments, tuned idle round starting conditions. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 4da83e859e3ddff3f2988c00f066ab63ddf58c04..8d36b87307006ff496f2ee622cb6faf93dde1731 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -143,6 +143,11 @@ 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),
+ scavenges_since_last_idle_round_(kIdleScavengeThreshold),
ulan 2011/11/23 16:18:06 The initial value allows to start the idle round o
configured_(false),
chunks_queued_for_free_(NULL) {
// Allow build-time customization of the max semispace size. Building
@@ -1010,8 +1015,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 +1103,8 @@ void Heap::Scavenge() {
LOG(isolate_, ResourceEvent("scavenge", "end"));
gc_state_ = NOT_IN_GC;
+
+ scavenges_since_last_idle_round_++;
}
@@ -4460,7 +4466,79 @@ void Heap::EnsureHeapIsIterable() {
}
-bool Heap::IdleNotification() {
+bool Heap::IdleNotification(int hint) {
+ if (!FLAG_incremental_marking || FLAG_expose_gc) {
+ 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.
+
+ 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 (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) {
+ FinishIdleRound();
+ return true;
+ }
+
+ if (incremental_marking()->IsStopped()) {
+ if (hint < 1000 && !WorthStartingGCWhenIdle()) {
ulan 2011/11/23 16:18:06 If hint >= 1000 then the embedder is asking us to
+ 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);
+ 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;

Powered by Google App Engine
This is Rietveld 408576698