54 } |
54 } |
55 ) |
55 ) |
56 if (!oopDesc::is_null(heap_oop)) { |
56 if (!oopDesc::is_null(heap_oop)) { |
57 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); |
57 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); |
58 if (!referent->is_gc_marked() && |
58 if (!referent->is_gc_marked() && |
59 MarkSweep::ref_processor()-> |
59 MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) { |
60 discover_reference(obj, ref->reference_type())) { |
60 // reference was discovered, referent will be traversed later |
61 // reference already enqueued, referent will be traversed later |
|
62 ref->instanceKlass::oop_follow_contents(obj); |
61 ref->instanceKlass::oop_follow_contents(obj); |
63 debug_only( |
62 debug_only( |
64 if(TraceReferenceGC && PrintGCDetails) { |
63 if(TraceReferenceGC && PrintGCDetails) { |
65 gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); |
64 gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); |
66 } |
65 } |
74 } |
73 } |
75 ) |
74 ) |
76 MarkSweep::mark_and_push(referent_addr); |
75 MarkSweep::mark_and_push(referent_addr); |
77 } |
76 } |
78 } |
77 } |
79 // treat next as normal oop. next is a link in the pending list. |
|
80 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
78 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
|
79 if (ReferenceProcessor::pending_list_uses_discovered_field()) { |
|
80 // Treat discovered as normal oop, if ref is not "active", |
|
81 // i.e. if next is non-NULL. |
|
82 T next_oop = oopDesc::load_heap_oop(next_addr); |
|
83 if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" |
|
84 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
|
85 debug_only( |
|
86 if(TraceReferenceGC && PrintGCDetails) { |
|
87 gclog_or_tty->print_cr(" Process discovered as normal " |
|
88 INTPTR_FORMAT, discovered_addr); |
|
89 } |
|
90 ) |
|
91 MarkSweep::mark_and_push(discovered_addr); |
|
92 } |
|
93 } else { |
|
94 #ifdef ASSERT |
|
95 // In the case of older JDKs which do not use the discovered |
|
96 // field for the pending list, an inactive ref (next != NULL) |
|
97 // must always have a NULL discovered field. |
|
98 oop next = oopDesc::load_decode_heap_oop(next_addr); |
|
99 oop discovered = java_lang_ref_Reference::discovered(obj); |
|
100 assert(oopDesc::is_null(next) || oopDesc::is_null(discovered), |
|
101 err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field", |
|
102 obj)); |
|
103 #endif |
|
104 } |
|
105 // treat next as normal oop. next is a link in the reference queue. |
81 debug_only( |
106 debug_only( |
82 if(TraceReferenceGC && PrintGCDetails) { |
107 if(TraceReferenceGC && PrintGCDetails) { |
83 gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); |
108 gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); |
84 } |
109 } |
85 ) |
110 ) |
128 } |
153 } |
129 ) |
154 ) |
130 PSParallelCompact::mark_and_push(cm, referent_addr); |
155 PSParallelCompact::mark_and_push(cm, referent_addr); |
131 } |
156 } |
132 } |
157 } |
133 // treat next as normal oop. next is a link in the pending list. |
|
134 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
158 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
135 debug_only( |
159 if (ReferenceProcessor::pending_list_uses_discovered_field()) { |
136 if(TraceReferenceGC && PrintGCDetails) { |
160 // Treat discovered as normal oop, if ref is not "active", |
137 gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); |
161 // i.e. if next is non-NULL. |
138 } |
162 T next_oop = oopDesc::load_heap_oop(next_addr); |
139 ) |
163 if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" |
|
164 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
|
165 debug_only( |
|
166 if(TraceReferenceGC && PrintGCDetails) { |
|
167 gclog_or_tty->print_cr(" Process discovered as normal " |
|
168 INTPTR_FORMAT, discovered_addr); |
|
169 } |
|
170 ) |
|
171 PSParallelCompact::mark_and_push(cm, discovered_addr); |
|
172 } |
|
173 } else { |
|
174 #ifdef ASSERT |
|
175 // In the case of older JDKs which do not use the discovered |
|
176 // field for the pending list, an inactive ref (next != NULL) |
|
177 // must always have a NULL discovered field. |
|
178 T next = oopDesc::load_heap_oop(next_addr); |
|
179 oop discovered = java_lang_ref_Reference::discovered(obj); |
|
180 assert(oopDesc::is_null(next) || oopDesc::is_null(discovered), |
|
181 err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field", |
|
182 obj)); |
|
183 #endif |
|
184 } |
140 PSParallelCompact::mark_and_push(cm, next_addr); |
185 PSParallelCompact::mark_and_push(cm, next_addr); |
141 ref->instanceKlass::oop_follow_contents(cm, obj); |
186 ref->instanceKlass::oop_follow_contents(cm, obj); |
142 } |
187 } |
143 |
188 |
144 void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm, |
189 void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm, |
195 } |
240 } |
196 return size; |
241 return size; |
197 } |
242 } |
198 |
243 |
199 #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains) \ |
244 #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains) \ |
|
245 T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); \ |
200 if (closure->apply_to_weak_ref_discovered_field()) { \ |
246 if (closure->apply_to_weak_ref_discovered_field()) { \ |
201 T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); \ |
|
202 closure->do_oop##nv_suffix(disc_addr); \ |
247 closure->do_oop##nv_suffix(disc_addr); \ |
203 } \ |
248 } \ |
204 \ |
249 \ |
205 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); \ |
250 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); \ |
206 T heap_oop = oopDesc::load_heap_oop(referent_addr); \ |
251 T heap_oop = oopDesc::load_heap_oop(referent_addr); \ |
207 if (!oopDesc::is_null(heap_oop) && contains(referent_addr)) { \ |
252 ReferenceProcessor* rp = closure->_ref_processor; \ |
208 ReferenceProcessor* rp = closure->_ref_processor; \ |
253 if (!oopDesc::is_null(heap_oop)) { \ |
209 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); \ |
254 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); \ |
210 if (!referent->is_gc_marked() && (rp != NULL) && \ |
255 if (!referent->is_gc_marked() && (rp != NULL) && \ |
211 rp->discover_reference(obj, reference_type())) { \ |
256 rp->discover_reference(obj, reference_type())) { \ |
212 return size; \ |
257 return size; \ |
213 } else { \ |
258 } else if (contains(referent_addr)) { \ |
214 /* treat referent as normal oop */ \ |
259 /* treat referent as normal oop */ \ |
215 SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\ |
260 SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\ |
216 closure->do_oop##nv_suffix(referent_addr); \ |
261 closure->do_oop##nv_suffix(referent_addr); \ |
217 } \ |
262 } \ |
218 } \ |
263 } \ |
|
264 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); \ |
|
265 if (ReferenceProcessor::pending_list_uses_discovered_field()) { \ |
|
266 T next_oop = oopDesc::load_heap_oop(next_addr); \ |
|
267 /* Treat discovered as normal oop, if ref is not "active" (next non-NULL) */\ |
|
268 if (!oopDesc::is_null(next_oop) && contains(disc_addr)) { \ |
|
269 /* i.e. ref is not "active" */ \ |
|
270 debug_only( \ |
|
271 if(TraceReferenceGC && PrintGCDetails) { \ |
|
272 gclog_or_tty->print_cr(" Process discovered as normal " \ |
|
273 INTPTR_FORMAT, disc_addr); \ |
|
274 } \ |
|
275 ) \ |
|
276 SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\ |
|
277 closure->do_oop##nv_suffix(disc_addr); \ |
|
278 } \ |
|
279 } else { \ |
|
280 /* In the case of older JDKs which do not use the discovered field for */ \ |
|
281 /* the pending list, an inactive ref (next != NULL) must always have a */ \ |
|
282 /* NULL discovered field. */ \ |
|
283 debug_only( \ |
|
284 T next_oop = oopDesc::load_heap_oop(next_addr); \ |
|
285 T disc_oop = oopDesc::load_heap_oop(disc_addr); \ |
|
286 assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop), \ |
|
287 err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL" \ |
|
288 "discovered field", obj)); \ |
|
289 ) \ |
|
290 } \ |
219 /* treat next as normal oop */ \ |
291 /* treat next as normal oop */ \ |
220 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); \ |
|
221 if (contains(next_addr)) { \ |
292 if (contains(next_addr)) { \ |
222 SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \ |
293 SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \ |
223 closure->do_oop##nv_suffix(next_addr); \ |
294 closure->do_oop##nv_suffix(next_addr); \ |
224 } \ |
295 } \ |
225 return size; \ |
296 return size; \ |
304 } else { |
375 } else { |
305 // treat referent as normal oop |
376 // treat referent as normal oop |
306 pm->claim_or_forward_depth(referent_addr); |
377 pm->claim_or_forward_depth(referent_addr); |
307 } |
378 } |
308 } |
379 } |
309 // treat next as normal oop |
380 // Treat discovered as normal oop, if ref is not "active", |
|
381 // i.e. if next is non-NULL. |
310 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
382 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
|
383 if (ReferenceProcessor::pending_list_uses_discovered_field()) { |
|
384 T next_oop = oopDesc::load_heap_oop(next_addr); |
|
385 if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" |
|
386 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
|
387 debug_only( |
|
388 if(TraceReferenceGC && PrintGCDetails) { |
|
389 gclog_or_tty->print_cr(" Process discovered as normal " |
|
390 INTPTR_FORMAT, discovered_addr); |
|
391 } |
|
392 ) |
|
393 if (PSScavenge::should_scavenge(discovered_addr)) { |
|
394 pm->claim_or_forward_depth(discovered_addr); |
|
395 } |
|
396 } |
|
397 } else { |
|
398 #ifdef ASSERT |
|
399 // In the case of older JDKs which do not use the discovered |
|
400 // field for the pending list, an inactive ref (next != NULL) |
|
401 // must always have a NULL discovered field. |
|
402 oop next = oopDesc::load_decode_heap_oop(next_addr); |
|
403 oop discovered = java_lang_ref_Reference::discovered(obj); |
|
404 assert(oopDesc::is_null(next) || oopDesc::is_null(discovered), |
|
405 err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field", |
|
406 obj)); |
|
407 #endif |
|
408 } |
|
409 |
|
410 // Treat next as normal oop; next is a link in the reference queue. |
311 if (PSScavenge::should_scavenge(next_addr)) { |
411 if (PSScavenge::should_scavenge(next_addr)) { |
312 pm->claim_or_forward_depth(next_addr); |
412 pm->claim_or_forward_depth(next_addr); |
313 } |
413 } |
314 ref->instanceKlass::oop_push_contents(pm, obj); |
414 ref->instanceKlass::oop_push_contents(pm, obj); |
315 } |
415 } |