< prev index next >

src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp

Print this page
rev 13068 : [mq]: partial.patch

@@ -24,10 +24,11 @@
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
 #include "gc/shenandoah/shenandoahFreeSet.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
+#include "gc/shenandoah/shenandoahPartialGC.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimes.hpp"
 #include "runtime/os.hpp"
 
 class ShenandoahHeuristics : public CHeapObj<mtGC> {
 

@@ -55,10 +56,12 @@
   size_t _region_garbage_size;
 
   size_t _bytes_allocated_start_CM;
   size_t _bytes_allocated_during_CM;
 
+  size_t _bytes_allocated_after_last_gc;
+
   uint _cancelled_cm_cycles_in_a_row;
   uint _successful_cm_cycles_in_a_row;
 
   size_t _bytes_in_cset;
 

@@ -70,17 +73,29 @@
   void record_bytes_allocated(size_t bytes);
   void record_bytes_reclaimed(size_t bytes);
   void record_bytes_start_CM(size_t bytes);
   void record_bytes_end_CM(size_t bytes);
 
+  void record_gc_start() {
+    // Do nothing.
+  }
+
+  void record_gc_end() {
+    _bytes_allocated_after_last_gc = ShenandoahHeap::heap()->used();
+  }
+
   size_t bytes_in_cset() const { return _bytes_in_cset; }
 
   virtual void print_thresholds() {
   }
 
   virtual bool should_start_concurrent_mark(size_t used, size_t capacity) const=0;
 
+  virtual bool should_start_partial_gc() {
+    return false;
+  }
+
   virtual bool handover_cancelled_marking() {
     return _cancelled_cm_cycles_in_a_row <= ShenandoahFullGCThreshold;
   }
 
   virtual void record_cm_cancelled() {

@@ -132,10 +147,11 @@
 ShenandoahHeuristics::ShenandoahHeuristics() :
   _bytes_allocated_since_CM(0),
   _bytes_reclaimed_this_cycle(0),
   _bytes_allocated_start_CM(0),
   _bytes_allocated_during_CM(0),
+  _bytes_allocated_after_last_gc(0),
   _bytes_in_cset(0),
   _cancelled_cm_cycles_in_a_row(0),
   _successful_cm_cycles_in_a_row(0),
   _region_garbage(NULL),
   _region_garbage_size(0)

@@ -272,10 +288,18 @@
   double end = os::elapsedTime();
   double elapsed = end - _timing_data[phase]._start;
   _timing_data[phase]._secs.add(elapsed);
 }
 
+void ShenandoahCollectorPolicy::record_gc_start() {
+  _heuristics->record_gc_start();
+}
+
+void ShenandoahCollectorPolicy::record_gc_end() {
+  _heuristics->record_gc_end();
+}
+
 void ShenandoahCollectorPolicy::report_concgc_cancelled() {
 }
 
 void ShenandoahHeuristics::record_bytes_allocated(size_t bytes) {
   _bytes_allocated_since_CM = bytes;

@@ -630,10 +654,40 @@
   virtual bool region_in_collection_set(ShenandoahHeapRegion* r, size_t immediate_garbage) {
     assert(false, "Shouldn't get here");
     return false;
   }
 };
+class PartialHeuristics : public AdaptiveHeuristics {
+public:
+  PartialHeuristics() : AdaptiveHeuristics() {
+    if (FLAG_IS_DEFAULT(ShenandoahAllocationThreshold)) {
+      FLAG_SET_DEFAULT(ShenandoahAllocationThreshold, 5);
+    }
+    FLAG_SET_DEFAULT(UseShenandoahMatrix, true);
+    // TODO: Disable this optimization for now, as it also requires the matrix barriers.
+    FLAG_SET_DEFAULT(ArrayCopyLoadStoreMaxElem, 0);
+  }
+
+  virtual ~PartialHeuristics() {}
+
+  bool should_start_concurrent_mark(size_t used, size_t capacity) const {
+    // Never do concurrent GCs.
+    return false;
+  }
+
+  bool should_start_partial_gc() {
+    ShenandoahHeap* heap = ShenandoahHeap::heap();
+    size_t capacity = heap->capacity();
+
+    size_t used = heap->used();
+    if ((used - _bytes_allocated_after_last_gc) * 100 / capacity > ShenandoahAllocationThreshold) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+};
 
 ShenandoahCollectorPolicy::ShenandoahCollectorPolicy() :
   _cycle_counter(0),
   _successful_cm(0),
   _degenerated_cm(0)

@@ -744,10 +798,13 @@
       log_info(gc, init)("Shenandoah heuristics: passive");
       _heuristics = new PassiveHeuristics();
     } else if (strcmp(ShenandoahGCHeuristics, "connections") == 0) {
       log_info(gc, init)("Shenandoah heuristics: connections");
       _heuristics = new ConnectionHeuristics();
+    } else if (strcmp(ShenandoahGCHeuristics, "partial") == 0) {
+      log_info(gc, init)("Shenandoah heuristics: partial GC");
+      _heuristics = new PartialHeuristics();
     } else {
       vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option");
     }
     _heuristics->print_thresholds();
   } else {

@@ -1063,5 +1120,8 @@
   return calc_default_active_workers(total_workers,
       (total_workers > 1 ? 2 : 1), active_workers,
       application_workers, 0, active_workers_by_liveset);
 }
 
+bool ShenandoahCollectorPolicy::should_start_partial_gc() {
+  return _heuristics->should_start_partial_gc();
+}
< prev index next >