changeset 49478:8f004146e407

8198515: Extract SoftReferencePolicy code out of CollectorPolicy Reviewed-by: pliden, sjohanss
author stefank
date Thu, 22 Feb 2018 18:36:07 +0100
parents c8e4dc1b9e39
children 4e8c86b75428
files src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp src/hotspot/share/gc/g1/g1CollectedHeap.cpp src/hotspot/share/gc/g1/g1CollectedHeap.hpp src/hotspot/share/gc/g1/g1FullGCScope.cpp src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp src/hotspot/share/gc/parallel/psMarkSweep.cpp src/hotspot/share/gc/parallel/psParallelCompact.cpp src/hotspot/share/gc/parallel/psScavenge.cpp src/hotspot/share/gc/serial/defNewGeneration.cpp src/hotspot/share/gc/serial/genMarkSweep.cpp src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp src/hotspot/share/gc/shared/collectedHeap.hpp src/hotspot/share/gc/shared/collectorPolicy.cpp src/hotspot/share/gc/shared/collectorPolicy.hpp src/hotspot/share/gc/shared/genCollectedHeap.cpp src/hotspot/share/gc/shared/genCollectedHeap.hpp src/hotspot/share/gc/shared/softRefGenPolicy.cpp src/hotspot/share/gc/shared/softRefGenPolicy.hpp src/hotspot/share/gc/shared/softRefPolicy.cpp src/hotspot/share/gc/shared/softRefPolicy.hpp src/hotspot/share/gc/shared/vmGCOperations.cpp src/hotspot/share/prims/whitebox.cpp
diffstat 24 files changed, 250 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -1496,7 +1496,7 @@
                                          max_eden_size,
                                          full,
                                          gc_cause,
-                                         heap->collector_policy());
+                                         heap->soft_ref_policy());
 
   // Reset the expansion cause, now that we just completed
   // a collection cycle.
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -1168,7 +1168,7 @@
   }
 
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
-      collector_policy()->should_clear_all_soft_refs();
+      soft_ref_policy()->should_clear_all_soft_refs();
 
   G1FullCollector collector(this, &_full_gc_memory_manager, explicit_gc, do_clear_all_soft_refs);
   GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
@@ -1343,7 +1343,7 @@
     return result;
   }
 
-  assert(!collector_policy()->should_clear_all_soft_refs(),
+  assert(!soft_ref_policy()->should_clear_all_soft_refs(),
          "Flag should have been handled and cleared prior to this point");
 
   // What else?  We might try synchronous finalization later.  If the total
@@ -1463,6 +1463,7 @@
   CollectedHeap(),
   _young_gen_sampling_thread(NULL),
   _collector_policy(collector_policy),
+  _soft_ref_policy(),
   _memory_manager("G1 Young Generation", "end of minor GC"),
   _full_gc_memory_manager("G1 Old Generation", "end of major GC"),
   _eden_pool(NULL),
@@ -1893,6 +1894,10 @@
   return _collector_policy;
 }
 
+SoftRefPolicy* G1CollectedHeap::soft_ref_policy() {
+  return &_soft_ref_policy;
+}
+
 size_t G1CollectedHeap::capacity() const {
   return _hrm.length() * HeapRegion::GrainBytes;
 }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -49,6 +49,7 @@
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/plab.hpp"
 #include "gc/shared/preservedMarks.hpp"
+#include "gc/shared/softRefPolicy.hpp"
 #include "memory/memRegion.hpp"
 #include "services/memoryManager.hpp"
 #include "utilities/stack.hpp"
@@ -150,6 +151,8 @@
   WorkGang* _workers;
   G1CollectorPolicy* _collector_policy;
 
+  SoftRefPolicy      _soft_ref_policy;
+
   GCMemoryManager _memory_manager;
   GCMemoryManager _full_gc_memory_manager;
 
@@ -998,6 +1001,8 @@
 
   virtual CollectorPolicy* collector_policy() const;
 
+  virtual SoftRefPolicy* soft_ref_policy();
+
   // Adaptive size policy.  No such thing for g1.
   virtual AdaptiveSizePolicy* size_policy() { return NULL; }
 
--- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -35,7 +35,7 @@
     _tracer(),
     _active(),
     _cpu_time(),
