diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp index 819f1e8d74e..8dd4fd71ab8 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp @@ -54,8 +54,8 @@ const double ShenandoahAdaptiveHeuristics::HIGHEST_EXPECTED_AVAILABLE_AT_END = 0 const double ShenandoahAdaptiveHeuristics::MINIMUM_CONFIDENCE = 0.319; // 25% const double ShenandoahAdaptiveHeuristics::MAXIMUM_CONFIDENCE = 3.291; // 99.9% -ShenandoahAdaptiveHeuristics::ShenandoahAdaptiveHeuristics() : - ShenandoahHeuristics(), +ShenandoahAdaptiveHeuristics::ShenandoahAdaptiveHeuristics(ShenandoahSpaceInfo* space_info) : + ShenandoahHeuristics(space_info), _margin_of_error_sd(ShenandoahAdaptiveInitialConfidence), _spike_threshold_sd(ShenandoahAdaptiveInitialSpikeThreshold), _last_trigger(OTHER) { } @@ -84,7 +84,7 @@ void ShenandoahAdaptiveHeuristics::choose_collection_set_from_regiondata(Shenand // we hit max_cset. When max_cset is hit, we terminate the cset selection. Note that in this scheme, // ShenandoahGarbageThreshold is the soft threshold which would be ignored until min_garbage is hit. - size_t capacity = ShenandoahHeap::heap()->soft_max_capacity(); + size_t capacity = _space_info->soft_max_capacity(); size_t max_cset = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste); size_t free_target = (capacity / 100 * ShenandoahMinFreeThreshold) + max_cset; size_t min_garbage = (free_target > actual_free ? (free_target - actual_free) : 0); @@ -128,7 +128,7 @@ void ShenandoahAdaptiveHeuristics::record_cycle_start() { void ShenandoahAdaptiveHeuristics::record_success_concurrent() { ShenandoahHeuristics::record_success_concurrent(); - size_t available = ShenandoahHeap::heap()->free_set()->available(); + size_t available = _space_info->available(); _available.add(available); double z_score = 0.0; @@ -196,11 +196,10 @@ static double saturate(double value, double min, double max) { } bool ShenandoahAdaptiveHeuristics::should_start_gc() { - ShenandoahHeap* heap = ShenandoahHeap::heap(); - size_t max_capacity = heap->max_capacity(); - size_t capacity = heap->soft_max_capacity(); - size_t available = heap->free_set()->available(); - size_t allocated = heap->bytes_allocated_since_gc_start(); + size_t max_capacity = _space_info->max_capacity(); + size_t capacity = _space_info->soft_max_capacity(); + size_t available = _space_info->available(); + size_t allocated = _space_info->bytes_allocated_since_gc_start(); // Make sure the code below treats available without the soft tail. size_t soft_tail = max_capacity - capacity; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp index a1a0e6321fa..f7695b7e953 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp @@ -26,6 +26,7 @@ #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHADAPTIVEHEURISTICS_HPP #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" +#include "gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "utilities/numberSeq.hpp" @@ -51,9 +52,20 @@ class ShenandoahAllocationRate : public CHeapObj { TruncatedSeq _rate_avg; }; +/* + * The adaptive heuristic tracks the allocation behavior and average cycle + * time of the application. It attempts to start a cycle with enough time + * to complete before the available memory is exhausted. It errors on the + * side of starting cycles early to avoid allocation failures (degenerated + * cycles). + * + * This heuristic limits the number of regions for evacuation such that the + * evacuation reserve is respected. This helps it avoid allocation failures + * during evacuation. It preferentially selects regions with the most garbage. + */ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics { public: - ShenandoahAdaptiveHeuristics(); + ShenandoahAdaptiveHeuristics(ShenandoahSpaceInfo* space_info); virtual ~ShenandoahAdaptiveHeuristics(); @@ -99,11 +111,12 @@ public: void adjust_margin_of_error(double amount); void adjust_spike_threshold(double amount); +protected: ShenandoahAllocationRate _allocation_rate; // The margin of error expressed in standard deviations to add to our // average cycle time and allocation rate. As this value increases we - // tend to over estimate the rate at which mutators will deplete the + // tend to overestimate the rate at which mutators will deplete the // heap. In other words, erring on the side of caution will trigger more // concurrent GCs. double _margin_of_error_sd; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp index 4ba3a0315b7..396b6ee8966 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp @@ -31,7 +31,8 @@ #include "logging/logTag.hpp" #include "runtime/os.hpp" -ShenandoahAggressiveHeuristics::ShenandoahAggressiveHeuristics() : ShenandoahHeuristics() { +ShenandoahAggressiveHeuristics::ShenandoahAggressiveHeuristics(ShenandoahSpaceInfo* space_info) : + ShenandoahHeuristics(space_info) { // Do not shortcut evacuation SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahImmediateThreshold, 100); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp index e90d2da7347..5075258f1ce 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp @@ -27,9 +27,13 @@ #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" +/* + * This is a diagnostic heuristic that continuously runs collections + * cycles and adds every region with any garbage to the collection set. + */ class ShenandoahAggressiveHeuristics : public ShenandoahHeuristics { public: - ShenandoahAggressiveHeuristics(); + ShenandoahAggressiveHeuristics(ShenandoahSpaceInfo* space_info); virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, RegionData* data, size_t size, diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp index 514a425f58b..c8e882a0f64 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp @@ -32,7 +32,8 @@ #include "logging/log.hpp" #include "logging/logTag.hpp" -ShenandoahCompactHeuristics::ShenandoahCompactHeuristics() : ShenandoahHeuristics() { +ShenandoahCompactHeuristics::ShenandoahCompactHeuristics(ShenandoahSpaceInfo* space_info) : + ShenandoahHeuristics(space_info) { SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahUncommit); @@ -45,11 +46,9 @@ ShenandoahCompactHeuristics::ShenandoahCompactHeuristics() : ShenandoahHeuristic } bool ShenandoahCompactHeuristics::should_start_gc() { - ShenandoahHeap* heap = ShenandoahHeap::heap(); - - size_t max_capacity = heap->max_capacity(); - size_t capacity = heap->soft_max_capacity(); - size_t available = heap->free_set()->available(); + size_t max_capacity = _space_info->max_capacity(); + size_t capacity = _space_info->soft_max_capacity(); + size_t available = _space_info->available(); // Make sure the code below treats available without the soft tail. size_t soft_tail = max_capacity - capacity; @@ -65,7 +64,7 @@ bool ShenandoahCompactHeuristics::should_start_gc() { return true; } - size_t bytes_allocated = heap->bytes_allocated_since_gc_start(); + size_t bytes_allocated = _space_info->bytes_allocated_since_gc_start(); if (bytes_allocated > threshold_bytes_allocated) { log_info(gc)("Trigger: Allocated since last cycle (" SIZE_FORMAT "%s) is larger than allocation threshold (" SIZE_FORMAT "%s)", byte_size_in_proper_unit(bytes_allocated), proper_unit_for_byte_size(bytes_allocated), diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp index 0fd9641d4a2..21ec99eabc0 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp @@ -27,9 +27,13 @@ #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" +/* + * This heuristic has simpler triggers than the adaptive heuristic. The + * size of the collection set is limited to 3/4 of available memory. + */ class ShenandoahCompactHeuristics : public ShenandoahHeuristics { public: - ShenandoahCompactHeuristics(); + ShenandoahCompactHeuristics(ShenandoahSpaceInfo* space_info); virtual bool should_start_gc(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index e571d39f6b3..2a18ae95a7b 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -42,7 +42,8 @@ int ShenandoahHeuristics::compare_by_garbage(RegionData a, RegionData b) { else return 0; } -ShenandoahHeuristics::ShenandoahHeuristics() : +ShenandoahHeuristics::ShenandoahHeuristics(ShenandoahSpaceInfo* space_info) : + _space_info(space_info), _region_data(nullptr), _degenerated_cycles_in_a_row(0), _successful_cycles_in_a_row(0), diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp index 288d306d089..4deb134a4b5 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP +#include "gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahSharedVariables.hpp" @@ -58,6 +59,11 @@ class ShenandoahCollectionSet; class ShenandoahHeapRegion; +/* + * Shenandoah heuristics are primarily responsible for deciding when to start + * a collection cycle and choosing which regions will be evacuated during the + * cycle. + */ class ShenandoahHeuristics : public CHeapObj { static const intx Concurrent_Adjust = -1; // recover from penalties static const intx Degenerated_Penalty = 10; // how much to penalize average GC duration history on Degenerated GC @@ -69,6 +75,9 @@ protected: size_t _garbage; } RegionData; + // Source of information about the memory space managed by this heuristic + ShenandoahSpaceInfo* _space_info; + RegionData* _region_data; uint _degenerated_cycles_in_a_row; @@ -93,7 +102,7 @@ protected: void adjust_penalty(intx step); public: - ShenandoahHeuristics(); + ShenandoahHeuristics(ShenandoahSpaceInfo* space_info); virtual ~ShenandoahHeuristics(); void record_metaspace_oom() { _metaspace_oom.set(); } diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp index 2e7da1f1dd2..2e6b3d46ebe 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp @@ -31,6 +31,9 @@ #include "logging/log.hpp" #include "logging/logTag.hpp" +ShenandoahPassiveHeuristics::ShenandoahPassiveHeuristics(ShenandoahSpaceInfo* space_info) : + ShenandoahHeuristics(space_info) {} + bool ShenandoahPassiveHeuristics::should_start_gc() { // Never do concurrent GCs. return false; @@ -53,7 +56,7 @@ void ShenandoahPassiveHeuristics::choose_collection_set_from_regiondata(Shenando // Do not select too large CSet that would overflow the available free space. // Take at least the entire evacuation reserve, and be free to overflow to free space. - size_t max_capacity = ShenandoahHeap::heap()->max_capacity(); + size_t max_capacity = _space_info->max_capacity(); size_t available = MAX2(max_capacity / 100 * ShenandoahEvacReserve, actual_free); size_t max_cset = (size_t)(available / ShenandoahEvacWaste); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp index 86ea5651b61..be4e91b1800 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp @@ -27,8 +27,19 @@ #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" +/* + * The passive heuristic is for use only with the passive mode. In + * the passive mode, Shenandoah only performs STW (i.e., degenerated) + * collections. All the barriers are disabled and there are no concurrent + * activities. Therefore, this heuristic _never_ triggers a cycle. It + * will select regions for evacuation based on ShenandoahEvacReserve, + * ShenandoahEvacWaste and ShenandoahGarbageThreshold. Note that it does + * not attempt to evacuate regions with more garbage. + */ class ShenandoahPassiveHeuristics : public ShenandoahHeuristics { public: + ShenandoahPassiveHeuristics(ShenandoahSpaceInfo* space_info); + virtual bool should_start_gc(); virtual bool should_unload_classes(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp new file mode 100644 index 00000000000..3a58196da3c --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp @@ -0,0 +1,45 @@ +/* + * Copyright Amazon.com Inc. 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_GC_SHENANDOAH_HEURISTICS_SHENANDOAHSPACEINFO_HPP +#define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHSPACEINFO_HPP + +#include "utilities/globalDefinitions.hpp" + +/* + * The purpose of this interface is to decouple the heuristics from a + * direct dependency on the ShenandoahHeap singleton instance. This is + * done to facilitate future unit testing of the heuristics and to support + * future operational modes of Shenandoah in which the heap may be split + * into generations. + */ +class ShenandoahSpaceInfo { +public: + virtual size_t soft_max_capacity() const = 0; + virtual size_t max_capacity() const = 0; + virtual size_t available() const = 0; + virtual size_t bytes_allocated_since_gc_start() const = 0; +}; + +#endif //SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHSPACEINFO_HPP diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp index db8740d9ae1..ee59194feb6 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp @@ -32,7 +32,8 @@ #include "logging/log.hpp" #include "logging/logTag.hpp" -ShenandoahStaticHeuristics::ShenandoahStaticHeuristics() : ShenandoahHeuristics() { +ShenandoahStaticHeuristics::ShenandoahStaticHeuristics(ShenandoahSpaceInfo* space_info) : + ShenandoahHeuristics(space_info) { SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); } @@ -40,11 +41,9 @@ ShenandoahStaticHeuristics::ShenandoahStaticHeuristics() : ShenandoahHeuristics( ShenandoahStaticHeuristics::~ShenandoahStaticHeuristics() {} bool ShenandoahStaticHeuristics::should_start_gc() { - ShenandoahHeap* heap = ShenandoahHeap::heap(); - - size_t max_capacity = heap->max_capacity(); - size_t capacity = heap->soft_max_capacity(); - size_t available = heap->free_set()->available(); + size_t max_capacity = _space_info->max_capacity(); + size_t capacity = _space_info->soft_max_capacity(); + size_t available = _space_info->available(); // Make sure the code below treats available without the soft tail. size_t soft_tail = max_capacity - capacity; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp index 5ecd1848d85..24cb5547921 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp @@ -27,9 +27,14 @@ #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" +/* + * The static heuristic will trigger cycles if the available memory falls + * below ShenandoahMinFreeThreshold percentage of total capacity. This + * heuristic will attempt to evacuation any region with any garbage. + */ class ShenandoahStaticHeuristics : public ShenandoahHeuristics { public: - ShenandoahStaticHeuristics(); + ShenandoahStaticHeuristics(ShenandoahSpaceInfo* space_info); virtual ~ShenandoahStaticHeuristics(); diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp index d4fa5a06305..3bc058f3548 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp @@ -28,6 +28,7 @@ #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "gc/shenandoah/mode/shenandoahIUMode.hpp" +#include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" #include "runtime/globals_extension.hpp" @@ -67,14 +68,15 @@ ShenandoahHeuristics* ShenandoahIUMode::initialize_heuristics() const { if (ShenandoahGCHeuristics == nullptr) { vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } + ShenandoahHeap* heap = ShenandoahHeap::heap(); if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { - return new ShenandoahAggressiveHeuristics(); + return new ShenandoahAggressiveHeuristics(heap); } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { - return new ShenandoahStaticHeuristics(); + return new ShenandoahStaticHeuristics(heap); } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { - return new ShenandoahAdaptiveHeuristics(); + return new ShenandoahAdaptiveHeuristics(heap); } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { - return new ShenandoahCompactHeuristics(); + return new ShenandoahCompactHeuristics(heap); } vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); return nullptr; diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp index 36de17d2d79..5ce68ef27d7 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" #include "gc/shenandoah/mode/shenandoahPassiveMode.hpp" +#include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" #include "runtime/globals_extension.hpp" @@ -59,5 +60,5 @@ ShenandoahHeuristics* ShenandoahPassiveMode::initialize_heuristics() const { if (ShenandoahGCHeuristics == nullptr) { vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } - return new ShenandoahPassiveHeuristics(); + return new ShenandoahPassiveHeuristics(ShenandoahHeap::heap()); } diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp index 5b4e1df49e0..77e6f3140e7 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp @@ -28,6 +28,7 @@ #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "gc/shenandoah/mode/shenandoahSATBMode.hpp" +#include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" #include "runtime/globals_extension.hpp" @@ -55,14 +56,15 @@ ShenandoahHeuristics* ShenandoahSATBMode::initialize_heuristics() const { if (ShenandoahGCHeuristics == nullptr) { vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } + ShenandoahHeap* heap = ShenandoahHeap::heap(); if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { - return new ShenandoahAggressiveHeuristics(); + return new ShenandoahAggressiveHeuristics(heap); } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { - return new ShenandoahStaticHeuristics(); + return new ShenandoahStaticHeuristics(heap); } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { - return new ShenandoahAdaptiveHeuristics(); + return new ShenandoahAdaptiveHeuristics(heap); } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { - return new ShenandoahCompactHeuristics(); + return new ShenandoahCompactHeuristics(heap); } vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); return nullptr; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index b26f5108c99..2ff070b8fa9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -662,6 +662,10 @@ size_t ShenandoahHeap::committed() const { return Atomic::load(&_committed); } +size_t ShenandoahHeap::available() const { + return free_set()->available(); +} + void ShenandoahHeap::increase_committed(size_t bytes) { shenandoah_assert_heaplocked_or_safepoint(); _committed += bytes; @@ -1899,7 +1903,7 @@ address ShenandoahHeap::gc_state_addr() { return (address) ShenandoahHeap::heap()->_gc_state.addr_of(); } -size_t ShenandoahHeap::bytes_allocated_since_gc_start() { +size_t ShenandoahHeap::bytes_allocated_since_gc_start() const { return Atomic::load(&_bytes_allocated_since_gc_start); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 63f5082cafd..b310a14a1be 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -29,6 +29,7 @@ #include "gc/shared/markBitMap.hpp" #include "gc/shared/softRefPolicy.hpp" #include "gc/shared/collectedHeap.hpp" +#include "gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahAllocRequest.hpp" #include "gc/shenandoah/shenandoahLock.hpp" @@ -116,7 +117,7 @@ typedef Stack ShenandoahScanObjectStack; // to encode forwarding data. See BrooksPointer for details on forwarding data encoding. // See ShenandoahControlThread for GC cycle structure. // -class ShenandoahHeap : public CollectedHeap { +class ShenandoahHeap : public CollectedHeap, public ShenandoahSpaceInfo { friend class ShenandoahAsserts; friend class VMStructs; friend class ShenandoahGCSession; @@ -191,16 +192,17 @@ public: void decrease_committed(size_t bytes); void increase_allocated(size_t bytes); - size_t bytes_allocated_since_gc_start(); + size_t bytes_allocated_since_gc_start() const override; void reset_bytes_allocated_since_gc_start(); size_t min_capacity() const; size_t max_capacity() const override; - size_t soft_max_capacity() const; + size_t soft_max_capacity() const override; size_t initial_capacity() const; size_t capacity() const override; size_t used() const override; size_t committed() const; + size_t available() const override; void set_soft_max_capacity(size_t v);