< prev index next >

src/share/vm/memory/referenceProcessor.cpp

Print this page
rev 7522 : * * *
8066827: Remove ReferenceProcessor::clean_up_discovered_references()
Summary: Abandon rather than clean up discovered references.
Reviewed-by:


  51   // os::javaTimeMillis() does not guarantee monotonicity.
  52   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  53 
  54   // Initialize the soft ref timestamp clock.
  55   _soft_ref_timestamp_clock = now;
  56   // Also update the soft ref clock in j.l.r.SoftReference
  57   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
  58 
  59   _always_clear_soft_ref_policy = new AlwaysClearPolicy();
  60   _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
  61                                       NOT_COMPILER2(LRUCurrentHeapPolicy());
  62   if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
  63     vm_exit_during_initialization("Could not allocate reference policy object");
  64   }
  65   guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
  66             RefDiscoveryPolicy == ReferentBasedDiscovery,
  67             "Unrecognized RefDiscoveryPolicy");
  68   _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
  69 }
  70 
  71 void ReferenceProcessor::enable_discovery(bool verify_disabled, bool check_no_refs) {
  72 #ifdef ASSERT
  73   // Verify that we're not currently discovering refs
  74   assert(!verify_disabled || !_discovering_refs, "nested call?");
  75 
  76   if (check_no_refs) {
  77     // Verify that the discovered lists are empty
  78     verify_no_references_recorded();
  79   }
  80 #endif // ASSERT
  81 
  82   // Someone could have modified the value of the static
  83   // field in the j.l.r.SoftReference class that holds the
  84   // soft reference timestamp clock using reflection or
  85   // Unsafe between GCs. Unconditionally update the static
  86   // field in ReferenceProcessor here so that we use the new
  87   // value during reference discovery.
  88 
  89   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
  90   _discovering_refs = true;
  91 }
  92 
  93 ReferenceProcessor::ReferenceProcessor(MemRegion span,
  94                                        bool      mt_processing,


 944     task_executor->execute(phase2);
 945   } else {
 946     for (uint i = 0; i < _max_num_q; i++) {
 947       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
 948     }
 949   }
 950 
 951   // Phase 3:
 952   // . Traverse the list and process referents as appropriate.
 953   if (mt_processing) {
 954     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
 955     task_executor->execute(phase3);
 956   } else {
 957     for (uint i = 0; i < _max_num_q; i++) {
 958       process_phase3(refs_lists[i], clear_referent,
 959                      is_alive, keep_alive, complete_gc);
 960     }
 961   }
 962 
 963   return total_list_count;
 964 }
 965 
 966 void ReferenceProcessor::clean_up_discovered_references() {
 967   // loop over the lists
 968   for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
 969     if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
 970       gclog_or_tty->print_cr(
 971         "\nScrubbing %s discovered list of Null referents",
 972         list_name(i));
 973     }
 974     clean_up_discovered_reflist(_discovered_refs[i]);
 975   }
 976 }
 977 
 978 void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
 979   assert(!discovery_is_atomic(), "Else why call this method?");
 980   DiscoveredListIterator iter(refs_list, NULL, NULL);
 981   while (iter.has_next()) {
 982     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
 983     oop next = java_lang_ref_Reference::next(iter.obj());
 984     assert(next->is_oop_or_null(), err_msg("Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next)));
 985     // If referent has been cleared or Reference is not active,
 986     // drop it.
 987     if (iter.referent() == NULL || next != NULL) {
 988       debug_only(
 989         if (PrintGCDetails && TraceReferenceGC) {
 990           gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: "
 991             INTPTR_FORMAT " with next field: " INTPTR_FORMAT
 992             " and referent: " INTPTR_FORMAT,
 993             (void *)iter.obj(), (void *)next, (void *)iter.referent());
 994         }
 995       )
 996       // Remove Reference object from list
 997       iter.remove();
 998       iter.move_to_next();
 999     } else {
1000       iter.next();
1001     }
1002   }
1003   NOT_PRODUCT(
1004     if (PrintGCDetails && TraceReferenceGC) {
1005       gclog_or_tty->print(
1006         " Removed %d Refs with NULL referents out of %d discovered Refs",
1007         iter.removed(), iter.processed());
1008     }
1009   )
1010 }
1011 
1012 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
1013   uint id = 0;
1014   // Determine the queue index to use for this object.
1015   if (_discovery_is_mt) {
1016     // During a multi-threaded discovery phase,
1017     // each thread saves to its "own" list.
1018     Thread* thr = Thread::current();
1019     id = thr->as_Worker_thread()->id();
1020   } else {
1021     // single-threaded discovery, we save in round-robin
1022     // fashion to each of the lists.
1023     if (_processing_is_mt) {
1024       id = next_id();
1025     }
1026   }
1027   assert(0 <= id && id < _max_num_q, "Id is out-of-bounds (call Freud?)");
1028 
1029   // Get the discovered queue to which we will add




  51   // os::javaTimeMillis() does not guarantee monotonicity.
  52   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  53 
  54   // Initialize the soft ref timestamp clock.
  55   _soft_ref_timestamp_clock = now;
  56   // Also update the soft ref clock in j.l.r.SoftReference
  57   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
  58 
  59   _always_clear_soft_ref_policy = new AlwaysClearPolicy();
  60   _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
  61                                       NOT_COMPILER2(LRUCurrentHeapPolicy());
  62   if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
  63     vm_exit_during_initialization("Could not allocate reference policy object");
  64   }
  65   guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
  66             RefDiscoveryPolicy == ReferentBasedDiscovery,
  67             "Unrecognized RefDiscoveryPolicy");
  68   _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
  69 }
  70 
  71 void ReferenceProcessor::enable_discovery(bool check_no_refs) {
  72 #ifdef ASSERT
  73   // Verify that we're not currently discovering refs
  74   assert(!_discovering_refs, "nested call?");
  75 
  76   if (check_no_refs) {
  77     // Verify that the discovered lists are empty
  78     verify_no_references_recorded();
  79   }
  80 #endif // ASSERT
  81 
  82   // Someone could have modified the value of the static
  83   // field in the j.l.r.SoftReference class that holds the
  84   // soft reference timestamp clock using reflection or
  85   // Unsafe between GCs. Unconditionally update the static
  86   // field in ReferenceProcessor here so that we use the new
  87   // value during reference discovery.
  88 
  89   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
  90   _discovering_refs = true;
  91 }
  92 
  93 ReferenceProcessor::ReferenceProcessor(MemRegion span,
  94                                        bool      mt_processing,


 944     task_executor->execute(phase2);
 945   } else {
 946     for (uint i = 0; i < _max_num_q; i++) {
 947       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
 948     }
 949   }
 950 
 951   // Phase 3:
 952   // . Traverse the list and process referents as appropriate.
 953   if (mt_processing) {
 954     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
 955     task_executor->execute(phase3);
 956   } else {
 957     for (uint i = 0; i < _max_num_q; i++) {
 958       process_phase3(refs_lists[i], clear_referent,
 959                      is_alive, keep_alive, complete_gc);
 960     }
 961   }
 962 
 963   return total_list_count;














































 964 }
 965 
 966 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
 967   uint id = 0;
 968   // Determine the queue index to use for this object.
 969   if (_discovery_is_mt) {
 970     // During a multi-threaded discovery phase,
 971     // each thread saves to its "own" list.
 972     Thread* thr = Thread::current();
 973     id = thr->as_Worker_thread()->id();
 974   } else {
 975     // single-threaded discovery, we save in round-robin
 976     // fashion to each of the lists.
 977     if (_processing_is_mt) {
 978       id = next_id();
 979     }
 980   }
 981   assert(0 <= id && id < _max_num_q, "Id is out-of-bounds (call Freud?)");
 982 
 983   // Get the discovered queue to which we will add


< prev index next >