429 pending_list_addr, _max_num_q);
430 task_executor->execute(tsk);
431 } else {
432 // Serial code: call the parent class's implementation
433 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
434 enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
435 _discovered_refs[i].set_head(NULL);
436 _discovered_refs[i].set_length(0);
437 }
438 }
439 }
440
441 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
442 _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
443 oop discovered = java_lang_ref_Reference::discovered(_ref);
444 assert(_discovered_addr && discovered->is_oop_or_null(),
445 err_msg("Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)));
446 _next = discovered;
447 _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
448 _referent = java_lang_ref_Reference::referent(_ref);
449 assert(Universe::heap()->is_in_reserved_or_null(_referent),
450 "Wrong oop found in java.lang.Reference object");
451 assert(allow_null_referent ?
452 _referent->is_oop_or_null()
453 : _referent->is_oop(),
454 err_msg("Expected an oop%s for referent field at " PTR_FORMAT,
455 (allow_null_referent ? " or NULL" : ""),
456 p2i(_referent)));
457 }
458
459 void DiscoveredListIterator::remove() {
460 assert(_ref->is_oop(), "Dropping a bad reference");
461 oop_store_raw(_discovered_addr, NULL);
462
463 // First _prev_next ref actually points into DiscoveredList (gross).
464 oop new_next;
465 if (_next == _ref) {
466 // At the end of the list, we should make _prev point to itself.
467 // If _ref is the first ref, then _prev_next will be in the DiscoveredList,
468 // and _prev will be NULL.
630 iter.make_referent_alive();
631 }
632 if (TraceReferenceGC) {
633 gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
634 clear_referent ? "cleared " : "",
635 p2i(iter.obj()), iter.obj()->klass()->internal_name());
636 }
637 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
638 iter.next();
639 }
640 // Close the reachable set
641 complete_gc->do_void();
642 }
643
644 void
645 ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) {
646 oop obj = NULL;
647 oop next = refs_list.head();
648 while (next != obj) {
649 obj = next;
650 next = java_lang_ref_Reference::discovered(obj);
651 java_lang_ref_Reference::set_discovered_raw(obj, NULL);
652 }
653 refs_list.set_head(NULL);
654 refs_list.set_length(0);
655 }
656
657 void ReferenceProcessor::abandon_partial_discovery() {
658 // loop over the lists
659 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
660 if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
661 gclog_or_tty->print_cr("\nAbandoning %s discovered list", list_name(i));
662 }
663 clear_discovered_references(_discovered_refs[i]);
664 }
665 }
666
667 class RefProcPhase1Task: public AbstractRefProcTaskExecutor::ProcessTask {
668 public:
669 RefProcPhase1Task(ReferenceProcessor& ref_processor,
1077 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
1078 const oop discovered = java_lang_ref_Reference::discovered(obj);
1079 assert(discovered->is_oop_or_null(), err_msg("Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)));
1080 if (discovered != NULL) {
1081 // The reference has already been discovered...
1082 if (TraceReferenceGC) {
1083 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
1084 p2i(obj), obj->klass()->internal_name());
1085 }
1086 if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
1087 // assumes that an object is not processed twice;
1088 // if it's been already discovered it must be on another
1089 // generation's discovered list; so we won't discover it.
1090 return false;
1091 } else {
1092 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery,
1093 "Unrecognized policy");
1094 // Check assumption that an object is not potentially
1095 // discovered twice except by concurrent collectors that potentially
1096 // trace the same Reference object twice.
1097 assert(UseConcMarkSweepGC || UseG1GC,
1098 "Only possible with a concurrent marking collector");
1099 return true;
1100 }
1101 }
1102
1103 if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
1104 verify_referent(obj);
1105 // Discover if and only if EITHER:
1106 // .. reference is in our span, OR
1107 // .. we are an atomic collector and referent is in our span
1108 if (_span.contains(obj_addr) ||
1109 (discovery_is_atomic() &&
1110 _span.contains(java_lang_ref_Reference::referent(obj)))) {
1111 // should_enqueue = true;
1112 } else {
1113 return false;
1114 }
1115 } else {
1116 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery &&
1117 _span.contains(obj_addr), "code inconsistency");
1276 iter.removed(), iter.processed(), p2i(refs_list.head()));
1277 }
1278 )
1279 }
1280
1281 const char* ReferenceProcessor::list_name(uint i) {
1282 assert(i <= _max_num_q * number_of_subclasses_of_ref(),
1283 "Out of bounds index");
1284
1285 int j = i / _max_num_q;
1286 switch (j) {
1287 case 0: return "SoftRef";
1288 case 1: return "WeakRef";
1289 case 2: return "FinalRef";
1290 case 3: return "PhantomRef";
1291 case 4: return "CleanerRef";
1292 }
1293 ShouldNotReachHere();
1294 return NULL;
1295 }
1296
|
429 pending_list_addr, _max_num_q);
430 task_executor->execute(tsk);
431 } else {
432 // Serial code: call the parent class's implementation
433 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
434 enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
435 _discovered_refs[i].set_head(NULL);
436 _discovered_refs[i].set_length(0);
437 }
438 }
439 }
440
441 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
442 _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
443 oop discovered = java_lang_ref_Reference::discovered(_ref);
444 assert(_discovered_addr && discovered->is_oop_or_null(),
445 err_msg("Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)));
446 _next = discovered;
447 _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
448 _referent = java_lang_ref_Reference::referent(_ref);
449 assert(_referent == oopDesc::bs()->read_barrier(_referent), "expect forwarded referent");
450 assert(Universe::heap()->is_in_reserved_or_null(_referent),
451 "Wrong oop found in java.lang.Reference object");
452 assert(allow_null_referent ?
453 _referent->is_oop_or_null()
454 : _referent->is_oop(),
455 err_msg("Expected an oop%s for referent field at " PTR_FORMAT,
456 (allow_null_referent ? " or NULL" : ""),
457 p2i(_referent)));
458 }
459
460 void DiscoveredListIterator::remove() {
461 assert(_ref->is_oop(), "Dropping a bad reference");
462 oop_store_raw(_discovered_addr, NULL);
463
464 // First _prev_next ref actually points into DiscoveredList (gross).
465 oop new_next;
466 if (_next == _ref) {
467 // At the end of the list, we should make _prev point to itself.
468 // If _ref is the first ref, then _prev_next will be in the DiscoveredList,
469 // and _prev will be NULL.
631 iter.make_referent_alive();
632 }
633 if (TraceReferenceGC) {
634 gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
635 clear_referent ? "cleared " : "",
636 p2i(iter.obj()), iter.obj()->klass()->internal_name());
637 }
638 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
639 iter.next();
640 }
641 // Close the reachable set
642 complete_gc->do_void();
643 }
644
645 void
646 ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) {
647 oop obj = NULL;
648 oop next = refs_list.head();
649 while (next != obj) {
650 obj = next;
651 assert(obj == oopDesc::bs()->read_barrier(obj), "expect forwarded obj");
652 next = java_lang_ref_Reference::discovered(obj);
653 java_lang_ref_Reference::set_discovered_raw(obj, NULL);
654 }
655 refs_list.set_head(NULL);
656 refs_list.set_length(0);
657 }
658
659 void ReferenceProcessor::abandon_partial_discovery() {
660 // loop over the lists
661 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
662 if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
663 gclog_or_tty->print_cr("\nAbandoning %s discovered list", list_name(i));
664 }
665 clear_discovered_references(_discovered_refs[i]);
666 }
667 }
668
669 class RefProcPhase1Task: public AbstractRefProcTaskExecutor::ProcessTask {
670 public:
671 RefProcPhase1Task(ReferenceProcessor& ref_processor,
1079 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
1080 const oop discovered = java_lang_ref_Reference::discovered(obj);
1081 assert(discovered->is_oop_or_null(), err_msg("Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)));
1082 if (discovered != NULL) {
1083 // The reference has already been discovered...
1084 if (TraceReferenceGC) {
1085 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
1086 p2i(obj), obj->klass()->internal_name());
1087 }
1088 if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
1089 // assumes that an object is not processed twice;
1090 // if it's been already discovered it must be on another
1091 // generation's discovered list; so we won't discover it.
1092 return false;
1093 } else {
1094 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery,
1095 "Unrecognized policy");
1096 // Check assumption that an object is not potentially
1097 // discovered twice except by concurrent collectors that potentially
1098 // trace the same Reference object twice.
1099 assert(UseConcMarkSweepGC || UseG1GC || UseShenandoahGC,
1100 "Only possible with a concurrent marking collector");
1101 return true;
1102 }
1103 }
1104
1105 if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
1106 verify_referent(obj);
1107 // Discover if and only if EITHER:
1108 // .. reference is in our span, OR
1109 // .. we are an atomic collector and referent is in our span
1110 if (_span.contains(obj_addr) ||
1111 (discovery_is_atomic() &&
1112 _span.contains(java_lang_ref_Reference::referent(obj)))) {
1113 // should_enqueue = true;
1114 } else {
1115 return false;
1116 }
1117 } else {
1118 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery &&
1119 _span.contains(obj_addr), "code inconsistency");
1278 iter.removed(), iter.processed(), p2i(refs_list.head()));
1279 }
1280 )
1281 }
1282
1283 const char* ReferenceProcessor::list_name(uint i) {
1284 assert(i <= _max_num_q * number_of_subclasses_of_ref(),
1285 "Out of bounds index");
1286
1287 int j = i / _max_num_q;
1288 switch (j) {
1289 case 0: return "SoftRef";
1290 case 1: return "WeakRef";
1291 case 2: return "FinalRef";
1292 case 3: return "PhantomRef";
1293 case 4: return "CleanerRef";
1294 }
1295 ShouldNotReachHere();
1296 return NULL;
1297 }
|