changeset 58651:a54ff90a3015

8241670: Enhance heap region size ergonomics to improve OOTB performance Reviewed-by: redestad, tschatzl
author sjohanss
date Thu, 02 Apr 2020 21:33:57 +0200
parents 0499b8336d20
children 6f7477dfb965
files src/hotspot/share/gc/g1/g1Arguments.cpp src/hotspot/share/gc/g1/heapRegion.cpp src/hotspot/share/gc/g1/heapRegion.hpp src/hotspot/share/gc/g1/heapRegionBounds.hpp test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java
diffstat 5 files changed, 20 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp	Thu Apr 02 11:20:53 2020 -0700
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp	Thu Apr 02 21:33:57 2020 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -50,7 +50,7 @@
   // There is a circular dependency here. We base the region size on the heap
   // size, but the heap size should be aligned with the region size. To get
   // around this we use the unaligned values for the heap.
-  HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize);
+  HeapRegion::setup_heap_region_size(MaxHeapSize);
   HeapRegionRemSet::setup_remset_size();
 
   SpaceAlignment = HeapRegion::GrainBytes;
--- a/src/hotspot/share/gc/g1/heapRegion.cpp	Thu Apr 02 11:20:53 2020 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.cpp	Thu Apr 02 21:33:57 2020 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/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
@@ -43,6 +43,7 @@
 #include "oops/access.inline.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "utilities/powerOfTwo.hpp"
 
 int    HeapRegion::LogOfHRGrainBytes = 0;
 int    HeapRegion::LogOfHRGrainWords = 0;
@@ -59,29 +60,23 @@
   return HeapRegionBounds::min_size() >> LogHeapWordSize;
 }
 
-void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
+void HeapRegion::setup_heap_region_size(size_t max_heap_size) {
   size_t region_size = G1HeapRegionSize;
-  if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
-    size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
-    region_size = MAX2(average_heap_size / HeapRegionBounds::target_number(),
+  // G1HeapRegionSize = 0 means decide ergonomically.
+  if (region_size == 0) {
+    region_size = MAX2(max_heap_size / HeapRegionBounds::target_number(),
                        HeapRegionBounds::min_size());
   }
 
-  int region_size_log = log2_long((jlong) region_size);
-  // Recalculate the region size to make sure it's a power of
-  // 2. This means that region_size is the largest power of 2 that's
-  // <= what we've calculated so far.
-  region_size = ((size_t)1 << region_size_log);
+  // Make sure region size is a power of 2. Rounding up since this
+  // is beneficial in most cases.
+  region_size = round_up_power_of_2(region_size);
 
   // Now make sure that we don't go over or under our limits.
-  if (region_size < HeapRegionBounds::min_size()) {
-    region_size = HeapRegionBounds::min_size();
-  } else if (region_size > HeapRegionBounds::max_size()) {
-    region_size = HeapRegionBounds::max_size();
-  }
+  region_size = clamp(region_size, HeapRegionBounds::min_size(), HeapRegionBounds::max_size());
 
-  // And recalculate the log.
-  region_size_log = log2_long((jlong) region_size);
+  // Calculate the log for the region size.
+  int region_size_log = exact_log2_long((jlong)region_size);
 
   // Now, set up the globals.
   guarantee(LogOfHRGrainBytes == 0, "we should only set it once");
--- a/src/hotspot/share/gc/g1/heapRegion.hpp	Thu Apr 02 11:20:53 2020 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp	Thu Apr 02 21:33:57 2020 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/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
@@ -323,7 +323,7 @@
   // CardsPerRegion). All those fields are considered constant
   // throughout the JVM's execution, therefore they should only be set
   // up once during initialization time.
-  static void setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size);
+  static void setup_heap_region_size(size_t max_heap_size);
 
   // The number of bytes marked live in the region in the last marking phase.
   size_t marked_bytes()    { return _prev_marked_bytes; }
--- a/src/hotspot/share/gc/g1/heapRegionBounds.hpp	Thu Apr 02 11:20:53 2020 -0700
+++ b/src/hotspot/share/gc/g1/heapRegionBounds.hpp	Thu Apr 02 21:33:57 2020 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, Oracle and/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
@@ -42,7 +42,7 @@
   static const size_t MAX_REGION_SIZE = 32 * 1024 * 1024;
 
   // The automatic region size calculation will try to have around this
-  // many regions in the heap (based on the min heap size).
+  // many regions in the heap.
   static const size_t TARGET_REGION_NUMBER = 2048;
 
 public:
--- a/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java	Thu Apr 02 11:20:53 2020 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java	Thu Apr 02 21:33:57 2020 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/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
@@ -81,7 +81,7 @@
 
     checkG1HeapRegionSize(new String[] { "-Xmx64m"   /* default is 1m */        },  1*M, 0);
     checkG1HeapRegionSize(new String[] { "-Xmx64m",  "-XX:G1HeapRegionSize=2m"  },  2*M, 0);
-    checkG1HeapRegionSize(new String[] { "-Xmx64m",  "-XX:G1HeapRegionSize=3m"  },  2*M, 0);
+    checkG1HeapRegionSize(new String[] { "-Xmx64m",  "-XX:G1HeapRegionSize=3m"  },  4*M, 0);
     checkG1HeapRegionSize(new String[] { "-Xmx256m", "-XX:G1HeapRegionSize=32m" }, 32*M, 0);
     checkG1HeapRegionSize(new String[] { "-Xmx256m", "-XX:G1HeapRegionSize=64m" }, 32*M, 1);
   }