src/share/vm/runtime/arguments.cpp

Print this page

        

@@ -50,11 +50,14 @@
 # include "os_windows.inline.hpp"
 #endif
 #ifdef TARGET_OS_FAMILY_bsd
 # include "os_bsd.inline.hpp"
 #endif
+#include "memory/genCollectedHeap.hpp"
 #if INCLUDE_ALL_GCS
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 #endif // INCLUDE_ALL_GCS
 
 // Note: This is a special bug reporting site for the JVM
 #define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"

@@ -67,10 +70,11 @@
 char*  Arguments::_java_command                 = NULL;
 SystemProperty* Arguments::_system_properties   = NULL;
 const char*  Arguments::_gc_log_filename        = NULL;
 bool   Arguments::_has_profile                  = false;
 bool   Arguments::_has_alloc_profile            = false;
+size_t Arguments::_max_heap_alignment           = 0;
 uintx  Arguments::_min_heap_size                = 0;
 Arguments::Mode Arguments::_mode                = _mixed;
 bool   Arguments::_java_compiler                = false;
 bool   Arguments::_xdebug_mode                  = false;
 const char*  Arguments::_java_vendor_url_bug    = DEFAULT_VENDOR_URL_BUG;

@@ -1352,16 +1356,36 @@
     return false;
   }
   return true;
 }
 
-inline uintx max_heap_for_compressed_oops() {
+bool Arguments::apply_ergonomics_on_classmetaspacesize() {
+  return FLAG_IS_DEFAULT(ClassMetaspaceSize);
+}
+
+size_t Arguments::max_heap_for_compressed_oops() {
+  // determine the maximum heap size that allows compressed oops. Use the theoretical
+  // maximum (OopEncodingHeapMax) and subtract the sizes of other areas that need
+  // to be below that maximum. Use a conservative estimate on the alignment returned
+  // by max_heap_alignment() to calculate these estimates for the other areas.
+  // We need to apply the alignment on all areas separately to make sure that later,
+  // when aligning the final heap size up, all sizes fit below the absolute maximum.
+
+  // the absolute theoretical maximum
+  size_t max_total_heap = OopEncodingHeapMax;
+
+  size_t max_class_metaspace_size = ClassMetaspaceSize;
+  if (apply_ergonomics_on_classmetaspacesize()) {
+    max_class_metaspace_size = MAX2(max_class_metaspace_size, ErgoClassMetaspaceSize);
+  }
+  size_t aligned_metaspace_size = align_size_up_(max_class_metaspace_size, max_heap_alignment());
+  size_t aligned_page_size = align_size_up_(os::vm_page_size(), max_heap_alignment());
   // Avoid sign flip.
-  if (OopEncodingHeapMax < ClassMetaspaceSize + os::vm_page_size()) {
+  if (max_total_heap < aligned_metaspace_size + aligned_page_size) {
     return 0;
   }
-  LP64_ONLY(return OopEncodingHeapMax - ClassMetaspaceSize - os::vm_page_size());
+  LP64_ONLY(return max_total_heap - aligned_metaspace_size - aligned_page_size);
   NOT_LP64(ShouldNotReachHere(); return 0);
 }
 
 bool Arguments::should_auto_select_low_pause_collector() {
   if (UseAutoGCSelectPolicy &&

@@ -1409,10 +1433,27 @@
   }
 #endif // _LP64
 #endif // ZERO
 }
 
+void Arguments::set_max_heap_alignment() {
+  size_t gc_alignment;
+#if INCLUDE_ALL_GCS
+  if (UseParallelGC) {
+    gc_alignment = ParallelScavengeHeap::max_heap_alignment();
+  } else if (UseG1GC) {
+    gc_alignment = G1CollectedHeap::max_heap_alignment();
+  } else {
+#endif // INCLUDE_ALL_GCS
+    gc_alignment = GenCollectedHeap::max_heap_alignment();
+#if INCLUDE_ALL_GCS
+  }
+#endif // INCLUDE_ALL_GCS
+  _max_heap_alignment = MAX3(gc_alignment, os::max_page_size(),
+    CollectorPolicy::compute_max_alignment());
+}
+
 void Arguments::set_ergonomics_flags() {
 
   if (os::is_server_class_machine()) {
     // If no other collector is requested explicitly,
     // let the VM select the collector based on

@@ -1436,10 +1477,12 @@
     if (!DumpSharedSpaces && !RequireSharedSpaces) {
       no_shared_spaces();
     }
   }
 
+  set_max_heap_alignment();
+
 #ifndef ZERO
 #ifdef _LP64
   set_use_compressed_oops();
   // UseCompressedOops must be on for UseCompressedKlassPointers to be on.
   if (!UseCompressedOops) {

@@ -1456,17 +1499,17 @@
     // expanded, since it cannot be expanded.
     if (UseCompressedKlassPointers) {
       if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
         warning("Class metaspace size is too large for UseCompressedKlassPointers");
         FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
-      } else if (FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
+      } else if (apply_ergonomics_on_classmetaspacesize()) {
         // 100,000 classes seems like a good size, so 100M assumes around 1K
         // per klass.   The vtable and oopMap is embedded so we don't have a fixed
         // size per klass.   Eventually, this will be parameterized because it
         // would also be useful to determine the optimal size of the
         // systemDictionary.
-        FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
+        FLAG_SET_ERGO(uintx, ClassMetaspaceSize, ErgoClassMetaspaceSize);
       }
     }
   }
   // Also checks that certain machines are slower with compressed oops
   // in vm_version initialization code.

@@ -3358,10 +3401,15 @@
     FLAG_SET_DEFAULT(PrintSharedSpaces, false);
   }
   no_shared_spaces();
 #endif // INCLUDE_CDS
 
+  // We need to initialize large page support here because ergonomics takes some
+  // decisions depending on large page support and the calculated large page size.
+  // Ergonomics may turn off large page support off later again.
+  os::large_page_init();
+
   // Set flags based on ergonomics.
   set_ergonomics_flags();
 
   set_shared_spaces_flags();