提交 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() { ...@@ -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, ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 { ...@@ -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).
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册