8213142: Use RAII to set the scanning source in G1ScanEvacuatedObjClosure
authortschatzl
Wed, 31 Oct 2018 13:43:57 +0100
changeset 52349 f34a2e0069c7
parent 52348 21fdf8d9a8b6
child 52350 9e3fd0cc3936
8213142: Use RAII to set the scanning source in G1ScanEvacuatedObjClosure Reviewed-by: sangheki, kbarrett
src/hotspot/share/gc/g1/g1OopClosures.hpp
src/hotspot/share/gc/g1/g1OopClosures.inline.hpp
src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp
--- a/src/hotspot/share/gc/g1/g1OopClosures.hpp	Wed Oct 31 13:43:57 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp	Wed Oct 31 13:43:57 2018 +0100
@@ -36,6 +36,7 @@
 class DirtyCardToOopClosure;
 class G1CMBitMap;
 class G1ParScanThreadState;
+class G1ScanEvacuatedObjClosure;
 class G1CMTask;
 class ReferenceProcessor;
 
@@ -82,15 +83,22 @@
   virtual void do_oop(narrowOop* p)    { do_oop_work(p); }
 };
 
+
 // This closure is applied to the fields of the objects that have just been copied during evacuation.
 class G1ScanEvacuatedObjClosure : public G1ScanClosureBase {
-  bool _scanning_in_young;
+  friend class G1ScanInYoungSetter;
+
+  enum ScanningInYoungValues {
+    False = 0,
+    True,
+    Uninitialized
+  };
+
+  ScanningInYoungValues _scanning_in_young;
 
 public:
   G1ScanEvacuatedObjClosure(G1CollectedHeap* g1h, G1ParScanThreadState* par_scan_state) :
-    G1ScanClosureBase(g1h, par_scan_state), _scanning_in_young(false) { }
-
-  void set_scanning_in_young(bool scanning_in_young) { _scanning_in_young = scanning_in_young; }
+    G1ScanClosureBase(g1h, par_scan_state), _scanning_in_young(Uninitialized) { }
 
   template <class T> void do_oop_work(T* p);
   virtual void do_oop(oop* p)          { do_oop_work(p); }
@@ -104,6 +112,21 @@
   }
 };
 
+// RAII object to properly set the _scanning_in_young field in G1ScanEvacuatedObjClosure.
+class G1ScanInYoungSetter : public StackObj {
+  G1ScanEvacuatedObjClosure* _closure;
+
+public:
+  G1ScanInYoungSetter(G1ScanEvacuatedObjClosure* closure, bool new_value) : _closure(closure) {
+    assert(_closure->_scanning_in_young == G1ScanEvacuatedObjClosure::Uninitialized, "Must not be set");
+    _closure->_scanning_in_young = new_value ? G1ScanEvacuatedObjClosure::True : G1ScanEvacuatedObjClosure::False;
+  }
+
+  ~G1ScanInYoungSetter() {
+    DEBUG_ONLY(_closure->_scanning_in_young = G1ScanEvacuatedObjClosure::Uninitialized;)
+  }
+};
+
 // Add back base class for metadata
 class G1ParCopyHelper : public OopClosure {
 protected:
--- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Wed Oct 31 13:43:57 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Wed Oct 31 13:43:57 2018 +0100
@@ -84,7 +84,8 @@
     prefetch_and_push(p, obj);
   } else if (!HeapRegion::is_in_same_region(p, obj)) {
     handle_non_cset_obj_common(state, p, obj);
-    if (_scanning_in_young) {
+    assert(_scanning_in_young != Uninitialized, "Scan location has not been initialized.");
+    if (_scanning_in_young == True) {
       return;
     }
     _par_scan_state->enqueue_card_if_tracked(p, obj);
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Wed Oct 31 13:43:57 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Wed Oct 31 13:43:57 2018 +0100
@@ -311,7 +311,7 @@
       oop* old_p = set_partial_array_mask(old);
       do_oop_partial_array(old_p);
     } else {
-      _scanner.set_scanning_in_young(dest_state.is_young());
+      G1ScanInYoungSetter x(&_scanner, dest_state.is_young());
       obj->oop_iterate_backwards(&_scanner);
     }
     return obj;
@@ -366,7 +366,7 @@
 
     _g1h->preserve_mark_during_evac_failure(_worker_id, old, m);
 
-    _scanner.set_scanning_in_young(r->is_young());
+    G1ScanInYoungSetter x(&_scanner, r->is_young());
     old->oop_iterate_backwards(&_scanner);
 
     return old;
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Wed Oct 31 13:43:57 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Wed Oct 31 13:43:57 2018 +0100
@@ -114,7 +114,7 @@
   }
 
   HeapRegion* hr = _g1h->heap_region_containing(to_obj);
-  _scanner.set_scanning_in_young(hr->is_young());
+  G1ScanInYoungSetter x(&_scanner, hr->is_young());
   // Process indexes [start,end). It will also process the header
   // along with the first chunk (i.e., the chunk with start == 0).
   // Note that at this point the length field of to_obj_array is not