Reviewers: jochen, ernstm,

Message:
This is the first in a series of refactoring CLs. I left two TODOs for the next
steps.

Description:
Make sure that there is enough time left before finishing incremental marking in
idle notification.

BUG=

Please review this at https://codereview.chromium.org/423303006/

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

Affected files (+33, -15 lines):
  M src/heap.h
  M src/heap.cc


Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 67ee043e0b1168d49e5fef8914fc9535cc575600..2b8ce1d9f4a75b3848f6b64ddc7506c302c87acf 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -4227,10 +4227,15 @@ void Heap::MakeHeapIterable() {
 }


-void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
+int Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
+  double start = base::OS::TimeCurrentMillis();
   incremental_marking()->Step(step_size,
                               IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+  return static_cast<int>(base::OS::TimeCurrentMillis() - start);
+}
+

+void Heap::FinalizeIdleIncrementalMarking() {
   if (incremental_marking()->IsComplete()) {
     bool uncommit = false;
     if (gc_count_at_last_idle_gc_ == gc_count_) {
@@ -4250,37 +4255,44 @@ 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);
+      int remaining_time = AdvanceIdleIncrementalMarking(step_size);
+ if (idle_time_in_ms - remaining_time > kMinHintForIncrementalMarking) {
+        FinalizeIdleIncrementalMarking();
+      }
     }

// After context disposal there is likely a lot of garbage remaining, reset
@@ -4315,17 +4327,20 @@ 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) {
-    AdvanceIdleIncrementalMarking(step_size);
+      idle_time_in_ms > kMinHintForIncrementalMarking) {
+    int remaining_time = AdvanceIdleIncrementalMarking(step_size);
+    if (idle_time_in_ms - remaining_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();
   }
Index: src/heap.h
diff --git a/src/heap.h b/src/heap.h
index 587b67bdf064c771de14f9b08bb9d839773c5b56..6f5d70982097db39add6dea0fc1e43df928b5919 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1090,7 +1090,7 @@ class Heap {
   void DisableInlineAllocation();

   // Implements the corresponding V8 API function.
-  bool IdleNotification(int hint);
+  bool IdleNotification(int idle_time_in_ms);

   // Declare all the root indices.  This defines the root list order.
   enum RootListIndex {
@@ -2063,7 +2063,10 @@ class Heap {
     return heap_size_mb / kMbPerMs;
   }

-  void AdvanceIdleIncrementalMarking(intptr_t step_size);
+  // Returns the time in ms spent in incremental marking.
+  int AdvanceIdleIncrementalMarking(intptr_t step_size);
+
+  void FinalizeIdleIncrementalMarking();

   void ClearObjectStats(bool clear_last_time_stats = false);



--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to