46 } 47 48 template <bool nv, typename T, class OopClosureType, class Contains> 49 void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) { 50 T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj); 51 if (contains(next_addr)) { 52 Devirtualizer<nv>::do_oop(closure, next_addr); 53 } 54 } 55 56 template <bool nv, typename T, class OopClosureType, class Contains> 57 void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) { 58 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj); 59 if (contains(discovered_addr)) { 60 Devirtualizer<nv>::do_oop(closure, discovered_addr); 61 } 62 } 63 64 template <typename T, class OopClosureType> 65 bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) { 66 ReferenceProcessor* rp = closure->ref_processor(); 67 if (rp != NULL) { 68 T referent_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::referent_addr_raw(obj)); 69 if (!CompressedOops::is_null(referent_oop)) { 70 oop referent = CompressedOops::decode_not_null(referent_oop); 71 if (!referent->is_gc_marked()) { 72 // Only try to discover if not yet marked. 73 return rp->discover_reference(obj, type); 74 } 75 } 76 } 77 return false; 78 } 79 80 template <bool nv, typename T, class OopClosureType, class Contains> 81 void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) { 82 // Try to discover reference and return if it succeeds. 83 if (try_discover<T>(obj, type, closure)) { 84 return; 85 } 86 87 // Treat referent as normal oop. 88 do_referent<nv, T>(obj, closure, contains); 89 90 // Treat discovered as normal oop, if ref is not "active" (next non-NULL). 91 T next_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::next_addr_raw(obj)); 92 if (!CompressedOops::is_null(next_oop)) { 93 do_discovered<nv, T>(obj, closure, contains); | 46 } 47 48 template <bool nv, typename T, class OopClosureType, class Contains> 49 void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) { 50 T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj); 51 if (contains(next_addr)) { 52 Devirtualizer<nv>::do_oop(closure, next_addr); 53 } 54 } 55 56 template <bool nv, typename T, class OopClosureType, class Contains> 57 void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) { 58 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj); 59 if (contains(discovered_addr)) { 60 Devirtualizer<nv>::do_oop(closure, discovered_addr); 61 } 62 } 63 64 template <typename T, class OopClosureType> 65 bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) { 66 ReferenceDiscoverer* rd = closure->ref_discoverer(); 67 if (rd != NULL) { 68 T referent_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::referent_addr_raw(obj)); 69 if (!CompressedOops::is_null(referent_oop)) { 70 oop referent = CompressedOops::decode_not_null(referent_oop); 71 if (!referent->is_gc_marked()) { 72 // Only try to discover if not yet marked. 73 return rd->discover_reference(obj, type); 74 } 75 } 76 } 77 return false; 78 } 79 80 template <bool nv, typename T, class OopClosureType, class Contains> 81 void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) { 82 // Try to discover reference and return if it succeeds. 83 if (try_discover<T>(obj, type, closure)) { 84 return; 85 } 86 87 // Treat referent as normal oop. 88 do_referent<nv, T>(obj, closure, contains); 89 90 // Treat discovered as normal oop, if ref is not "active" (next non-NULL). 91 T next_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::next_addr_raw(obj)); 92 if (!CompressedOops::is_null(next_oop)) { 93 do_discovered<nv, T>(obj, closure, contains); |