Mercurial > hg > truffle
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 |