8064940: JMH javac performance regressions on solaris-sparcv9 in 9-b34
authorthartmann
Wed, 28 Jan 2015 07:55:27 +0100
changeset 28730 106944a21769
parent 28729 062f02fa1d17
child 28742 e6ec6ed5be00
child 28912 27fac2f8fdbe
child 28917 6d1774924b15
8064940: JMH javac performance regressions on solaris-sparcv9 in 9-b34 Summary: Aligning code heap sizes to large page size if supported. Reviewed-by: kvn, anoll
hotspot/src/share/vm/code/codeCache.cpp
hotspot/src/share/vm/code/codeCache.hpp
hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java
--- a/hotspot/src/share/vm/code/codeCache.cpp	Tue Jan 27 13:58:55 2015 -0500
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Wed Jan 28 07:55:27 2015 +0100
@@ -199,15 +199,10 @@
   }
   guarantee(NonProfiledCodeHeapSize + ProfiledCodeHeapSize + NonNMethodCodeHeapSize <= ReservedCodeCacheSize, "Size check");
 
-  // Align reserved sizes of CodeHeaps
-  size_t non_method_size   = ReservedCodeSpace::allocation_align_size_up(NonNMethodCodeHeapSize);
-  size_t profiled_size     = ReservedCodeSpace::allocation_align_size_up(ProfiledCodeHeapSize);
-  size_t non_profiled_size = ReservedCodeSpace::allocation_align_size_up(NonProfiledCodeHeapSize);
-
-  // Compute initial sizes of CodeHeaps
-  size_t init_non_method_size   = MIN2(InitialCodeCacheSize, non_method_size);
-  size_t init_profiled_size     = MIN2(InitialCodeCacheSize, profiled_size);
-  size_t init_non_profiled_size = MIN2(InitialCodeCacheSize, non_profiled_size);
+  // Align CodeHeaps
+  size_t alignment = heap_alignment();
+  size_t non_method_size = align_size_up(NonNMethodCodeHeapSize, alignment);
+  size_t profiled_size   = align_size_down(ProfiledCodeHeapSize, alignment);
 
   // Reserve one continuous chunk of memory for CodeHeaps and split it into
   // parts for the individual heaps. The memory layout looks like this:
@@ -216,18 +211,27 @@
   //      Profiled nmethods
   //         Non-nmethods
   // ---------- low ------------
-  ReservedCodeSpace rs = reserve_heap_memory(non_profiled_size + profiled_size + non_method_size);
+  ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
   ReservedSpace non_method_space    = rs.first_part(non_method_size);
   ReservedSpace rest                = rs.last_part(non_method_size);
   ReservedSpace profiled_space      = rest.first_part(profiled_size);
   ReservedSpace non_profiled_space  = rest.last_part(profiled_size);
 
   // Non-nmethods (stubs, adapters, ...)
-  add_heap(non_method_space, "CodeHeap 'non-nmethods'", init_non_method_size, CodeBlobType::NonNMethod);
+  add_heap(non_method_space, "CodeHeap 'non-nmethods'", CodeBlobType::NonNMethod);
   // Tier 2 and tier 3 (profiled) methods
-  add_heap(profiled_space, "CodeHeap 'profiled nmethods'", init_profiled_size, CodeBlobType::MethodProfiled);
+  add_heap(profiled_space, "CodeHeap 'profiled nmethods'", CodeBlobType::MethodProfiled);
   // Tier 1 and tier 4 (non-profiled) methods and native methods
-  add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", init_non_profiled_size, CodeBlobType::MethodNonProfiled);
+  add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", CodeBlobType::MethodNonProfiled);
+}
+
+size_t CodeCache::heap_alignment() {
+  // If large page support is enabled, align code heaps according to large
+  // page size to make sure that code cache is covered by large pages.
+  const size_t page_size = os::can_execute_large_page_memory() ?
+             os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8) :
+             os::vm_page_size();
+  return MAX2(page_size, (size_t) os::vm_allocation_granularity());
 }
 
 ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
@@ -284,7 +288,7 @@
   return NULL;
 }
 
-void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type) {
+void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) {
   // Check if heap is needed
   if (!heap_available(code_blob_type)) {
     return;
@@ -295,8 +299,8 @@
   _heaps->append(heap);
 
   // Reserve Space
+  size_t size_initial = MIN2(InitialCodeCacheSize, rs.size());
   size_initial = round_to(size_initial, os::vm_page_size());
-
   if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) {
     vm_exit_during_initialization("Could not reserve enough space for code cache");
   }
@@ -840,7 +844,7 @@
   } else {
     // Use a single code heap
     ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
-    add_heap(rs, "CodeCache", InitialCodeCacheSize, CodeBlobType::All);
+    add_heap(rs, "CodeCache", CodeBlobType::All);
   }
 
   // Initialize ICache flush mechanism
--- a/hotspot/src/share/vm/code/codeCache.hpp	Tue Jan 27 13:58:55 2015 -0500
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Wed Jan 28 07:55:27 2015 +0100
@@ -98,12 +98,13 @@
   // CodeHeap management
   static void initialize_heaps();                             // Initializes the CodeHeaps
   // Creates a new heap with the given name and size, containing CodeBlobs of the given type
-  static void add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type);
+  static void add_heap(ReservedSpace rs, const char* name, int code_blob_type);
   static CodeHeap* get_code_heap(const CodeBlob* cb);         // Returns the CodeHeap for the given CodeBlob
   static CodeHeap* get_code_heap(int code_blob_type);         // Returns the CodeHeap for the given CodeBlobType
   // Returns the name of the VM option to set the size of the corresponding CodeHeap
   static const char* get_code_heap_flag_name(int code_blob_type);
   static bool heap_available(int code_blob_type);             // Returns true if an own CodeHeap for the given CodeBlobType is available
+  static size_t heap_alignment();                             // Returns the alignment of the CodeHeaps in bytes
   static ReservedCodeSpace reserve_heap_memory(size_t size);  // Reserves one continuous chunk of memory for the CodeHeaps
 
   // Iteration
--- a/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java	Tue Jan 27 13:58:55 2015 -0500
+++ b/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java	Wed Jan 28 07:55:27 2015 +0100
@@ -82,6 +82,9 @@
                 ExitCode.OK,
                 testCaseDescription.getTestOptions(options,
                         CommandLineOptionTest.prepareBooleanFlag(
-                                "PrintCodeCache", printCodeCache)));
+                                "PrintCodeCache", printCodeCache),
+                        // Do not use large pages to avoid large page
+                        // alignment of code heaps affecting their size.
+                        "-XX:-UseLargePages"));
     }
 }