8155917: Memory access in free regions during G1 full gc causes regressions in SPECjvm2008 scimark.fft,lu,sor,sparse with 9+116 on Linux-x64
authortschatzl
Tue, 30 Aug 2016 09:17:49 +0200
changeset 40888 f09b053be364
parent 40887 8d35e19f5548
child 40890 6ac37e8b717a
8155917: Memory access in free regions during G1 full gc causes regressions in SPECjvm2008 scimark.fft,lu,sor,sparse with 9+116 on Linux-x64 Summary: Do not unnecessarily touch the memory of free regions during the compaction phase in G1 full gc causing some OSes to allocate physical memory for them, decreasing performance in some situations. Reviewed-by: mgerdin, jmasa
hotspot/src/share/vm/gc/shared/space.inline.hpp
--- a/hotspot/src/share/vm/gc/shared/space.inline.hpp	Mon Aug 29 20:13:45 2016 -0400
+++ b/hotspot/src/share/vm/gc/shared/space.inline.hpp	Tue Aug 30 09:17:49 2016 +0200
@@ -293,10 +293,11 @@
 
   verify_up_to_first_dead(space);
 
+  HeapWord* const bottom = space->bottom();
   HeapWord* const end_of_live = space->_end_of_live;
 
   assert(space->_first_dead <= end_of_live, "Invariant. _first_dead: " PTR_FORMAT " <= end_of_live: " PTR_FORMAT, p2i(space->_first_dead), p2i(end_of_live));
-  if (space->_first_dead == end_of_live && !oop(space->bottom())->is_gc_marked()) {
+  if (space->_first_dead == end_of_live && (bottom == end_of_live || !oop(bottom)->is_gc_marked())) {
     // Nothing to compact. The space is either empty or all live object should be left in place.
     clear_empty_region(space);
     return;
@@ -305,8 +306,8 @@
   const intx scan_interval = PrefetchScanIntervalInBytes;
   const intx copy_interval = PrefetchCopyIntervalInBytes;
 
-  assert(space->bottom() < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(space->bottom()), p2i(end_of_live));
-  HeapWord* cur_obj = space->bottom();
+  assert(bottom < end_of_live, "bottom: " PTR_FORMAT " should be < end_of_live: " PTR_FORMAT, p2i(bottom), p2i(end_of_live));
+  HeapWord* cur_obj = bottom;
   if (space->_first_dead > cur_obj && !oop(cur_obj)->is_gc_marked()) {
     // All object before _first_dead can be skipped. They should not be moved.
     // A pointer to the first live object is stored at the memory location for _first_dead.