< prev index next >
src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp
Print this page
rev 50076 : Fold Partial GC into Traversal GC
@@ -26,11 +26,11 @@
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/shenandoahConnectionMatrix.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/shenandoahTraversalGC.hpp"
#include "runtime/os.hpp"
#include "utilities/quickSort.hpp"
#define SHENANDOAH_ERGO_DISABLE_FLAG(name) \
do { \
@@ -177,20 +177,12 @@
virtual bool update_refs() const {
return _update_refs_early;
}
- virtual bool should_start_partial_gc() {
- return false;
- }
-
- virtual bool can_do_partial_gc() {
- return false;
- }
-
- virtual bool should_start_traversal_gc() {
- return false;
+ virtual ShenandoahHeap::GCCycleMode should_start_traversal_gc() {
+ return ShenandoahHeap::NONE;
}
virtual bool can_do_traversal_gc() {
return false;
}
@@ -406,16 +398,14 @@
// Passive runs with max speed, reacts on allocation failure.
FLAG_SET_DEFAULT(ShenandoahPacing, false);
// Disable known barriers by default.
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahSATBBarrier);
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahConditionalSATBBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahKeepAliveBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahWriteBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahReadBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStoreValEnqueueBarrier);
- SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStoreValWriteBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStoreValReadBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCASBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahAcmpBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier);
SHENANDOAH_ERGO_DISABLE_FLAG(UseShenandoahMatrix);
@@ -883,25 +873,138 @@
virtual bool is_experimental() {
return false;
}
};
-class ShenandoahPartialHeuristics : public ShenandoahAdaptiveHeuristics {
+class ShenandoahTraversalHeuristics : public ShenandoahHeuristics {
protected:
- size_t* _from_idxs;
public:
- ShenandoahPartialHeuristics() : ShenandoahAdaptiveHeuristics() {
- FLAG_SET_DEFAULT(UseShenandoahMatrix, true);
-
- // Set up special barriers for concurrent partial GC.
- FLAG_SET_DEFAULT(ShenandoahConditionalSATBBarrier, true);
+ ShenandoahTraversalHeuristics() : ShenandoahHeuristics() {
+ FLAG_SET_DEFAULT(UseShenandoahMatrix, false);
FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahStoreValWriteBarrier, true);
FLAG_SET_DEFAULT(ShenandoahStoreValReadBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true);
+ FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahBarriersForConst, true);
+ FLAG_SET_DEFAULT(ShenandoahWriteBarrierRB, false);
+ FLAG_SET_DEFAULT(ShenandoahAllocImplicitLive, false);
+ FLAG_SET_DEFAULT(ShenandoahAllowMixedAllocs, false);
+ FLAG_SET_DEFAULT(ShenandoahRecycleClearsBitmap, true);
SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahRefProcFrequency, 1);
+ SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1);
+
+ }
+
+ virtual bool should_start_normal_gc() const {
+ return false;
+ }
+
+ virtual bool is_experimental() {
+ return true;
+ }
+
+ virtual bool is_diagnostic() {
+ return false;
+ }
+
+ virtual bool can_do_traversal_gc() {
+ return true;
+ }
+
+ virtual const char* name() {
+ return "traversal";
+ }
+
+ virtual void choose_collection_set(ShenandoahCollectionSet* collection_set) {
+ ShenandoahHeap* heap = ShenandoahHeap::heap();
+
+ // No root regions in this mode.
+ ShenandoahTraversalGC* traversal_gc = heap->traversal_gc();
+ ShenandoahHeapRegionSet* root_regions = traversal_gc->root_regions();
+ root_regions->clear();
+
+ ShenandoahHeapRegionSet* traversal_set = traversal_gc->traversal_set();
+ traversal_set->clear();
+ for (size_t i = 0; i < heap->num_regions(); i++) {
+ ShenandoahHeapRegion* r = heap->get_region(i);
+ assert(!collection_set->is_in(r), "must not yet be in cset");
+ if (r->is_regular() && r->used() > 0) {
+ size_t garbage_percent = r->garbage() * 100 / ShenandoahHeapRegion::region_size_bytes();
+ if (garbage_percent > ShenandoahGarbageThreshold) {
+ collection_set->add_region(r);
+ }
+ }
+ r->clear_live_data();
+ traversal_set->add_region(r);
+ }
+ collection_set->update_region_status();
+ }
+
+ virtual ShenandoahHeap::GCCycleMode should_start_traversal_gc() {
+
+ ShenandoahHeap* heap = ShenandoahHeap::heap();
+
+ if (heap->has_forwarded_objects()) return ShenandoahHeap::NONE;
+
+ double last_time_ms = (os::elapsedTime() - _last_cycle_end) * 1000;
+ bool periodic_gc = (last_time_ms > ShenandoahGuaranteedGCInterval);
+ if (periodic_gc) {
+ log_info(gc,ergo)("Periodic GC triggered. Time since last GC: %.0f ms, Guaranteed Interval: " UINTX_FORMAT " ms",
+ last_time_ms, ShenandoahGuaranteedGCInterval);
+ return ShenandoahHeap::MAJOR;
+ }
+
+ size_t capacity = heap->capacity();
+ size_t used = heap->used();
+ return 100 - (used * 100 / capacity) < ShenandoahFreeThreshold ? ShenandoahHeap::MAJOR : ShenandoahHeap::NONE;
+ }
+
+protected:
+ virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set,
+ RegionData* data, size_t data_size,
+ size_t free) {
+ ShouldNotReachHere();
+ }
+};
+
+class ShenandoahPartialHeuristics : public ShenandoahTraversalHeuristics {
+protected:
+ size_t* _from_idxs;
+
+ bool is_minor_gc() const { return ShenandoahHeap::heap()->is_minor_gc(); }
+
+ // Utility method to remove any cset regions from root set and
+ // add all cset regions to the traversal set.
+ void filter_regions() {
+ ShenandoahHeap* heap = ShenandoahHeap::heap();
+ ShenandoahTraversalGC* traversal_gc = heap->traversal_gc();
+ size_t num_regions = heap->num_regions();
+ ShenandoahCollectionSet* collection_set = heap->collection_set();
+ ShenandoahHeapRegionSet* root_regions = traversal_gc->root_regions();
+ ShenandoahHeapRegionSet* traversal_set = traversal_gc->traversal_set();
+ traversal_set->clear();
+
+ for (size_t i = 0; i < num_regions; i++) {
+ ShenandoahHeapRegion* region = heap->get_region(i);
+ if (collection_set->is_in(i)) {
+ if (root_regions->is_in(i)) {
+ root_regions->remove_region(region);
+ }
+ traversal_set->add_region_check_for_duplicates(region);
+ assert(traversal_set->is_in(i), "must be in traversal set now");
+ }
+ }
+ }
+
+public:
+ ShenandoahPartialHeuristics() :
+ ShenandoahTraversalHeuristics() {
+
+ FLAG_SET_DEFAULT(UseShenandoahMatrix, true);
+
// TODO: Disable this optimization for now, as it also requires the matrix barriers.
#ifdef COMPILER2
FLAG_SET_DEFAULT(ArrayCopyLoadStoreMaxElem, 0);
#endif
}
@@ -913,19 +1016,23 @@
virtual ~ShenandoahPartialHeuristics() {
FREE_C_HEAP_ARRAY(size_t, _from_idxs);
}
bool should_start_update_refs() {
- return true;
+ return false;
}
bool update_refs() const {
- return true;
+ return false;
}
- bool can_do_partial_gc() {
- return true;
+ virtual bool should_unload_classes() {
+ return ShenandoahUnloadClassesFrequency != 0;
+ }
+
+ virtual bool should_process_references() {
+ return ShenandoahRefProcFrequency != 0;
}
bool should_start_normal_gc() const {
return false;
}
@@ -936,36 +1043,38 @@
virtual bool is_experimental() {
return true;
}
- virtual bool should_start_partial_gc() = 0;
- virtual void choose_collection_set(ShenandoahCollectionSet* collection_set) = 0;
-
};
class ShenandoahPartialConnectedHeuristics : public ShenandoahPartialHeuristics {
public:
virtual const char* name() {
return "connectedness";
}
- bool should_start_partial_gc() {
+ ShenandoahHeap::GCCycleMode should_start_traversal_gc() {
+ ShenandoahHeap::GCCycleMode cycle_mode = ShenandoahPartialHeuristics::should_start_traversal_gc();
+ if (cycle_mode != ShenandoahHeap::NONE) {
+ return cycle_mode;
+ }
+
ShenandoahHeap* heap = ShenandoahHeap::heap();
if (heap->has_forwarded_objects()) {
// Cannot start partial if heap is not completely updated.
- return false;
+ return ShenandoahHeap::NONE;
}
size_t capacity = heap->capacity();
size_t used = heap->used();
size_t prev_used = heap->used_at_last_gc();
if (used < prev_used) {
// Major collection must have happened, "used" data is unreliable, wait for update.
- return false;
+ return ShenandoahHeap::NONE;
}
size_t threshold = heap->capacity() * ShenandoahConnectednessPercentage / 100;
size_t allocated = used - prev_used;
bool result = allocated > threshold;
@@ -978,24 +1087,30 @@
if (result) {
log_info(gc,ergo)("%s", msg.buffer());
} else {
log_trace(gc,ergo)("%s", msg.buffer());
}
- return result;
+ return result ? ShenandoahHeap::MINOR : ShenandoahHeap::NONE;
}
void choose_collection_set(ShenandoahCollectionSet* collection_set) {
+ if (!is_minor_gc()) {
+ return ShenandoahPartialHeuristics::choose_collection_set(collection_set);
+ }
+
ShenandoahHeap* heap = ShenandoahHeap::heap();
+ ShenandoahTraversalGC* traversal_gc = heap->traversal_gc();
ShenandoahConnectionMatrix* matrix = heap->connection_matrix();
+ ShenandoahHeapRegionSet* root_regions = traversal_gc->root_regions();
+ root_regions->clear();
size_t num_regions = heap->num_regions();
RegionConnections* connects = get_region_connects_cache(num_regions);
size_t connect_cnt = 0;
for (uint to_idx = 0; to_idx < num_regions; to_idx++) {
ShenandoahHeapRegion* region = heap->get_region(to_idx);
- region->set_root(false);
if (!region->is_regular()) continue;
uint count = matrix->count_connected_to(to_idx, num_regions);
if (count < ShenandoahPartialInboundThreshold) {
connects[connect_cnt]._region = region;
@@ -1027,17 +1142,15 @@
_from_idxs, from_idx_count,
ShenandoahPartialInboundThreshold)) {
maybe_add_heap_region(region, collection_set);
for (size_t i = 0; i < from_idx_count; i++) {
ShenandoahHeapRegion* r = heap->get_region(_from_idxs[i]);
- if (!r->is_root()) {
- r->set_root(true);
- }
+ root_regions->add_region_check_for_duplicates(r);
}
}
}
-
+ filter_regions();
collection_set->update_region_status();
}
};
class ShenandoahGenerationalPartialHeuristics : public ShenandoahPartialHeuristics {
@@ -1050,11 +1163,16 @@
virtual const char* name() {
return "generational";
}
virtual void choose_collection_set(ShenandoahCollectionSet* collection_set) {
+ if (!is_minor_gc()) {
+ return ShenandoahPartialHeuristics::choose_collection_set(collection_set);
+ }
+
ShenandoahHeap* heap = ShenandoahHeap::heap();
+ ShenandoahTraversalGC* traversal_gc = heap->traversal_gc();
ShenandoahConnectionMatrix* matrix = heap->connection_matrix();
uint64_t alloc_seq_at_last_gc_end = heap->alloc_seq_at_last_gc_end();
uint64_t alloc_seq_at_last_gc_start = heap->alloc_seq_at_last_gc_start();
size_t num_regions = heap->num_regions();
@@ -1074,14 +1192,12 @@
size_t used = heap->used();
size_t prev_used = heap->used_at_last_gc();
guarantee(used >= prev_used, "Invariant");
size_t target = MIN2(ShenandoahHeapRegion::required_regions(used - prev_used), num_regions);
- for (uint to_idx = 0; to_idx < num_regions; to_idx++) {
- ShenandoahHeapRegion* region = heap->get_region(to_idx);
- region->set_root(false);
- }
+ ShenandoahHeapRegionSet* root_regions = traversal_gc->root_regions();
+ root_regions->clear();
uint count = 0;
for (uint i = 0; (i < num_regions) && (count < target); i++) {
ShenandoahHeapRegion* contender = candidates[i]._region;
@@ -1097,37 +1213,41 @@
count++;
}
for (uint f = 0; f < from_idx_count; f++) {
ShenandoahHeapRegion* r = heap->get_region(_from_idxs[f]);
- if (!r->is_root()) {
- r->set_root(true);
- }
+ root_regions->add_region_check_for_duplicates(r);
}
}
}
+ filter_regions();
collection_set->update_region_status();
log_info(gc,ergo)("Regions: Max: " SIZE_FORMAT ", Target: " SIZE_FORMAT " (" SIZE_FORMAT "%%), In CSet: " SIZE_FORMAT,
num_regions, target, ShenandoahGenerationalYoungGenPercentage, collection_set->count());
}
- bool should_start_partial_gc() {
+ ShenandoahHeap::GCCycleMode should_start_traversal_gc() {
+ ShenandoahHeap::GCCycleMode cycle_mode = ShenandoahPartialHeuristics::should_start_traversal_gc();
+ if (cycle_mode != ShenandoahHeap::NONE) {
+ return cycle_mode;
+ }
+
ShenandoahHeap* heap = ShenandoahHeap::heap();
if (heap->has_forwarded_objects()) {
// Cannot start partial if heap is not completely updated.
- return false;
+ return ShenandoahHeap::NONE;
}
size_t capacity = heap->capacity();
size_t used = heap->used();
size_t prev_used = heap->used_at_last_gc();
if (used < prev_used) {
// Major collection must have happened, "used" data is unreliable, wait for update.
- return false;
+ return ShenandoahHeap::NONE;
}
size_t threshold = heap->capacity() * ShenandoahGenerationalYoungGenPercentage / 100;
size_t allocated = used - prev_used;
@@ -1142,11 +1262,11 @@
if (result) {
log_info(gc,ergo)("%s", msg.buffer());
} else {
log_trace(gc,ergo)("%s", msg.buffer());
}
- return result;
+ return result ? ShenandoahHeap::MINOR : ShenandoahHeap::NONE;
}
};
class ShenandoahLRUPartialHeuristics : public ShenandoahPartialHeuristics {
public:
@@ -1157,11 +1277,16 @@
virtual const char* name() {
return "LRU";
}
virtual void choose_collection_set(ShenandoahCollectionSet* collection_set) {
+ if (!is_minor_gc()) {
+ return ShenandoahPartialHeuristics::choose_collection_set(collection_set);
+ }
+
ShenandoahHeap* heap = ShenandoahHeap::heap();
+ ShenandoahTraversalGC* traversal_gc = heap->traversal_gc();
ShenandoahConnectionMatrix* matrix = heap->connection_matrix();
uint64_t alloc_seq_at_last_gc_start = heap->alloc_seq_at_last_gc_start();
size_t num_regions = heap->num_regions();
@@ -1185,14 +1310,13 @@
size_t used = heap->used();
size_t prev_used = heap->used_at_last_gc();
guarantee(used >= prev_used, "Invariant");
size_t target = MIN2(ShenandoahHeapRegion::required_regions(used - prev_used), sorted_count);
- for (uint to_idx = 0; to_idx < num_regions; to_idx++) {
- ShenandoahHeapRegion* region = heap->get_region(to_idx);
- region->set_root(false);
- }
+ ShenandoahHeapRegionSet* root_regions = traversal_gc->root_regions();
+ root_regions->clear();
+
uint count = 0;
for (uint i = 0; (i < sorted_count) && (count < target); i++) {
ShenandoahHeapRegion* contender = candidates[i]._region;
if (contender->seqnum_last_alloc() >= alloc_seq_at_last_gc_start) {
@@ -1206,37 +1330,41 @@
if (maybe_add_heap_region(contender, collection_set)) {
count++;
}
for (uint f = 0; f < from_idx_count; f++) {
ShenandoahHeapRegion* r = heap->get_region(_from_idxs[f]);
- if (!r->is_root()) {
- r->set_root(true);
- }
+ root_regions->add_region_check_for_duplicates(r);
}
}
}
+ filter_regions();
collection_set->update_region_status();
log_info(gc,ergo)("Regions: Max: " SIZE_FORMAT ", Target: " SIZE_FORMAT " (" SIZE_FORMAT "%%), In CSet: " SIZE_FORMAT,
num_regions, target, ShenandoahLRUOldGenPercentage, collection_set->count());
}
- bool should_start_partial_gc() {
+ ShenandoahHeap::GCCycleMode should_start_traversal_gc() {
+ ShenandoahHeap::GCCycleMode cycle_mode = ShenandoahPartialHeuristics::should_start_traversal_gc();
+ if (cycle_mode != ShenandoahHeap::NONE) {
+ return cycle_mode;
+ }
+
ShenandoahHeap* heap = ShenandoahHeap::heap();
if (heap->has_forwarded_objects()) {
// Cannot start partial if heap is not completely updated.
- return false;
+ return ShenandoahHeap::NONE;
}
size_t capacity = heap->capacity();
size_t used = heap->used();
size_t prev_used = heap->used_at_last_gc();
if (used < prev_used) {
// Major collection must have happened, "used" data is unreliable, wait for update.
- return false;
+ return ShenandoahHeap::NONE;
}
// For now don't start until we are 40% full
size_t allocated = used - prev_used;
size_t threshold = heap->capacity() * ShenandoahLRUOldGenPercentage / 100;
@@ -1252,101 +1380,18 @@
if (result) {
log_info(gc,ergo)("%s", msg.buffer());
} else {
log_trace(gc,ergo)("%s", msg.buffer());
}
- return result;
- }
-
-};
-
-class ShenandoahTraversalHeuristics : public ShenandoahHeuristics {
-public:
- ShenandoahTraversalHeuristics() : ShenandoahHeuristics() {
- FLAG_SET_DEFAULT(UseShenandoahMatrix, false);
- FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahConditionalSATBBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahStoreValReadBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahStoreValWriteBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true);
- FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false);
- FLAG_SET_DEFAULT(ShenandoahBarriersForConst, true);
- FLAG_SET_DEFAULT(ShenandoahWriteBarrierRB, false);
- FLAG_SET_DEFAULT(ShenandoahAllocImplicitLive, false);
- FLAG_SET_DEFAULT(ShenandoahAllowMixedAllocs, false);
- }
-
- virtual bool should_start_normal_gc() const {
- return false;
- }
-
- virtual bool is_experimental() {
- return true;
- }
-
- virtual bool is_diagnostic() {
- return false;
- }
-
- virtual bool can_do_traversal_gc() {
- return true;
- }
-
- virtual const char* name() {
- return "traversal";
- }
-
- virtual void choose_collection_set(ShenandoahCollectionSet* collection_set) {
- ShenandoahHeap* heap = ShenandoahHeap::heap();
- for (size_t i = 0; i < heap->num_regions(); i++) {
- ShenandoahHeapRegion* r = heap->get_region(i);
- assert(!r->is_root(), "must not be root region");
- assert(!collection_set->is_in(r), "must not yet be in cset");
- if (r->is_regular() && r->used() > 0) {
- size_t garbage_percent = r->garbage() * 100 / ShenandoahHeapRegion::region_size_bytes();
- if (garbage_percent > ShenandoahGarbageThreshold) {
- collection_set->add_region(r);
- }
- }
- heap->set_next_top_at_mark_start(r->bottom(), r->top());
- heap->set_complete_top_at_mark_start(r->bottom(), r->top()); // For debugging purposes
- r->clear_live_data();
- }
- collection_set->update_region_status();
+ return result ? ShenandoahHeap::MINOR : ShenandoahHeap::NONE;
}
- virtual bool should_start_traversal_gc() {
-
- ShenandoahHeap* heap = ShenandoahHeap::heap();
-
- if (heap->has_forwarded_objects()) return false;
-
- double last_time_ms = (os::elapsedTime() - _last_cycle_end) * 1000;
- bool periodic_gc = (last_time_ms > ShenandoahGuaranteedGCInterval);
- if (periodic_gc) {
- log_info(gc,ergo)("Periodic GC triggered. Time since last GC: %.0f ms, Guaranteed Interval: " UINTX_FORMAT " ms",
- last_time_ms, ShenandoahGuaranteedGCInterval);
- return true;
- }
-
- size_t capacity = heap->capacity();
- size_t used = heap->used();
- return 100 - (used * 100 / capacity) < ShenandoahFreeThreshold;
- }
-
- virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set,
- RegionData* data, size_t data_size,
- size_t free) {
- ShouldNotReachHere();
- }
};
-
ShenandoahCollectorPolicy::ShenandoahCollectorPolicy() :
_cycle_counter(0),
_success_concurrent_gcs(0),
- _success_partial_gcs(0),
_success_degenerated_gcs(0),
_success_full_gcs(0),
_explicit_concurrent(0),
_explicit_full(0),
_alloc_failure_degenerated(0),
@@ -1360,11 +1405,10 @@
initialize_all();
_tracer = new (ResourceObj::C_HEAP, mtGC) ShenandoahTracer();
if (ShenandoahGCHeuristics != NULL) {
- _minor_heuristics = NULL;
if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) {
_heuristics = new ShenandoahAggressiveHeuristics();
} else if (strcmp(ShenandoahGCHeuristics, "static") == 0) {
_heuristics = new ShenandoahStaticHeuristics();
} else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) {
@@ -1372,18 +1416,15 @@
} else if (strcmp(ShenandoahGCHeuristics, "passive") == 0) {
_heuristics = new ShenandoahPassiveHeuristics();
} else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) {
_heuristics = new ShenandoahCompactHeuristics();
} else if (strcmp(ShenandoahGCHeuristics, "connected") == 0) {
- _heuristics = new ShenandoahAdaptiveHeuristics();
- _minor_heuristics = new ShenandoahPartialConnectedHeuristics();
+ _heuristics = new ShenandoahPartialConnectedHeuristics();
} else if (strcmp(ShenandoahGCHeuristics, "generational") == 0) {
- _heuristics = new ShenandoahAdaptiveHeuristics();
- _minor_heuristics = new ShenandoahGenerationalPartialHeuristics();
+ _heuristics = new ShenandoahGenerationalPartialHeuristics();
} else if (strcmp(ShenandoahGCHeuristics, "LRU") == 0) {
- _heuristics = new ShenandoahAdaptiveHeuristics();
- _minor_heuristics = new ShenandoahLRUPartialHeuristics();
+ _heuristics = new ShenandoahLRUPartialHeuristics();
} else if (strcmp(ShenandoahGCHeuristics, "traversal") == 0) {
_heuristics = new ShenandoahTraversalHeuristics();
} else {
vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option");
}
@@ -1396,40 +1437,16 @@
if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) {
vm_exit_during_initialization(
err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.",
_heuristics->name()));
}
- if (_minor_heuristics != NULL && _minor_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) {
- vm_exit_during_initialization(
- err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.",
- _minor_heuristics->name()));
- }
- if (_minor_heuristics != NULL && _minor_heuristics->is_experimental() && !UnlockExperimentalVMOptions) {
- vm_exit_during_initialization(
- err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.",
- _minor_heuristics->name()));
- }
- if (ShenandoahConditionalSATBBarrier && ShenandoahSATBBarrier) {
- vm_exit_during_initialization("Cannot use both ShenandoahSATBBarrier and ShenandoahConditionalSATBBarrier");
- }
- if (ShenandoahStoreValWriteBarrier && ShenandoahStoreValReadBarrier) {
- vm_exit_during_initialization("Cannot use both ShenandoahStoreValWriteBarrier and ShenandoahStoreValReadBarrier");
- }
if (ShenandoahStoreValEnqueueBarrier && ShenandoahStoreValReadBarrier) {
vm_exit_during_initialization("Cannot use both ShenandoahStoreValEnqueueBarrier and ShenandoahStoreValReadBarrier");
}
- if (ShenandoahStoreValWriteBarrier && ShenandoahStoreValEnqueueBarrier) {
- vm_exit_during_initialization("Cannot use both ShenandoahStoreValWriteBarrier and ShenandoahStoreValEnqueueBarrier");
- }
- if (_minor_heuristics != NULL) {
- log_info(gc, init)("Shenandoah heuristics: %s minor with %s major",
- _minor_heuristics->name(), _heuristics->name());
- } else {
log_info(gc, init)("Shenandoah heuristics: %s",
_heuristics->name());
- }
_heuristics->print_thresholds();
} else {
ShouldNotReachHere();
}
}
@@ -1461,13 +1478,10 @@
_heap_alignment = ShenandoahHeapRegion::region_size_bytes();
}
void ShenandoahCollectorPolicy::post_heap_initialize() {
_heuristics->initialize();
- if (_minor_heuristics != NULL) {
- _minor_heuristics->initialize();
- }
}
void ShenandoahCollectorPolicy::record_explicit_to_concurrent() {
_heuristics->record_explicit_gc();
_explicit_concurrent++;
@@ -1497,14 +1511,10 @@
void ShenandoahCollectorPolicy::record_success_concurrent() {
_heuristics->record_success_concurrent();
_success_concurrent_gcs++;
}
-void ShenandoahCollectorPolicy::record_success_partial() {
- _success_partial_gcs++;
-}
-
void ShenandoahCollectorPolicy::record_success_degenerated() {
_heuristics->record_success_degenerated();
_success_degenerated_gcs++;
}
@@ -1520,32 +1530,23 @@
bool ShenandoahCollectorPolicy::should_degenerate_cycle() {
return _heuristics->should_degenerate_cycle();
}
bool ShenandoahCollectorPolicy::update_refs() {
- if (_minor_heuristics != NULL && _minor_heuristics->update_refs()) {
- return true;
- }
return _heuristics->update_refs();
}
bool ShenandoahCollectorPolicy::should_start_update_refs() {
- if (_minor_heuristics != NULL && _minor_heuristics->should_start_update_refs()) {
- return true;
- }
return _heuristics->should_start_update_refs();
}
void ShenandoahCollectorPolicy::record_peak_occupancy() {
_heuristics->record_peak_occupancy();
}
void ShenandoahCollectorPolicy::choose_collection_set(ShenandoahCollectionSet* collection_set,
bool minor) {
- if (minor)
- _minor_heuristics->choose_collection_set(collection_set);
- else
_heuristics->choose_collection_set(collection_set);
}
bool ShenandoahCollectorPolicy::should_process_references() {
return _heuristics->should_process_references();
@@ -1561,27 +1562,11 @@
void ShenandoahCollectorPolicy::record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs) {
_heuristics->record_phase_time(phase, secs);
}
-bool ShenandoahCollectorPolicy::should_start_partial_gc() {
- if (_minor_heuristics != NULL) {
- return _minor_heuristics->should_start_partial_gc();
- } else {
- return false; // no minor heuristics -> no partial gc
- }
-}
-
-bool ShenandoahCollectorPolicy::can_do_partial_gc() {
- if (_minor_heuristics != NULL) {
- return _minor_heuristics->can_do_partial_gc();
- } else {
- return false; // no minor heuristics -> no partial gc
- }
-}
-
-bool ShenandoahCollectorPolicy::should_start_traversal_gc() {
+ShenandoahHeap::GCCycleMode ShenandoahCollectorPolicy::should_start_traversal_gc() {
return _heuristics->should_start_traversal_gc();
}
bool ShenandoahCollectorPolicy::can_do_traversal_gc() {
return _heuristics->can_do_traversal_gc();
@@ -1609,13 +1594,10 @@
out->print_cr("under stop-the-world pause or result in stop-the-world Full GC. Increase heap size,");
out->print_cr("tune GC heuristics, set more aggressive pacing delay, or lower allocation rate");
out->print_cr("to avoid Degenerated and Full GC cycles.");
out->cr();
- out->print_cr(SIZE_FORMAT_W(5) " successful partial concurrent GCs", _success_partial_gcs);
- out->cr();
-
out->print_cr(SIZE_FORMAT_W(5) " successful concurrent GCs", _success_concurrent_gcs);
out->print_cr(" " SIZE_FORMAT_W(5) " invoked explicitly", _explicit_concurrent);
out->cr();
out->print_cr(SIZE_FORMAT_W(5) " Degenerated GCs", _success_degenerated_gcs);
< prev index next >