-    _soft_refs(clear_soft, _g1h->collector_policy()),
+    _soft_refs(clear_soft, _g1h->soft_ref_policy()),
     _memory_stats(memory_manager, _g1h->gc_cause()),
     _collector_stats(_g1h->g1mm()->full_collection_counters()),
     _heap_transition(_g1h) {
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -331,7 +331,7 @@
         // excesses).  Fill op.result() with a filler object so that the
         // heap remains parsable.
         const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
-        const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
+        const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
 
         if (limit_exceeded && softrefs_clear) {
           *gc_overhead_limit_was_exceeded = true;
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -34,6 +34,7 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "gc/shared/gcWhen.hpp"
+#include "gc/shared/softRefPolicy.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "memory/metaspace.hpp"
 #include "utilities/growableArray.hpp"
@@ -59,6 +60,8 @@
 
   GenerationSizer* _collector_policy;
 
+  SoftRefPolicy _soft_ref_policy;
+
   // Collection of generations that are adjacent in the
   // space reserved for the heap.
   AdjoiningGenerations* _gens;
@@ -106,6 +109,8 @@
 
   virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
 
+  virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; }
+
   virtual GrowableArray<GCMemoryManager*> memory_managers();
   virtual GrowableArray<MemoryPool*> memory_pools();
 
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -98,7 +98,7 @@
   }
 
   const bool clear_all_soft_refs =
-    heap->collector_policy()->should_clear_all_soft_refs();
+    heap->soft_ref_policy()->should_clear_all_soft_refs();
 
   uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
   UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
@@ -126,7 +126,7 @@
 
   // The scope of casr should end after code that can change
   // CollectorPolicy::_should_clear_all_soft_refs.
-  ClearedAllSoftRefs casr(clear_all_softrefs, heap->collector_policy());
+  ClearedAllSoftRefs casr(clear_all_softrefs, heap->soft_ref_policy());
 
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
@@ -320,7 +320,7 @@
                                              max_eden_size,
                                              true /* full gc*/,
                                              gc_cause,
-                                             heap->collector_policy());
+                                             heap->soft_ref_policy());
 
         size_policy->decay_supplemental_growth(true /* full gc*/);
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -1707,7 +1707,7 @@
   }
 
   const bool clear_all_soft_refs =
-    heap->collector_policy()->should_clear_all_soft_refs();
+    heap->soft_ref_policy()->should_clear_all_soft_refs();
 
   PSParallelCompact::invoke_no_policy(clear_all_soft_refs ||
                                       maximum_heap_compaction);
@@ -1741,7 +1741,7 @@
   // The scope of casr should end after code that can change
   // CollectorPolicy::_should_clear_all_soft_refs.
   ClearedAllSoftRefs casr(maximum_heap_compaction,
-                          heap->collector_policy());
+                          heap->soft_ref_policy());
 
   if (ZapUnusedHeapArea) {
     // Save information needed to minimize mangling
@@ -1869,7 +1869,7 @@
                                              max_eden_size,
                                              true /* full gc*/,
                                              gc_cause,
-                                             heap->collector_policy());
+                                             heap->soft_ref_policy());
 
         size_policy->decay_supplemental_growth(true /* full gc*/);
 
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -228,8 +228,8 @@
 
   if (need_full_gc) {
     GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
-    CollectorPolicy* cp = heap->collector_policy();
-    const bool clear_all_softrefs = cp->should_clear_all_soft_refs();
+    SoftRefPolicy* srp = heap->soft_ref_policy();
+    const bool clear_all_softrefs = srp->should_clear_all_soft_refs();
 
     if (UseParallelOldGC) {
       full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
@@ -569,7 +569,7 @@
                                                max_eden_size,
                                                false /* not full gc*/,
                                                gc_cause,
-                                               heap->collector_policy());
+                                               heap->soft_ref_policy());
 
           size_policy->decay_supplemental_growth(false /* not full gc*/);
         }
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -616,9 +616,6 @@
   assert(gch->no_allocs_since_save_marks(),
          "save marks have not been newly set.");
 
