comparison src/share/vm/oops/instanceRefKlass.cpp @ 4137:04b9a2566eec

Merge with hsx23/hotspot.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 17 Dec 2011 21:40:27 +0100
parents f94227b6117b
children b632e80fc9dc
comparison
equal deleted inserted replaced
3737:9dc19b7d89a3 4137:04b9a2566eec
43 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 43 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
44 #include "oops/oop.pcgc.inline.hpp" 44 #include "oops/oop.pcgc.inline.hpp"
45 #endif 45 #endif
46 46
47 template <class T> 47 template <class T>
48 static void specialized_oop_follow_contents(instanceRefKlass* ref, oop obj) { 48 void specialized_oop_follow_contents(instanceRefKlass* ref, oop obj) {
49 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); 49 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
50 T heap_oop = oopDesc::load_heap_oop(referent_addr); 50 T heap_oop = oopDesc::load_heap_oop(referent_addr);
51 debug_only( 51 debug_only(
52 if(TraceReferenceGC && PrintGCDetails) { 52 if(TraceReferenceGC && PrintGCDetails) {
53 gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj); 53 gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj);
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 (oopDesc*)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 (oopDesc*)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", (oopDesc*)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 (oopDesc*)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 }