7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
Relaxed the assert by allowing NULL referents when discovery may be concurrent. Reviewed-by: johnc, jcoomes
This commit is contained in:
parent
544b475fc5
commit
8baafdfd45
@ -2060,7 +2060,6 @@ void G1CollectedHeap::ref_processing_init() {
|
|||||||
_ref_processor = ReferenceProcessor::create_ref_processor(
|
_ref_processor = ReferenceProcessor::create_ref_processor(
|
||||||
mr, // span
|
mr, // span
|
||||||
false, // Reference discovery is not atomic
|
false, // Reference discovery is not atomic
|
||||||
// (though it shouldn't matter here.)
|
|
||||||
true, // mt_discovery
|
true, // mt_discovery
|
||||||
NULL, // is alive closure: need to fill this in for efficiency
|
NULL, // is alive closure: need to fill this in for efficiency
|
||||||
ParallelGCThreads,
|
ParallelGCThreads,
|
||||||
|
@ -1146,6 +1146,20 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
// Non-atomic (i.e. concurrent) discovery might allow us
|
||||||
|
// to observe j.l.References with NULL referents, being those
|
||||||
|
// cleared concurrently by mutators during (or after) discovery.
|
||||||
|
void ReferenceProcessor::verify_referent(oop obj) {
|
||||||
|
bool da = discovery_is_atomic();
|
||||||
|
oop referent = java_lang_ref_Reference::referent(obj);
|
||||||
|
assert(da ? referent->is_oop() : referent->is_oop_or_null(),
|
||||||
|
err_msg("Bad referent " INTPTR_FORMAT " found in Reference "
|
||||||
|
INTPTR_FORMAT " during %satomic discovery ",
|
||||||
|
(intptr_t)referent, (intptr_t)obj, da ? "" : "non-"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// We mention two of several possible choices here:
|
// We mention two of several possible choices here:
|
||||||
// #0: if the reference object is not in the "originating generation"
|
// #0: if the reference object is not in the "originating generation"
|
||||||
// (or part of the heap being collected, indicated by our "span"
|
// (or part of the heap being collected, indicated by our "span"
|
||||||
@ -1196,14 +1210,8 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
|||||||
// We only enqueue references whose referents are not (yet) strongly
|
// We only enqueue references whose referents are not (yet) strongly
|
||||||
// reachable.
|
// reachable.
|
||||||
if (is_alive_non_header() != NULL) {
|
if (is_alive_non_header() != NULL) {
|
||||||
oop referent = java_lang_ref_Reference::referent(obj);
|
verify_referent(obj);
|
||||||
// In the case of non-concurrent discovery, the last
|
if (is_alive_non_header()->do_object_b(java_lang_ref_Reference::referent(obj))) {
|
||||||
// disjunct below should hold. It may not hold in the
|
|
||||||
// case of concurrent discovery because mutators may
|
|
||||||
// concurrently clear() a Reference.
|
|
||||||
assert(UseConcMarkSweepGC || UseG1GC || referent != NULL,
|
|
||||||
"Refs with null referents already filtered");
|
|
||||||
if (is_alive_non_header()->do_object_b(referent)) {
|
|
||||||
return false; // referent is reachable
|
return false; // referent is reachable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1247,13 +1255,13 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
|
if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
|
||||||
oop referent = java_lang_ref_Reference::referent(obj);
|
verify_referent(obj);
|
||||||
assert(referent->is_oop(), "bad referent");
|
|
||||||
// enqueue if and only if either:
|
// enqueue if and only if either:
|
||||||
// reference is in our span or
|
// reference is in our span or
|
||||||
// we are an atomic collector and referent is in our span
|
// we are an atomic collector and referent is in our span
|
||||||
if (_span.contains(obj_addr) ||
|
if (_span.contains(obj_addr) ||
|
||||||
(discovery_is_atomic() && _span.contains(referent))) {
|
(discovery_is_atomic() &&
|
||||||
|
_span.contains(java_lang_ref_Reference::referent(obj)))) {
|
||||||
// should_enqueue = true;
|
// should_enqueue = true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -1301,7 +1309,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(obj->is_oop(), "Enqueued a bad reference");
|
assert(obj->is_oop(), "Enqueued a bad reference");
|
||||||
assert(java_lang_ref_Reference::referent(obj)->is_oop(), "Enqueued a bad referent");
|
verify_referent(obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +345,7 @@ class ReferenceProcessor : public CHeapObj {
|
|||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
void verify_no_references_recorded() PRODUCT_RETURN;
|
void verify_no_references_recorded() PRODUCT_RETURN;
|
||||||
|
void verify_referent(oop obj) PRODUCT_RETURN;
|
||||||
static void verify();
|
static void verify();
|
||||||
|
|
||||||
// clear the discovered lists (unlinking each entry).
|
// clear the discovered lists (unlinking each entry).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user