comparison src/share/vm/memory/referenceProcessor.cpp @ 1995:8df09fb45352

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
author ysr
date Thu, 09 Dec 2010 09:22:57 -0800
parents fd1d227ef1b9
children 92da084fefc9
comparison
equal deleted inserted replaced
1994:6cd6d394f280 1995:8df09fb45352
1144 obj, obj->blueprint()->internal_name()); 1144 obj, obj->blueprint()->internal_name());
1145 } 1145 }
1146 } 1146 }
1147 } 1147 }
1148 1148
1149 #ifndef PRODUCT
1150 // Non-atomic (i.e. concurrent) discovery might allow us
1151 // to observe j.l.References with NULL referents, being those
1152 // cleared concurrently by mutators during (or after) discovery.
1153 void ReferenceProcessor::verify_referent(oop obj) {
1154 bool da = discovery_is_atomic();
1155 oop referent = java_lang_ref_Reference::referent(obj);
1156 assert(da ? referent->is_oop() : referent->is_oop_or_null(),
1157 err_msg("Bad referent " INTPTR_FORMAT " found in Reference "
1158 INTPTR_FORMAT " during %satomic discovery ",
1159 (intptr_t)referent, (intptr_t)obj, da ? "" : "non-"));
1160 }
1161 #endif
1162
1149 // We mention two of several possible choices here: 1163 // We mention two of several possible choices here:
1150 // #0: if the reference object is not in the "originating generation" 1164 // #0: if the reference object is not in the "originating generation"
1151 // (or part of the heap being collected, indicated by our "span" 1165 // (or part of the heap being collected, indicated by our "span"
1152 // we don't treat it specially (i.e. we scan it as we would 1166 // we don't treat it specially (i.e. we scan it as we would
1153 // a normal oop, treating its references as strong references). 1167 // a normal oop, treating its references as strong references).
1194 } 1208 }
1195 1209
1196 // We only enqueue references whose referents are not (yet) strongly 1210 // We only enqueue references whose referents are not (yet) strongly
1197 // reachable. 1211 // reachable.
1198 if (is_alive_non_header() != NULL) { 1212 if (is_alive_non_header() != NULL) {
1199 oop referent = java_lang_ref_Reference::referent(obj); 1213 verify_referent(obj);
1200 // In the case of non-concurrent discovery, the last 1214 if (is_alive_non_header()->do_object_b(java_lang_ref_Reference::referent(obj))) {
1201 // disjunct below should hold. It may not hold in the
1202 // case of concurrent discovery because mutators may
1203 // concurrently clear() a Reference.
1204 assert(UseConcMarkSweepGC || UseG1GC || referent != NULL,
1205 "Refs with null referents already filtered");
1206 if (is_alive_non_header()->do_object_b(referent)) {
1207 return false; // referent is reachable 1215 return false; // referent is reachable
1208 } 1216 }
1209 } 1217 }
1210 if (rt == REF_SOFT) { 1218 if (rt == REF_SOFT) {
1211 // For soft refs we can decide now if these are not 1219 // For soft refs we can decide now if these are not
1245 return true; 1253 return true;
1246 } 1254 }
1247 } 1255 }
1248 1256
1249 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { 1257 if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
1250 oop referent = java_lang_ref_Reference::referent(obj); 1258 verify_referent(obj);
1251 assert(referent->is_oop(), "bad referent");
1252 // enqueue if and only if either: 1259 // enqueue if and only if either:
1253 // reference is in our span or 1260 // reference is in our span or
1254 // we are an atomic collector and referent is in our span 1261 // we are an atomic collector and referent is in our span
1255 if (_span.contains(obj_addr) || 1262 if (_span.contains(obj_addr) ||
1256 (discovery_is_atomic() && _span.contains(referent))) { 1263 (discovery_is_atomic() &&
1264 _span.contains(java_lang_ref_Reference::referent(obj)))) {
1257 // should_enqueue = true; 1265 // should_enqueue = true;
1258 } else { 1266 } else {
1259 return false; 1267 return false;
1260 } 1268 }
1261 } else { 1269 } else {
1299 gclog_or_tty->print_cr("Enqueued reference (" INTPTR_FORMAT ": %s)", 1307 gclog_or_tty->print_cr("Enqueued reference (" INTPTR_FORMAT ": %s)",
1300 obj, obj->blueprint()->internal_name()); 1308 obj, obj->blueprint()->internal_name());
1301 } 1309 }
1302 } 1310 }
1303 assert(obj->is_oop(), "Enqueued a bad reference"); 1311 assert(obj->is_oop(), "Enqueued a bad reference");
1304 assert(java_lang_ref_Reference::referent(obj)->is_oop(), "Enqueued a bad referent"); 1312 verify_referent(obj);
1305 return true; 1313 return true;
1306 } 1314 }
1307 1315
1308 // Preclean the discovered references by removing those 1316 // Preclean the discovered references by removing those
1309 // whose referents are alive, and by marking from those that 1317 // whose referents are alive, and by marking from those that