Mercurial > hg > graal-jvmci-8
annotate src/share/vm/memory/referenceProcessor.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | fd1d227ef1b9 |
children | 8df09fb45352 |
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 | |
1149 // We mention two of several possible choices here: | |
1150 // #0: if the reference object is not in the "originating generation" | |
1151 // (or part of the heap being collected, indicated by our "span" | |
1152 // we don't treat it specially (i.e. we scan it as we would | |
1153 // a normal oop, treating its references as strong references). | |
1154 // This means that references can't be enqueued unless their | |
1155 // referent is also in the same span. This is the simplest, | |
1156 // most "local" and most conservative approach, albeit one | |
1157 // that may cause weak references to be enqueued least promptly. | |
1158 // We call this choice the "ReferenceBasedDiscovery" policy. | |
1159 // #1: the reference object may be in any generation (span), but if | |
1160 // the referent is in the generation (span) being currently collected | |
1161 // then we can discover the reference object, provided | |
1162 // the object has not already been discovered by | |
1163 // a different concurrently running collector (as may be the | |
1164 // case, for instance, if the reference object is in CMS and | |
1165 // the referent in DefNewGeneration), and provided the processing | |
1166 // of this reference object by the current collector will | |
1167 // appear atomic to every other collector in the system. | |
1168 // (Thus, for instance, a concurrent collector may not | |
1169 // discover references in other generations even if the | |
1170 // referent is in its own generation). This policy may, | |
1171 // in certain cases, enqueue references somewhat sooner than | |
1172 // might Policy #0 above, but at marginally increased cost | |
1173 // and complexity in processing these references. | |
1174 // We call this choice the "RefeferentBasedDiscovery" policy. | |
1175 bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { | |
1176 // We enqueue references only if we are discovering refs | |
1177 // (rather than processing discovered refs). | |
1178 if (!_discovering_refs || !RegisterReferences) { | |
1179 return false; | |
1180 } | |
1181 // 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
|
1182 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
|
1183 if (next != NULL) { |
0 | 1184 return false; |
1185 } | |
1186 | |
1187 HeapWord* obj_addr = (HeapWord*)obj; | |
1188 if (RefDiscoveryPolicy == ReferenceBasedDiscovery && | |
1189 !_span.contains(obj_addr)) { | |
1190 // Reference is not in the originating generation; | |
1191 // don't treat it specially (i.e. we want to scan it as a normal | |
1192 // object with strong references). | |
1193 return false; | |
1194 } | |
1195 | |
1196 // We only enqueue references whose referents are not (yet) strongly | |
1197 // reachable. | |
1198 if (is_alive_non_header() != NULL) { | |
1199 oop referent = java_lang_ref_Reference::referent(obj); | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1200 // In the case of non-concurrent discovery, the last |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1201 // disjunct below should hold. It may not hold in the |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1202 // case of concurrent discovery because mutators may |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1203 // concurrently clear() a Reference. |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1204 assert(UseConcMarkSweepGC || UseG1GC || referent != NULL, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1205 "Refs with null referents already filtered"); |
0 | 1206 if (is_alive_non_header()->do_object_b(referent)) { |
1207 return false; // referent is reachable | |
1208 } | |
1209 } | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1210 if (rt == REF_SOFT) { |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1211 // 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
|
1212 // current candidates for clearing, in which case we |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1213 // can mark through them now, rather than delaying that |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1214 // to the reference-processing phase. Since all current |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1215 // time-stamp policies advance the soft-ref clock only |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1216 // at a major collection cycle, this is always currently |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1217 // accurate. |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1218 if (!_current_soft_ref_policy->should_clear_reference(obj)) { |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1219 return false; |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1220 } |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
452
diff
changeset
|
1221 } |
0 | 1222 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1223 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
|
1224 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
|
1225 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
|
1226 if (discovered != NULL) { |
0 | 1227 // The reference has already been discovered... |
1228 if (TraceReferenceGC) { | |
1229 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
|
1230 obj, obj->blueprint()->internal_name()); |
0 | 1231 } |
1232 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { | |
1233 // assumes that an object is not processed twice; | |
1234 // if it's been already discovered it must be on another | |
1235 // generation's discovered list; so we won't discover it. | |
1236 return false; | |
1237 } else { | |
1238 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery, | |
1239 "Unrecognized policy"); | |
1240 // Check assumption that an object is not potentially | |
1241 // discovered twice except by concurrent collectors that potentially | |
1242 // trace the same Reference object twice. | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1972
diff
changeset
|
1243 assert(UseConcMarkSweepGC || UseG1GC, |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1972
diff
changeset
|
1244 "Only possible with a concurrent marking collector"); |
0 | 1245 return true; |
1246 } | |
1247 } | |
1248 | |
1249 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { | |
1250 oop referent = java_lang_ref_Reference::referent(obj); | |
1251 assert(referent->is_oop(), "bad referent"); | |
1252 // enqueue if and only if either: | |
1253 // reference is in our span or | |
1254 // we are an atomic collector and referent is in our span | |
1255 if (_span.contains(obj_addr) || | |
1256 (discovery_is_atomic() && _span.contains(referent))) { | |
1257 // should_enqueue = true; | |
1258 } else { | |
1259 return false; | |
1260 } | |
1261 } else { | |
1262 assert(RefDiscoveryPolicy == ReferenceBasedDiscovery && | |
1263 _span.contains(obj_addr), "code inconsistency"); | |
1264 } | |
1265 | |
1266 // Get the right type of discovered queue head. | |
1267 DiscoveredList* list = get_discovered_list(rt); | |
1268 if (list == NULL) { | |
1269 return false; // nothing special needs to be done | |
1270 } | |
1271 | |
1272 if (_discovery_is_mt) { | |
1273 add_to_discovered_list_mt(*list, obj, discovered_addr); | |
1274 } else { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1275 // If "_discovered_list_needs_barrier", we do write barriers when |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1276 // 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
|
1277 // 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
|
1278 // references. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1279 oop current_head = list->head(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1280 // 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
|
1281 // 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
|
1282 assert(discovered == NULL, "control point invariant"); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1283 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
|
1284 if (UseCompressedOops) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1285 _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
|
1286 } else { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1287 _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
|
1288 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1289 guarantee(false, "Need to check non-G1 collector"); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1290 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1291 oop_store_raw(discovered_addr, current_head); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1292 if (_discovered_list_needs_barrier) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
1293 _bs->write_ref_field((void*)discovered_addr, current_head); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1294 } |
0 | 1295 list->set_head(obj); |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1296 list->inc_length(1); |
0 | 1297 |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1972
diff
changeset
|
1298 if (TraceReferenceGC) { |
0 | 1299 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
|
1300 obj, obj->blueprint()->internal_name()); |
0 | 1301 } |
1302 } | |
1303 assert(obj->is_oop(), "Enqueued a bad reference"); | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1972
diff
changeset
|
1304 assert(java_lang_ref_Reference::referent(obj)->is_oop(), "Enqueued a bad referent"); |
0 | 1305 return true; |
1306 } | |
1307 | |
1308 // Preclean the discovered references by removing those | |
1309 // whose referents are alive, and by marking from those that | |
1310 // are not active. These lists can be handled here | |
1311 // in any order and, indeed, concurrently. | |
1312 void ReferenceProcessor::preclean_discovered_references( | |
1313 BoolObjectClosure* is_alive, | |
1314 OopClosure* keep_alive, | |
1315 VoidClosure* complete_gc, | |
1190
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1316 YieldClosure* yield, |
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1317 bool should_unload_classes) { |
0 | 1318 |
1319 NOT_PRODUCT(verify_ok_to_handle_reflists()); | |
1320 | |
935 | 1321 #ifdef ASSERT |
1322 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
|
1323 CMSClassUnloadingEnabled && UseConcMarkSweepGC || |
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1324 ExplicitGCInvokesConcurrentAndUnloadsClasses && |
4788266644c1
6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents:
1144
diff
changeset
|
1325 UseConcMarkSweepGC && should_unload_classes; |
935 | 1326 RememberKlassesChecker mx(must_remember_klasses); |
1327 #endif | |
0 | 1328 // Soft references |
1329 { | |
1330 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, | |
1331 false, gclog_or_tty); | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1552
diff
changeset
|
1332 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
|
1333 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1334 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1335 } |
0 | 1336 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, |
1337 keep_alive, complete_gc, yield); | |
1338 } | |
1339 } | |
1340 | |
1341 // Weak references | |
1342 { | |
1343 TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, | |
1344 false, gclog_or_tty); | |
1345 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
|
1346 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1347 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1348 } |
0 | 1349 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, |
1350 keep_alive, complete_gc, yield); | |
1351 } | |
1352 } | |
1353 | |
1354 // Final references | |
1355 { | |
1356 TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, | |
1357 false, gclog_or_tty); | |
1358 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
|
1359 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1360 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1361 } |
0 | 1362 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, |
1363 keep_alive, complete_gc, yield); | |
1364 } | |
1365 } | |
1366 | |
1367 // Phantom references | |
1368 { | |
1369 TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, | |
1370 false, gclog_or_tty); | |
1371 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
|
1372 if (yield->should_return()) { |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1373 return; |
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1374 } |
0 | 1375 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, |
1376 keep_alive, complete_gc, yield); | |
1377 } | |
1378 } | |
1379 } | |
1380 | |
1381 // Walk the given discovered ref list, and remove all reference objects | |
1382 // 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
|
1383 // 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
|
1384 // 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
|
1385 // 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
|
1386 // 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
|
1387 // 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
|
1388 // (in this thread). |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1389 void |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1390 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
|
1391 BoolObjectClosure* is_alive, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1392 OopClosure* keep_alive, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1393 VoidClosure* complete_gc, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1394 YieldClosure* yield) { |
0 | 1395 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); |
1396 while (iter.has_next()) { | |
1397 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
|
1398 oop obj = iter.obj(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1399 oop next = java_lang_ref_Reference::next(obj); |
0 | 1400 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
|
1401 next != NULL) { |
0 | 1402 // The referent has been cleared, or is alive, or the Reference is not |
1403 // active; we need to trace and mark its cohort. | |
1404 if (TraceReferenceGC) { | |
1405 gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)", | |
1406 iter.obj(), iter.obj()->blueprint()->internal_name()); | |
1407 } | |
1408 // Remove Reference object from list | |
1409 iter.remove(); | |
1410 // Keep alive its cohort. | |
1411 iter.make_referent_alive(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1412 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1413 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
|
1414 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
|
1415 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1416 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
|
1417 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
|
1418 } |
452
00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents:
356
diff
changeset
|
1419 iter.move_to_next(); |
0 | 1420 } else { |
1421 iter.next(); | |
1422 } | |
1423 } | |
1424 // Close the reachable set | |
1425 complete_gc->do_void(); | |
1426 | |
1427 NOT_PRODUCT( | |
1428 if (PrintGCDetails && PrintReferenceGC) { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1552
diff
changeset
|
1429 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
|
1430 "Refs in discovered list " INTPTR_FORMAT, |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1552
diff
changeset
|
1431 iter.removed(), iter.processed(), (address)refs_list.head()); |
0 | 1432 } |
1433 ) | |
1434 } | |
1435 | |
1436 const char* ReferenceProcessor::list_name(int i) { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1552
diff
changeset
|
1437 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
|
1438 int j = i / _max_num_q; |
0 | 1439 switch (j) { |
1440 case 0: return "SoftRef"; | |
1441 case 1: return "WeakRef"; | |
1442 case 2: return "FinalRef"; | |
1443 case 3: return "PhantomRef"; | |
1444 } | |
1445 ShouldNotReachHere(); | |
1446 return NULL; | |
1447 } | |
1448 | |
1449 #ifndef PRODUCT | |
1450 void ReferenceProcessor::verify_ok_to_handle_reflists() { | |
1451 // empty for now | |
1452 } | |
1453 #endif | |
1454 | |
1455 void ReferenceProcessor::verify() { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1456 guarantee(sentinel_ref() != NULL && sentinel_ref()->is_oop(), "Lost _sentinelRef"); |
0 | 1457 } |
1458 | |
1459 #ifndef PRODUCT | |
1460 void ReferenceProcessor::clear_discovered_references() { | |
1461 guarantee(!_discovering_refs, "Discovering refs?"); | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1552
diff
changeset
|
1462 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { |
0 | 1463 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
|
1464 while (obj != sentinel_ref()) { |
0 | 1465 oop next = java_lang_ref_Reference::discovered(obj); |
1466 java_lang_ref_Reference::set_discovered(obj, (oop) NULL); | |
1467 obj = next; | |
1468 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
5
diff
changeset
|
1469 _discoveredSoftRefs[i].set_head(sentinel_ref()); |
0 | 1470 _discoveredSoftRefs[i].set_length(0); |
1471 } | |
1472 } | |
1473 #endif // PRODUCT |