8162928: Micro-optimizations in scanning the remembered sets
authortschatzl
Fri, 02 Jun 2017 13:45:21 +0200
changeset 46518 69f8479862a2
parent 46517 14de3e5151a9
child 46519 40c9c132f961
8162928: Micro-optimizations in scanning the remembered sets Reviewed-by: ehelin, kbarrett
hotspot/src/share/vm/gc/g1/g1RemSet.cpp
hotspot/src/share/vm/gc/g1/g1RemSet.hpp
hotspot/src/share/vm/gc/g1/heapRegion.cpp
hotspot/src/share/vm/gc/g1/heapRegion.hpp
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Fri Jun 02 13:45:15 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Fri Jun 02 13:45:21 2017 +0200
@@ -305,13 +305,8 @@
   _block_size = MAX2<size_t>(G1RSetScanBlockSize, 1);
 }
 
-void G1ScanRSClosure::scan_card(size_t index, HeapRegion *r) {
-  // Stack allocate the DirtyCardToOopClosure instance
-  HeapRegionDCTOC cl(_g1h, r, _push_heap_cl, CardTableModRefBS::Precise);
-
-  // Set the "from" region in the closure.
-  _push_heap_cl->set_region(r);
-  MemRegion card_region(_bot->address_for_index(index), BOTConstants::N_words);
+void G1ScanRSClosure::scan_card(size_t index, HeapWord* card_start, HeapRegion *r) {
+  MemRegion card_region(card_start, BOTConstants::N_words);
   MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
   MemRegion mr = pre_gc_allocated.intersection(card_region);
   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
@@ -319,8 +314,9 @@
     // but they're benign), which reduces the number of duplicate
     // scans (the rsets of the regions in the cset can intersect).
     _ct_bs->set_card_claimed(index);
+    _push_heap_cl->set_region(r);
+    r->oops_on_card_seq_iterate_careful<true>(mr, _push_heap_cl);
     _cards_done++;
-    cl.do_MemRegion(mr);
   }
 }
 
@@ -367,7 +363,7 @@
     // If the card is dirty, then we will scan it during updateRS.
     if (!card_region->in_collection_set() &&
         !_ct_bs->is_card_dirty(card_index)) {
-      scan_card(card_index, card_region);
+      scan_card(card_index, card_start, card_region);
     }
   }
   if (_scan_state->set_iter_complete(region_idx)) {
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Fri Jun 02 13:45:15 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Fri Jun 02 13:45:21 2017 +0200
@@ -197,7 +197,7 @@
   uint   _worker_i;
   size_t _block_size;
 
-  void scan_card(size_t index, HeapRegion *r);
+  void scan_card(size_t index, HeapWord* card_start, HeapRegion *r);
   void scan_strong_code_roots(HeapRegion* r);
 public:
   G1ScanRSClosure(G1RemSetScanState* scan_state,
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Fri Jun 02 13:45:15 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Fri Jun 02 13:45:21 2017 +0200
@@ -48,56 +48,6 @@
 size_t HeapRegion::GrainWords        = 0;
 size_t HeapRegion::CardsPerRegion    = 0;
 
-HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1,
-                                 HeapRegion* hr,
-                                 G1ParPushHeapRSClosure* cl,
-                                 CardTableModRefBS::PrecisionStyle precision) :
-  DirtyCardToOopClosure(hr, cl, precision, NULL),
-  _hr(hr), _rs_scan(cl), _g1(g1) { }
-
-void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
-                                      HeapWord* bottom,
-                                      HeapWord* top) {
-  G1CollectedHeap* g1h = _g1;
-  size_t oop_size;
-  HeapWord* cur = bottom;
-
-  // Start filtering what we add to the remembered set. If the object is
-  // not considered dead, either because it is marked (in the mark bitmap)
-  // or it was allocated after marking finished, then we add it. Otherwise
-  // we can safely ignore the object.
-  if (!g1h->is_obj_dead(oop(cur))) {
-    oop_size = oop(cur)->oop_iterate_size(_rs_scan, mr);
-  } else {
-    oop_size = _hr->block_size(cur);
-  }
-
-  cur += oop_size;
-
-  if (cur < top) {
-    oop cur_oop = oop(cur);
-    oop_size = _hr->block_size(cur);
-    HeapWord* next_obj = cur + oop_size;
-    while (next_obj < top) {
-      // Keep filtering the remembered set.
-      if (!g1h->is_obj_dead(cur_oop)) {
-        // Bottom lies entirely below top, so we can call the
-        // non-memRegion version of oop_iterate below.
-        cur_oop->oop_iterate(_rs_scan);
-      }
-      cur = next_obj;
-      cur_oop = oop(cur);
-      oop_size = _hr->block_size(cur);
-      next_obj = cur + oop_size;
-    }
-
-    // Last object. Need to do dead-obj filtering here too.
-    if (!g1h->is_obj_dead(oop(cur))) {
-      oop(cur)->oop_iterate(_rs_scan, mr);
-    }
-  }
-}
-
 size_t HeapRegion::max_region_size() {
   return HeapRegionBounds::max_size();
 }
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Fri Jun 02 13:45:15 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Fri Jun 02 13:45:21 2017 +0200
@@ -72,32 +72,6 @@
 // sentinel value for hrm_index
 #define G1_NO_HRM_INDEX ((uint) -1)
 
-// A dirty card to oop closure for heap regions. It
-// knows how to get the G1 heap and how to use the bitmap
-// in the concurrent marker used by G1 to filter remembered
-// sets.
-
-class HeapRegionDCTOC : public DirtyCardToOopClosure {
-private:
-  HeapRegion* _hr;
-  G1ParPushHeapRSClosure* _rs_scan;
-  G1CollectedHeap* _g1;
-
-  // Walk the given memory region from bottom to (actual) top
-  // looking for objects and applying the oop closure (_cl) to
-  // them. The base implementation of this treats the area as
-  // blocks, where a block may or may not be an object. Sub-
-  // classes should override this to provide more accurate
-  // or possibly more efficient walking.
-  void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top);
-
-public:
-  HeapRegionDCTOC(G1CollectedHeap* g1,
-                  HeapRegion* hr,
-                  G1ParPushHeapRSClosure* cl,
-                  CardTableModRefBS::PrecisionStyle precision);
-};
-
 // The complicating factor is that BlockOffsetTable diverged
 // significantly, and we need functionality that is only in the G1 version.
 // So I copied that code, which led to an alternate G1 version of