-  // Not very pretty.
-  CollectorPolicy* cp = gch->collector_policy();
-
   FastScanClosure fsc_with_no_gc_barrier(this, false);
   FastScanClosure fsc_with_gc_barrier(this, true);
 
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -60,7 +60,7 @@
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 #ifdef ASSERT
-  if (gch->collector_policy()->should_clear_all_soft_refs()) {
+  if (gch->soft_ref_policy()->should_clear_all_soft_refs()) {
     assert(clear_all_softrefs, "Policy should have been checked earlier");
   }
 #endif
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -27,10 +27,12 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcUtil.inline.hpp"
+#include "gc/shared/softRefPolicy.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "logging/log.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/ostream.hpp"
+
 elapsedTimer AdaptiveSizePolicy::_minor_timer;
 elapsedTimer AdaptiveSizePolicy::_major_timer;
 bool AdaptiveSizePolicy::_debug_perturbation = false;
@@ -409,7 +411,7 @@
                                           size_t max_eden_size,
                                           bool   is_full_gc,
                                           GCCause::Cause gc_cause,
-                                          CollectorPolicy* collector_policy) {
+                                          SoftRefPolicy* soft_ref_policy) {
 
   // Ignore explicit GC's.  Exiting here does not set the flag and
   // does not reset the count.  Updating of the averages for system
@@ -506,7 +508,7 @@
           // The clearing will be done on the next GC.
           bool near_limit = gc_overhead_limit_near();
           if (near_limit) {
-            collector_policy->set_should_clear_all_soft_refs(true);
+            soft_ref_policy->set_should_clear_all_soft_refs(true);
             log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
           }
         }
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -37,7 +37,7 @@
 
 // Forward decls
 class elapsedTimer;
-class CollectorPolicy;
+class SoftRefPolicy;
 
 class AdaptiveSizePolicy : public CHeapObj<mtGC> {
  friend class GCAdaptivePolicyCounters;
@@ -486,7 +486,7 @@
                                size_t max_eden_size,
                                bool   is_full_gc,
                                GCCause::Cause gc_cause,
-                               CollectorPolicy* collector_policy);
+                               SoftRefPolicy* soft_ref_policy);
 
   static bool should_update_promo_stats(GCCause::Cause cause) {
     return ((GCCause::is_user_requested_gc(cause)  &&
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -50,6 +50,7 @@
 class GCMemoryManager;
 class MemoryPool;
 class MetaspaceSummary;
+class SoftRefPolicy;
 class Thread;
 class ThreadClosure;
 class VirtualSpaceSummary;
@@ -442,6 +443,9 @@
   // Return the CollectorPolicy for the heap
   virtual CollectorPolicy* collector_policy() const = 0;
 
+  // Return the SoftRefPolicy for the heap;
+  virtual SoftRefPolicy* soft_ref_policy() = 0;
+
   virtual GrowableArray<GCMemoryManager*> memory_managers() = 0;
   virtual GrowableArray<MemoryPool*> memory_pools() = 0;
 
--- a/src/hotspot/share/gc/shared/collectorPolicy.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectorPolicy.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -50,9 +50,7 @@
     _heap_alignment(0),
     _initial_heap_byte_size(InitialHeapSize),
     _max_heap_byte_size(MaxHeapSize),
-    _min_heap_byte_size(Arguments::min_heap_size()),
-    _should_clear_all_soft_refs(false),
-    _all_soft_refs_clear(false)
+    _min_heap_byte_size(Arguments::min_heap_size())
 {}
 
 #ifdef ASSERT
@@ -145,16 +143,6 @@
   DEBUG_ONLY(CollectorPolicy::assert_size_info();)
 }
 
-bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
-  bool result = _should_clear_all_soft_refs;
-  set_should_clear_all_soft_refs(false);
-  return result;
-}
-
-void CollectorPolicy::cleared_all_soft_refs() {
-  _all_soft_refs_clear = true;
-}
-
 size_t CollectorPolicy::compute_heap_alignment() {
   // The card marking array and the offset arrays for old generations are
   // committed in os pages as well. Make sure they are entirely full (to
@@ -210,17 +198,6 @@
                                         GCTimeRatio);
 }
 
