399 } |
399 } |
400 |
400 |
401 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) { |
401 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) { |
402 _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref); |
402 _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref); |
403 oop discovered = java_lang_ref_Reference::discovered(_ref); |
403 oop discovered = java_lang_ref_Reference::discovered(_ref); |
404 assert(_discovered_addr && discovered->is_oop_or_null(), |
404 assert(_discovered_addr && oopDesc::is_oop_or_null(discovered), |
405 "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)); |
405 "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)); |
406 _next = discovered; |
406 _next = discovered; |
407 _referent_addr = java_lang_ref_Reference::referent_addr(_ref); |
407 _referent_addr = java_lang_ref_Reference::referent_addr(_ref); |
408 _referent = java_lang_ref_Reference::referent(_ref); |
408 _referent = java_lang_ref_Reference::referent(_ref); |
409 assert(Universe::heap()->is_in_reserved_or_null(_referent), |
409 assert(Universe::heap()->is_in_reserved_or_null(_referent), |
410 "Wrong oop found in java.lang.Reference object"); |
410 "Wrong oop found in java.lang.Reference object"); |
411 assert(allow_null_referent ? |
411 assert(allow_null_referent ? |
412 _referent->is_oop_or_null() |
412 oopDesc::is_oop_or_null(_referent) |
413 : _referent->is_oop(), |
413 : oopDesc::is_oop(_referent), |
414 "Expected an oop%s for referent field at " PTR_FORMAT, |
414 "Expected an oop%s for referent field at " PTR_FORMAT, |
415 (allow_null_referent ? " or NULL" : ""), |
415 (allow_null_referent ? " or NULL" : ""), |
416 p2i(_referent)); |
416 p2i(_referent)); |
417 } |
417 } |
418 |
418 |
419 void DiscoveredListIterator::remove() { |
419 void DiscoveredListIterator::remove() { |
420 assert(_ref->is_oop(), "Dropping a bad reference"); |
420 assert(oopDesc::is_oop(_ref), "Dropping a bad reference"); |
421 oop_store_raw(_discovered_addr, NULL); |
421 oop_store_raw(_discovered_addr, NULL); |
422 |
422 |
423 // First _prev_next ref actually points into DiscoveredList (gross). |
423 // First _prev_next ref actually points into DiscoveredList (gross). |
424 oop new_next; |
424 oop new_next; |
425 if (_next == _ref) { |
425 if (_next == _ref) { |
532 iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); |
532 iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); |
533 HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj()); |
533 HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj()); |
534 oop next = java_lang_ref_Reference::next(iter.obj()); |
534 oop next = java_lang_ref_Reference::next(iter.obj()); |
535 if ((iter.referent() == NULL || iter.is_referent_alive() || |
535 if ((iter.referent() == NULL || iter.is_referent_alive() || |
536 next != NULL)) { |
536 next != NULL)) { |
537 assert(next->is_oop_or_null(), "Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next)); |
537 assert(oopDesc::is_oop_or_null(next), "Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next)); |
538 // Remove Reference object from list |
538 // Remove Reference object from list |
539 iter.remove(); |
539 iter.remove(); |
540 // Trace the cohorts |
540 // Trace the cohorts |
541 iter.make_referent_alive(); |
541 iter.make_referent_alive(); |
542 if (UseCompressedOops) { |
542 if (UseCompressedOops) { |
580 // keep the referent around |
580 // keep the referent around |
581 iter.make_referent_alive(); |
581 iter.make_referent_alive(); |
582 } |
582 } |
583 log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", |
583 log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", |
584 clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name()); |
584 clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name()); |
585 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference"); |
585 assert(oopDesc::is_oop(iter.obj(), UseConcMarkSweepGC), "Adding a bad reference"); |
586 iter.next(); |
586 iter.next(); |
587 } |
587 } |
588 // Close the reachable set |
588 // Close the reachable set |
589 complete_gc->do_void(); |
589 complete_gc->do_void(); |
590 } |
590 } |
977 // to observe j.l.References with NULL referents, being those |
977 // to observe j.l.References with NULL referents, being those |
978 // cleared concurrently by mutators during (or after) discovery. |
978 // cleared concurrently by mutators during (or after) discovery. |
979 void ReferenceProcessor::verify_referent(oop obj) { |
979 void ReferenceProcessor::verify_referent(oop obj) { |
980 bool da = discovery_is_atomic(); |
980 bool da = discovery_is_atomic(); |
981 oop referent = java_lang_ref_Reference::referent(obj); |
981 oop referent = java_lang_ref_Reference::referent(obj); |
982 assert(da ? referent->is_oop() : referent->is_oop_or_null(), |
982 assert(da ? oopDesc::is_oop(referent) : oopDesc::is_oop_or_null(referent), |
983 "Bad referent " INTPTR_FORMAT " found in Reference " |
983 "Bad referent " INTPTR_FORMAT " found in Reference " |
984 INTPTR_FORMAT " during %satomic discovery ", |
984 INTPTR_FORMAT " during %satomic discovery ", |
985 p2i(referent), p2i(obj), da ? "" : "non-"); |
985 p2i(referent), p2i(obj), da ? "" : "non-"); |
986 } |
986 } |
987 #endif |
987 #endif |
1055 |
1055 |
1056 ResourceMark rm; // Needed for tracing. |
1056 ResourceMark rm; // Needed for tracing. |
1057 |
1057 |
1058 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj); |
1058 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj); |
1059 const oop discovered = java_lang_ref_Reference::discovered(obj); |
1059 const oop discovered = java_lang_ref_Reference::discovered(obj); |
1060 assert(discovered->is_oop_or_null(), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)); |
1060 assert(oopDesc::is_oop_or_null(discovered), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)); |
1061 if (discovered != NULL) { |
1061 if (discovered != NULL) { |
1062 // The reference has already been discovered... |
1062 // The reference has already been discovered... |
1063 log_develop_trace(gc, ref)("Already discovered reference (" INTPTR_FORMAT ": %s)", |
1063 log_develop_trace(gc, ref)("Already discovered reference (" INTPTR_FORMAT ": %s)", |
1064 p2i(obj), obj->klass()->internal_name()); |
1064 p2i(obj), obj->klass()->internal_name()); |
1065 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { |
1065 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { |
1116 list->set_head(obj); |
1116 list->set_head(obj); |
1117 list->inc_length(1); |
1117 list->inc_length(1); |
1118 |
1118 |
1119 log_develop_trace(gc, ref)("Discovered reference (" INTPTR_FORMAT ": %s)", p2i(obj), obj->klass()->internal_name()); |
1119 log_develop_trace(gc, ref)("Discovered reference (" INTPTR_FORMAT ": %s)", p2i(obj), obj->klass()->internal_name()); |
1120 } |
1120 } |
1121 assert(obj->is_oop(), "Discovered a bad reference"); |
1121 assert(oopDesc::is_oop(obj), "Discovered a bad reference"); |
1122 verify_referent(obj); |
1122 verify_referent(obj); |
1123 return true; |
1123 return true; |
1124 } |
1124 } |
1125 |
1125 |
1126 bool ReferenceProcessor::has_discovered_references() { |
1126 bool ReferenceProcessor::has_discovered_references() { |