We have seen crashes with G1 during concurrent root region scan.
It turned out that the reason for the crashes was reloading an oop after a null check.
The compiler may legally do this, as the pointer is not declared as volatile.
The code runs concurrently to mutator threads.
template <class T>
inline void G1RootRegionScanClosure::do_oop_nv(T* p) {
T heap_oop = oopDesc::load_heap_oop(p); // 1. load
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); // 2. Compiler decides to reload
HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
_cm->grayRoot(obj, obj->size(), _worker_id, hr);
}
}
We have seen the problem on AIX with the xlC compiler. However, we have seen similar optimizations on other platforms.
As this code pattern is used quite often throughout the whole jvm, I would suggest a global fix in oopDesc::load_heap_oop(p).
It turned out that the reason for the crashes was reloading an oop after a null check.
The compiler may legally do this, as the pointer is not declared as volatile.
The code runs concurrently to mutator threads.
template <class T>
inline void G1RootRegionScanClosure::do_oop_nv(T* p) {
T heap_oop = oopDesc::load_heap_oop(p); // 1. load
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); // 2. Compiler decides to reload
HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
_cm->grayRoot(obj, obj->size(), _worker_id, hr);
}
}
We have seen the problem on AIX with the xlC compiler. However, we have seen similar optimizations on other platforms.
As this code pattern is used quite often throughout the whole jvm, I would suggest a global fix in oopDesc::load_heap_oop(p).
- is blocked by
-
JDK-8193063 Enabling narrowOop values for RawAccess accesses
-
- Resolved
-