-void GenCollectorPolicy::cleared_all_soft_refs() {
-  // If near gc overhear limit, continue to clear SoftRefs.  SoftRefs may
-  // have been cleared in the last collection but if the gc overhear
-  // limit continues to be near, SoftRefs should still be cleared.
-  if (size_policy() != NULL) {
-    _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();
-  }
-
-  CollectorPolicy::cleared_all_soft_refs();
-}
-
 size_t GenCollectorPolicy::young_gen_size_lower_bound() {
   // The young generation must be aligned and have room for eden + two survivors
   return align_up(3 * _space_alignment, _gen_alignment);
--- a/src/hotspot/share/gc/shared/collectorPolicy.hpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectorPolicy.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -72,17 +72,6 @@
   size_t _space_alignment;
   size_t _heap_alignment;
 
-  // Set to true when policy wants soft refs cleared.
-  // Reset to false by gc after it clears all soft refs.
-  bool _should_clear_all_soft_refs;
-
-  // Set to true by the GC if the just-completed gc cleared all
-  // softrefs.  This is set to true whenever a gc clears all softrefs, and
-  // set to false each time gc returns to the mutator.  For example, in the
-  // ParallelScavengeHeap case the latter would be done toward the end of
-  // mem_allocate() where it returns op.result()
-  bool _all_soft_refs_clear;
-
   CollectorPolicy();
 
  public:
@@ -101,36 +90,6 @@
   size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
   size_t max_heap_byte_size()     { return _max_heap_byte_size; }
   size_t min_heap_byte_size()     { return _min_heap_byte_size; }
-
-  bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
-  void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
-  // Returns the current value of _should_clear_all_soft_refs.
-  // _should_clear_all_soft_refs is set to false as a side effect.
-  bool use_should_clear_all_soft_refs(bool v);
-  bool all_soft_refs_clear() { return _all_soft_refs_clear; }
-  void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
-
-  // Called by the GC after Soft Refs have been cleared to indicate
-  // that the request in _should_clear_all_soft_refs has been fulfilled.
-  virtual void cleared_all_soft_refs();
-};
-
-class ClearedAllSoftRefs : public StackObj {
-  bool _clear_all_soft_refs;
-  CollectorPolicy* _collector_policy;
- public:
-  ClearedAllSoftRefs(bool clear_all_soft_refs,
-                     CollectorPolicy* collector_policy) :
-    _clear_all_soft_refs(clear_all_soft_refs),
-    _collector_policy(collector_policy) {}
-
-  ~ClearedAllSoftRefs() {
-    if (_clear_all_soft_refs) {
-      _collector_policy->cleared_all_soft_refs();
-    }
-  }
-
-  bool should_clear() { return _clear_all_soft_refs; }
 };
 
 class GenCollectorPolicy : public CollectorPolicy {
@@ -219,9 +178,6 @@
   virtual void initialize_size_policy(size_t init_eden_size,
                                       size_t init_promo_size,
                                       size_t init_survivor_size);
-
-  virtual void cleared_all_soft_refs();
-
 };
 
 class MarkSweepPolicy : public GenCollectorPolicy {
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -65,6 +65,7 @@
   CollectedHeap(),
   _rem_set(NULL),
   _gen_policy(policy),
+  _soft_ref_gen_policy(),
   _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
   _full_collections_completed(0)
 {
@@ -150,6 +151,7 @@
   _gen_policy->initialize_size_policy(def_new_gen->eden()->capacity(),
                                       _old_gen->capacity(),
                                       def_new_gen->from()->capacity());
+
   _gen_policy->initialize_gc_policy_counters();
 }
 
@@ -331,7 +333,7 @@
       // so that the overhead exceeded does not persist.
 
       const bool limit_exceeded = gen_policy()->size_policy()->gc_overhead_limit_exceeded();
-      const bool softrefs_clear = gen_policy()->all_soft_refs_clear();
+      const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
 
       if (limit_exceeded && softrefs_clear) {
         *gc_overhead_limit_was_exceeded = true;
@@ -522,9 +524,9 @@
   GCIdMark gc_id_mark;
 
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
-                          collector_policy()->should_clear_all_soft_refs();
+                          soft_ref_policy()->should_clear_all_soft_refs();
 
-  ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy());
+  ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy());
 
   const size_t metadata_prev_used = MetaspaceAux::used_bytes();
 
@@ -720,7 +722,7 @@
     return result;
   }
 
