--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp Wed Apr 11 11:37:19 2018 +0200
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp Wed Apr 11 11:41:30 2018 +0200
@@ -30,14 +30,15 @@
#include "oops/access.inline.hpp"
#include "oops/oop.inline.hpp"
-template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from) {
+template <class T> void G1ParScanThreadState::do_oop_evac(T* p) {
// Reference should not be NULL here as such are never pushed to the task queue.
oop obj = RawAccess<OOP_NOT_NULL>::oop_load(p);
// Although we never intentionally push references outside of the collection
// set, due to (benign) races in the claim mechanism during RSet scanning more
// than one thread might claim the same card. So the same card may be
- // processed multiple times. So redo this check.
+ // processed multiple times, and so we might get references into old gen here.
+ // So we need to redo this check.
const InCSetState in_cset_state = _g1h->in_cset_state(obj);
if (in_cset_state.is_in_cset()) {
markOop m = obj->mark_raw();
@@ -46,16 +47,17 @@
} else {
obj = copy_to_survivor_space(in_cset_state, obj, m);
}
- RawAccess<>::oop_store(p, obj);
+ RawAccess<OOP_NOT_NULL>::oop_store(p, obj);
} else if (in_cset_state.is_humongous()) {
_g1h->set_humongous_is_live(obj);
} else {
assert(in_cset_state.is_default(),
- "In_cset_state must be NotInCSet here, but is " CSETSTATE_FORMAT, in_cset_state.value());
+ "In_cset_state must be NotInCSet here, but is " CSETSTATE_FORMAT, in_cset_state.value());
}
assert(obj != NULL, "Must be");
if (!HeapRegion::is_in_same_region(p, obj)) {
+ HeapRegion* from = _g1h->heap_region_containing(p);
update_rs(from, p, obj);
}
}
@@ -114,15 +116,19 @@
to_obj_array->oop_iterate_range(&_scanner, start, end);
}
-template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) {
+inline void G1ParScanThreadState::deal_with_reference(oop* ref_to_scan) {
if (!has_partial_array_mask(ref_to_scan)) {
- HeapRegion* r = _g1h->heap_region_containing(ref_to_scan);
- do_oop_evac(ref_to_scan, r);
+ do_oop_evac(ref_to_scan);
} else {
- do_oop_partial_array((oop*)ref_to_scan);
+ do_oop_partial_array(ref_to_scan);
}
}
+inline void G1ParScanThreadState::deal_with_reference(narrowOop* ref_to_scan) {
+ assert(!has_partial_array_mask(ref_to_scan), "NarrowOop* elements should never be partial arrays.");
+ do_oop_evac(ref_to_scan);
+}
+
inline void G1ParScanThreadState::dispatch_reference(StarTask ref) {
assert(verify_task(ref), "sanity");
if (ref.is_narrow()) {