src/share/vm/oops/instanceRefKlass.cpp

Print this page

        

*** 54,66 **** } ) if (!oopDesc::is_null(heap_oop)) { oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); if (!referent->is_gc_marked() && ! MarkSweep::ref_processor()-> ! discover_reference(obj, ref->reference_type())) { ! // reference already enqueued, referent will be traversed later ref->instanceKlass::oop_follow_contents(obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); } --- 54,65 ---- } ) if (!oopDesc::is_null(heap_oop)) { oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); if (!referent->is_gc_marked() && ! MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) { ! // reference was discovered, referent will be traversed later ref->instanceKlass::oop_follow_contents(obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); }
*** 74,87 **** } ) MarkSweep::mark_and_push(referent_addr); } } - // treat next as normal oop. next is a link in the pending list. T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); } ) MarkSweep::mark_and_push(next_addr); ref->instanceKlass::oop_follow_contents(obj); --- 73,112 ---- } ) MarkSweep::mark_and_push(referent_addr); } } T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); + if (ReferenceProcessor::pending_list_uses_discovered_field()) { + // Treat discovered as normal oop, if ref is not "active", + // i.e. if next is non-NULL. + T next_oop = oopDesc::load_heap_oop(next_addr); + if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" + T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { + gclog_or_tty->print_cr(" Process discovered as normal " + INTPTR_FORMAT, discovered_addr); + } + ) + MarkSweep::mark_and_push(discovered_addr); + } + } else { + #ifdef ASSERT + // In the case of older JDKs which do not use the discoveredd + // field for the pending list, an inactive ref (next != NULL) + // must always have a NULL discovered field. + oop next = oopDesc::load_decode_heap_oop(next_addr); + oop discovered = java_lang_ref_Reference::discovered(obj); + assert(oopDesc::is_null(next) || oopDesc::is_null(discovered), + err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field", + obj)); + #endif + } + // treat next as normal oop. next is a link in the reference queue. + debug_only( + if(TraceReferenceGC && PrintGCDetails) { gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); } ) MarkSweep::mark_and_push(next_addr); ref->instanceKlass::oop_follow_contents(obj);
*** 128,144 **** } ) PSParallelCompact::mark_and_push(cm, referent_addr); } } - // treat next as normal oop. next is a link in the pending list. T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { ! gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); } ) PSParallelCompact::mark_and_push(cm, next_addr); ref->instanceKlass::oop_follow_contents(cm, obj); } void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm, --- 153,189 ---- } ) PSParallelCompact::mark_and_push(cm, referent_addr); } } T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); + if (ReferenceProcessor::pending_list_uses_discovered_field()) { + // Treat discovered as normal oop, if ref is not "active", + // i.e. if next is non-NULL. + T next_oop = oopDesc::load_heap_oop(next_addr); + if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" + T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { ! gclog_or_tty->print_cr(" Process discovered as normal " ! INTPTR_FORMAT, discovered_addr); } ) + PSParallelCompact::mark_and_push(cm, discovered_addr); + } + } else { + #ifdef ASSERT + // In the case of older JDKs which do not use the discoveredd + // field for the pending list, an inactive ref (next != NULL) + // must always have a NULL discovered field. + T next = oopDesc::load_heap_oop(next_addr); + oop discovered = java_lang_ref_Reference::discovered(obj); + assert(oopDesc::is_null(next) || oopDesc::is_null(discovered), + err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field", + obj)); + #endif + } PSParallelCompact::mark_and_push(cm, next_addr); ref->instanceKlass::oop_follow_contents(cm, obj); } void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
*** 195,225 **** } return size; } #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains) \ - if (closure->apply_to_weak_ref_discovered_field()) { \ T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); \ closure->do_oop##nv_suffix(disc_addr); \ } \ \ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); \ T heap_oop = oopDesc::load_heap_oop(referent_addr); \ - if (!oopDesc::is_null(heap_oop) && contains(referent_addr)) { \ ReferenceProcessor* rp = closure->_ref_processor; \ oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); \ if (!referent->is_gc_marked() && (rp != NULL) && \ rp->discover_reference(obj, reference_type())) { \ return size; \ ! } else { \ /* treat referent as normal oop */ \ SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\ closure->do_oop##nv_suffix(referent_addr); \ } \ } \ - /* treat next as normal oop */ \ T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); \ if (contains(next_addr)) { \ SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \ closure->do_oop##nv_suffix(next_addr); \ } \ return size; \ --- 240,296 ---- } return size; } #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains) \ T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); \ + if (closure->apply_to_weak_ref_discovered_field()) { \ closure->do_oop##nv_suffix(disc_addr); \ } \ \ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); \ T heap_oop = oopDesc::load_heap_oop(referent_addr); \ ReferenceProcessor* rp = closure->_ref_processor; \ + if (!oopDesc::is_null(heap_oop)) { \ oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); \ if (!referent->is_gc_marked() && (rp != NULL) && \ rp->discover_reference(obj, reference_type())) { \ return size; \ ! } else if (contains(referent_addr)) { \ /* treat referent as normal oop */ \ SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\ closure->do_oop##nv_suffix(referent_addr); \ } \ } \ T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); \ + if (ReferenceProcessor::pending_list_uses_discovered_field()) { \ + T next_oop = oopDesc::load_heap_oop(next_addr); \ + /* Treat discovered as normal oop, if ref is not "active" (next non-NULL) */\ + if (!oopDesc::is_null(next_oop) && contains(disc_addr)) { \ + /* i.e. ref is not "active" */ \ + debug_only( \ + if(TraceReferenceGC && PrintGCDetails) { \ + gclog_or_tty->print_cr(" Process discovered as normal " \ + INTPTR_FORMAT, disc_addr); \ + } \ + ) \ + SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\ + closure->do_oop##nv_suffix(disc_addr); \ + } \ + } else { \ + /* In the case of older JDKs which do not use the discovered field for */ \ + /* the pending list, an inactive ref (next != NULL) must always have a */ \ + /* NULL discovered field. */ \ + debug_only( \ + T next_oop = oopDesc::load_heap_oop(next_addr); \ + T disc_oop = oopDesc::load_heap_oop(disc_addr); \ + assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop), \ + err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL" \ + "discovered field", obj)); \ + ) \ + } \ + /* treat next as normal oop */ \ if (contains(next_addr)) { \ SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \ closure->do_oop##nv_suffix(next_addr); \ } \ return size; \
*** 293,315 **** #ifndef SERIALGC template <class T> void specialized_oop_push_contents(instanceRefKlass *ref, PSPromotionManager* pm, oop obj) { T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); - if (PSScavenge::should_scavenge(referent_addr)) { ReferenceProcessor* rp = PSScavenge::reference_processor(); if (rp->discover_reference(obj, ref->reference_type())) { // reference already enqueued, referent and next will be traversed later ref->instanceKlass::oop_push_contents(pm, obj); return; } else { // treat referent as normal oop pm->claim_or_forward_depth(referent_addr); } } ! // treat next as normal oop T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); if (PSScavenge::should_scavenge(next_addr)) { pm->claim_or_forward_depth(next_addr); } ref->instanceKlass::oop_push_contents(pm, obj); } --- 364,415 ---- #ifndef SERIALGC template <class T> void specialized_oop_push_contents(instanceRefKlass *ref, PSPromotionManager* pm, oop obj) { T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); ReferenceProcessor* rp = PSScavenge::reference_processor(); + if (PSScavenge::should_scavenge(referent_addr)) { if (rp->discover_reference(obj, ref->reference_type())) { // reference already enqueued, referent and next will be traversed later ref->instanceKlass::oop_push_contents(pm, obj); return; } else { // treat referent as normal oop pm->claim_or_forward_depth(referent_addr); } } ! // Treat discovered as normal oop, if ref is not "active", ! // i.e. if next is non-NULL. T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); + if (ReferenceProcessor::pending_list_uses_discovered_field()) { + T next_oop = oopDesc::load_heap_oop(next_addr); + if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" + T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); + debug_only( + if(TraceReferenceGC && PrintGCDetails) { + gclog_or_tty->print_cr(" Process discovered as normal " + INTPTR_FORMAT, discovered_addr); + } + ) + if (PSScavenge::should_scavenge(discovered_addr)) { + pm->claim_or_forward_depth(discovered_addr); + } + } + } else { + #ifdef ASSERT + // In the case of older JDKs which do not use the discoveredd + // field for the pending list, an inactive ref (next != NULL) + // must always have a NULL discovered field. + oop next = oopDesc::load_decode_heap_oop(next_addr); + oop discovered = java_lang_ref_Reference::discovered(obj); + assert(oopDesc::is_null(next) || oopDesc::is_null(discovered), + err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field", + obj)); + #endif + } + + // Treat next as normal oop; next is a link in the reference queue. if (PSScavenge::should_scavenge(next_addr)) { pm->claim_or_forward_depth(next_addr); } ref->instanceKlass::oop_push_contents(pm, obj); }