169
170 template <DecoratorSet decorators, typename BarrierSetT>
171 template <typename T>
172 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap(oop new_value, T* addr) {
173 oop result = oop_atomic_xchg_in_heap_impl(new_value, addr);
174 keep_alive_if_weak(addr, result);
175 return result;
176 }
177
178 template <DecoratorSet decorators, typename BarrierSetT>
179 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) {
180 oop result = oop_atomic_xchg_in_heap_impl(new_value, AccessInternal::oop_field_addr<decorators>(base, offset));
181 keep_alive_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), result);
182 return result;
183 }
184
185 // Clone barrier support
186 template <DecoratorSet decorators, typename BarrierSetT>
187 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
188 if (ShenandoahCloneBarrier) {
189 ShenandoahBarrierSet::barrier_set()->clone_barrier(src);
190 }
191 Raw::clone(src, dst, size);
192 }
193
194 template <DecoratorSet decorators, typename BarrierSetT>
195 template <typename T>
196 bool ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
197 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
198 size_t length) {
199 ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
200 bs->arraycopy_pre(arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw),
201 arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw),
202 length);
203 return Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
204 }
205
206 template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE>
207 void ShenandoahBarrierSet::arraycopy_work(T* src, size_t count) {
208 Thread* thread = Thread::current();
209 SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue(thread);
254
255 template <class T>
256 void ShenandoahBarrierSet::arraycopy_update_impl(T* src, size_t count) {
257 if (_heap->is_evacuation_in_progress()) {
258 ShenandoahEvacOOMScope oom_evac;
259 arraycopy_work<T, true, true, false>(src, count);
260 } else if (_heap->is_concurrent_traversal_in_progress()){
261 ShenandoahEvacOOMScope oom_evac;
262 arraycopy_work<T, true, true, true>(src, count);
263 } else if (_heap->has_forwarded_objects()) {
264 arraycopy_work<T, true, false, false>(src, count);
265 }
266 }
267
268 void ShenandoahBarrierSet::arraycopy_update(oop* src, size_t count) {
269 arraycopy_update_impl(src, count);
270 }
271
272 void ShenandoahBarrierSet::arraycopy_update(narrowOop* src, size_t count) {
273 arraycopy_update_impl(src, count);
274 }
275
276 template <bool EVAC, bool ENQUEUE>
277 class ShenandoahUpdateRefsForOopClosure: public BasicOopIterateClosure {
278 private:
279 ShenandoahHeap* const _heap;
280 ShenandoahBarrierSet* const _bs;
281 const ShenandoahCollectionSet* const _cset;
282 Thread* const _thread;
283
284 template <class T>
285 inline void do_oop_work(T* p) {
286 T o = RawAccess<>::oop_load(p);
287 if (!CompressedOops::is_null(o)) {
288 oop obj = CompressedOops::decode_not_null(o);
289 if (_cset->is_in((HeapWord *)obj)) {
290 oop fwd = _bs->resolve_forwarded_not_null(obj);
291 if (EVAC && obj == fwd) {
292 fwd = _heap->evacuate_object(obj, _thread);
293 }
294 if (ENQUEUE) {
295 _bs->enqueue(fwd);
296 }
297 assert(obj != fwd || _heap->cancelled_gc(), "must be forwarded");
298 ShenandoahHeap::cas_oop(fwd, p, o);
299 }
300
301 }
302 }
303 public:
304 ShenandoahUpdateRefsForOopClosure() :
305 _heap(ShenandoahHeap::heap()),
306 _bs(ShenandoahBarrierSet::barrier_set()),
307 _cset(_heap->collection_set()),
308 _thread(Thread::current()) {
309 }
310
311 virtual void do_oop(oop* p) { do_oop_work(p); }
312 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
313 };
314
315 void ShenandoahBarrierSet::clone_barrier(oop obj) {
316 assert(ShenandoahCloneBarrier, "only get here with clone barriers enabled");
317 if (!_heap->has_forwarded_objects()) return;
318
319 // This is called for cloning an object (see jvm.cpp) after the clone
320 // has been made. We are not interested in any 'previous value' because
321 // it would be NULL in any case. But we *are* interested in any oop*
322 // that potentially need to be updated.
323
324 shenandoah_assert_correct(NULL, obj);
325 if (_heap->is_evacuation_in_progress()) {
326 ShenandoahEvacOOMScope evac_scope;
327 ShenandoahUpdateRefsForOopClosure</* evac = */ true, /* enqueue */ false> cl;
328 obj->oop_iterate(&cl);
329 } else if (_heap->is_concurrent_traversal_in_progress()) {
330 ShenandoahEvacOOMScope evac_scope;
331 ShenandoahUpdateRefsForOopClosure</* evac = */ true, /* enqueue */ true> cl;
332 obj->oop_iterate(&cl);
333 } else {
334 ShenandoahUpdateRefsForOopClosure</* evac = */ false, /* enqueue */ false> cl;
335 obj->oop_iterate(&cl);
336 }
337 }
338
339 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
|
169
170 template <DecoratorSet decorators, typename BarrierSetT>
171 template <typename T>
172 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap(oop new_value, T* addr) {
173 oop result = oop_atomic_xchg_in_heap_impl(new_value, addr);
174 keep_alive_if_weak(addr, result);
175 return result;
176 }
177
178 template <DecoratorSet decorators, typename BarrierSetT>
179 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) {
180 oop result = oop_atomic_xchg_in_heap_impl(new_value, AccessInternal::oop_field_addr<decorators>(base, offset));
181 keep_alive_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), result);
182 return result;
183 }
184
185 // Clone barrier support
186 template <DecoratorSet decorators, typename BarrierSetT>
187 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
188 if (ShenandoahCloneBarrier) {
189 ShenandoahBarrierSet::barrier_set()->clone_barrier_runtime(src);
190 }
191 Raw::clone(src, dst, size);
192 }
193
194 template <DecoratorSet decorators, typename BarrierSetT>
195 template <typename T>
196 bool ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
197 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
198 size_t length) {
199 ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
200 bs->arraycopy_pre(arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw),
201 arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw),
202 length);
203 return Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
204 }
205
206 template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE>
207 void ShenandoahBarrierSet::arraycopy_work(T* src, size_t count) {
208 Thread* thread = Thread::current();
209 SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue(thread);
254
255 template <class T>
256 void ShenandoahBarrierSet::arraycopy_update_impl(T* src, size_t count) {
257 if (_heap->is_evacuation_in_progress()) {
258 ShenandoahEvacOOMScope oom_evac;
259 arraycopy_work<T, true, true, false>(src, count);
260 } else if (_heap->is_concurrent_traversal_in_progress()){
261 ShenandoahEvacOOMScope oom_evac;
262 arraycopy_work<T, true, true, true>(src, count);
263 } else if (_heap->has_forwarded_objects()) {
264 arraycopy_work<T, true, false, false>(src, count);
265 }
266 }
267
268 void ShenandoahBarrierSet::arraycopy_update(oop* src, size_t count) {
269 arraycopy_update_impl(src, count);
270 }
271
272 void ShenandoahBarrierSet::arraycopy_update(narrowOop* src, size_t count) {
273 arraycopy_update_impl(src, count);
274 }
275
276 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
|