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 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() && |
110 ) |
110 ) |
111 MarkSweep::mark_and_push(next_addr); |
111 MarkSweep::mark_and_push(next_addr); |
112 ref->InstanceKlass::oop_follow_contents(obj); |
112 ref->InstanceKlass::oop_follow_contents(obj); |
113 } |
113 } |
114 |
114 |
115 void instanceRefKlass::oop_follow_contents(oop obj) { |
115 void InstanceRefKlass::oop_follow_contents(oop obj) { |
116 if (UseCompressedOops) { |
116 if (UseCompressedOops) { |
117 specialized_oop_follow_contents<narrowOop>(this, obj); |
117 specialized_oop_follow_contents<narrowOop>(this, obj); |
118 } else { |
118 } else { |
119 specialized_oop_follow_contents<oop>(this, obj); |
119 specialized_oop_follow_contents<oop>(this, obj); |
120 } |
120 } |
121 } |
121 } |
122 |
122 |
123 #ifndef SERIALGC |
123 #ifndef SERIALGC |
124 template <class T> |
124 template <class T> |
125 void specialized_oop_follow_contents(instanceRefKlass* ref, |
125 void specialized_oop_follow_contents(InstanceRefKlass* ref, |
126 ParCompactionManager* cm, |
126 ParCompactionManager* cm, |
127 oop obj) { |
127 oop obj) { |
128 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
128 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
129 T heap_oop = oopDesc::load_heap_oop(referent_addr); |
129 T heap_oop = oopDesc::load_heap_oop(referent_addr); |
130 debug_only( |
130 debug_only( |
131 if(TraceReferenceGC && PrintGCDetails) { |
131 if(TraceReferenceGC && PrintGCDetails) { |
132 gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj); |
132 gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj); |
133 } |
133 } |
134 ) |
134 ) |
135 if (!oopDesc::is_null(heap_oop)) { |
135 if (!oopDesc::is_null(heap_oop)) { |
136 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); |
136 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); |
137 if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) && |
137 if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) && |
184 } |
184 } |
185 PSParallelCompact::mark_and_push(cm, next_addr); |
185 PSParallelCompact::mark_and_push(cm, next_addr); |
186 ref->InstanceKlass::oop_follow_contents(cm, obj); |
186 ref->InstanceKlass::oop_follow_contents(cm, obj); |
187 } |
187 } |
188 |
188 |
189 void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm, |
189 void InstanceRefKlass::oop_follow_contents(ParCompactionManager* cm, |
190 oop obj) { |
190 oop obj) { |
191 if (UseCompressedOops) { |
191 if (UseCompressedOops) { |
192 specialized_oop_follow_contents<narrowOop>(this, cm, obj); |
192 specialized_oop_follow_contents<narrowOop>(this, cm, obj); |
193 } else { |
193 } else { |
194 specialized_oop_follow_contents<oop>(this, cm, obj); |
194 specialized_oop_follow_contents<oop>(this, cm, obj); |
216 (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL); |
216 (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL); |
217 } |
217 } |
218 } |
218 } |
219 #endif |
219 #endif |
220 |
220 |
221 template <class T> void specialized_oop_adjust_pointers(instanceRefKlass *ref, oop obj) { |
221 template <class T> void specialized_oop_adjust_pointers(InstanceRefKlass *ref, oop obj) { |
222 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
222 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
223 MarkSweep::adjust_pointer(referent_addr); |
223 MarkSweep::adjust_pointer(referent_addr); |
224 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
224 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
225 MarkSweep::adjust_pointer(next_addr); |
225 MarkSweep::adjust_pointer(next_addr); |
226 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
226 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
227 MarkSweep::adjust_pointer(discovered_addr); |
227 MarkSweep::adjust_pointer(discovered_addr); |
228 debug_only(trace_reference_gc("instanceRefKlass::oop_adjust_pointers", obj, |
228 debug_only(trace_reference_gc("InstanceRefKlass::oop_adjust_pointers", obj, |
229 referent_addr, next_addr, discovered_addr);) |
229 referent_addr, next_addr, discovered_addr);) |
230 } |
230 } |
231 |
231 |
232 int instanceRefKlass::oop_adjust_pointers(oop obj) { |
232 int InstanceRefKlass::oop_adjust_pointers(oop obj) { |
233 int size = size_helper(); |
233 int size = size_helper(); |
234 InstanceKlass::oop_adjust_pointers(obj); |
234 InstanceKlass::oop_adjust_pointers(obj); |
235 |
235 |
236 if (UseCompressedOops) { |
236 if (UseCompressedOops) { |
237 specialized_oop_adjust_pointers<narrowOop>(this, obj); |
237 specialized_oop_adjust_pointers<narrowOop>(this, obj); |
296 return size; \ |
296 return size; \ |
297 |
297 |
298 |
298 |
299 template <class T> bool contains(T *t) { return true; } |
299 template <class T> bool contains(T *t) { return true; } |
300 |
300 |
301 // Macro to define instanceRefKlass::oop_oop_iterate for virtual/nonvirtual for |
301 // Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for |
302 // all closures. Macros calling macros above for each oop size. |
302 // all closures. Macros calling macros above for each oop size. |
303 |
303 |
304 #define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
304 #define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
305 \ |
305 \ |
306 int instanceRefKlass:: \ |
306 int InstanceRefKlass:: \ |
307 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \ |
307 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \ |
308 /* Get size before changing pointers */ \ |
308 /* Get size before changing pointers */ \ |
309 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\ |
309 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\ |
310 \ |
310 \ |
311 int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \ |
311 int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \ |
318 } |
318 } |
319 |
319 |
320 #ifndef SERIALGC |
320 #ifndef SERIALGC |
321 #define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ |
321 #define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ |
322 \ |
322 \ |
323 int instanceRefKlass:: \ |
323 int InstanceRefKlass:: \ |
324 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \ |
324 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \ |
325 /* Get size before changing pointers */ \ |
325 /* Get size before changing pointers */ \ |
326 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\ |
326 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\ |
327 \ |
327 \ |
328 int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \ |
328 int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \ |
361 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) |
361 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) |
362 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) |
362 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) |
363 |
363 |
364 #ifndef SERIALGC |
364 #ifndef SERIALGC |
365 template <class T> |
365 template <class T> |
366 void specialized_oop_push_contents(instanceRefKlass *ref, |
366 void specialized_oop_push_contents(InstanceRefKlass *ref, |
367 PSPromotionManager* pm, oop obj) { |
367 PSPromotionManager* pm, oop obj) { |
368 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
368 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
369 if (PSScavenge::should_scavenge(referent_addr)) { |
369 if (PSScavenge::should_scavenge(referent_addr)) { |
370 ReferenceProcessor* rp = PSScavenge::reference_processor(); |
370 ReferenceProcessor* rp = PSScavenge::reference_processor(); |
371 if (rp->discover_reference(obj, ref->reference_type())) { |
371 if (rp->discover_reference(obj, ref->reference_type())) { |
412 pm->claim_or_forward_depth(next_addr); |
412 pm->claim_or_forward_depth(next_addr); |
413 } |
413 } |
414 ref->InstanceKlass::oop_push_contents(pm, obj); |
414 ref->InstanceKlass::oop_push_contents(pm, obj); |
415 } |
415 } |
416 |
416 |
417 void instanceRefKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { |
417 void InstanceRefKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { |
418 if (UseCompressedOops) { |
418 if (UseCompressedOops) { |
419 specialized_oop_push_contents<narrowOop>(this, pm, obj); |
419 specialized_oop_push_contents<narrowOop>(this, pm, obj); |
420 } else { |
420 } else { |
421 specialized_oop_push_contents<oop>(this, pm, obj); |
421 specialized_oop_push_contents<oop>(this, pm, obj); |
422 } |
422 } |
423 } |
423 } |
424 |
424 |
425 template <class T> |
425 template <class T> |
426 void specialized_oop_update_pointers(instanceRefKlass *ref, |
426 void specialized_oop_update_pointers(InstanceRefKlass *ref, |
427 ParCompactionManager* cm, oop obj) { |
427 ParCompactionManager* cm, oop obj) { |
428 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
428 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
429 PSParallelCompact::adjust_pointer(referent_addr); |
429 PSParallelCompact::adjust_pointer(referent_addr); |
430 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
430 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
431 PSParallelCompact::adjust_pointer(next_addr); |
431 PSParallelCompact::adjust_pointer(next_addr); |
432 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
432 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
433 PSParallelCompact::adjust_pointer(discovered_addr); |
433 PSParallelCompact::adjust_pointer(discovered_addr); |
434 debug_only(trace_reference_gc("instanceRefKlass::oop_update_ptrs", obj, |
434 debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj, |
435 referent_addr, next_addr, discovered_addr);) |
435 referent_addr, next_addr, discovered_addr);) |
436 } |
436 } |
437 |
437 |
438 int instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { |
438 int InstanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { |
439 InstanceKlass::oop_update_pointers(cm, obj); |
439 InstanceKlass::oop_update_pointers(cm, obj); |
440 if (UseCompressedOops) { |
440 if (UseCompressedOops) { |
441 specialized_oop_update_pointers<narrowOop>(this, cm, obj); |
441 specialized_oop_update_pointers<narrowOop>(this, cm, obj); |
442 } else { |
442 } else { |
443 specialized_oop_update_pointers<oop>(this, cm, obj); |
443 specialized_oop_update_pointers<oop>(this, cm, obj); |
444 } |
444 } |
445 return size_helper(); |
445 return size_helper(); |
446 } |
446 } |
447 #endif // SERIALGC |
447 #endif // SERIALGC |
448 |
448 |
449 void instanceRefKlass::update_nonstatic_oop_maps(Klass* k) { |
449 void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) { |
450 // Clear the nonstatic oop-map entries corresponding to referent |
450 // Clear the nonstatic oop-map entries corresponding to referent |
451 // and nextPending field. They are treated specially by the |
451 // and nextPending field. They are treated specially by the |
452 // garbage collector. |
452 // garbage collector. |
453 // The discovered field is used only by the garbage collector |
453 // The discovered field is used only by the garbage collector |
454 // and is also treated specially. |
454 // and is also treated specially. |
504 guarantee(next->is_oop(), "next field verify failed"); |
504 guarantee(next->is_oop(), "next field verify failed"); |
505 guarantee(next->is_instanceRef(), "next field verify failed"); |
505 guarantee(next->is_instanceRef(), "next field verify failed"); |
506 } |
506 } |
507 } |
507 } |
508 |
508 |
509 bool instanceRefKlass::owns_pending_list_lock(JavaThread* thread) { |
509 bool InstanceRefKlass::owns_pending_list_lock(JavaThread* thread) { |
510 if (java_lang_ref_Reference::pending_list_lock() == NULL) return false; |
510 if (java_lang_ref_Reference::pending_list_lock() == NULL) return false; |
511 Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock()); |
511 Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock()); |
512 return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock); |
512 return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock); |
513 } |
513 } |
514 |
514 |
515 void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) { |
515 void InstanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) { |
516 // we may enter this with pending exception set |
516 // we may enter this with pending exception set |
517 PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument |
517 PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument |
518 |
518 |
519 // Create a HandleMark in case we retry a GC multiple times. |
519 // Create a HandleMark in case we retry a GC multiple times. |
520 // Each time we attempt the GC, we allocate the handle below |
520 // Each time we attempt the GC, we allocate the handle below |
527 JavaThread::current(), h_lock), |
527 JavaThread::current(), h_lock), |
528 "Locking should have succeeded"); |
528 "Locking should have succeeded"); |
529 if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION; |
529 if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION; |
530 } |
530 } |
531 |
531 |
532 void instanceRefKlass::release_and_notify_pending_list_lock( |
532 void InstanceRefKlass::release_and_notify_pending_list_lock( |
533 BasicLock *pending_list_basic_lock) { |
533 BasicLock *pending_list_basic_lock) { |
534 // we may enter this with pending exception set |
534 // we may enter this with pending exception set |
535 PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument |
535 PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument |
536 |
536 |
537 // Create a HandleMark in case we retry a GC multiple times. |
537 // Create a HandleMark in case we retry a GC multiple times. |