-  assert(!gen_policy()->should_clear_all_soft_refs(),
+  assert(!soft_ref_policy()->should_clear_all_soft_refs(),
     "Flag should have been handled and cleared prior to this point");
 
   // What else?  We might try synchronous finalization later.  If the total
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -29,6 +29,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/generation.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
 
 class StrongRootsScope;
 class SubTasksDone;
@@ -70,6 +71,8 @@
   // The generational collector policy.
   GenCollectorPolicy* _gen_policy;
 
+  SoftRefGenPolicy _soft_ref_gen_policy;
+
   // Indicates that the most recent previous incremental collection failed.
   // The flag is cleared when an action is taken that might clear the
   // condition that caused that incremental collection to fail.
@@ -166,6 +169,8 @@
 
   virtual CollectorPolicy* collector_policy() const { return gen_policy(); }
 
+  virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_gen_policy; }
+
   // Adaptive size policy
   virtual AdaptiveSizePolicy* size_policy() {
     return gen_policy()->size_policy();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/genCollectedHeap.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
+
+void SoftRefGenPolicy::cleared_all_soft_refs() {
+  // If near gc overhear limit, continue to clear SoftRefs.  SoftRefs may
+  // have been cleared in the last collection but if the gc overhear
+  // limit continues to be near, SoftRefs should still be cleared.
+  AdaptiveSizePolicy* size_policy = GenCollectedHeap::heap()->size_policy();
+  if (size_policy != NULL) {
+    set_should_clear_all_soft_refs(size_policy->gc_overhead_limit_near());
+  }
+
+  SoftRefPolicy::cleared_all_soft_refs();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
+
+#include "gc/shared/softRefPolicy.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class AdaptiveSizePolicy;
+
+class SoftRefGenPolicy : public SoftRefPolicy {
+public:
+  virtual void cleared_all_soft_refs();
+};
+
+#endif // SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefPolicy.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/softRefPolicy.hpp"
+
+SoftRefPolicy::SoftRefPolicy() :
+    _should_clear_all_soft_refs(false),
+    _all_soft_refs_clear(false) {
+}
+
+bool SoftRefPolicy::use_should_clear_all_soft_refs(bool v) {
+  bool result = _should_clear_all_soft_refs;
+  set_should_clear_all_soft_refs(false);
+  return result;
+}
+
+void SoftRefPolicy::cleared_all_soft_refs() {
+  _all_soft_refs_clear = true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefPolicy.hpp	Thu Feb 22 18:36:07 2018 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
+
+#include "memory/allocation.hpp"
+
+class SoftRefPolicy {
+ private:
+  // Set to true when policy wants soft refs cleared.
+  // Reset to false by gc after it clears all soft refs.
+  bool _should_clear_all_soft_refs;
+
+  // Set to true by the GC if the just-completed gc cleared all
+  // softrefs.  This is set to true whenever a gc clears all softrefs, and
+  // set to false each time gc returns to the mutator.  For example, in the
+  // ParallelScavengeHeap case the latter would be done toward the end of
+  // mem_allocate() where it returns op.result()
+  bool _all_soft_refs_clear;
+
+ public:
+  SoftRefPolicy();
+
+  bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
+  void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
+  // Returns the current value of _should_clear_all_soft_refs.
+  // _should_clear_all_soft_refs is set to false as a side effect.
+  bool use_should_clear_all_soft_refs(bool v);
+  bool all_soft_refs_clear() { return _all_soft_refs_clear; }
+  void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
+
+  // Called by the GC after Soft Refs have been cleared to indicate
+  // that the request in _should_clear_all_soft_refs has been fulfilled.
+  virtual void cleared_all_soft_refs();
+};
+
+class ClearedAllSoftRefs : public StackObj {
+  bool           _clear_all_soft_refs;
+  SoftRefPolicy* _soft_ref_policy;
+ public:
+  ClearedAllSoftRefs(bool clear_all_soft_refs, SoftRefPolicy* soft_ref_policy) :
+    _clear_all_soft_refs(clear_all_soft_refs),
+    _soft_ref_policy(soft_ref_policy) {}
+
+  ~ClearedAllSoftRefs() {
+    if (_clear_all_soft_refs) {
+      _soft_ref_policy->cleared_all_soft_refs();
+    }
+  }
+
+  bool should_clear() { return _clear_all_soft_refs; }
+};
+
+#endif // SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
--- a/src/hotspot/share/gc/shared/vmGCOperations.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/gc/shared/vmGCOperations.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -46,7 +46,7 @@
 
 VM_GC_Operation::~VM_GC_Operation() {
   CollectedHeap* ch = Universe::heap();
-  ch->collector_policy()->set_all_soft_refs_clear(false);
+  ch->soft_ref_policy()->set_all_soft_refs_clear(false);
 }
 
 // The same dtrace probe can't be inserted in two different files, so we
--- a/src/hotspot/share/prims/whitebox.cpp	Thu Feb 22 18:35:40 2018 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp	Thu Feb 22 18:36:07 2018 +0100
@@ -1219,12 +1219,12 @@
 WB_END
 
 WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
-  Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
+  Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(true);
   Universe::heap()->collect(GCCause::_wb_full_gc);
 #if INCLUDE_ALL_GCS
   if (UseG1GC) {
     // Needs to be cleared explicitly for G1
-    Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false);
+    Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
   }
 #endif // INCLUDE_ALL_GCS
 WB_END