Reviewers: ulan,

Message:
adding tests...

Description:
Check if there is still time before finalizing an incremental collection.

BUG=

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

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

Affected files (+77, -14 lines):
  M src/heap/gc-idle-time-handler.h
  M src/heap/gc-idle-time-handler.cc
  M src/heap/heap.h
  M src/heap/heap.cc
  M src/heap/incremental-marking.h
  M src/heap/incremental-marking.cc
  M src/heap/mark-compact.h
  M src/heap/mark-compact.cc


Index: src/heap/gc-idle-time-handler.cc
diff --git a/src/heap/gc-idle-time-handler.cc b/src/heap/gc-idle-time-handler.cc index 3e3644956b15956239feef2bb06117786089ee62..5c46842e22f17fd04bd4e50a8a6b0ca927f02e2f 100644
--- a/src/heap/gc-idle-time-handler.cc
+++ b/src/heap/gc-idle-time-handler.cc
@@ -63,6 +63,9 @@ size_t GCIdleTimeHandler::EstimateMarkingStepSize(

 size_t GCIdleTimeHandler::EstimateMarkCompactTime(
     size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms) {
+  // TODO(hpayer): Be more precise about the type of mark-compact event. It
+  // makes a huge difference if it is incremental or non-incremental and if
+  // compaction is happening.
   if (mark_compact_speed_in_bytes_per_ms == 0) {
mark_compact_speed_in_bytes_per_ms = kInitialConservativeMarkCompactSpeed;
   }
@@ -110,6 +113,15 @@ bool GCIdleTimeHandler::DoScavenge(
 }


+bool GCIdleTimeHandler::DoMarkCompact(
+    size_t idle_time_in_ms, size_t size_of_objects,
+    size_t mark_compact_speed_in_bytes_per_ms) {
+  return idle_time_in_ms >=
+         EstimateMarkCompactTime(size_of_objects,
+                                 mark_compact_speed_in_bytes_per_ms);
+}
+
+
 // The following logic is implemented by the controller:
// (1) If the new space is almost full and we can affort a Scavenge or if the
 // next Scavenge will very likely take long, then a Scavenge is performed.
@@ -148,10 +160,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
   }

   if (heap_state.incremental_marking_stopped) {
-    size_t estimated_time_in_ms =
-        EstimateMarkCompactTime(heap_state.size_of_objects,
- heap_state.mark_compact_speed_in_bytes_per_ms);
-    if (idle_time_in_ms >= estimated_time_in_ms ||
+    if (DoMarkCompact(idle_time_in_ms, heap_state.size_of_objects,
+                      heap_state.mark_compact_speed_in_bytes_per_ms) ||
         (heap_state.size_of_objects < kSmallHeapSize &&
          heap_state.contexts_disposed > 0)) {
// If there are no more than two GCs left in this idle round and we are
Index: src/heap/gc-idle-time-handler.h
diff --git a/src/heap/gc-idle-time-handler.h b/src/heap/gc-idle-time-handler.h index 15aaea668f8e98047e78176642d5d2d2667adc04..3f6f9c76249a874b235af36213d3ef974102f024 100644
--- a/src/heap/gc-idle-time-handler.h
+++ b/src/heap/gc-idle-time-handler.h
@@ -155,6 +155,9 @@ class GCIdleTimeHandler {
   static size_t EstimateMarkCompactTime(
       size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);

+  static bool DoMarkCompact(size_t idle_time_in_ms, size_t size_of_objects,
+                            size_t mark_compact_speed_in_bytes_per_ms);
+
   static bool DoScavenge(
size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
       size_t scavenger_speed_in_bytes_per_ms,
Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 0ccd0ab2f2b86ddab87573070841954d5f53c548..8bc55e3c946266059e16ef6e77e55db1658f44da 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -4267,11 +4267,14 @@ void Heap::MakeHeapIterable() {
 }


-void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
-  incremental_marking()->Step(step_size,
- IncrementalMarking::NO_GC_VIA_STACK_GUARD, true);
-
-  if (incremental_marking()->IsComplete()) {
+void Heap::TryFinalizeIdleIncrementalMarking(
+    size_t idle_time_in_ms, size_t size_of_objects,
+    size_t mark_compact_speed_in_bytes_per_ms) {
+  if (incremental_marking()->IsComplete() ||
+      (mark_compact_collector()->IsMarkingDequeEmpty() &&
+       gc_idle_time_handler_.DoMarkCompact(
+           idle_time_in_ms, size_of_objects,
+           mark_compact_speed_in_bytes_per_ms))) {
     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.
@@ -4339,7 +4342,12 @@ bool Heap::IdleNotification(int idle_time_in_ms) {
       if (incremental_marking()->IsStopped()) {
         incremental_marking()->Start();
       }
-      AdvanceIdleIncrementalMarking(action.parameter);
+      incremental_marking()->Step(action.parameter,
+ IncrementalMarking::NO_GC_VIA_STACK_GUARD,
+                                  true, false);
+      TryFinalizeIdleIncrementalMarking(
+          idle_time_in_ms, heap_state.size_of_objects,
+          heap_state.mark_compact_speed_in_bytes_per_ms);
       break;
     case DO_FULL_GC: {
       HistogramTimerScope scope(isolate_->counters()->gc_context());
Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index c37464c9bcd6e9cc5c2fbf34347cc68b2cff4398..13187118e76b3d55fd74362cf315959a50b7f83f 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -1940,7 +1940,9 @@ class Heap {

   void SelectScavengingVisitorsTable();

-  void AdvanceIdleIncrementalMarking(intptr_t step_size);
+  void TryFinalizeIdleIncrementalMarking(
+      size_t idle_time_in_ms, size_t size_of_objects,
+      size_t mark_compact_speed_in_bytes_per_ms);

   bool WorthActivatingIncrementalMarking();

Index: src/heap/incremental-marking.cc
diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc index d72423a60aa81619516404c2995ebc26df4e60a2..c3f60f4bc66950f6ffbdc533b2a6b56bd5a953c6 100644
--- a/src/heap/incremental-marking.cc
+++ b/src/heap/incremental-marking.cc
@@ -27,6 +27,7 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
       should_hurry_(false),
       marking_speed_(0),
       allocated_(0),
+      idle_marking_delay_counter_(0),
       no_marking_scope_depth_(0),
       unscanned_bytes_of_large_object_(0) {}

@@ -893,7 +894,7 @@ void IncrementalMarking::SpeedUp() {


void IncrementalMarking::Step(intptr_t allocated_bytes, CompletionAction action,
-                              bool force_marking) {
+                              bool force_marking, bool force_completion) {
   if (heap_->gc_state() != Heap::NOT_IN_GC || !FLAG_incremental_marking ||
       !FLAG_incremental_marking_steps ||
       (state_ != SWEEPING && state_ != MARKING)) {
@@ -943,7 +944,11 @@ void IncrementalMarking::Step(intptr_t allocated_bytes, CompletionAction action,
       }
     } else if (state_ == MARKING) {
       bytes_processed = ProcessMarkingDeque(bytes_to_process);
-      if (marking_deque_.IsEmpty()) MarkingComplete(action);
+      IncrementIdleMarkingDelayCounter();
+      if (marking_deque_.IsEmpty() &&
+          (force_completion || IsIdleMarkingDelayCounterLimitReached())) {
+        MarkingComplete(action);
+      }
     }

     steps_count_++;
@@ -978,5 +983,20 @@ void IncrementalMarking::ResetStepCounters() {
 int64_t IncrementalMarking::SpaceLeftInOldSpace() {
return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects();
 }
+
+
+bool IncrementalMarking::IsIdleMarkingDelayCounterLimitReached() {
+  return idle_marking_delay_counter_ >= kMaxIdleMarkingDelayCounter;
+}
+
+
+void IncrementalMarking::IncrementIdleMarkingDelayCounter() {
+  idle_marking_delay_counter_++;
+}
+
+
+void IncrementalMarking::ClearIdleMarkingDelayCounter() {
+  idle_marking_delay_counter_ = 0;
+}
 }
 }  // namespace v8::internal
Index: src/heap/incremental-marking.h
diff --git a/src/heap/incremental-marking.h b/src/heap/incremental-marking.h
index e4a8e972ca8fb10a08073a9dd8bf0fdb6efcdb03..434b73f12b85b2727cb1779cfd36ce5de2207171 100644
--- a/src/heap/incremental-marking.h
+++ b/src/heap/incremental-marking.h
@@ -83,10 +83,14 @@ class IncrementalMarking {
   static const intptr_t kMarkingSpeedAccelleration = 2;
   static const intptr_t kMaxMarkingSpeed = 1000;

+  // This is the upper bound for how many times we allow finalization of
+  // incremental marking to be postponed.
+  static const size_t kMaxIdleMarkingDelayCounter = 3;
+
   void OldSpaceStep(intptr_t allocated);

   void Step(intptr_t allocated, CompletionAction action,
-            bool force_marking = false);
+            bool force_marking = false, bool force_completion = true);

   inline void RestartIfNotMarking() {
     if (state_ == COMPLETE) {
@@ -165,6 +169,8 @@ class IncrementalMarking {
     unscanned_bytes_of_large_object_ = unscanned_bytes;
   }

+  void ClearIdleMarkingDelayCounter();
+
  private:
   int64_t SpaceLeftInOldSpace();

@@ -195,6 +201,10 @@ class IncrementalMarking {

   INLINE(void VisitObject(Map* map, HeapObject* obj, int size));

+  bool IsIdleMarkingDelayCounterLimitReached();
+
+  void IncrementIdleMarkingDelayCounter();
+
   Heap* heap_;

   State state_;
@@ -213,6 +223,7 @@ class IncrementalMarking {
   intptr_t bytes_scanned_;
   intptr_t allocated_;
   intptr_t write_barriers_invoked_since_last_step_;
+  size_t idle_marking_delay_counter_;

   int no_marking_scope_depth_;

Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 69fc579e2fe65ec359644efd01362e5bea362d61..da3ef1e0991fffe02431fb776ece61057811ac4f 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -965,6 +965,8 @@ void MarkCompactCollector::Finish() {
     Deoptimizer::DeoptimizeMarkedCode(isolate());
     have_code_to_deoptimize_ = false;
   }
+
+  heap_->incremental_marking()->ClearIdleMarkingDelayCounter();
 }


@@ -2040,6 +2042,11 @@ void MarkCompactCollector::MarkAllocationSite(AllocationSite* site) {
 }


+bool MarkCompactCollector::IsMarkingDequeEmpty() {
+  return marking_deque_.IsEmpty();
+}
+
+
 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
   // Mark the heap roots including global variables, stack variables,
   // etc., and all objects reachable from them.
Index: src/heap/mark-compact.h
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index 5e615b306ef8b8cab0dd2793313f3ae64b7ba9c7..d56881f7a80b21d655dd9ce61c9345365c2ed484 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -657,6 +657,8 @@ class MarkCompactCollector {
   // to artificially keep AllocationSites alive for a time.
   void MarkAllocationSite(AllocationSite* site);

+  bool IsMarkingDequeEmpty();
+
  private:
   class SweeperTask;



--
--
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