Date: Mon, 5 Jun 2023 20:12:44 +0800
Subject: [PATCH 07/59] 8241670: Enhance heap region size ergonomics to improve OOTB performance

---
 .../g1/g1CollectorPolicy.cpp                  |  3 +-
 .../vm/gc_implementation/g1/heapRegion.cpp    | 29 ++++++++-----------
 .../vm/gc_implementation/g1/heapRegion.hpp    |  3 +-
 .../gc_implementation/g1/heapRegionBounds.hpp |  3 +-
 .../gc/arguments/TestG1HeapRegionSize.java    |  3 +-
 5 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index 05ce59987..0acdd2b69 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
@@ -184,7 +185,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
   // 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();
 
   G1ErgoVerbose::initialize();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
index 87cc73bee..28b21a9be 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
@@ -107,29 +108,23 @@ size_t HeapRegion::max_region_size() {
   return HeapRegionBounds::max_size();
 }
 
-void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
-  uintx 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(),
+void HeapRegion::setup_heap_region_size(size_t max_heap_size) {
+  uintx region_size = G1HeapRegionSize; 
+  // G1HeapRegionSize = 0 means decide ergonomically.
+  if (region_size == 0) {
+    region_size = MAX2(max_heap_size / HeapRegionBounds::target_number(),
                        (uintx) 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 = ((uintx)1 << region_size_log);
+  // Make sure region size is a power of 2. Rounding up since this
+  // is beneficial in most cases.
+  region_size = is_power_of_2(region_size) ? region_size : (size_t)1 << (log2_intptr(region_size) + 1);
 
   // 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 = MIN2(MAX2(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");
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
index 5d2415e84..4e0afbac1 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
@@ -333,7 +334,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
   // 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);
 
   // All allocated blocks are occupied by objects in a HeapRegion
   bool block_is_obj(const HeapWord* p) const;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp
index 1da7f24c1..c76dead88 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
@@ -40,7 +41,7 @@ private:
   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:
diff --git a/hotspot/test/gc/arguments/TestG1HeapRegionSize.java b/hotspot/test/gc/arguments/TestG1HeapRegionSize.java
index 0442d2c61..a9b5fa0cb 100644
--- a/hotspot/test/gc/arguments/TestG1HeapRegionSize.java
+++ b/hotspot/test/gc/arguments/TestG1HeapRegionSize.java
@@ -1,5 +1,6 @@
 /*
 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2022, Huawei Technologies Co., Ltd. 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
@@ -28,7 +29,7 @@
  * @summary Verify that the flag G1HeapRegionSize is updated properly
  * @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576
  * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152
- * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 4194304
  * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432
  */
 
-- 
2.22.0

