85 virtual void on_thread_create(Thread* thread); |
85 virtual void on_thread_create(Thread* thread); |
86 virtual void on_thread_destroy(Thread* thread); |
86 virtual void on_thread_destroy(Thread* thread); |
87 virtual void on_thread_attach(Thread* thread); |
87 virtual void on_thread_attach(Thread* thread); |
88 virtual void on_thread_detach(Thread* thread); |
88 virtual void on_thread_detach(Thread* thread); |
89 |
89 |
90 virtual oop read_barrier(oop src); |
|
91 |
|
92 static inline oop resolve_forwarded_not_null(oop p); |
90 static inline oop resolve_forwarded_not_null(oop p); |
93 static inline oop resolve_forwarded(oop p); |
91 static inline oop resolve_forwarded(oop p); |
94 |
92 |
95 virtual oop write_barrier(oop obj); |
93 void storeval_barrier(oop obj); |
96 |
94 void keep_alive_barrier(oop obj); |
97 oop write_barrier_mutator(oop obj); |
95 |
98 |
96 oop load_reference_barrier(oop obj); |
99 virtual oop storeval_barrier(oop obj); |
97 oop load_reference_barrier_mutator(oop obj); |
100 |
98 oop load_reference_barrier_not_null(oop obj); |
101 virtual void keep_alive_barrier(oop obj); |
|
102 |
|
103 bool obj_equals(oop obj1, oop obj2); |
|
104 |
|
105 #ifdef CHECK_UNHANDLED_OOPS |
|
106 bool oop_equals_operator_allowed() { return !ShenandoahVerifyObjectEquals; } |
|
107 #endif |
|
108 |
99 |
109 void enqueue(oop obj); |
100 void enqueue(oop obj); |
110 |
101 |
111 private: |
102 private: |
112 inline bool need_update_refs_barrier(); |
103 inline bool need_update_refs_barrier(); |
113 |
104 |
114 template <class T, bool STOREVAL_WRITE_BARRIER> |
105 template <class T, bool STOREVAL_WRITE_BARRIER> |
115 void write_ref_array_loop(HeapWord* start, size_t count); |
106 void write_ref_array_loop(HeapWord* start, size_t count); |
116 |
107 |
117 oop write_barrier_impl(oop obj); |
108 oop load_reference_barrier_impl(oop obj); |
118 |
109 |
119 static void keep_alive_if_weak(DecoratorSet decorators, oop value) { |
110 static void keep_alive_if_weak(DecoratorSet decorators, oop value) { |
120 assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known"); |
111 assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known"); |
121 const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0; |
112 const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0; |
122 const bool peek = (decorators & AS_NO_KEEPALIVE) != 0; |
113 const bool peek = (decorators & AS_NO_KEEPALIVE) != 0; |
147 // Callbacks for runtime accesses. |
138 // Callbacks for runtime accesses. |
148 template <DecoratorSet decorators, typename BarrierSetT = ShenandoahBarrierSet> |
139 template <DecoratorSet decorators, typename BarrierSetT = ShenandoahBarrierSet> |
149 class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> { |
140 class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> { |
150 typedef BarrierSet::AccessBarrier<decorators, BarrierSetT> Raw; |
141 typedef BarrierSet::AccessBarrier<decorators, BarrierSetT> Raw; |
151 |
142 |
|
143 template <typename T> |
|
144 static oop oop_atomic_cmpxchg_in_heap_impl(oop new_value, T* addr, oop compare_value); |
|
145 |
|
146 template <typename T> |
|
147 static oop oop_atomic_xchg_in_heap_impl(oop new_value, T* addr); |
|
148 |
152 public: |
149 public: |
153 // Primitive heap accesses. These accessors get resolved when |
|
154 // IN_HEAP is set (e.g. when using the HeapAccess API), it is |
|
155 // not an oop_* overload, and the barrier strength is AS_NORMAL. |
|
156 template <typename T> |
|
157 static T load_in_heap(T* addr) { |
|
158 ShouldNotReachHere(); |
|
159 return Raw::template load<T>(addr); |
|
160 } |
|
161 |
|
162 template <typename T> |
|
163 static T load_in_heap_at(oop base, ptrdiff_t offset) { |
|
164 base = ShenandoahBarrierSet::resolve_forwarded(base); |
|
165 return Raw::template load_at<T>(base, offset); |
|
166 } |
|
167 |
|
168 template <typename T> |
|
169 static void store_in_heap(T* addr, T value) { |
|
170 ShouldNotReachHere(); |
|
171 Raw::store(addr, value); |
|
172 } |
|
173 |
|
174 template <typename T> |
|
175 static void store_in_heap_at(oop base, ptrdiff_t offset, T value) { |
|
176 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base); |
|
177 Raw::store_at(base, offset, value); |
|
178 } |
|
179 |
|
180 template <typename T> |
|
181 static T atomic_cmpxchg_in_heap(T new_value, T* addr, T compare_value) { |
|
182 ShouldNotReachHere(); |
|
183 return Raw::atomic_cmpxchg(new_value, addr, compare_value); |
|
184 } |
|
185 |
|
186 template <typename T> |
|
187 static T atomic_cmpxchg_in_heap_at(T new_value, oop base, ptrdiff_t offset, T compare_value) { |
|
188 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base); |
|
189 return Raw::atomic_cmpxchg_at(new_value, base, offset, compare_value); |
|
190 } |
|
191 |
|
192 template <typename T> |
|
193 static T atomic_xchg_in_heap(T new_value, T* addr) { |
|
194 ShouldNotReachHere(); |
|
195 return Raw::atomic_xchg(new_value, addr); |
|
196 } |
|
197 |
|
198 template <typename T> |
|
199 static T atomic_xchg_in_heap_at(T new_value, oop base, ptrdiff_t offset) { |
|
200 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base); |
|
201 return Raw::atomic_xchg_at(new_value, base, offset); |
|
202 } |
|
203 |
|
204 template <typename T> |
|
205 static void arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
|
206 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
|
207 size_t length); |
|
208 |
|
209 // Heap oop accesses. These accessors get resolved when |
150 // Heap oop accesses. These accessors get resolved when |
210 // IN_HEAP is set (e.g. when using the HeapAccess API), it is |
151 // IN_HEAP is set (e.g. when using the HeapAccess API), it is |
211 // an oop_* overload, and the barrier strength is AS_NORMAL. |
152 // an oop_* overload, and the barrier strength is AS_NORMAL. |
212 template <typename T> |
153 template <typename T> |
213 static oop oop_load_in_heap(T* addr) { |
154 static oop oop_load_in_heap(T* addr); |
214 // ShouldNotReachHere(); |
155 static oop oop_load_in_heap_at(oop base, ptrdiff_t offset); |
215 oop value = Raw::template oop_load<oop>(addr); |
156 |
216 keep_alive_if_weak(decorators, value); |
157 template <typename T> |
217 return value; |
158 static void oop_store_in_heap(T* addr, oop value); |
218 } |
159 static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value); |
219 |
|
220 static oop oop_load_in_heap_at(oop base, ptrdiff_t offset) { |
|
221 base = ShenandoahBarrierSet::resolve_forwarded(base); |
|
222 oop value = Raw::template oop_load_at<oop>(base, offset); |
|
223 keep_alive_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value); |
|
224 return value; |
|
225 } |
|
226 |
|
227 template <typename T> |
|
228 static void oop_store_in_heap(T* addr, oop value) { |
|
229 const bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0; |
|
230 if (keep_alive) { |
|
231 ShenandoahBarrierSet::barrier_set()->write_ref_field_pre_work(addr, value); |
|
232 } |
|
233 Raw::oop_store(addr, value); |
|
234 } |
|
235 |
|
236 static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) { |
|
237 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base); |
|
238 value = ShenandoahBarrierSet::barrier_set()->storeval_barrier(value); |
|
239 |
|
240 oop_store_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), value); |
|
241 } |
|
242 |
160 |
243 template <typename T> |
161 template <typename T> |
244 static oop oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value); |
162 static oop oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value); |
245 |
163 static oop oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value); |
246 static oop oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) { |
|
247 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base); |
|
248 new_value = ShenandoahBarrierSet::barrier_set()->storeval_barrier(new_value); |
|
249 return oop_atomic_cmpxchg_in_heap(new_value, AccessInternal::oop_field_addr<decorators>(base, offset), compare_value); |
|
250 } |
|
251 |
164 |
252 template <typename T> |
165 template <typename T> |
253 static oop oop_atomic_xchg_in_heap(oop new_value, T* addr); |
166 static oop oop_atomic_xchg_in_heap(oop new_value, T* addr); |
254 |
167 static oop oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset); |
255 static oop oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) { |
|
256 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base); |
|
257 new_value = ShenandoahBarrierSet::barrier_set()->storeval_barrier(new_value); |
|
258 return oop_atomic_xchg_in_heap(new_value, AccessInternal::oop_field_addr<decorators>(base, offset)); |
|
259 } |
|
260 |
168 |
261 template <typename T> |
169 template <typename T> |
262 static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
170 static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
263 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
171 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
264 size_t length); |
172 size_t length); |