< prev index next >

src/share/vm/gc/shared/referenceProcessor.cpp

Print this page




 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 }

< prev index next >