comparison src/share/vm/memory/referenceProcessor.cpp @ 453:c96030fff130

6684579: SoftReference processing can be made more efficient Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not. Reviewed-by: jmasa
author ysr
date Thu, 20 Nov 2008 16:56:09 -0800
parents 00b023ae2d78
children 27a80744a83b
comparison
equal deleted inserted replaced
452:00b023ae2d78 453:c96030fff130
23 */ 23 */
24 24
25 # include "incls/_precompiled.incl" 25 # include "incls/_precompiled.incl"
26 # include "incls/_referenceProcessor.cpp.incl" 26 # include "incls/_referenceProcessor.cpp.incl"
27 27
28 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
29 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL;
30 oop ReferenceProcessor::_sentinelRef = NULL;
31 const int subclasses_of_ref = REF_PHANTOM - REF_OTHER;
32
28 // List of discovered references. 33 // List of discovered references.
29 class DiscoveredList { 34 class DiscoveredList {
30 public: 35 public:
31 DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { } 36 DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { }
32 oop head() const { 37 oop head() const {
56 oop _oop_head; 61 oop _oop_head;
57 narrowOop _compressed_head; 62 narrowOop _compressed_head;
58 size_t _len; 63 size_t _len;
59 }; 64 };
60 65
61 oop ReferenceProcessor::_sentinelRef = NULL;
62
63 const int subclasses_of_ref = REF_PHANTOM - REF_OTHER;
64
65 void referenceProcessor_init() { 66 void referenceProcessor_init() {
66 ReferenceProcessor::init_statics(); 67 ReferenceProcessor::init_statics();
67 } 68 }
68 69
69 void ReferenceProcessor::init_statics() { 70 void ReferenceProcessor::init_statics() {
80 Handle ex(THREAD, PENDING_EXCEPTION); 81 Handle ex(THREAD, PENDING_EXCEPTION);
81 vm_exit_during_initialization(ex); 82 vm_exit_during_initialization(ex);
82 } 83 }
83 assert(_sentinelRef != NULL && _sentinelRef->is_oop(), 84 assert(_sentinelRef != NULL && _sentinelRef->is_oop(),
84 "Just constructed it!"); 85 "Just constructed it!");
86 _always_clear_soft_ref_policy = new AlwaysClearPolicy();
87 _default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
88 NOT_COMPILER2(LRUCurrentHeapPolicy());
89 if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
90 vm_exit_during_initialization("Could not allocate reference policy object");
91 }
85 guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery || 92 guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
86 RefDiscoveryPolicy == ReferentBasedDiscovery, 93 RefDiscoveryPolicy == ReferentBasedDiscovery,
87 "Unrecongnized RefDiscoveryPolicy"); 94 "Unrecongnized RefDiscoveryPolicy");
88 } 95 }
89 96
106 dl_needs_barrier); 113 dl_needs_barrier);
107 if (rp == NULL) { 114 if (rp == NULL) {
108 vm_exit_during_initialization("Could not allocate ReferenceProcessor object"); 115 vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
109 } 116 }
110 rp->set_is_alive_non_header(is_alive_non_header); 117 rp->set_is_alive_non_header(is_alive_non_header);
118 rp->snap_policy(false /* default soft ref policy */);
111 return rp; 119 return rp;
112 } 120 }
113 121
114 ReferenceProcessor::ReferenceProcessor(MemRegion span, 122 ReferenceProcessor::ReferenceProcessor(MemRegion span,
115 bool atomic_discovery, 123 bool atomic_discovery,
192 // Else leave clock stalled at its old value until time progresses 200 // Else leave clock stalled at its old value until time progresses
193 // past clock value. 201 // past clock value.
194 } 202 }
195 203
196 void ReferenceProcessor::process_discovered_references( 204 void ReferenceProcessor::process_discovered_references(
197 ReferencePolicy* policy,
198 BoolObjectClosure* is_alive, 205 BoolObjectClosure* is_alive,
199 OopClosure* keep_alive, 206 OopClosure* keep_alive,
200 VoidClosure* complete_gc, 207 VoidClosure* complete_gc,
201 AbstractRefProcTaskExecutor* task_executor) { 208 AbstractRefProcTaskExecutor* task_executor) {
202 NOT_PRODUCT(verify_ok_to_handle_reflists()); 209 NOT_PRODUCT(verify_ok_to_handle_reflists());
207 214
208 bool trace_time = PrintGCDetails && PrintReferenceGC; 215 bool trace_time = PrintGCDetails && PrintReferenceGC;
209 // Soft references 216 // Soft references
210 { 217 {
211 TraceTime tt("SoftReference", trace_time, false, gclog_or_tty); 218 TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);
212 process_discovered_reflist(_discoveredSoftRefs, policy, true, 219 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
213 is_alive, keep_alive, complete_gc, task_executor); 220 is_alive, keep_alive, complete_gc, task_executor);
214 } 221 }
215 222
216 update_soft_ref_master_clock(); 223 update_soft_ref_master_clock();
217 224
1090 1097
1091 // We only enqueue references whose referents are not (yet) strongly 1098 // We only enqueue references whose referents are not (yet) strongly
1092 // reachable. 1099 // reachable.
1093 if (is_alive_non_header() != NULL) { 1100 if (is_alive_non_header() != NULL) {
1094 oop referent = java_lang_ref_Reference::referent(obj); 1101 oop referent = java_lang_ref_Reference::referent(obj);
1095 // We'd like to assert the following: 1102 // In the case of non-concurrent discovery, the last
1096 // assert(referent != NULL, "Refs with null referents already filtered"); 1103 // disjunct below should hold. It may not hold in the
1097 // However, since this code may be executed concurrently with 1104 // case of concurrent discovery because mutators may
1098 // mutators, which can clear() the referent, it is not 1105 // concurrently clear() a Reference.
1099 // guaranteed that the referent is non-NULL. 1106 assert(UseConcMarkSweepGC || UseG1GC || referent != NULL,
1107 "Refs with null referents already filtered");
1100 if (is_alive_non_header()->do_object_b(referent)) { 1108 if (is_alive_non_header()->do_object_b(referent)) {
1101 return false; // referent is reachable 1109 return false; // referent is reachable
1110 }
1111 }
1112 if (rt == REF_SOFT) {
1113 // For soft refs we can decide now if these are not
1114 // current candidates for clearing, in which case we
1115 // can mark through them now, rather than delaying that
1116 // to the reference-processing phase. Since all current
1117 // time-stamp policies advance the soft-ref clock only
1118 // at a major collection cycle, this is always currently
1119 // accurate.
1120 if (!_current_soft_ref_policy->should_clear_reference(obj)) {
1121 return false;
1102 } 1122 }
1103 } 1123 }
1104 1124
1105 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj); 1125 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
1106 const oop discovered = java_lang_ref_Reference::discovered(obj); 1126 const oop discovered = java_lang_ref_Reference::discovered(obj);