< prev index next >
src/share/vm/runtime/arguments.cpp
Print this page
*** 64,73 ****
--- 64,76 ----
#endif
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
+ #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
+ #include "gc_implementation/shenandoah/shenandoahLogging.hpp"
+ #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
#endif // INCLUDE_ALL_GCS
// Note: This is a special bug reporting site for the JVM
#ifdef VENDOR_URL_VM_BUG
# define DEFAULT_VENDOR_URL_BUG VENDOR_URL_VM_BUG
*** 1540,1550 ****
}
#endif // _LP64
#endif // ZERO
}
-
// NOTE: set_use_compressed_klass_ptrs() must be called after calling
// set_use_compressed_oops().
void Arguments::set_use_compressed_klass_ptrs() {
#ifndef ZERO
#ifdef _LP64
--- 1543,1552 ----
*** 1580,1589 ****
--- 1582,1593 ----
#if INCLUDE_ALL_GCS
if (UseParallelGC) {
heap_alignment = ParallelScavengeHeap::conservative_max_heap_alignment();
} else if (UseG1GC) {
heap_alignment = G1CollectedHeap::conservative_max_heap_alignment();
+ } else if (UseShenandoahGC) {
+ heap_alignment = ShenandoahHeap::conservative_max_heap_alignment();
}
#endif // INCLUDE_ALL_GCS
_conservative_max_heap_alignment = MAX4(heap_alignment,
(size_t)os::vm_allocation_granularity(),
os::max_page_size(),
*** 1731,1740 ****
--- 1735,1916 ----
(unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
tty->print_cr("ConcGCThreads: %u", (uint) ConcGCThreads);
}
}
+ void Arguments::set_shenandoah_gc_flags() {
+
+ #if !(defined AARCH64 || defined AMD64 || defined IA32)
+ UNSUPPORTED_GC_OPTION(UseShenandoahGC);
+ #endif
+
+ #if 0 // leave this block as stepping stone for future platforms
+ warning("Shenandoah GC is not fully supported on this platform:");
+ warning(" concurrent modes are not supported, only STW cycles are enabled;");
+ warning(" arch-specific barrier code is not implemented, disabling barriers;");
+
+ #if INCLUDE_ALL_GCS
+ FLAG_SET_DEFAULT(ShenandoahGCHeuristics, "passive");
+
+ FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahLoadRefBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahCASBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahCloneBarrier, false);
+
+ FLAG_SET_DEFAULT(ShenandoahVerifyOptoBarriers, false);
+ #endif
+ #endif
+
+ #if INCLUDE_ALL_GCS
+ if (!FLAG_IS_DEFAULT(ShenandoahGarbageThreshold)) {
+ if (0 > ShenandoahGarbageThreshold || ShenandoahGarbageThreshold > 100) {
+ vm_exit_during_initialization("The flag -XX:ShenandoahGarbageThreshold is out of range", NULL);
+ }
+ }
+
+ if (!FLAG_IS_DEFAULT(ShenandoahAllocationThreshold)) {
+ if (0 > ShenandoahAllocationThreshold || ShenandoahAllocationThreshold > 100) {
+ vm_exit_during_initialization("The flag -XX:ShenandoahAllocationThreshold is out of range", NULL);
+ }
+ }
+
+ if (!FLAG_IS_DEFAULT(ShenandoahMinFreeThreshold)) {
+ if (0 > ShenandoahMinFreeThreshold || ShenandoahMinFreeThreshold > 100) {
+ vm_exit_during_initialization("The flag -XX:ShenandoahMinFreeThreshold is out of range", NULL);
+ }
+ }
+ #endif
+
+ #if INCLUDE_ALL_GCS
+ if (UseLargePages && (MaxHeapSize / os::large_page_size()) < ShenandoahHeapRegion::MIN_NUM_REGIONS) {
+ warning("Large pages size (" SIZE_FORMAT "K) is too large to afford page-sized regions, disabling uncommit",
+ os::large_page_size() / K);
+ FLAG_SET_DEFAULT(ShenandoahUncommit, false);
+ }
+ #endif
+
+ // Enable NUMA by default. While Shenandoah is not NUMA-aware, enabling NUMA makes
+ // storage allocation code NUMA-aware.
+ if (FLAG_IS_DEFAULT(UseNUMA)) {
+ FLAG_SET_DEFAULT(UseNUMA, true);
+ }
+
+ // Set up default number of concurrent threads. We want to have cycles complete fast
+ // enough, but we also do not want to steal too much CPU from the concurrently running
+ // application. Using 1/4 of available threads for concurrent GC seems a good
+ // compromise here.
+ bool ergo_conc = FLAG_IS_DEFAULT(ConcGCThreads);
+ if (ergo_conc) {
+ FLAG_SET_DEFAULT(ConcGCThreads, MAX2(1, os::initial_active_processor_count() / 4));
+ }
+
+ if (ConcGCThreads == 0) {
+ vm_exit_during_initialization("Shenandoah expects ConcGCThreads > 0, check -XX:ConcGCThreads=#");
+ }
+
+ // Set up default number of parallel threads. We want to have decent pauses performance
+ // which would use parallel threads, but we also do not want to do too many threads
+ // that will overwhelm the OS scheduler. Using 1/2 of available threads seems to be a fair
+ // compromise here. Due to implementation constraints, it should not be lower than
+ // the number of concurrent threads.
+ bool ergo_parallel = FLAG_IS_DEFAULT(ParallelGCThreads);
+ if (ergo_parallel) {
+ FLAG_SET_DEFAULT(ParallelGCThreads, MAX2(1, os::initial_active_processor_count() / 2));
+ }
+
+ if (ParallelGCThreads == 0) {
+ vm_exit_during_initialization("Shenandoah expects ParallelGCThreads > 0, check -XX:ParallelGCThreads=#");
+ }
+
+ // Make sure ergonomic decisions do not break the thread count invariants.
+ // This may happen when user overrides one of the flags, but not the other.
+ // When that happens, we want to adjust the setting that was set ergonomically.
+ if (ParallelGCThreads < ConcGCThreads) {
+ if (ergo_conc && !ergo_parallel) {
+ FLAG_SET_DEFAULT(ConcGCThreads, ParallelGCThreads);
+ } else if (!ergo_conc && ergo_parallel) {
+ FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads);
+ } else if (ergo_conc && ergo_parallel) {
+ // Should not happen, check the ergonomic computation above. Fail with relevant error.
+ vm_exit_during_initialization("Shenandoah thread count ergonomic error");
+ } else {
+ // User settings error, report and ask user to rectify.
+ vm_exit_during_initialization("Shenandoah expects ConcGCThreads <= ParallelGCThreads, check -XX:ParallelGCThreads, -XX:ConcGCThreads");
+ }
+ }
+
+ if (FLAG_IS_DEFAULT(ParallelRefProcEnabled)) {
+ FLAG_SET_DEFAULT(ParallelRefProcEnabled, true);
+ }
+
+ #if INCLUDE_ALL_GCS
+ if (ShenandoahRegionSampling && FLAG_IS_DEFAULT(PerfDataMemorySize)) {
+ // When sampling is enabled, max out the PerfData memory to get more
+ // Shenandoah data in, including Matrix.
+ FLAG_SET_DEFAULT(PerfDataMemorySize, 2048*K);
+ }
+ #endif
+
+ #ifdef COMPILER2
+ // Shenandoah cares more about pause times, rather than raw throughput.
+ // Enabling safepoints in counted loops makes it more responsive with
+ // long loops. However, it is risky in 8u, due to bugs it brings, for
+ // example JDK-8176506. Warn user about this, and proceed.
+ if (UseCountedLoopSafepoints) {
+ warning("Enabling -XX:UseCountedLoopSafepoints is known to cause JVM bugs. Use at your own risk.");
+ }
+
+ #ifdef ASSERT
+ // C2 barrier verification is only reliable when all default barriers are enabled
+ if (ShenandoahVerifyOptoBarriers &&
+ (!FLAG_IS_DEFAULT(ShenandoahSATBBarrier) ||
+ !FLAG_IS_DEFAULT(ShenandoahLoadRefBarrier) ||
+ !FLAG_IS_DEFAULT(ShenandoahStoreValEnqueueBarrier) ||
+ !FLAG_IS_DEFAULT(ShenandoahCASBarrier) ||
+ !FLAG_IS_DEFAULT(ShenandoahCloneBarrier)
+ )) {
+ warning("Unusual barrier configuration, disabling C2 barrier verification");
+ FLAG_SET_DEFAULT(ShenandoahVerifyOptoBarriers, false);
+ }
+ #else
+ guarantee(!ShenandoahVerifyOptoBarriers, "Should be disabled");
+ #endif // ASSERT
+ #endif // COMPILER2
+
+ #if INCLUDE_ALL_GCS
+ if ((InitialHeapSize == MaxHeapSize) && ShenandoahUncommit) {
+ if (PrintGC) {
+ tty->print_cr("Min heap equals to max heap, disabling ShenandoahUncommit");
+ }
+ FLAG_SET_DEFAULT(ShenandoahUncommit, false);
+ }
+
+ // If class unloading is disabled, no unloading for concurrent cycles as well.
+ if (!ClassUnloading) {
+ FLAG_SET_DEFAULT(ClassUnloadingWithConcurrentMark, false);
+ }
+
+ // TLAB sizing policy makes resizing decisions before each GC cycle. It averages
+ // historical data, assigning more recent data the weight according to TLABAllocationWeight.
+ // Current default is good for generational collectors that run frequent young GCs.
+ // With Shenandoah, GC cycles are much less frequent, so we need we need sizing policy
+ // to converge faster over smaller number of resizing decisions.
+ if (FLAG_IS_DEFAULT(TLABAllocationWeight)) {
+ FLAG_SET_DEFAULT(TLABAllocationWeight, 90);
+ }
+
+ if (FLAG_IS_DEFAULT(ShenandoahSoftMaxHeapSize)) {
+ FLAG_SET_DEFAULT(ShenandoahSoftMaxHeapSize, MaxHeapSize);
+ } else {
+ if (ShenandoahSoftMaxHeapSize > MaxHeapSize) {
+ vm_exit_during_initialization("ShenandoahSoftMaxHeapSize must be less than or equal to the maximum heap size\n");
+ }
+ }
+ #endif
+ }
+
#if !INCLUDE_ALL_GCS
#ifdef ASSERT
static bool verify_serial_gc_flags() {
return (UseSerialGC &&
!(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC ||
*** 1752,1761 ****
--- 1928,1939 ----
set_cms_and_parnew_gc_flags();
} else if (UseParNewGC) { // Skipped if CMS is set above
set_parnew_gc_flags();
} else if (UseG1GC) {
set_g1_gc_flags();
+ } else if (UseShenandoahGC) {
+ set_shenandoah_gc_flags();
}
check_deprecated_gcs();
check_deprecated_gc_flags();
if (AssumeMP && !UseSerialGC) {
if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
*** 1772,1781 ****
--- 1950,1960 ----
// If class unloading is disabled, also disable concurrent class unloading.
if (!ClassUnloading) {
FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false);
FLAG_SET_CMDLINE(bool, ClassUnloadingWithConcurrentMark, false);
FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false);
+ FLAG_SET_CMDLINE(uintx, ShenandoahUnloadClassesFrequency, 0);
}
#else // INCLUDE_ALL_GCS
assert(verify_serial_gc_flags(), "SerialGC unset");
#endif // INCLUDE_ALL_GCS
}
*** 2152,2161 ****
--- 2331,2345 ----
if (UseGCLogFileRotation && (GCLogFileSize != 0) && (GCLogFileSize < 8*K)) {
FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K);
jio_fprintf(defaultStream::output_stream(),
"GCLogFileSize changed to minimum 8K\n");
}
+
+ // Record more information about previous cycles for improved debugging pleasure
+ if (FLAG_IS_DEFAULT(LogEventsBufferEntries)) {
+ FLAG_SET_DEFAULT(LogEventsBufferEntries, 250);
+ }
}
// This function is called for -Xloggc:<filename>, it can be used
// to check if a given file name(or string) conforms to the following
// specification:
*** 2247,2256 ****
--- 2431,2441 ----
uint i = 0;
if (UseSerialGC) i++;
if (UseConcMarkSweepGC || UseParNewGC) i++;
if (UseParallelGC || UseParallelOldGC) i++;
if (UseG1GC) i++;
+ if (UseShenandoahGC) i++;
if (i > 1) {
jio_fprintf(defaultStream::error_stream(),
"Conflicting collector combinations in option list; "
"please refer to the release notes for the combinations "
"allowed\n");
*** 2634,2648 ****
} else if (ReservedCodeCacheSize < min_code_cache_size) {
jio_fprintf(defaultStream::error_stream(),
"Invalid ReservedCodeCacheSize=%dK. Must be at least %uK.\n", ReservedCodeCacheSize/K,
min_code_cache_size/K);
status = false;
! } else if (ReservedCodeCacheSize > 2*G) {
! // Code cache size larger than MAXINT is not supported.
jio_fprintf(defaultStream::error_stream(),
"Invalid ReservedCodeCacheSize=%dM. Must be at most %uM.\n", ReservedCodeCacheSize/M,
! (2*G)/M);
status = false;
}
status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction");
status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
--- 2819,2833 ----
} else if (ReservedCodeCacheSize < min_code_cache_size) {
jio_fprintf(defaultStream::error_stream(),
"Invalid ReservedCodeCacheSize=%dK. Must be at least %uK.\n", ReservedCodeCacheSize/K,
min_code_cache_size/K);
status = false;
! } else if (ReservedCodeCacheSize > CODE_CACHE_SIZE_LIMIT) {
! // Code cache size larger than CODE_CACHE_SIZE_LIMIT is not supported.
jio_fprintf(defaultStream::error_stream(),
"Invalid ReservedCodeCacheSize=%dM. Must be at most %uM.\n", ReservedCodeCacheSize/M,
! CODE_CACHE_SIZE_LIMIT/M);
status = false;
}
status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction");
status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
< prev index next >