1.1 --- a/src/share/vm/memory/referenceProcessor.cpp Thu Nov 20 12:27:41 2008 -0800 1.2 +++ b/src/share/vm/memory/referenceProcessor.cpp Thu Nov 20 16:56:09 2008 -0800 1.3 @@ -25,6 +25,11 @@ 1.4 # include "incls/_precompiled.incl" 1.5 # include "incls/_referenceProcessor.cpp.incl" 1.6 1.7 +ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; 1.8 +ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; 1.9 +oop ReferenceProcessor::_sentinelRef = NULL; 1.10 +const int subclasses_of_ref = REF_PHANTOM - REF_OTHER; 1.11 + 1.12 // List of discovered references. 1.13 class DiscoveredList { 1.14 public: 1.15 @@ -58,10 +63,6 @@ 1.16 size_t _len; 1.17 }; 1.18 1.19 -oop ReferenceProcessor::_sentinelRef = NULL; 1.20 - 1.21 -const int subclasses_of_ref = REF_PHANTOM - REF_OTHER; 1.22 - 1.23 void referenceProcessor_init() { 1.24 ReferenceProcessor::init_statics(); 1.25 } 1.26 @@ -82,6 +83,12 @@ 1.27 } 1.28 assert(_sentinelRef != NULL && _sentinelRef->is_oop(), 1.29 "Just constructed it!"); 1.30 + _always_clear_soft_ref_policy = new AlwaysClearPolicy(); 1.31 + _default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy()) 1.32 + NOT_COMPILER2(LRUCurrentHeapPolicy()); 1.33 + if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) { 1.34 + vm_exit_during_initialization("Could not allocate reference policy object"); 1.35 + } 1.36 guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery || 1.37 RefDiscoveryPolicy == ReferentBasedDiscovery, 1.38 "Unrecongnized RefDiscoveryPolicy"); 1.39 @@ -108,6 +115,7 @@ 1.40 vm_exit_during_initialization("Could not allocate ReferenceProcessor object"); 1.41 } 1.42 rp->set_is_alive_non_header(is_alive_non_header); 1.43 + rp->snap_policy(false /* default soft ref policy */); 1.44 return rp; 1.45 } 1.46 1.47 @@ -194,7 +202,6 @@ 1.48 } 1.49 1.50 void ReferenceProcessor::process_discovered_references( 1.51 - ReferencePolicy* policy, 1.52 BoolObjectClosure* is_alive, 1.53 OopClosure* keep_alive, 1.54 VoidClosure* complete_gc, 1.55 @@ -209,7 +216,7 @@ 1.56 // Soft references 1.57 { 1.58 TraceTime tt("SoftReference", trace_time, false, gclog_or_tty); 1.59 - process_discovered_reflist(_discoveredSoftRefs, policy, true, 1.60 + process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, 1.61 is_alive, keep_alive, complete_gc, task_executor); 1.62 } 1.63 1.64 @@ -1092,15 +1099,28 @@ 1.65 // reachable. 1.66 if (is_alive_non_header() != NULL) { 1.67 oop referent = java_lang_ref_Reference::referent(obj); 1.68 - // We'd like to assert the following: 1.69 - // assert(referent != NULL, "Refs with null referents already filtered"); 1.70 - // However, since this code may be executed concurrently with 1.71 - // mutators, which can clear() the referent, it is not 1.72 - // guaranteed that the referent is non-NULL. 1.73 + // In the case of non-concurrent discovery, the last 1.74 + // disjunct below should hold. It may not hold in the 1.75 + // case of concurrent discovery because mutators may 1.76 + // concurrently clear() a Reference. 1.77 + assert(UseConcMarkSweepGC || UseG1GC || referent != NULL, 1.78 + "Refs with null referents already filtered"); 1.79 if (is_alive_non_header()->do_object_b(referent)) { 1.80 return false; // referent is reachable 1.81 } 1.82 } 1.83 + if (rt == REF_SOFT) { 1.84 + // For soft refs we can decide now if these are not 1.85 + // current candidates for clearing, in which case we 1.86 + // can mark through them now, rather than delaying that 1.87 + // to the reference-processing phase. Since all current 1.88 + // time-stamp policies advance the soft-ref clock only 1.89 + // at a major collection cycle, this is always currently 1.90 + // accurate. 1.91 + if (!_current_soft_ref_policy->should_clear_reference(obj)) { 1.92 + return false; 1.93 + } 1.94 + } 1.95 1.96 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj); 1.97 const oop discovered = java_lang_ref_Reference::discovered(obj);