8059758: Footprint regressions with JDK-8038423
authortschatzl
Thu, 09 Oct 2014 11:40:11 +0200
changeset 27149 9246fc481aa3
parent 27009 e7e723732b6b
child 27150 5a09b3a7b974
8059758: Footprint regressions with JDK-8038423 Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything. Reviewed-by: jwilhelm, brutisso
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp
hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp
hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp
hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp
hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp
hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Oct 09 11:40:11 2014 +0200
@@ -131,7 +131,10 @@
   storage->set_mapping_changed_listener(&_listener);
 }
 
-void CMBitMapMappingChangedListener::on_commit(uint start_region, size_t num_regions) {
+void CMBitMapMappingChangedListener::on_commit(uint start_region, size_t num_regions, bool zero_filled) {
+  if (zero_filled) {
+    return;
+  }
   // We need to clear the bitmap on commit, removing any existing information.
   MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_region), num_regions * HeapRegion::GrainWords);
   _bm->clearRange(mr);
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu Oct 09 11:40:11 2014 +0200
@@ -127,7 +127,7 @@
 
   void set_bitmap(CMBitMap* bm) { _bm = bm; }
 
-  virtual void on_commit(uint start_idx, size_t num_regions);
+  virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
 };
 
 class CMBitMap : public CMBitMapRO {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp	Thu Oct 09 11:40:11 2014 +0200
@@ -109,7 +109,7 @@
 
 class G1BlockOffsetSharedArrayMappingChangedListener : public G1MappingChangedListener {
  public:
-  virtual void on_commit(uint start_idx, size_t num_regions) {
+  virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
     // Nothing to do. The BOT is hard-wired to be part of the HeapRegion, and we cannot
     // retrieve it here since this would cause firing of several asserts. The code
     // executed after commit of a region already needs to do some re-initialization of
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp	Thu Oct 09 11:40:11 2014 +0200
@@ -33,7 +33,10 @@
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
-void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_regions) {
+void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
+  if (zero_filled) {
+    return;
+  }
   MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
   _counts->clear_range(mr);
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp	Thu Oct 09 11:40:11 2014 +0200
@@ -42,7 +42,7 @@
  public:
   void set_cardcounts(G1CardCounts* counts) { _counts = counts; }
 
-  virtual void on_commit(uint start_idx, size_t num_regions);
+  virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
 };
 
 // Table to track the number of times a card has been refined. Once
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Oct 09 11:40:11 2014 +0200
@@ -389,7 +389,9 @@
   OtherRegionsTable::invalidate(start_idx, num_regions);
 }
 
-void G1RegionMappingChangedListener::on_commit(uint start_idx, size_t num_regions) {
+void G1RegionMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
+  // The from card cache is not the memory that is actually committed. So we cannot
+  // take advantage of the zero_filled parameter.
   reset_from_card_cache(start_idx, num_regions);
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Oct 09 11:40:11 2014 +0200
@@ -172,7 +172,7 @@
  private:
   void reset_from_card_cache(uint start_idx, size_t num_regions);
  public:
-  virtual void on_commit(uint start_idx, size_t num_regions);
+  virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
 };
 
 class G1CollectedHeap : public SharedHeap {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp	Thu Oct 09 11:40:11 2014 +0200
@@ -69,7 +69,7 @@
   virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
     _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
     _commit_map.set_range(start_idx, start_idx + num_regions);
-    fire_on_commit(start_idx, num_regions);
+    fire_on_commit(start_idx, num_regions, true);
   }
 
   virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
@@ -115,12 +115,14 @@
       assert(!_commit_map.at(i), err_msg("Trying to commit storage at region "INTPTR_FORMAT" that is already committed", i));
       uintptr_t idx = region_idx_to_page_idx(i);
       uint old_refcount = _refcounts.get_by_index(idx);
+      bool zero_filled = false;
       if (old_refcount == 0) {
         _storage.commit(idx, 1);
+        zero_filled = true;
       }
       _refcounts.set_by_index(idx, old_refcount + 1);
       _commit_map.set_bit(i);
-      fire_on_commit(i, 1);
+      fire_on_commit(i, 1, zero_filled);
     }
   }
 
@@ -139,9 +141,9 @@
   }
 };
 
-void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions) {
+void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
   if (_listener != NULL) {
-    _listener->on_commit(start_idx, num_regions);
+    _listener->on_commit(start_idx, num_regions, zero_filled);
   }
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Thu Oct 09 11:40:11 2014 +0200
@@ -33,7 +33,9 @@
  public:
   // Fired after commit of the memory, i.e. the memory this listener is registered
   // for can be accessed.
-  virtual void on_commit(uint start_idx, size_t num_regions) = 0;
+  // Zero_filled indicates that the memory can be considered as filled with zero bytes
+  // when called.
+  virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled) = 0;
 };
 
 // Maps region based commit/uncommit requests to the underlying page sized virtual
@@ -51,7 +53,7 @@
 
   G1RegionToSpaceMapper(ReservedSpace rs, size_t commit_granularity, size_t region_granularity, MemoryType type);
 
-  void fire_on_commit(uint start_idx, size_t num_regions);
+  void fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled);
  public:
   MemRegion reserved() { return _storage.reserved(); }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Thu Oct 09 11:40:11 2014 +0200
@@ -125,7 +125,8 @@
 }
 #endif
 
-void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, size_t num_regions) {
+void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
+  // Default value for a clean card on the card table is -1. So we cannot take advantage of the zero_filled parameter.
   MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
   _card_table->clear(mr);
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Tue Oct 07 14:54:53 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Thu Oct 09 11:40:11 2014 +0200
@@ -136,7 +136,7 @@
 
   void set_card_table(G1SATBCardTableLoggingModRefBS* card_table) { _card_table = card_table; }
 
-  virtual void on_commit(uint start_idx, size_t num_regions);
+  virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
 };
 
 // Adds card-table logging to the post-barrier.