Mercurial > hg > graal-jvmci-8
annotate src/share/vm/memory/referenceProcessor.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | 8b10f48633dc |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1190
diff
changeset
|
2 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1190
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1190
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1190
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_referenceProcessor.cpp.incl" | |
27 | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
28 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
29 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
30 oop ReferenceProcessor::_sentinelRef = NULL; |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
31 const int subclasses_of_ref = REF_PHANTOM - REF_OTHER; |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
32 |
0 | 33 // List of discovered references. |
34 class DiscoveredList { | |
35 public: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
36 DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
37 oop head() const { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
38 return UseCompressedOops ? oopDesc::decode_heap_oop_not_null(_compressed_head) : |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
39 _oop_head; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
40 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
41 HeapWord* adr_head() { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
42 return UseCompressedOops ? (HeapWord*)&_compressed_head : |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
43 (HeapWord*)&_oop_head; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
44 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
45 void set_head(oop o) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
46 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
47 // Must compress the head ptr. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
48 _compressed_head = oopDesc::encode_heap_oop_not_null(o); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
49 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
50 _oop_head = o; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
51 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
52 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
53 bool empty() const { return head() == ReferenceProcessor::sentinel_ref(); } |
0 | 54 size_t length() { return _len; } |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
55 void set_length(size_t len) { _len = len; } |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
56 void inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); } |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
57 void dec_length(size_t dec) { _len -= dec; } |
0 | 58 private: |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
59 // Set value depending on UseCompressedOops. This could be a template class |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
60 // but then we have to fix all the instantiations and declarations that use this class. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
61 oop _oop_head; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
62 narrowOop _compressed_head; |
0 | 63 size_t _len; |
64 }; | |
65 | |
66 void referenceProcessor_init() { | |
67 ReferenceProcessor::init_statics(); | |
68 } | |
69 | |
70 void ReferenceProcessor::init_statics() { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
71 assert(_sentinelRef == NULL, "should be initialized precisely once"); |
0 | 72 EXCEPTION_MARK; |
73 _sentinelRef = instanceKlass::cast( | |
1142 | 74 SystemDictionary::Reference_klass())-> |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
75 allocate_permanent_instance(THREAD); |
0 | 76 |
77 // Initialize the master soft ref clock. | |
78 java_lang_ref_SoftReference::set_clock(os::javaTimeMillis()); | |
79 | |
80 if (HAS_PENDING_EXCEPTION) { | |
81 Handle ex(THREAD, PENDING_EXCEPTION); | |
82 vm_exit_during_initialization(ex); | |
83 } | |
84 assert(_sentinelRef != NULL && _sentinelRef->is_oop(), | |
85 "Just constructed it!"); | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
86 _always_clear_soft_ref_policy = new AlwaysClearPolicy(); |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
87 _default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy()) |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
88 NOT_COMPILER2(LRUCurrentHeapPolicy()); |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
89 if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) { |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
90 vm_exit_during_initialization("Could not allocate reference policy object"); |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
91 } |
0 | 92 guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery || |
93 RefDiscoveryPolicy == ReferentBasedDiscovery, | |
94 "Unrecongnized RefDiscoveryPolicy"); | |
95 } | |
96 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
97 ReferenceProcessor* |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
98 ReferenceProcessor::create_ref_processor(MemRegion span, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
99 bool atomic_discovery, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
100 bool mt_discovery, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
101 BoolObjectClosure* is_alive_non_header, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
102 int parallel_gc_threads, |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
103 bool mt_processing, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
104 bool dl_needs_barrier) { |
0 | 105 int mt_degree = 1; |
106 if (parallel_gc_threads > 1) { | |
107 mt_degree = parallel_gc_threads; | |
108 } | |
109 ReferenceProcessor* rp = | |
110 new ReferenceProcessor(span, atomic_discovery, | |
111 mt_discovery, mt_degree, | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
112 mt_processing && (parallel_gc_threads > 0), |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
113 dl_needs_barrier); |
0 | 114 if (rp == NULL) { |
115 vm_exit_during_initialization("Could not allocate ReferenceProcessor object"); | |
116 } | |
117 rp->set_is_alive_non_header(is_alive_non_header); | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
118 rp->setup_policy(false /* default soft ref policy */); |
0 | 119 return rp; |
120 } | |
121 | |
122 ReferenceProcessor::ReferenceProcessor(MemRegion span, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
123 bool atomic_discovery, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
124 bool mt_discovery, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
125 int mt_degree, |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
126 bool mt_processing, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
127 bool discovered_list_needs_barrier) : |
0 | 128 _discovering_refs(false), |
129 _enqueuing_is_done(false), | |
130 _is_alive_non_header(NULL), | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
131 _discovered_list_needs_barrier(discovered_list_needs_barrier), |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
132 _bs(NULL), |
0 | 133 _processing_is_mt(mt_processing), |
134 _next_id(0) | |
135 { | |
136 _span = span; | |
137 _discovery_is_atomic = atomic_discovery; | |
138 _discovery_is_mt = mt_discovery; | |
139 _num_q = mt_degree; | |
140 _discoveredSoftRefs = NEW_C_HEAP_ARRAY(DiscoveredList, _num_q * subclasses_of_ref); | |
141 if (_discoveredSoftRefs == NULL) { | |
142 vm_exit_during_initialization("Could not allocated RefProc Array"); | |
143 } | |
144 _discoveredWeakRefs = &_discoveredSoftRefs[_num_q]; | |
145 _discoveredFinalRefs = &_discoveredWeakRefs[_num_q]; | |
146 _discoveredPhantomRefs = &_discoveredFinalRefs[_num_q]; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
147 assert(sentinel_ref() != NULL, "_sentinelRef is NULL"); |
0 | 148 // Initialized all entries to _sentinelRef |
149 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
150 _discoveredSoftRefs[i].set_head(sentinel_ref()); |
0 | 151 _discoveredSoftRefs[i].set_length(0); |
152 } | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
153 // If we do barreirs, cache a copy of the barrier set. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
154 if (discovered_list_needs_barrier) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
155 _bs = Universe::heap()->barrier_set(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
156 } |
0 | 157 } |
158 | |
159 #ifndef PRODUCT | |
160 void ReferenceProcessor::verify_no_references_recorded() { | |
161 guarantee(!_discovering_refs, "Discovering refs?"); | |
162 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | |
163 guarantee(_discoveredSoftRefs[i].empty(), | |
164 "Found non-empty discovered list"); | |
165 } | |
166 } | |
167 #endif | |
168 | |
169 void ReferenceProcessor::weak_oops_do(OopClosure* f) { | |
170 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
171 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
172 f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head()); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
173 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
174 f->do_oop((oop*)_discoveredSoftRefs[i].adr_head()); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
175 } |
0 | 176 } |
177 } | |
178 | |
179 void ReferenceProcessor::oops_do(OopClosure* f) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
180 f->do_oop(adr_sentinel_ref()); |
0 | 181 } |
182 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
183 void ReferenceProcessor::update_soft_ref_master_clock() { |
0 | 184 // Update (advance) the soft ref master clock field. This must be done |
185 // after processing the soft ref list. | |
186 jlong now = os::javaTimeMillis(); | |
187 jlong clock = java_lang_ref_SoftReference::clock(); | |
188 NOT_PRODUCT( | |
189 if (now < clock) { | |
190 warning("time warp: %d to %d", clock, now); | |
191 } | |
192 ) | |
193 // In product mode, protect ourselves from system time being adjusted | |
194 // externally and going backward; see note in the implementation of | |
195 // GenCollectedHeap::time_since_last_gc() for the right way to fix | |
196 // this uniformly throughout the VM; see bug-id 4741166. XXX | |
197 if (now > clock) { | |
198 java_lang_ref_SoftReference::set_clock(now); | |
199 } | |
200 // Else leave clock stalled at its old value until time progresses | |
201 // past clock value. | |
202 } | |
203 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
204 void ReferenceProcessor::process_discovered_references( |
0 | 205 BoolObjectClosure* is_alive, |
206 OopClosure* keep_alive, | |
207 VoidClosure* complete_gc, | |
208 AbstractRefProcTaskExecutor* task_executor) { | |
209 NOT_PRODUCT(verify_ok_to_handle_reflists()); | |
210 | |
211 assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); | |
212 // Stop treating discovered references specially. | |
213 disable_discovery(); | |
214 | |
215 bool trace_time = PrintGCDetails && PrintReferenceGC; | |
216 // Soft references | |
217 { | |
218 TraceTime tt("SoftReference", trace_time, false, gclog_or_tty); | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
219 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, |
0 | 220 is_alive, keep_alive, complete_gc, task_executor); |
221 } | |
222 | |
223 update_soft_ref_master_clock(); | |
224 | |
225 // Weak references | |
226 { | |
227 TraceTime tt("WeakReference", trace_time, false, gclog_or_tty); | |
228 process_discovered_reflist(_discoveredWeakRefs, NULL, true, | |
229 is_alive, keep_alive, complete_gc, task_executor); | |
230 } | |
231 | |
232 // Final references | |
233 { | |
234 TraceTime tt("FinalReference", trace_time, false, gclog_or_tty); | |
235 process_discovered_reflist(_discoveredFinalRefs, NULL, false, | |
236 is_alive, keep_alive, complete_gc, task_executor); | |
237 } | |
238 | |
239 // Phantom references | |
240 { | |
241 TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty); | |
242 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, | |
243 is_alive, keep_alive, complete_gc, task_executor); | |
244 } | |
245 | |
246 // Weak global JNI references. It would make more sense (semantically) to | |
247 // traverse these simultaneously with the regular weak references above, but | |
248 // that is not how the JDK1.2 specification is. See #4126360. Native code can | |
249 // thus use JNI weak references to circumvent the phantom references and | |
250 // resurrect a "post-mortem" object. | |
251 { | |
252 TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty); | |
253 if (task_executor != NULL) { | |
254 task_executor->set_single_threaded_mode(); | |
255 } | |
256 process_phaseJNI(is_alive, keep_alive, complete_gc); | |
257 } | |
258 } | |
259 | |
260 #ifndef PRODUCT | |
261 // Calculate the number of jni handles. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
262 uint ReferenceProcessor::count_jni_refs() { |
0 | 263 class AlwaysAliveClosure: public BoolObjectClosure { |
264 public: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
265 virtual bool do_object_b(oop obj) { return true; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
266 virtual void do_object(oop obj) { assert(false, "Don't call"); } |
0 | 267 }; |
268 | |
269 class CountHandleClosure: public OopClosure { | |
270 private: | |
271 int _count; | |
272 public: | |
273 CountHandleClosure(): _count(0) {} | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
274 void do_oop(oop* unused) { _count++; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
275 void do_oop(narrowOop* unused) { ShouldNotReachHere(); } |
0 | 276 int count() { return _count; } |
277 }; | |
278 CountHandleClosure global_handle_count; | |
279 AlwaysAliveClosure always_alive; | |
280 JNIHandles::weak_oops_do(&always_alive, &global_handle_count); | |
281 return global_handle_count.count(); | |
282 } | |
283 #endif | |
284 | |
285 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive, | |
286 OopClosure* keep_alive, | |
287 VoidClosure* complete_gc) { | |
288 #ifndef PRODUCT | |
289 if (PrintGCDetails && PrintReferenceGC) { | |
290 unsigned int count = count_jni_refs(); | |
291 gclog_or_tty->print(", %u refs", count); | |
292 } | |
293 #endif | |
294 JNIHandles::weak_oops_do(is_alive, keep_alive); | |
295 // Finally remember to keep sentinel around | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
296 keep_alive->do_oop(adr_sentinel_ref()); |
0 | 297 complete_gc->do_void(); |
298 } | |
299 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
300 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
301 template <class T> |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
935
diff
changeset
|
302 bool enqueue_discovered_ref_helper(ReferenceProcessor* ref, |
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
935
diff
changeset
|
303 AbstractRefProcTaskExecutor* task_executor) { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
304 |
0 | 305 // Remember old value of pending references list |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
306 T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
307 T old_pending_list_value = *pending_list_addr; |
0 | 308 |
309 // Enqueue references that are not made active again, and | |
310 // clear the decks for the next collection (cycle). | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
311 ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor); |
0 | 312 // Do the oop-check on pending_list_addr missed in |
313 // enqueue_discovered_reflist. We should probably | |
314 // do a raw oop_check so that future such idempotent | |
315 // oop_stores relying on the oop-check side-effect | |
316 // may be elided automatically and safely without | |
317 // affecting correctness. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
318 oop_store(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr)); |
0 | 319 |
320 // Stop treating discovered references specially. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
321 ref->disable_discovery(); |
0 | 322 |
323 // Return true if new pending references were added | |
324 return old_pending_list_value != *pending_list_addr; | |
325 } | |
326 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
327 bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
328 NOT_PRODUCT(verify_ok_to_handle_reflists()); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
329 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
330 return enqueue_discovered_ref_helper<narrowOop>(this, task_executor); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
331 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
332 return enqueue_discovered_ref_helper<oop>(this, task_executor); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
333 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
334 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
335 |
0 | 336 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list, |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
337 HeapWord* pending_list_addr) { |
0 | 338 // Given a list of refs linked through the "discovered" field |
339 // (java.lang.ref.Reference.discovered) chain them through the | |
340 // "next" field (java.lang.ref.Reference.next) and prepend | |
341 // to the pending list. | |
342 if (TraceReferenceGC && PrintGCDetails) { | |
343 gclog_or_tty->print_cr("ReferenceProcessor::enqueue_discovered_reflist list " | |
344 INTPTR_FORMAT, (address)refs_list.head()); | |
345 } | |
346 oop obj = refs_list.head(); | |
347 // Walk down the list, copying the discovered field into | |
348 // the next field and clearing it (except for the last | |
349 // non-sentinel object which is treated specially to avoid | |
350 // confusion with an active reference). | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
351 while (obj != sentinel_ref()) { |
0 | 352 assert(obj->is_instanceRef(), "should be reference object"); |
353 oop next = java_lang_ref_Reference::discovered(obj); | |
354 if (TraceReferenceGC && PrintGCDetails) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
355 gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next " INTPTR_FORMAT, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
356 obj, next); |
0 | 357 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
358 assert(java_lang_ref_Reference::next(obj) == NULL, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
359 "The reference should not be enqueued"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
360 if (next == sentinel_ref()) { // obj is last |
0 | 361 // Swap refs_list into pendling_list_addr and |
362 // set obj's next to what we read from pending_list_addr. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
363 oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr); |
0 | 364 // Need oop_check on pending_list_addr above; |
365 // see special oop-check code at the end of | |
366 // enqueue_discovered_reflists() further below. | |
367 if (old == NULL) { | |
368 // obj should be made to point to itself, since | |
369 // pending list was empty. | |
370 java_lang_ref_Reference::set_next(obj, obj); | |
371 } else { | |
372 java_lang_ref_Reference::set_next(obj, old); | |
373 } | |
374 } else { | |
375 java_lang_ref_Reference::set_next(obj, next); | |
376 } | |
377 java_lang_ref_Reference::set_discovered(obj, (oop) NULL); | |
378 obj = next; | |
379 } | |
380 } | |
381 | |
382 // Parallel enqueue task | |
383 class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask { | |
384 public: | |
385 RefProcEnqueueTask(ReferenceProcessor& ref_processor, | |
386 DiscoveredList discovered_refs[], | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
387 HeapWord* pending_list_addr, |
0 | 388 oop sentinel_ref, |
389 int n_queues) | |
390 : EnqueueTask(ref_processor, discovered_refs, | |
391 pending_list_addr, sentinel_ref, n_queues) | |
392 { } | |
393 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
394 virtual void work(unsigned int work_id) { |
0 | 395 assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds"); |
396 // Simplest first cut: static partitioning. | |
397 int index = work_id; | |
398 for (int j = 0; j < subclasses_of_ref; j++, index += _n_queues) { | |
399 _ref_processor.enqueue_discovered_reflist( | |
400 _refs_lists[index], _pending_list_addr); | |
401 _refs_lists[index].set_head(_sentinel_ref); | |
402 _refs_lists[index].set_length(0); | |
403 } | |
404 } | |
405 }; | |
406 | |
407 // Enqueue references that are not made active again | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
408 void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr, |
0 | 409 AbstractRefProcTaskExecutor* task_executor) { |
410 if (_processing_is_mt && task_executor != NULL) { | |
411 // Parallel code | |
412 RefProcEnqueueTask tsk(*this, _discoveredSoftRefs, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
413 pending_list_addr, sentinel_ref(), _num_q); |
0 | 414 task_executor->execute(tsk); |
415 } else { | |
416 // Serial code: call the parent class's implementation | |
417 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | |
418 enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
419 _discoveredSoftRefs[i].set_head(sentinel_ref()); |
0 | 420 _discoveredSoftRefs[i].set_length(0); |
421 } | |
422 } | |
423 } | |
424 | |
425 // Iterator for the list of discovered references. | |
426 class DiscoveredListIterator { | |
427 public: | |
428 inline DiscoveredListIterator(DiscoveredList& refs_list, | |
429 OopClosure* keep_alive, | |
430 BoolObjectClosure* is_alive); | |
431 | |
432 // End Of List. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
433 inline bool has_next() const { return _next != ReferenceProcessor::sentinel_ref(); } |
0 | 434 |
435 // Get oop to the Reference object. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
436 inline oop obj() const { return _ref; } |
0 | 437 |
438 // Get oop to the referent object. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
439 inline oop referent() const { return _referent; } |
0 | 440 |
441 // Returns true if referent is alive. | |
442 inline bool is_referent_alive() const; | |
443 | |
444 // Loads data for the current reference. | |
445 // The "allow_null_referent" argument tells us to allow for the possibility | |
446 // of a NULL referent in the discovered Reference object. This typically | |
447 // happens in the case of concurrent collectors that may have done the | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
448 // discovery concurrently, or interleaved, with mutator execution. |
0 | 449 inline void load_ptrs(DEBUG_ONLY(bool allow_null_referent)); |
450 | |
451 // Move to the next discovered reference. | |
452 inline void next(); | |
453 | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
454 // Remove the current reference from the list |
0 | 455 inline void remove(); |
456 | |
457 // Make the Reference object active again. | |
458 inline void make_active() { java_lang_ref_Reference::set_next(_ref, NULL); } | |
459 | |
460 // Make the referent alive. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
461 inline void make_referent_alive() { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
462 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
463 _keep_alive->do_oop((narrowOop*)_referent_addr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
464 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
465 _keep_alive->do_oop((oop*)_referent_addr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
466 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
467 } |
0 | 468 |
469 // Update the discovered field. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
470 inline void update_discovered() { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
471 // First _prev_next ref actually points into DiscoveredList (gross). |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
472 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
473 _keep_alive->do_oop((narrowOop*)_prev_next); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
474 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
475 _keep_alive->do_oop((oop*)_prev_next); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
476 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
477 } |
0 | 478 |
479 // NULL out referent pointer. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
480 inline void clear_referent() { oop_store_raw(_referent_addr, NULL); } |
0 | 481 |
482 // Statistics | |
483 NOT_PRODUCT( | |
484 inline size_t processed() const { return _processed; } | |
485 inline size_t removed() const { return _removed; } | |
486 ) | |
487 | |
488 inline void move_to_next(); | |
489 | |
490 private: | |
491 DiscoveredList& _refs_list; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
492 HeapWord* _prev_next; |
0 | 493 oop _ref; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
494 HeapWord* _discovered_addr; |
0 | 495 oop _next; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
496 HeapWord* _referent_addr; |
0 | 497 oop _referent; |
498 OopClosure* _keep_alive; | |
499 BoolObjectClosure* _is_alive; | |
500 DEBUG_ONLY( | |
501 oop _first_seen; // cyclic linked list check | |
502 ) | |
503 NOT_PRODUCT( | |
504 size_t _processed; | |
505 size_t _removed; | |
506 ) | |
507 }; | |
508 | |
509 inline DiscoveredListIterator::DiscoveredListIterator(DiscoveredList& refs_list, | |
510 OopClosure* keep_alive, | |
511 BoolObjectClosure* is_alive) | |
512 : _refs_list(refs_list), | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
513 _prev_next(refs_list.adr_head()), |
0 | 514 _ref(refs_list.head()), |
515 #ifdef ASSERT | |
516 _first_seen(refs_list.head()), | |
517 #endif | |
518 #ifndef PRODUCT | |
519 _processed(0), | |
520 _removed(0), | |
521 #endif | |
522 _next(refs_list.head()), | |
523 _keep_alive(keep_alive), | |
524 _is_alive(is_alive) | |
525 { } | |
526 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
527 inline bool DiscoveredListIterator::is_referent_alive() const { |
0 | 528 return _is_alive->do_object_b(_referent); |
529 } | |
530 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
531 inline void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) { |
0 | 532 _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
533 oop discovered = java_lang_ref_Reference::discovered(_ref); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
534 assert(_discovered_addr && discovered->is_oop_or_null(), |
0 | 535 "discovered field is bad"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
536 _next = discovered; |
0 | 537 _referent_addr = java_lang_ref_Reference::referent_addr(_ref); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
538 _referent = java_lang_ref_Reference::referent(_ref); |
0 | 539 assert(Universe::heap()->is_in_reserved_or_null(_referent), |
540 "Wrong oop found in java.lang.Reference object"); | |
541 assert(allow_null_referent ? | |
542 _referent->is_oop_or_null() | |
543 : _referent->is_oop(), | |
544 "bad referent"); | |
545 } | |
546 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
547 inline void DiscoveredListIterator::next() { |
0 | 548 _prev_next = _discovered_addr; |
549 move_to_next(); | |
550 } | |
551 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
552 inline void DiscoveredListIterator::remove() { |
0 | 553 assert(_ref->is_oop(), "Dropping a bad reference"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
554 oop_store_raw(_discovered_addr, NULL); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
555 // First _prev_next ref actually points into DiscoveredList (gross). |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
556 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
557 // Remove Reference object from list. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
558 oopDesc::encode_store_heap_oop_not_null((narrowOop*)_prev_next, _next); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
559 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
560 // Remove Reference object from list. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
561 oopDesc::store_heap_oop((oop*)_prev_next, _next); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
562 } |
0 | 563 NOT_PRODUCT(_removed++); |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
564 _refs_list.dec_length(1); |
0 | 565 } |
566 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
567 inline void DiscoveredListIterator::move_to_next() { |
0 | 568 _ref = _next; |
569 assert(_ref != _first_seen, "cyclic ref_list found"); | |
570 NOT_PRODUCT(_processed++); | |
571 } | |
572 | |
573 // NOTE: process_phase*() are largely similar, and at a high level | |
574 // merely iterate over the extant list applying a predicate to | |
575 // each of its elements and possibly removing that element from the | |
576 // list and applying some further closures to that element. | |
577 // We should consider the possibility of replacing these | |
578 // process_phase*() methods by abstracting them into | |
579 // a single general iterator invocation that receives appropriate | |
580 // closures that accomplish this work. | |
581 | |
582 // (SoftReferences only) Traverse the list and remove any SoftReferences whose | |
583 // referents are not alive, but that should be kept alive for policy reasons. | |
584 // Keep alive the transitive closure of all such referents. | |
585 void | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
586 ReferenceProcessor::process_phase1(DiscoveredList& refs_list, |
0 | 587 ReferencePolicy* policy, |
588 BoolObjectClosure* is_alive, | |
589 OopClosure* keep_alive, | |
590 VoidClosure* complete_gc) { | |
591 assert(policy != NULL, "Must have a non-NULL policy"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
592 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); |
0 | 593 // Decide which softly reachable refs should be kept alive. |
594 while (iter.has_next()) { | |
595 iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */)); | |
596 bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive(); | |
597 if (referent_is_dead && !policy->should_clear_reference(iter.obj())) { | |
598 if (TraceReferenceGC) { | |
599 gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy", | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
600 iter.obj(), iter.obj()->blueprint()->internal_name()); |
0 | 601 } |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
602 // Remove Reference object from list |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
603 iter.remove(); |
0 | 604 // Make the Reference object active again |
605 iter.make_active(); | |
606 // keep the referent around | |
607 iter.make_referent_alive(); | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
608 iter.move_to_next(); |
0 | 609 } else { |
610 iter.next(); | |
611 } | |
612 } | |
613 // Close the reachable set | |
614 complete_gc->do_void(); | |
615 NOT_PRODUCT( | |
616 if (PrintGCDetails && TraceReferenceGC) { | |
617 gclog_or_tty->print(" Dropped %d dead Refs out of %d " | |
618 "discovered Refs by policy ", iter.removed(), iter.processed()); | |
619 } | |
620 ) | |
621 } | |
622 | |
623 // Traverse the list and remove any Refs that are not active, or | |
624 // whose referents are either alive or NULL. | |
625 void | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
626 ReferenceProcessor::pp2_work(DiscoveredList& refs_list, |
0 | 627 BoolObjectClosure* is_alive, |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
628 OopClosure* keep_alive) { |
0 | 629 assert(discovery_is_atomic(), "Error"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
630 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); |
0 | 631 while (iter.has_next()) { |
632 iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
633 DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
634 assert(next == NULL, "Should not discover inactive Reference"); |
0 | 635 if (iter.is_referent_alive()) { |
636 if (TraceReferenceGC) { | |
637 gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)", | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
638 iter.obj(), iter.obj()->blueprint()->internal_name()); |
0 | 639 } |
640 // The referent is reachable after all. | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
641 // Remove Reference object from list. |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
642 iter.remove(); |
0 | 643 // Update the referent pointer as necessary: Note that this |
644 // should not entail any recursive marking because the | |
645 // referent must already have been traversed. | |
646 iter.make_referent_alive(); | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
647 iter.move_to_next(); |
0 | 648 } else { |
649 iter.next(); | |
650 } | |
651 } | |
652 NOT_PRODUCT( | |
653 if (PrintGCDetails && TraceReferenceGC) { | |
654 gclog_or_tty->print(" Dropped %d active Refs out of %d " | |
655 "Refs in discovered list ", iter.removed(), iter.processed()); | |
656 } | |
657 ) | |
658 } | |
659 | |
660 void | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
661 ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList& refs_list, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
662 BoolObjectClosure* is_alive, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
663 OopClosure* keep_alive, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
664 VoidClosure* complete_gc) { |
0 | 665 assert(!discovery_is_atomic(), "Error"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
666 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); |
0 | 667 while (iter.has_next()) { |
668 iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
669 HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj()); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
670 oop next = java_lang_ref_Reference::next(iter.obj()); |
0 | 671 if ((iter.referent() == NULL || iter.is_referent_alive() || |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
672 next != NULL)) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
673 assert(next->is_oop_or_null(), "bad next field"); |
0 | 674 // Remove Reference object from list |
675 iter.remove(); | |
676 // Trace the cohorts | |
677 iter.make_referent_alive(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
678 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
679 keep_alive->do_oop((narrowOop*)next_addr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
680 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
681 keep_alive->do_oop((oop*)next_addr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
682 } |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
683 iter.move_to_next(); |
0 | 684 } else { |
685 iter.next(); | |
686 } | |
687 } | |
688 // Now close the newly reachable set | |
689 complete_gc->do_void(); | |
690 NOT_PRODUCT( | |
691 if (PrintGCDetails && TraceReferenceGC) { | |
692 gclog_or_tty->print(" Dropped %d active Refs out of %d " | |
693 "Refs in discovered list ", iter.removed(), iter.processed()); | |
694 } | |
695 ) | |
696 } | |
697 | |
698 // Traverse the list and process the referents, by either | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
699 // clearing them or keeping them (and their reachable |
0 | 700 // closure) alive. |
701 void | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
702 ReferenceProcessor::process_phase3(DiscoveredList& refs_list, |
0 | 703 bool clear_referent, |
704 BoolObjectClosure* is_alive, | |
705 OopClosure* keep_alive, | |
706 VoidClosure* complete_gc) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
707 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); |
0 | 708 while (iter.has_next()) { |
709 iter.update_discovered(); | |
710 iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); | |
711 if (clear_referent) { | |
712 // NULL out referent pointer | |
713 iter.clear_referent(); | |
714 } else { | |
715 // keep the referent around | |
716 iter.make_referent_alive(); | |
717 } | |
718 if (TraceReferenceGC) { | |
719 gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", | |
720 clear_referent ? "cleared " : "", | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
721 iter.obj(), iter.obj()->blueprint()->internal_name()); |
0 | 722 } |
723 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference"); | |
724 iter.next(); | |
725 } | |
726 // Remember to keep sentinel pointer around | |
727 iter.update_discovered(); | |
728 // Close the reachable set | |
729 complete_gc->do_void(); | |
730 } | |
731 | |
732 void | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
733 ReferenceProcessor::abandon_partial_discovered_list(DiscoveredList& refs_list) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
734 oop obj = refs_list.head(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
735 while (obj != sentinel_ref()) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
736 oop discovered = java_lang_ref_Reference::discovered(obj); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
737 java_lang_ref_Reference::set_discovered_raw(obj, NULL); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
738 obj = discovered; |
0 | 739 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
740 refs_list.set_head(sentinel_ref()); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
741 refs_list.set_length(0); |
0 | 742 } |
743 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
744 void ReferenceProcessor::abandon_partial_discovery() { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
745 // loop over the lists |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
746 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
747 if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
748 gclog_or_tty->print_cr( |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
749 "\nAbandoning %s discovered list", |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
750 list_name(i)); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
751 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
752 abandon_partial_discovered_list(_discoveredSoftRefs[i]); |
0 | 753 } |
754 } | |
755 | |
756 class RefProcPhase1Task: public AbstractRefProcTaskExecutor::ProcessTask { | |
757 public: | |
758 RefProcPhase1Task(ReferenceProcessor& ref_processor, | |
759 DiscoveredList refs_lists[], | |
760 ReferencePolicy* policy, | |
761 bool marks_oops_alive) | |
762 : ProcessTask(ref_processor, refs_lists, marks_oops_alive), | |
763 _policy(policy) | |
764 { } | |
765 virtual void work(unsigned int i, BoolObjectClosure& is_alive, | |
766 OopClosure& keep_alive, | |
767 VoidClosure& complete_gc) | |
768 { | |
769 _ref_processor.process_phase1(_refs_lists[i], _policy, | |
770 &is_alive, &keep_alive, &complete_gc); | |
771 } | |
772 private: | |
773 ReferencePolicy* _policy; | |
774 }; | |
775 | |
776 class RefProcPhase2Task: public AbstractRefProcTaskExecutor::ProcessTask { | |
777 public: | |
778 RefProcPhase2Task(ReferenceProcessor& ref_processor, | |
779 DiscoveredList refs_lists[], | |
780 bool marks_oops_alive) | |
781 : ProcessTask(ref_processor, refs_lists, marks_oops_alive) | |
782 { } | |
783 virtual void work(unsigned int i, BoolObjectClosure& is_alive, | |
784 OopClosure& keep_alive, | |
785 VoidClosure& complete_gc) | |
786 { | |
787 _ref_processor.process_phase2(_refs_lists[i], | |
788 &is_alive, &keep_alive, &complete_gc); | |
789 } | |
790 }; | |
791 | |
792 class RefProcPhase3Task: public AbstractRefProcTaskExecutor::ProcessTask { | |
793 public: | |
794 RefProcPhase3Task(ReferenceProcessor& ref_processor, | |
795 DiscoveredList refs_lists[], | |
796 bool clear_referent, | |
797 bool marks_oops_alive) | |
798 : ProcessTask(ref_processor, refs_lists, marks_oops_alive), | |
799 _clear_referent(clear_referent) | |
800 { } | |
801 virtual void work(unsigned int i, BoolObjectClosure& is_alive, | |
802 OopClosure& keep_alive, | |
803 VoidClosure& complete_gc) | |
804 { | |
805 _ref_processor.process_phase3(_refs_lists[i], _clear_referent, | |
806 &is_alive, &keep_alive, &complete_gc); | |
807 } | |
808 private: | |
809 bool _clear_referent; | |
810 }; | |
811 | |
812 // Balances reference queues. | |
813 void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[]) | |
814 { | |
815 // calculate total length | |
816 size_t total_refs = 0; | |
817 for (int i = 0; i < _num_q; ++i) { | |
818 total_refs += ref_lists[i].length(); | |
819 } | |
820 size_t avg_refs = total_refs / _num_q + 1; | |
821 int to_idx = 0; | |
822 for (int from_idx = 0; from_idx < _num_q; from_idx++) { | |
823 while (ref_lists[from_idx].length() > avg_refs) { | |
824 assert(to_idx < _num_q, "Sanity Check!"); | |
825 if (ref_lists[to_idx].length() < avg_refs) { | |
826 // move superfluous refs | |
827 size_t refs_to_move = | |
828 MIN2(ref_lists[from_idx].length() - avg_refs, | |
829 avg_refs - ref_lists[to_idx].length()); | |
830 oop move_head = ref_lists[from_idx].head(); | |
831 oop move_tail = move_head; | |
832 oop new_head = move_head; | |
833 // find an element to split the list on | |
834 for (size_t j = 0; j < refs_to_move; ++j) { | |
835 move_tail = new_head; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
836 new_head = java_lang_ref_Reference::discovered(new_head); |
0 | 837 } |
838 java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head()); | |
839 ref_lists[to_idx].set_head(move_head); | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
840 ref_lists[to_idx].inc_length(refs_to_move); |
0 | 841 ref_lists[from_idx].set_head(new_head); |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
842 ref_lists[from_idx].dec_length(refs_to_move); |
0 | 843 } else { |
844 ++to_idx; | |
845 } | |
846 } | |
847 } | |
848 } | |
849 | |
850 void | |
851 ReferenceProcessor::process_discovered_reflist( | |
852 DiscoveredList refs_lists[], | |
853 ReferencePolicy* policy, | |
854 bool clear_referent, | |
855 BoolObjectClosure* is_alive, | |
856 OopClosure* keep_alive, | |
857 VoidClosure* complete_gc, | |
858 AbstractRefProcTaskExecutor* task_executor) | |
859 { | |
860 bool mt = task_executor != NULL && _processing_is_mt; | |
861 if (mt && ParallelRefProcBalancingEnabled) { | |
862 balance_queues(refs_lists); | |
863 } | |
864 if (PrintReferenceGC && PrintGCDetails) { | |
865 size_t total = 0; | |
866 for (int i = 0; i < _num_q; ++i) { | |
867 total += refs_lists[i].length(); | |
868 } | |
869 gclog_or_tty->print(", %u refs", total); | |
870 } | |
871 | |
872 // Phase 1 (soft refs only): | |
873 // . Traverse the list and remove any SoftReferences whose | |
874 // referents are not alive, but that should be kept alive for | |
875 // policy reasons. Keep alive the transitive closure of all | |
876 // such referents. | |
877 if (policy != NULL) { | |
878 if (mt) { | |
879 RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/); | |
880 task_executor->execute(phase1); | |
881 } else { | |
882 for (int i = 0; i < _num_q; i++) { | |
883 process_phase1(refs_lists[i], policy, | |
884 is_alive, keep_alive, complete_gc); | |
885 } | |
886 } | |
887 } else { // policy == NULL | |
888 assert(refs_lists != _discoveredSoftRefs, | |
889 "Policy must be specified for soft references."); | |
890 } | |
891 | |
892 // Phase 2: | |
893 // . Traverse the list and remove any refs whose referents are alive. | |
894 if (mt) { | |
895 RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/); | |
896 task_executor->execute(phase2); | |
897 } else { | |
898 for (int i = 0; i < _num_q; i++) { | |
899 process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc); | |
900 } | |
901 } | |
902 | |
903 // Phase 3: | |
904 // . Traverse the list and process referents as appropriate. | |
905 if (mt) { | |
906 RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/); | |
907 task_executor->execute(phase3); | |
908 } else { | |
909 for (int i = 0; i < _num_q; i++) { | |
910 process_phase3(refs_lists[i], clear_referent, | |
911 is_alive, keep_alive, complete_gc); | |
912 } | |
913 } | |
914 } | |
915 | |
916 void ReferenceProcessor::clean_up_discovered_references() { | |
917 // loop over the lists | |
918 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | |
919 if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) { | |
920 gclog_or_tty->print_cr( | |
921 "\nScrubbing %s discovered list of Null referents", | |
922 list_name(i)); | |
923 } | |
924 clean_up_discovered_reflist(_discoveredSoftRefs[i]); | |
925 } | |
926 } | |
927 | |
928 void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) { | |
929 assert(!discovery_is_atomic(), "Else why call this method?"); | |
930 DiscoveredListIterator iter(refs_list, NULL, NULL); | |
931 while (iter.has_next()) { | |
932 iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
933 oop next = java_lang_ref_Reference::next(iter.obj()); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
934 assert(next->is_oop_or_null(), "bad next field"); |
0 | 935 // If referent has been cleared or Reference is not active, |
936 // drop it. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
937 if (iter.referent() == NULL || next != NULL) { |
0 | 938 debug_only( |
939 if (PrintGCDetails && TraceReferenceGC) { | |
940 gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: " | |
941 INTPTR_FORMAT " with next field: " INTPTR_FORMAT | |
942 " and referent: " INTPTR_FORMAT, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
943 iter.obj(), next, iter.referent()); |
0 | 944 } |
945 ) | |
946 // Remove Reference object from list | |
947 iter.remove(); | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
948 iter.move_to_next(); |
0 | 949 } else { |
950 iter.next(); | |
951 } | |
952 } | |
953 NOT_PRODUCT( | |
954 if (PrintGCDetails && TraceReferenceGC) { | |
955 gclog_or_tty->print( | |
956 " Removed %d Refs with NULL referents out of %d discovered Refs", | |
957 iter.removed(), iter.processed()); | |
958 } | |
959 ) | |
960 } | |
961 | |
962 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) { | |
963 int id = 0; | |
964 // Determine the queue index to use for this object. | |
965 if (_discovery_is_mt) { | |
966 // During a multi-threaded discovery phase, | |
967 // each thread saves to its "own" list. | |
968 Thread* thr = Thread::current(); | |
969 assert(thr->is_GC_task_thread(), | |
970 "Dubious cast from Thread* to WorkerThread*?"); | |
971 id = ((WorkerThread*)thr)->id(); | |
972 } else { | |
973 // single-threaded discovery, we save in round-robin | |
974 // fashion to each of the lists. | |
975 if (_processing_is_mt) { | |
976 id = next_id(); | |
977 } | |
978 } | |
979 assert(0 <= id && id < _num_q, "Id is out-of-bounds (call Freud?)"); | |
980 | |
981 // Get the discovered queue to which we will add | |
982 DiscoveredList* list = NULL; | |
983 switch (rt) { | |
984 case REF_OTHER: | |
985 // Unknown reference type, no special treatment | |
986 break; | |
987 case REF_SOFT: | |
988 list = &_discoveredSoftRefs[id]; | |
989 break; | |
990 case REF_WEAK: | |
991 list = &_discoveredWeakRefs[id]; | |
992 break; | |
993 case REF_FINAL: | |
994 list = &_discoveredFinalRefs[id]; | |
995 break; | |
996 case REF_PHANTOM: | |
997 list = &_discoveredPhantomRefs[id]; | |
998 break; | |
999 case REF_NONE: | |
1000 // we should not reach here if we are an instanceRefKlass | |
1001 default: | |
1002 ShouldNotReachHere(); | |
1003 } | |
1004 return list; | |
1005 } | |
1006 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1007 inline void |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1008 ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1009 oop obj, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1010 HeapWord* discovered_addr) { |
0 | 1011 assert(_discovery_is_mt, "!_discovery_is_mt should have been handled by caller"); |
1012 // First we must make sure this object is only enqueued once. CAS in a non null | |
1013 // discovered_addr. | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1014 oop current_head = refs_list.head(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1015 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1016 // Note: In the case of G1, this specific pre-barrier is strictly |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1017 // not necessary because the only case we are interested in |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1018 // here is when *discovered_addr is NULL (see the CAS further below), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1019 // so this will expand to nothing. As a result, we have manually |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1020 // elided this out for G1, but left in the test for some future |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1021 // collector that might have need for a pre-barrier here. |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1022 if (_discovered_list_needs_barrier && !UseG1GC) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1023 if (UseCompressedOops) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1024 _bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1025 } else { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1026 _bs->write_ref_field_pre((oop*)discovered_addr, current_head); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1027 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1028 guarantee(false, "Need to check non-G1 collector"); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1029 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1030 oop retest = oopDesc::atomic_compare_exchange_oop(current_head, discovered_addr, |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1031 NULL); |
0 | 1032 if (retest == NULL) { |
1033 // This thread just won the right to enqueue the object. | |
1034 // We have separate lists for enqueueing so no synchronization | |
1035 // is necessary. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1036 refs_list.set_head(obj); |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1037 refs_list.inc_length(1); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1038 if (_discovered_list_needs_barrier) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1039 _bs->write_ref_field((void*)discovered_addr, current_head); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1040 } |
0 | 1041 } else { |
1042 // If retest was non NULL, another thread beat us to it: | |
1043 // The reference has already been discovered... | |
1044 if (TraceReferenceGC) { | |
1045 gclog_or_tty->print_cr("Already enqueued reference (" INTPTR_FORMAT ": %s)", | |
1046 obj, obj->blueprint()->internal_name()); | |
1047 } | |
1048 } | |
1049 } | |
1050 | |
1051 // We mention two of several possible choices here: | |
1052 // #0: if the reference object is not in the "originating generation" | |
1053 // (or part of the heap being collected, indicated by our "span" | |
1054 // we don't treat it specially (i.e. we scan it as we would | |
1055 // a normal oop, treating its references as strong references). | |
1056 // This means that references can't be enqueued unless their | |
1057 // referent is also in the same span. This is the simplest, | |
1058 // most "local" and most conservative approach, albeit one | |
1059 // that may cause weak references to be enqueued least promptly. | |
1060 // We call this choice the "ReferenceBasedDiscovery" policy. | |
1061 // #1: the reference object may be in any generation (span), but if | |
1062 // the referent is in the generation (span) being currently collected | |
1063 // then we can discover the reference object, provided | |
1064 // the object has not already been discovered by | |
1065 // a different concurrently running collector (as may be the | |
1066 // case, for instance, if the reference object is in CMS and | |
1067 // the referent in DefNewGeneration), and provided the processing | |
1068 // of this reference object by the current collector will | |
1069 // appear atomic to every other collector in the system. | |
1070 // (Thus, for instance, a concurrent collector may not | |
1071 // discover references in other generations even if the | |
1072 // referent is in its own generation). This policy may, | |
1073 // in certain cases, enqueue references somewhat sooner than | |
1074 // might Policy #0 above, but at marginally increased cost | |
1075 // and complexity in processing these references. | |
1076 // We call this choice the "RefeferentBasedDiscovery" policy. | |
1077 bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { | |
1078 // We enqueue references only if we are discovering refs | |
1079 // (rather than processing discovered refs). | |
1080 if (!_discovering_refs || !RegisterReferences) { | |
1081 return false; | |
1082 } | |
1083 // We only enqueue active references. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1084 oop next = java_lang_ref_Reference::next(obj); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1085 if (next != NULL) { |
0 | 1086 return false; |
1087 } | |
1088 | |
1089 HeapWord* obj_addr = (HeapWord*)obj; | |
1090 if (RefDiscoveryPolicy == ReferenceBasedDiscovery && | |
1091 !_span.contains(obj_addr)) { | |
1092 // Reference is not in the originating generation; | |
1093 // don't treat it specially (i.e. we want to scan it as a normal | |
1094 // object with strong references). | |
1095 return false; | |
1096 } | |
1097 | |
1098 // We only enqueue references whose referents are not (yet) strongly | |
1099 // reachable. | |
1100 if (is_alive_non_header() != NULL) { | |
1101 oop referent = java_lang_ref_Reference::referent(obj); | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1102 // In the case of non-concurrent discovery, the last |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1103 // disjunct below should hold. It may not hold in the |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1104 // case of concurrent discovery because mutators may |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1105 // concurrently clear() a Reference. |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1106 assert(UseConcMarkSweepGC || UseG1GC || referent != NULL, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1107 "Refs with null referents already filtered"); |
0 | 1108 if (is_alive_non_header()->do_object_b(referent)) { |
1109 return false; // referent is reachable | |
1110 } | |
1111 } | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1112 if (rt == REF_SOFT) { |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1113 // For soft refs we can decide now if these are not |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1114 // current candidates for clearing, in which case we |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1115 // can mark through them now, rather than delaying that |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1116 // to the reference-processing phase. Since all current |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1117 // time-stamp policies advance the soft-ref clock only |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1118 // at a major collection cycle, this is always currently |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1119 // accurate. |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1120 if (!_current_soft_ref_policy->should_clear_reference(obj)) { |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1121 return false; |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1122 } |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1123 } |
0 | 1124 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1125 HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1126 const oop discovered = java_lang_ref_Reference::discovered(obj); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1127 assert(discovered->is_oop_or_null(), "bad discovered field"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1128 if (discovered != NULL) { |
0 | 1129 // The reference has already been discovered... |
1130 if (TraceReferenceGC) { | |
1131 gclog_or_tty->print_cr("Already enqueued reference (" INTPTR_FORMAT ": %s)", | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1132 obj, obj->blueprint()->internal_name()); |
0 | 1133 } |
1134 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { | |
1135 // assumes that an object is not processed twice; | |
1136 // if it's been already discovered it must be on another | |
1137 // generation's discovered list; so we won't discover it. | |
1138 return false; | |
1139 } else { | |
1140 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery, | |
1141 "Unrecognized policy"); | |
1142 // Check assumption that an object is not potentially | |
1143 // discovered twice except by concurrent collectors that potentially | |
1144 // trace the same Reference object twice. | |
1145 assert(UseConcMarkSweepGC, | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1146 "Only possible with an incremental-update concurrent collector"); |
0 | 1147 return true; |
1148 } | |
1149 } | |
1150 | |
1151 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { | |
1152 oop referent = java_lang_ref_Reference::referent(obj); | |
1153 assert(referent->is_oop(), "bad referent"); | |
1154 // enqueue if and only if either: | |
1155 // reference is in our span or | |
1156 // we are an atomic collector and referent is in our span | |
1157 if (_span.contains(obj_addr) || | |
1158 (discovery_is_atomic() && _span.contains(referent))) { | |
1159 // should_enqueue = true; | |
1160 } else { | |
1161 return false; | |
1162 } | |
1163 } else { | |
1164 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery && | |
1165 _span.contains(obj_addr), "code inconsistency"); | |
1166 } | |
1167 | |
1168 // Get the right type of discovered queue head. | |
1169 DiscoveredList* list = get_discovered_list(rt); | |
1170 if (list == NULL) { | |
1171 return false; // nothing special needs to be done | |
1172 } | |
1173 | |
1174 if (_discovery_is_mt) { | |
1175 add_to_discovered_list_mt(*list, obj, discovered_addr); | |
1176 } else { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1177 // If "_discovered_list_needs_barrier", we do write barriers when |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1178 // updating the discovered reference list. Otherwise, we do a raw store |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1179 // here: the field will be visited later when processing the discovered |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1180 // references. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1181 oop current_head = list->head(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1182 // As in the case further above, since we are over-writing a NULL |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1183 // pre-value, we can safely elide the pre-barrier here for the case of G1. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1184 assert(discovered == NULL, "control point invariant"); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1185 if (_discovered_list_needs_barrier && !UseG1GC) { // safe to elide for G1 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1186 if (UseCompressedOops) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1187 _bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1188 } else { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1189 _bs->write_ref_field_pre((oop*)discovered_addr, current_head); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1190 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1191 guarantee(false, "Need to check non-G1 collector"); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1192 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1193 oop_store_raw(discovered_addr, current_head); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1194 if (_discovered_list_needs_barrier) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1195 _bs->write_ref_field((void*)discovered_addr, current_head); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1196 } |
0 | 1197 list->set_head(obj); |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1198 list->inc_length(1); |
0 | 1199 } |
1200 | |
1201 // In the MT discovery case, it is currently possible to see | |
1202 // the following message multiple times if several threads | |
1203 // discover a reference about the same time. Only one will | |
1204 // however have actually added it to the disocvered queue. | |
1205 // One could let add_to_discovered_list_mt() return an | |
1206 // indication for success in queueing (by 1 thread) or | |
1207 // failure (by all other threads), but I decided the extra | |
1208 // code was not worth the effort for something that is | |
1209 // only used for debugging support. | |
1210 if (TraceReferenceGC) { | |
1211 oop referent = java_lang_ref_Reference::referent(obj); | |
1212 if (PrintGCDetails) { | |
1213 gclog_or_tty->print_cr("Enqueued reference (" INTPTR_FORMAT ": %s)", | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1214 obj, obj->blueprint()->internal_name()); |
0 | 1215 } |
1216 assert(referent->is_oop(), "Enqueued a bad referent"); | |
1217 } | |
1218 assert(obj->is_oop(), "Enqueued a bad reference"); | |
1219 return true; | |
1220 } | |
1221 | |
1222 // Preclean the discovered references by removing those | |
1223 // whose referents are alive, and by marking from those that | |
1224 // are not active. These lists can be handled here | |
1225 // in any order and, indeed, concurrently. | |
1226 void ReferenceProcessor::preclean_discovered_references( | |
1227 BoolObjectClosure* is_alive, | |
1228 OopClosure* keep_alive, | |
1229 VoidClosure* complete_gc, | |
1190
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1230 YieldClosure* yield, |
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1231 bool should_unload_classes) { |
0 | 1232 |
1233 NOT_PRODUCT(verify_ok_to_handle_reflists()); | |
1234 | |
935 | 1235 #ifdef ASSERT |
1236 bool must_remember_klasses = ClassUnloading && !UseConcMarkSweepGC || | |
1190
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1237 CMSClassUnloadingEnabled && UseConcMarkSweepGC || |
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1238 ExplicitGCInvokesConcurrentAndUnloadsClasses && |
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1239 UseConcMarkSweepGC && should_unload_classes; |
935 | 1240 RememberKlassesChecker mx(must_remember_klasses); |
1241 #endif | |
0 | 1242 // Soft references |
1243 { | |
1244 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, | |
1245 false, gclog_or_tty); | |
1246 for (int i = 0; i < _num_q; i++) { | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1247 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1248 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1249 } |
0 | 1250 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, |
1251 keep_alive, complete_gc, yield); | |
1252 } | |
1253 } | |
1254 | |
1255 // Weak references | |
1256 { | |
1257 TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, | |
1258 false, gclog_or_tty); | |
1259 for (int i = 0; i < _num_q; i++) { | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1260 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1261 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1262 } |
0 | 1263 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, |
1264 keep_alive, complete_gc, yield); | |
1265 } | |
1266 } | |
1267 | |
1268 // Final references | |
1269 { | |
1270 TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, | |
1271 false, gclog_or_tty); | |
1272 for (int i = 0; i < _num_q; i++) { | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1273 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1274 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1275 } |
0 | 1276 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, |
1277 keep_alive, complete_gc, yield); | |
1278 } | |
1279 } | |
1280 | |
1281 // Phantom references | |
1282 { | |
1283 TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, | |
1284 false, gclog_or_tty); | |
1285 for (int i = 0; i < _num_q; i++) { | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1286 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1287 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1288 } |
0 | 1289 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, |
1290 keep_alive, complete_gc, yield); | |
1291 } | |
1292 } | |
1293 } | |
1294 | |
1295 // Walk the given discovered ref list, and remove all reference objects | |
1296 // whose referents are still alive, whose referents are NULL or which | |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1297 // are not active (have a non-NULL next field). NOTE: When we are |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1298 // thus precleaning the ref lists (which happens single-threaded today), |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1299 // we do not disable refs discovery to honour the correct semantics of |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1300 // java.lang.Reference. As a result, we need to be careful below |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1301 // that ref removal steps interleave safely with ref discovery steps |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1302 // (in this thread). |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1303 void |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1304 ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1305 BoolObjectClosure* is_alive, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1306 OopClosure* keep_alive, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1307 VoidClosure* complete_gc, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1308 YieldClosure* yield) { |
0 | 1309 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); |
1310 while (iter.has_next()) { | |
1311 iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1312 oop obj = iter.obj(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1313 oop next = java_lang_ref_Reference::next(obj); |
0 | 1314 if (iter.referent() == NULL || iter.is_referent_alive() || |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1315 next != NULL) { |
0 | 1316 // The referent has been cleared, or is alive, or the Reference is not |
1317 // active; we need to trace and mark its cohort. | |
1318 if (TraceReferenceGC) { | |
1319 gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)", | |
1320 iter.obj(), iter.obj()->blueprint()->internal_name()); | |
1321 } | |
1322 // Remove Reference object from list | |
1323 iter.remove(); | |
1324 // Keep alive its cohort. | |
1325 iter.make_referent_alive(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1326 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1327 narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1328 keep_alive->do_oop(next_addr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1329 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1330 oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1331 keep_alive->do_oop(next_addr); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1332 } |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1333 iter.move_to_next(); |
0 | 1334 } else { |
1335 iter.next(); | |
1336 } | |
1337 } | |
1338 // Close the reachable set | |
1339 complete_gc->do_void(); | |
1340 | |
1341 NOT_PRODUCT( | |
1342 if (PrintGCDetails && PrintReferenceGC) { | |
1343 gclog_or_tty->print(" Dropped %d Refs out of %d " | |
1344 "Refs in discovered list ", iter.removed(), iter.processed()); | |
1345 } | |
1346 ) | |
1347 } | |
1348 | |
1349 const char* ReferenceProcessor::list_name(int i) { | |
1350 assert(i >= 0 && i <= _num_q * subclasses_of_ref, "Out of bounds index"); | |
1351 int j = i / _num_q; | |
1352 switch (j) { | |
1353 case 0: return "SoftRef"; | |
1354 case 1: return "WeakRef"; | |
1355 case 2: return "FinalRef"; | |
1356 case 3: return "PhantomRef"; | |
1357 } | |
1358 ShouldNotReachHere(); | |
1359 return NULL; | |
1360 } | |
1361 | |
1362 #ifndef PRODUCT | |
1363 void ReferenceProcessor::verify_ok_to_handle_reflists() { | |
1364 // empty for now | |
1365 } | |
1366 #endif | |
1367 | |
1368 void ReferenceProcessor::verify() { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1369 guarantee(sentinel_ref() != NULL && sentinel_ref()->is_oop(), "Lost _sentinelRef"); |
0 | 1370 } |
1371 | |
1372 #ifndef PRODUCT | |
1373 void ReferenceProcessor::clear_discovered_references() { | |
1374 guarantee(!_discovering_refs, "Discovering refs?"); | |
1375 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | |
1376 oop obj = _discoveredSoftRefs[i].head(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1377 while (obj != sentinel_ref()) { |
0 | 1378 oop next = java_lang_ref_Reference::discovered(obj); |
1379 java_lang_ref_Reference::set_discovered(obj, (oop) NULL); | |
1380 obj = next; | |
1381 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1382 _discoveredSoftRefs[i].set_head(sentinel_ref()); |
0 | 1383 _discoveredSoftRefs[i].set_length(0); |
1384 } | |
1385 } | |
1386 #endif // PRODUCT |