8220162: Shenandoah should not commit HugeTLBFS memory
authorshade
Mon, 11 Mar 2019 00:06:48 +0100
changeset 54047 0a9cb99a98a0
parent 54046 f02c6b980c04
child 54048 744dc9c33676
8220162: Shenandoah should not commit HugeTLBFS memory Reviewed-by: rkennke, zgu
src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Mar 11 00:06:47 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Mar 11 00:06:48 2019 +0100
@@ -173,13 +173,16 @@
   ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, heap_alignment);
   initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*) (heap_rs.base() + heap_rs.size()));
   _heap_region = MemRegion((HeapWord*)heap_rs.base(), heap_rs.size() / HeapWordSize);
+  _heap_region_special = heap_rs.special();
 
   assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0,
          "Misaligned heap: " PTR_FORMAT, p2i(base()));
 
   ReservedSpace sh_rs = heap_rs.first_part(max_byte_size);
-  os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false,
-                            "Cannot commit heap memory");
+  if (!_heap_region_special) {
+    os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false,
+                              "Cannot commit heap memory");
+  }
 
   //
   // Reserve and commit memory for bitmap(s)
@@ -214,19 +217,24 @@
   ReservedSpace bitmap(_bitmap_size, bitmap_page_size);
   MemTracker::record_virtual_memory_type(bitmap.base(), mtGC);
   _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize);
+  _bitmap_region_special = bitmap.special();
 
   size_t bitmap_init_commit = _bitmap_bytes_per_slice *
                               align_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice;
   bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit);
-  os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, bitmap_page_size, false,
-                            "Cannot commit bitmap memory");
+  if (!_bitmap_region_special) {
+    os::commit_memory_or_exit((char *) _bitmap_region.start(), bitmap_init_commit, bitmap_page_size, false,
+                              "Cannot commit bitmap memory");
+  }
 
   _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions);
 
   if (ShenandoahVerify) {
     ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size);
-    os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), bitmap_page_size, false,
-                              "Cannot commit verification bitmap memory");
+    if (!verify_bitmap.special()) {
+      os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), bitmap_page_size, false,
+                                "Cannot commit verification bitmap memory");
+    }
     MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC);
     MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize);
     _verification_bit_map.initialize(_heap_region, verify_bitmap_region);
@@ -237,6 +245,7 @@
   ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size);
   MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC);
   _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize);
+  _aux_bitmap_region_special = aux_bitmap.special();
   _aux_bit_map.initialize(_heap_region, _aux_bitmap_region);
 
   //
@@ -406,6 +415,7 @@
   _max_workers(MAX2(ConcGCThreads, ParallelGCThreads)),
   _workers(NULL),
   _safepoint_workers(NULL),
+  _heap_region_special(false),
   _num_regions(0),
   _regions(NULL),
   _update_refs_iterator(this),
@@ -431,6 +441,8 @@
   _bitmap_size(0),
   _bitmap_regions_per_slice(0),
   _bitmap_bytes_per_slice(0),
+  _bitmap_region_special(false),
+  _aux_bitmap_region_special(false),
   _liveness_cache(NULL),
   _collection_set(NULL)
 {
@@ -1316,7 +1328,7 @@
  */
 void ShenandoahHeap::object_iterate(ObjectClosure* cl) {
   assert(SafepointSynchronize::is_at_safepoint(), "safe iteration is only available during safepoints");
-  if (!os::commit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size(), false)) {
+  if (!_aux_bitmap_region_special && !os::commit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size(), false)) {
     log_warning(gc)("Could not commit native memory for auxiliary marking bitmap for heap iteration");
     return;
   }
@@ -1343,7 +1355,7 @@
 
   assert(oop_stack.is_empty(), "should be empty");
 
-  if (!os::uncommit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size())) {
+  if (!_aux_bitmap_region_special && !os::uncommit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size())) {
     log_warning(gc)("Could not uncommit native memory for auxiliary marking bitmap for heap iteration");
   }
 }
@@ -2270,6 +2282,11 @@
 bool ShenandoahHeap::commit_bitmap_slice(ShenandoahHeapRegion* r) {
   assert_heaplock_owned_by_current_thread();
 
+  // Bitmaps in special regions do not need commits
+  if (_bitmap_region_special) {
+    return true;
+  }
+
   if (is_bitmap_slice_committed(r, true)) {
     // Some other region from the group is already committed, meaning the bitmap
     // slice is already committed, we exit right away.
@@ -2289,6 +2306,11 @@
 bool ShenandoahHeap::uncommit_bitmap_slice(ShenandoahHeapRegion *r) {
   assert_heaplock_owned_by_current_thread();
 
+  // Bitmaps in special regions do not need uncommits
+  if (_bitmap_region_special) {
+    return true;
+  }
+
   if (is_bitmap_slice_committed(r, true)) {
     // Some other region from the group is still committed, meaning the bitmap
     // slice is should stay committed, exit right away.
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Mon Mar 11 00:06:47 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Mon Mar 11 00:06:48 2019 +0100
@@ -242,12 +242,14 @@
 //
 private:
   MemRegion _heap_region;
+  bool      _heap_region_special;
   size_t    _num_regions;
   ShenandoahHeapRegion** _regions;
   ShenandoahRegionIterator _update_refs_iterator;
 
 public:
   inline size_t num_regions() const { return _num_regions; }
+  inline bool is_heap_region_special() { return _heap_region_special; }
 
   inline ShenandoahHeapRegion* const heap_region_containing(const void* addr) const;
   inline size_t heap_region_index_containing(const void* addr) const;
@@ -649,6 +651,9 @@
   size_t _bitmap_regions_per_slice;
   size_t _bitmap_bytes_per_slice;
 
+  bool _bitmap_region_special;
+  bool _aux_bitmap_region_special;
+
   // Used for buffering per-region liveness data.
   // Needed since ShenandoahHeapRegion uses atomics to update liveness.
   //
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Mon Mar 11 00:06:47 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Mon Mar 11 00:06:48 2019 +0100
@@ -659,7 +659,7 @@
 }
 
 void ShenandoahHeapRegion::do_commit() {
-  if (!os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) {
+  if (!_heap->is_heap_region_special() && !os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) {
     report_java_out_of_memory("Unable to commit region");
   }
   if (!_heap->commit_bitmap_slice(this)) {
@@ -669,7 +669,7 @@
 }
 
 void ShenandoahHeapRegion::do_uncommit() {
-  if (!os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) {
+  if (!_heap->is_heap_region_special() && !os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) {
     report_java_out_of_memory("Unable to uncommit region");
   }
   if (!_heap->uncommit_bitmap_slice(this)) {