365 obj = next_d; |
365 obj = next_d; |
366 assert(obj->is_instanceRef(), "should be reference object"); |
366 assert(obj->is_instanceRef(), "should be reference object"); |
367 next_d = java_lang_ref_Reference::discovered(obj); |
367 next_d = java_lang_ref_Reference::discovered(obj); |
368 if (TraceReferenceGC && PrintGCDetails) { |
368 if (TraceReferenceGC && PrintGCDetails) { |
369 gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, |
369 gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, |
370 obj, next_d); |
370 (void *)obj, (void *)next_d); |
371 } |
371 } |
372 assert(java_lang_ref_Reference::next(obj) == NULL, |
372 assert(java_lang_ref_Reference::next(obj) == NULL, |
373 "Reference not active; should not be discovered"); |
373 "Reference not active; should not be discovered"); |
374 // Self-loop next, so as to make Ref not active. |
374 // Self-loop next, so as to make Ref not active. |
375 java_lang_ref_Reference::set_next(obj, obj); |
375 java_lang_ref_Reference::set_next(obj, obj); |
390 obj = next_d; |
390 obj = next_d; |
391 assert(obj->is_instanceRef(), "should be reference object"); |
391 assert(obj->is_instanceRef(), "should be reference object"); |
392 next_d = java_lang_ref_Reference::discovered(obj); |
392 next_d = java_lang_ref_Reference::discovered(obj); |
393 if (TraceReferenceGC && PrintGCDetails) { |
393 if (TraceReferenceGC && PrintGCDetails) { |
394 gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, |
394 gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, |
395 obj, next_d); |
395 (void *)obj, (void *)next_d); |
396 } |
396 } |
397 assert(java_lang_ref_Reference::next(obj) == NULL, |
397 assert(java_lang_ref_Reference::next(obj) == NULL, |
398 "The reference should not be enqueued"); |
398 "The reference should not be enqueued"); |
399 if (next_d == obj) { // obj is last |
399 if (next_d == obj) { // obj is last |
400 // Swap refs_list into pendling_list_addr and |
400 // Swap refs_list into pendling_list_addr and |
560 bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive(); |
560 bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive(); |
561 if (referent_is_dead && |
561 if (referent_is_dead && |
562 !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) { |
562 !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) { |
563 if (TraceReferenceGC) { |
563 if (TraceReferenceGC) { |
564 gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy", |
564 gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy", |
565 iter.obj(), iter.obj()->klass()->internal_name()); |
565 (void *)iter.obj(), iter.obj()->klass()->internal_name()); |
566 } |
566 } |
567 // Remove Reference object from list |
567 // Remove Reference object from list |
568 iter.remove(); |
568 iter.remove(); |
569 // Make the Reference object active again |
569 // Make the Reference object active again |
570 iter.make_active(); |
570 iter.make_active(); |
599 DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());) |
599 DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());) |
600 assert(next == NULL, "Should not discover inactive Reference"); |
600 assert(next == NULL, "Should not discover inactive Reference"); |
601 if (iter.is_referent_alive()) { |
601 if (iter.is_referent_alive()) { |
602 if (TraceReferenceGC) { |
602 if (TraceReferenceGC) { |
603 gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)", |
603 gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)", |
604 iter.obj(), iter.obj()->klass()->internal_name()); |
604 (void *)iter.obj(), iter.obj()->klass()->internal_name()); |
605 } |
605 } |
606 // The referent is reachable after all. |
606 // The referent is reachable after all. |
607 // Remove Reference object from list. |
607 // Remove Reference object from list. |
608 iter.remove(); |
608 iter.remove(); |
609 // Update the referent pointer as necessary: Note that this |
609 // Update the referent pointer as necessary: Note that this |
685 iter.make_referent_alive(); |
685 iter.make_referent_alive(); |
686 } |
686 } |
687 if (TraceReferenceGC) { |
687 if (TraceReferenceGC) { |
688 gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", |
688 gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", |
689 clear_referent ? "cleared " : "", |
689 clear_referent ? "cleared " : "", |
690 iter.obj(), iter.obj()->klass()->internal_name()); |
690 (void *)iter.obj(), iter.obj()->klass()->internal_name()); |
691 } |
691 } |
692 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference"); |
692 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference"); |
693 iter.next(); |
693 iter.next(); |
694 } |
694 } |
695 // Remember to update the next pointer of the last ref. |
695 // Remember to update the next pointer of the last ref. |
1001 debug_only( |
1001 debug_only( |
1002 if (PrintGCDetails && TraceReferenceGC) { |
1002 if (PrintGCDetails && TraceReferenceGC) { |
1003 gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: " |
1003 gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: " |
1004 INTPTR_FORMAT " with next field: " INTPTR_FORMAT |
1004 INTPTR_FORMAT " with next field: " INTPTR_FORMAT |
1005 " and referent: " INTPTR_FORMAT, |
1005 " and referent: " INTPTR_FORMAT, |
1006 iter.obj(), next, iter.referent()); |
1006 (void *)iter.obj(), (void *)next, (void *)iter.referent()); |
1007 } |
1007 } |
1008 ) |
1008 ) |
1009 // Remove Reference object from list |
1009 // Remove Reference object from list |
1010 iter.remove(); |
1010 iter.remove(); |
1011 iter.move_to_next(); |
1011 iter.move_to_next(); |
1101 _bs->write_ref_field((void*)discovered_addr, next_discovered); |
1101 _bs->write_ref_field((void*)discovered_addr, next_discovered); |
1102 } |
1102 } |
1103 |
1103 |
1104 if (TraceReferenceGC) { |
1104 if (TraceReferenceGC) { |
1105 gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)", |
1105 gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)", |
1106 obj, obj->klass()->internal_name()); |
1106 (void *)obj, obj->klass()->internal_name()); |
1107 } |
1107 } |
1108 } else { |
1108 } else { |
1109 // If retest was non NULL, another thread beat us to it: |
1109 // If retest was non NULL, another thread beat us to it: |
1110 // The reference has already been discovered... |
1110 // The reference has already been discovered... |
1111 if (TraceReferenceGC) { |
1111 if (TraceReferenceGC) { |
1112 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", |
1112 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", |
1113 obj, obj->klass()->internal_name()); |
1113 (void *)obj, obj->klass()->internal_name()); |
1114 } |
1114 } |
1115 } |
1115 } |
1116 } |
1116 } |
1117 |
1117 |
1118 #ifndef PRODUCT |
1118 #ifndef PRODUCT |
1123 bool da = discovery_is_atomic(); |
1123 bool da = discovery_is_atomic(); |
1124 oop referent = java_lang_ref_Reference::referent(obj); |
1124 oop referent = java_lang_ref_Reference::referent(obj); |
1125 assert(da ? referent->is_oop() : referent->is_oop_or_null(), |
1125 assert(da ? referent->is_oop() : referent->is_oop_or_null(), |
1126 err_msg("Bad referent " INTPTR_FORMAT " found in Reference " |
1126 err_msg("Bad referent " INTPTR_FORMAT " found in Reference " |
1127 INTPTR_FORMAT " during %satomic discovery ", |
1127 INTPTR_FORMAT " during %satomic discovery ", |
1128 (intptr_t)referent, (intptr_t)obj, da ? "" : "non-")); |
1128 (void *)referent, (void *)obj, da ? "" : "non-")); |
1129 } |
1129 } |
1130 #endif |
1130 #endif |
1131 |
1131 |
1132 // We mention two of several possible choices here: |
1132 // We mention two of several possible choices here: |
1133 // #0: if the reference object is not in the "originating generation" |
1133 // #0: if the reference object is not in the "originating generation" |
1203 assert(discovered->is_oop_or_null(), "bad discovered field"); |
1203 assert(discovered->is_oop_or_null(), "bad discovered field"); |
1204 if (discovered != NULL) { |
1204 if (discovered != NULL) { |
1205 // The reference has already been discovered... |
1205 // The reference has already been discovered... |
1206 if (TraceReferenceGC) { |
1206 if (TraceReferenceGC) { |
1207 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", |
1207 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", |
1208 obj, obj->klass()->internal_name()); |
1208 (void *)obj, obj->klass()->internal_name()); |
1209 } |
1209 } |
1210 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { |
1210 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { |
1211 // assumes that an object is not processed twice; |
1211 // assumes that an object is not processed twice; |
1212 // if it's been already discovered it must be on another |
1212 // if it's been already discovered it must be on another |
1213 // generation's discovered list; so we won't discover it. |
1213 // generation's discovered list; so we won't discover it. |
1271 list->set_head(obj); |
1271 list->set_head(obj); |
1272 list->inc_length(1); |
1272 list->inc_length(1); |
1273 |
1273 |
1274 if (TraceReferenceGC) { |
1274 if (TraceReferenceGC) { |
1275 gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)", |
1275 gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)", |
1276 obj, obj->klass()->internal_name()); |
1276 (void *)obj, obj->klass()->internal_name()); |
1277 } |
1277 } |
1278 } |
1278 } |
1279 assert(obj->is_oop(), "Discovered a bad reference"); |
1279 assert(obj->is_oop(), "Discovered a bad reference"); |
1280 verify_referent(obj); |
1280 verify_referent(obj); |
1281 return true; |
1281 return true; |
1370 next != NULL) { |
1370 next != NULL) { |
1371 // The referent has been cleared, or is alive, or the Reference is not |
1371 // The referent has been cleared, or is alive, or the Reference is not |
1372 // active; we need to trace and mark its cohort. |
1372 // active; we need to trace and mark its cohort. |
1373 if (TraceReferenceGC) { |
1373 if (TraceReferenceGC) { |
1374 gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)", |
1374 gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)", |
1375 iter.obj(), iter.obj()->klass()->internal_name()); |
1375 (void *)iter.obj(), iter.obj()->klass()->internal_name()); |
1376 } |
1376 } |
1377 // Remove Reference object from list |
1377 // Remove Reference object from list |
1378 iter.remove(); |
1378 iter.remove(); |
1379 // Keep alive its cohort. |
1379 // Keep alive its cohort. |
1380 iter.make_referent_alive(); |
1380 iter.make_referent_alive(); |