< prev index next >

src/share/vm/runtime/arguments.cpp

Print this page

        

@@ -64,10 +64,13 @@
 #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

@@ -1159,11 +1162,13 @@
     vm_exit_during_initialization(
       "Incompatible compilation policy selected", NULL);
   }
   // Increase the code cache size - tiered compiles a lot more.
   if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
-    FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 5);
+    NOT_AARCH64(FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 5));
+    AARCH64_ONLY(FLAG_SET_DEFAULT(ReservedCodeCacheSize,
+                                  MIN2(CODE_CACHE_DEFAULT_LIMIT, ReservedCodeCacheSize * 5)));
   }
   if (!UseInterpreter) { // -Xcomp
     Tier3InvokeNotifyFreqLog = 0;
     Tier4InvocationThreshold = 0;
   }

@@ -1535,11 +1540,10 @@
   }
 #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

@@ -1575,10 +1579,12 @@
 #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(),

@@ -1726,10 +1732,180 @@
       (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 class unloading is enabled, users should opt-in for unloading during
+  // concurrent cycles.
+  if (!ClassUnloading || !FLAG_IS_CMDLINE(ClassUnloadingWithConcurrentMark)) {
+    if (PrintGC) {
+      tty->print_cr("Consider -XX:+ClassUnloadingWithConcurrentMark if large pause times "
+                    "are observed on class-unloading sensitive workloads");
+    }
+    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);
+  }
+#endif
+}
+
 #if !INCLUDE_ALL_GCS
 #ifdef ASSERT
 static bool verify_serial_gc_flags() {
   return (UseSerialGC &&
         !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC ||

@@ -1747,10 +1923,12 @@
     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) {

@@ -1767,10 +1945,11 @@
   // 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
 }

@@ -2147,10 +2326,15 @@
   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:

@@ -2242,10 +2426,11 @@
   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");

@@ -2629,15 +2814,15 @@
   } 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.
+  } 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,
-                (2*G)/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 >