提交 546975c0 编写于 作者: Y ysr

7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent

Summary: Relaxed the assert by allowing NULL referents when discovery may be concurrent.
Reviewed-by: johnc, jcoomes
上级 8be7836d
......@@ -2060,7 +2060,6 @@ void G1CollectedHeap::ref_processing_init() {
_ref_processor = ReferenceProcessor::create_ref_processor(
mr, // span
false, // Reference discovery is not atomic
// (though it shouldn't matter here.)
true, // mt_discovery
NULL, // is alive closure: need to fill this in for efficiency
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:
// #0: if the reference object is not in the "originating generation"
// (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
// reachable.
if (is_alive_non_header() != NULL) {
oop referent = java_lang_ref_Reference::referent(obj);
// In the case of non-concurrent discovery, the last
// 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)) {
verify_referent(obj);
if (is_alive_non_header()->do_object_b(java_lang_ref_Reference::referent(obj))) {
return false; // referent is reachable
}
}
......@@ -1247,13 +1255,13 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
}
if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
oop referent = java_lang_ref_Reference::referent(obj);
assert(referent->is_oop(), "bad referent");
verify_referent(obj);
// enqueue if and only if either:
// reference is in our span or
// we are an atomic collector and referent is in our span
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;
} else {
return false;
......@@ -1301,7 +1309,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
}
}
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;
}
......
......@@ -345,6 +345,7 @@ class ReferenceProcessor : public CHeapObj {
// debugging
void verify_no_references_recorded() PRODUCT_RETURN;
void verify_referent(oop obj) PRODUCT_RETURN;
static void verify();
// clear the discovered lists (unlinking each entry).
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册