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