Reviewers: jochen (slow - soon OOO), ulan,

Description:
Perform full gcs when context disposals happen too frequent.

Removed context disposal logic from IdleNotification.

BUG=

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

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

Affected files (+36, -45 lines):
  M include/v8.h
  M src/api.cc
  M src/heap/heap.h
  M src/heap/heap.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index f702166cd4d281965f2caba33a616888eb7cb0fb..d3103fdafa42080f42ba0e121429724ebef9c0dc 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -4481,12 +4481,10 @@ class V8_EXPORT Isolate {
   void LowMemoryNotification();

   /**
-   * Optional notification that a context has been disposed. V8 uses
-   * these notifications to guide the GC heuristic. Returns the number
-   * of context disposals - including this one - since the last time
-   * V8 had a chance to clean up.
+ * Optional notification that a context has been disposed. This may trigger
+   * a full garbage collection if invoked too frequently.
    */
-  int ContextDisposedNotification();
+  void ContextDisposedNotification();

  private:
   template<class K, class V, class Traits> friend class PersistentValueMap;
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index bd49c84630b23748a747c13a867ef04d15ad5ee4..60c6b3c727a2c797195fde255e8e76ee142835d6 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -6724,9 +6724,9 @@ void v8::Isolate::LowMemoryNotification() {
 }


-int v8::Isolate::ContextDisposedNotification() {
+void v8::Isolate::ContextDisposedNotification() {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  return isolate->heap()->NotifyContextDisposed();
+  isolate->heap()->NotifyContextDisposed();
 }


Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 3f3d591025ce5522b99ff474f5e6d5561de47c2e..6455ee066cbe0d84de1cf89af33ada3bfe1d31e7 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -68,9 +68,9 @@ Heap::Heap()
       survived_since_last_expansion_(0),
       sweep_generation_(0),
       always_allocate_scope_depth_(0),
-      contexts_disposed_(0),
       global_ic_age_(0),
       flush_monomorphic_ics_(false),
+      last_notify_context_disposed_(0.0),
       scan_on_scavenge_pages_(0),
       new_space_(this),
       old_pointer_space_(NULL),
@@ -858,14 +858,26 @@ bool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason,
 }


-int Heap::NotifyContextDisposed() {
+void Heap::NotifyContextDisposed() {
+  double current_notify_context_disposed = base::OS::TimeCurrentMillis();
   if (isolate()->concurrent_recompilation_enabled()) {
     // Flush the queued recompilation tasks.
     isolate()->optimizing_compiler_thread()->Flush();
   }
   flush_monomorphic_ics_ = true;
   AgeInlineCaches();
-  return ++contexts_disposed_;
+  if (last_notify_context_disposed_ > 0.0 &&
+      (current_notify_context_disposed - last_notify_context_disposed_ <
+       static_cast<double>(kNotifyContextDisposedFullGCLimitInMS))) {
+    CollectAllGarbage(kReduceMemoryFootprintMask,
+                      "notify contexts disposed at high rate");
+  }
+
+ // After context disposal there is likely a lot of garbage remaining, reset + // the idle notification counters in order to allow more idle notifcations.
+  StartIdleRound();
+
+  last_notify_context_disposed_ = base::OS::TimeCurrentMillis();
 }


@@ -4302,33 +4314,6 @@ bool Heap::IdleNotification(int hint) {
   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 &&
-        incremental_marking()->IsStopped()) {
-      HistogramTimerScope scope(isolate_->counters()->gc_context());
-      CollectAllGarbage(kReduceMemoryFootprintMask,
-                        "idle notification: contexts disposed");
-    } else {
-      AdvanceIdleIncrementalMarking(step_size);
-    }
-
- // After context disposal there is likely a lot of garbage remaining, reset - // the idle notification counters in order to trigger more incremental GCs
-    // on subsequent idle notifications.
-    StartIdleRound();
-    return false;
-  }
-
-  // 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,
-  // Use mark-sweep-compact events to count incremental GCs in a round.
-
   if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
     if (EnoughGarbageSinceLastIdleRound()) {
       StartIdleRound();
@@ -4337,10 +4322,15 @@ bool Heap::IdleNotification(int hint) {
     }
   }

-  int remaining_mark_sweeps =
-      kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_;
-
-  if (incremental_marking()->IsStopped()) {
+  int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000);
+  // Perform a full gc if there is enough idle time.
+  if (hint >= mark_sweep_time) {
+    CollectAllGarbage(kReduceMemoryFootprintMask,
+                      "idle notification: finalize idle round");
+    mark_sweeps_since_idle_round_started_++;
+  } else if (incremental_marking()->IsStopped()) {
+    int remaining_mark_sweeps =
+        kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_;
     // If there are no more than two GCs left in this idle round and we are
// allowed to do a full GC, then make those GCs full in order to compact
     // the code space.
Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index 528ef4d517e2d5536f639418aeec85ab30137f16..07361040922fce1eba0f6be29efa9b680587b301 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -754,7 +754,7 @@ class Heap {
   bool IsHeapIterable();

   // Notify the heap that a context has been disposed.
-  int NotifyContextDisposed();
+  void NotifyContextDisposed();

   inline void increment_scan_on_scavenge_pages() {
     scan_on_scavenge_pages_++;
@@ -1462,13 +1462,16 @@ class Heap {

   int always_allocate_scope_depth_;

-  // For keeping track of context disposals.
-  int contexts_disposed_;
-
   int global_ic_age_;

   bool flush_monomorphic_ics_;

+  // If context disposals happen at a high rate, we do a full gc in between
+  // context disposal.
+  // TODO(hpayer): We should get rid of that mode.
+  static const int kNotifyContextDisposedFullGCLimitInMS = 1000;
+  double last_notify_context_disposed_;
+
   int scan_on_scavenge_pages_;

   NewSpace new_space_;


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