8213142: Use RAII to set the scanning source in G1ScanEvacuatedObjClosure

Reviewed-by: sangheki, kbarrett
This commit is contained in:
Thomas Schatzl 2018-10-31 13:43:57 +01:00
parent 28c9f22ebb
commit 4da555c7a8
4 changed files with 32 additions and 8 deletions

View File

@ -36,6 +36,7 @@ class G1ConcurrentMark;
class DirtyCardToOopClosure;
class G1CMBitMap;
class G1ParScanThreadState;
class G1ScanEvacuatedObjClosure;
class G1CMTask;
class ReferenceProcessor;
@ -82,15 +83,22 @@ public:
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 @@ public:
}
};
// 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:

View File

@ -84,7 +84,8 @@ inline void G1ScanEvacuatedObjClosure::do_oop_work(T* p) {
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);

View File

@ -311,7 +311,7 @@ oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state,
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 @@ oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markOop m) {
_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;

View File

@ -114,7 +114,7 @@ inline void G1ParScanThreadState::do_oop_partial_array(oop* p) {
}
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