92 return "Phantom"; 93 94 default: 95 ShouldNotReachHere(); 96 return NULL; 97 } 98 } 99 100 volatile oop* ZReferenceProcessor::reference_referent_addr(oop obj) const { 101 return (volatile oop*)java_lang_ref_Reference::referent_addr_raw(obj); 102 } 103 104 oop ZReferenceProcessor::reference_referent(oop obj) const { 105 return *reference_referent_addr(obj); 106 } 107 108 bool ZReferenceProcessor::is_referent_alive_or_null(oop obj, ReferenceType type) const { 109 volatile oop* const p = reference_referent_addr(obj); 110 111 // Check if the referent is alive or null, in which case we don't want to discover 112 // the reference. It can only be null if the application called Reference.clear(). 113 if (type == REF_PHANTOM) { 114 const oop o = ZBarrier::weak_load_barrier_on_phantom_oop_field(p); 115 return o == NULL || ZHeap::heap()->is_object_live(ZOop::to_address(o)); 116 } else { 117 const oop o = ZBarrier::weak_load_barrier_on_weak_oop_field(p); 118 return o == NULL || ZHeap::heap()->is_object_strongly_live(ZOop::to_address(o)); 119 } 120 } 121 122 bool ZReferenceProcessor::is_referent_softly_alive(oop obj, ReferenceType type) const { 123 if (type != REF_SOFT) { 124 // Not a soft reference 125 return false; 126 } 127 128 // Ask soft reference policy 129 const jlong clock = java_lang_ref_SoftReference::clock(); 130 assert(clock != 0, "Clock not initialized"); 131 assert(_soft_reference_policy != NULL, "Policy not initialized"); 132 return !_soft_reference_policy->should_clear_reference(obj, clock); 133 } 134 135 bool ZReferenceProcessor::should_drop_reference(oop obj, ReferenceType type) const { 136 // This check is racing with a call to Reference.clear() from the application. 137 // If the application clears the reference after this check it will still end 138 // up on the pending list, and there's nothing we can do about that without 139 // changing the Reference.clear() API. 140 const oop o = reference_referent(obj); 141 if (o == NULL) { 142 // Reference has already been cleared, by an application call to 143 // Reference.clear(), which means we should drop the reference. 144 return true; 145 } 146 147 // Check if the referent is still alive, in which case we should 148 // drop the reference. 149 if (type == REF_PHANTOM) { 150 return ZBarrier::is_alive_barrier_on_phantom_oop(o); 151 } else { 152 return ZBarrier::is_alive_barrier_on_weak_oop(o); 153 } 154 } 155 156 bool ZReferenceProcessor::should_mark_referent(ReferenceType type) const { 157 // Referents of final references (and its reachable sub graph) are 158 // always marked finalizable during discovery. This avoids the problem 159 // of later having to mark those objects if the referent is still final 160 // reachable during processing. 161 return type == REF_FINAL; 162 } 163 | 92 return "Phantom"; 93 94 default: 95 ShouldNotReachHere(); 96 return NULL; 97 } 98 } 99 100 volatile oop* ZReferenceProcessor::reference_referent_addr(oop obj) const { 101 return (volatile oop*)java_lang_ref_Reference::referent_addr_raw(obj); 102 } 103 104 oop ZReferenceProcessor::reference_referent(oop obj) const { 105 return *reference_referent_addr(obj); 106 } 107 108 bool ZReferenceProcessor::is_referent_alive_or_null(oop obj, ReferenceType type) const { 109 volatile oop* const p = reference_referent_addr(obj); 110 111 // Check if the referent is alive or null, in which case we don't want to discover 112 // the reference. It can only be null if the application called Reference.enqueue() 113 // or Reference.clear(). 114 if (type == REF_PHANTOM) { 115 const oop o = ZBarrier::weak_load_barrier_on_phantom_oop_field(p); 116 return o == NULL || ZHeap::heap()->is_object_live(ZOop::to_address(o)); 117 } else { 118 const oop o = ZBarrier::weak_load_barrier_on_weak_oop_field(p); 119 return o == NULL || ZHeap::heap()->is_object_strongly_live(ZOop::to_address(o)); 120 } 121 } 122 123 bool ZReferenceProcessor::is_referent_softly_alive(oop obj, ReferenceType type) const { 124 if (type != REF_SOFT) { 125 // Not a soft reference 126 return false; 127 } 128 129 // Ask soft reference policy 130 const jlong clock = java_lang_ref_SoftReference::clock(); 131 assert(clock != 0, "Clock not initialized"); 132 assert(_soft_reference_policy != NULL, "Policy not initialized"); 133 return !_soft_reference_policy->should_clear_reference(obj, clock); 134 } 135 136 bool ZReferenceProcessor::should_drop_reference(oop obj, ReferenceType type) const { 137 // This check is racing with a call to Reference.clear() from the application. 138 // If the application clears the reference after this check it will still end 139 // up on the pending list, and there's nothing we can do about that without 140 // changing the Reference.clear() API. This check is also racing with a call 141 // to Reference.enqueue() from the application, which is unproblematic, since 142 // the application wants the reference to be enqueued anyway. 143 const oop o = reference_referent(obj); 144 if (o == NULL) { 145 // Reference has been cleared, by a call to Reference.enqueue() 146 // or Reference.clear() from the application, which means we 147 // should drop the reference. 148 return true; 149 } 150 151 // Check if the referent is still alive, in which case we should 152 // drop the reference. 153 if (type == REF_PHANTOM) { 154 return ZBarrier::is_alive_barrier_on_phantom_oop(o); 155 } else { 156 return ZBarrier::is_alive_barrier_on_weak_oop(o); 157 } 158 } 159 160 bool ZReferenceProcessor::should_mark_referent(ReferenceType type) const { 161 // Referents of final references (and its reachable sub graph) are 162 // always marked finalizable during discovery. This avoids the problem 163 // of later having to mark those objects if the referent is still final 164 // reachable during processing. 165 return type == REF_FINAL; 166 } 167 |