comparison src/share/vm/memory/referenceProcessor.cpp @ 1974:fd1d227ef1b9

6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent Summary: Enable reference discovery during concurrent marking by setting the reference processor field of the concurrent marking closure. Keep reference objects on the discovered reference lists alive during incremental evacuation pauses until they are processed at the end of concurrent marking. Reviewed-by: ysr, tonyp
author johnc
date Wed, 01 Dec 2010 17:34:02 -0800
parents f95d63e2154a
children 8df09fb45352
comparison
equal deleted inserted replaced
1973:631f79e71e90 1974:fd1d227ef1b9
768 768
769 void ReferenceProcessor::abandon_partial_discovery() { 769 void ReferenceProcessor::abandon_partial_discovery() {
770 // loop over the lists 770 // loop over the lists
771 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { 771 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
772 if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) { 772 if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
773 gclog_or_tty->print_cr( 773 gclog_or_tty->print_cr("\nAbandoning %s discovered list",
774 "\nAbandoning %s discovered list", 774 list_name(i));
775 list_name(i));
776 } 775 }
777 abandon_partial_discovered_list(_discoveredSoftRefs[i]); 776 abandon_partial_discovered_list(_discoveredSoftRefs[i]);
778 } 777 }
779 } 778 }
780 779
1057 // Determine the queue index to use for this object. 1056 // Determine the queue index to use for this object.
1058 if (_discovery_is_mt) { 1057 if (_discovery_is_mt) {
1059 // During a multi-threaded discovery phase, 1058 // During a multi-threaded discovery phase,
1060 // each thread saves to its "own" list. 1059 // each thread saves to its "own" list.
1061 Thread* thr = Thread::current(); 1060 Thread* thr = Thread::current();
1062 assert(thr->is_GC_task_thread(), 1061 id = thr->as_Worker_thread()->id();
1063 "Dubious cast from Thread* to WorkerThread*?");
1064 id = ((WorkerThread*)thr)->id();
1065 } else { 1062 } else {
1066 // single-threaded discovery, we save in round-robin 1063 // single-threaded discovery, we save in round-robin
1067 // fashion to each of the lists. 1064 // fashion to each of the lists.
1068 if (_processing_is_mt) { 1065 if (_processing_is_mt) {
1069 id = next_id(); 1066 id = next_id();
1093 // we should not reach here if we are an instanceRefKlass 1090 // we should not reach here if we are an instanceRefKlass
1094 default: 1091 default:
1095 ShouldNotReachHere(); 1092 ShouldNotReachHere();
1096 } 1093 }
1097 if (TraceReferenceGC && PrintGCDetails) { 1094 if (TraceReferenceGC && PrintGCDetails) {
1098 gclog_or_tty->print_cr("Thread %d gets list " INTPTR_FORMAT, 1095 gclog_or_tty->print_cr("Thread %d gets list " INTPTR_FORMAT, id, list);
1099 id, list);
1100 } 1096 }
1101 return list; 1097 return list;
1102 } 1098 }
1103 1099
1104 inline void 1100 inline void
1132 // is necessary. 1128 // is necessary.
1133 refs_list.set_head(obj); 1129 refs_list.set_head(obj);
1134 refs_list.inc_length(1); 1130 refs_list.inc_length(1);
1135 if (_discovered_list_needs_barrier) { 1131 if (_discovered_list_needs_barrier) {
1136 _bs->write_ref_field((void*)discovered_addr, current_head); 1132 _bs->write_ref_field((void*)discovered_addr, current_head);
1133 }
1134
1135 if (TraceReferenceGC) {
1136 gclog_or_tty->print_cr("Enqueued reference (mt) (" INTPTR_FORMAT ": %s)",
1137 obj, obj->blueprint()->internal_name());
1137 } 1138 }
1138 } else { 1139 } else {
1139 // If retest was non NULL, another thread beat us to it: 1140 // If retest was non NULL, another thread beat us to it:
1140 // The reference has already been discovered... 1141 // The reference has already been discovered...
1141 if (TraceReferenceGC) { 1142 if (TraceReferenceGC) {
1237 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery, 1238 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery,
1238 "Unrecognized policy"); 1239 "Unrecognized policy");
1239 // Check assumption that an object is not potentially 1240 // Check assumption that an object is not potentially
1240 // discovered twice except by concurrent collectors that potentially 1241 // discovered twice except by concurrent collectors that potentially
1241 // trace the same Reference object twice. 1242 // trace the same Reference object twice.
1242 assert(UseConcMarkSweepGC, 1243 assert(UseConcMarkSweepGC || UseG1GC,
1243 "Only possible with an incremental-update concurrent collector"); 1244 "Only possible with a concurrent marking collector");
1244 return true; 1245 return true;
1245 } 1246 }
1246 } 1247 }
1247 1248
1248 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { 1249 if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
1291 if (_discovered_list_needs_barrier) { 1292 if (_discovered_list_needs_barrier) {
1292 _bs->write_ref_field((void*)discovered_addr, current_head); 1293 _bs->write_ref_field((void*)discovered_addr, current_head);
1293 } 1294 }
1294 list->set_head(obj); 1295 list->set_head(obj);
1295 list->inc_length(1); 1296 list->inc_length(1);
1296 } 1297
1297 1298 if (TraceReferenceGC) {
1298 // In the MT discovery case, it is currently possible to see
1299 // the following message multiple times if several threads
1300 // discover a reference about the same time. Only one will
1301 // however have actually added it to the disocvered queue.
1302 // One could let add_to_discovered_list_mt() return an
1303 // indication for success in queueing (by 1 thread) or
1304 // failure (by all other threads), but I decided the extra
1305 // code was not worth the effort for something that is
1306 // only used for debugging support.
1307 if (TraceReferenceGC) {
1308 oop referent = java_lang_ref_Reference::referent(obj);
1309 if (PrintGCDetails) {
1310 gclog_or_tty->print_cr("Enqueued reference (" INTPTR_FORMAT ": %s)", 1299 gclog_or_tty->print_cr("Enqueued reference (" INTPTR_FORMAT ": %s)",
1311 obj, obj->blueprint()->internal_name()); 1300 obj, obj->blueprint()->internal_name());
1312 } 1301 }
1313 assert(referent->is_oop(), "Enqueued a bad referent");
1314 } 1302 }
1315 assert(obj->is_oop(), "Enqueued a bad reference"); 1303 assert(obj->is_oop(), "Enqueued a bad reference");
1304 assert(java_lang_ref_Reference::referent(obj)->is_oop(), "Enqueued a bad referent");
1316 return true; 1305 return true;
1317 } 1306 }
1318 1307
1319 // Preclean the discovered references by removing those 1308 // Preclean the discovered references by removing those
1320 // whose referents are alive, and by marking from those that 1309 // whose referents are alive, and by marking from those that