Reviewers: Vyacheslav Egorov,

Message:
Please take a look, it is to be committed after the push to trunk.

Description:
Start incremental marking on idle notification.

Once marking is finished, perform global GC in the same way IdleNotification
did before.

BUG=v8:1458
TEST=cctest/test-heap/IdleNotificationAdvancesIncrementalMarking


Please review this at http://codereview.chromium.org/8084002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/heap.h
  M src/heap.cc
  M src/incremental-marking.h
  M test/cctest/test-heap.cc


Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 522861deda05e2a163861ac527be202631387441..945587f92fb4e63b301d846c4f2e648796c08ca7 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -140,6 +140,7 @@ Heap::Heap()
       store_buffer_(this),
       marking_(this),
       incremental_marking_(this),
+      idle_work_(IDLE_INCREMENTAL_MARKING),
       number_idle_notifications_(0),
       last_idle_notification_gc_count_(0),
       last_idle_notification_gc_count_init_(false),
@@ -4515,6 +4516,36 @@ void Heap::EnsureHeapIsIterable() {


 bool Heap::IdleNotification() {
+  switch (idle_work_) {
+    case IDLE_INCREMENTAL_MARKING:
+      if (IdleIncrementalMarking()) {
+        idle_work_ = IDLE_GLOBAL_GC;
+      }
+      break;
+    case IDLE_GLOBAL_GC:
+      if (IdleGlobalGC()) {
+        idle_work_ = IDLE_INCREMENTAL_MARKING;
+        return true;
+      }
+      break;
+    default:
+      UNREACHABLE();
+  }
+  return false;
+}
+
+bool Heap::IdleIncrementalMarking() {
+  if (incremental_marking()->IsStopped()) {
+    if (!incremental_marking()->WorthActivating()) {
+      return true;
+    }
+    incremental_marking()->Start();
+  }
+  incremental_marking()->Step(IncrementalMarking::kStepFakeAllocatedBytes);
+  return incremental_marking()->IsComplete();
+}
+
+bool Heap::IdleGlobalGC() {
   static const int kIdlesBeforeScavenge = 4;
   static const int kIdlesBeforeMarkSweep = 7;
   static const int kIdlesBeforeMarkCompact = 8;
Index: src/heap.h
diff --git a/src/heap.h b/src/heap.h
index 4a1e01dcaa3135aa4ebd452259c847f60a9e70ab..e042957f31f76c2029db3c80cca73abebbdaa653 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1757,6 +1757,12 @@ class Heap {

   void SelectScavengingVisitorsTable();

+  // Returns true if incremental marking is finished.
+  bool IdleIncrementalMarking();
+
+  // Returns true if no more GC work is left.
+  bool IdleGlobalGC();
+
   static const int kInitialSymbolTableSize = 2048;
   static const int kInitialEvalCacheSize = 64;

@@ -1782,6 +1788,13 @@ class Heap {

   IncrementalMarking incremental_marking_;

+  enum IdleWork {
+    IDLE_INCREMENTAL_MARKING,
+    IDLE_GLOBAL_GC
+  };
+
+  IdleWork idle_work_;
+
   int number_idle_notifications_;
   unsigned int last_idle_notification_gc_count_;
   bool last_idle_notification_gc_count_init_;
Index: src/incremental-marking.h
diff --git a/src/incremental-marking.h b/src/incremental-marking.h
index 30dbbc1605c7c5415767101469cc1f55c2d504ef..94500978b0b00882127a2734befc5ce79fadd19c 100644
--- a/src/incremental-marking.h
+++ b/src/incremental-marking.h
@@ -63,6 +63,8 @@ class IncrementalMarking {

   inline bool IsMarkingIncomplete() { return state() == MARKING; }

+  inline bool IsComplete() { return state() == COMPLETE; }
+
   bool WorthActivating();

   void Start();
@@ -97,6 +99,9 @@ class IncrementalMarking {
   // This is how much we increase the marking/allocating factor by.
   static const intptr_t kAllocationMarkingFactorSpeedup = 2;
   static const intptr_t kMaxAllocationMarkingFactor = 1000000000;
+ // This is given to Step() function when it is called without any allocation.
+  static const intptr_t kStepFakeAllocatedBytes = kAllocatedThreshold * 3;
+

   void OldSpaceStep(intptr_t allocated) {
     Step(allocated * kFastMarking / kInitialAllocationMarkingFactor);
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 40482be7edbd755cc06430d60b8816f448ad2cb2..058559c8ad4d727e6a77f7b69b51b5e224a121af 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -1272,3 +1272,34 @@ TEST(GrowAndShrinkNewSpace) {
   new_capacity = new_space->Capacity();
   CHECK(old_capacity == new_capacity);
 }
+
+TEST(IdleNotificationAdvancesIncrementalMarking) {
+  if (!FLAG_incremental_marking || !FLAG_incremental_marking_steps) return;
+  InitializeVM();
+  v8::HandleScope scope;
+  const char* source = "function binom(n, m) {"
+                       "  var C = [[1]];"
+                       "  for (var i = 1; i <= n; ++i) {"
+                       "    C[i] = [1];"
+                       "    for (var j = 1; j < i; ++j) {"
+                       "      C[i][j] = C[i-1][j-1] + C[i-1][j];"
+                       "    }"
+                       "    C[i][i] = 1;"
+                       "  }"
+                       "  return C[n][m];"
+                       "};"
+                       "binom(1000, 500)";
+  {
+    AlwaysAllocateScope aa_scope;
+    CompileRun(source);
+  }
+  intptr_t old_size = HEAP->SizeOfObjects();
+  int old_steps = HEAP->incremental_marking()->steps_count();
+  HEAP->IdleNotification();
+  int new_steps = HEAP->incremental_marking()->steps_count();
+  CHECK(new_steps > old_steps);
+  while (!HEAP->IdleNotification());
+  intptr_t new_size = HEAP->SizeOfObjects();
+  CHECK(new_size < old_size);
+}
+


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to