351 DecoratorSet resolved_decorators = AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);
352 auto addr = AccessInternal::oop_field_addr<decorators>(base, offset);
353 oop result = bs->oop_xchg(resolved_decorators, addr, new_value);
354 if (ShenandoahCardBarrier) {
355 bs->write_ref_field_post<decorators>(addr);
356 }
357 return result;
358 }
359
360 // Clone barrier support
361 template <DecoratorSet decorators, typename BarrierSetT>
362 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
363 if (ShenandoahCloneBarrier) {
364 ShenandoahBarrierSet::barrier_set()->clone_barrier_runtime(src);
365 }
366 Raw::clone(src, dst, size);
367 }
368
369 template <DecoratorSet decorators, typename BarrierSetT>
370 template <typename T>
371 bool ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
372 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
373 size_t length) {
374 T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
375 T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
376
377 ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
378 bs->arraycopy_barrier(src, dst, length);
379 bool result = Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
380 if (ShenandoahCardBarrier) {
381 bs->write_ref_array((HeapWord*) dst, length);
382 }
383 return result;
384 }
385
386 template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE>
387 void ShenandoahBarrierSet::arraycopy_work(T* src, size_t count) {
388 // Young cycles are allowed to run when old marking is in progress. When old marking is in progress,
389 // this barrier will be called with ENQUEUE=true and HAS_FWD=false, even though the young generation
390 // may have forwarded objects. In this case, the `arraycopy_work` is first called with HAS_FWD=true and
391 // ENQUEUE=false.
392 assert(HAS_FWD == _heap->has_forwarded_objects() || _heap->is_concurrent_old_mark_in_progress(),
393 "Forwarded object status is sane");
394 // This function cannot be called to handle marking and evacuation at the same time (they operate on
395 // different sides of the copy).
396 assert((HAS_FWD || EVAC) != ENQUEUE, "Cannot evacuate and mark both sides of copy.");
397
398 Thread* thread = Thread::current();
399 SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue(thread);
400 ShenandoahMarkingContext* ctx = _heap->marking_context();
401 const ShenandoahCollectionSet* const cset = _heap->collection_set();
402 T* end = src + count;
403 for (T* elem_ptr = src; elem_ptr < end; elem_ptr++) {
|
351 DecoratorSet resolved_decorators = AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);
352 auto addr = AccessInternal::oop_field_addr<decorators>(base, offset);
353 oop result = bs->oop_xchg(resolved_decorators, addr, new_value);
354 if (ShenandoahCardBarrier) {
355 bs->write_ref_field_post<decorators>(addr);
356 }
357 return result;
358 }
359
360 // Clone barrier support
361 template <DecoratorSet decorators, typename BarrierSetT>
362 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
363 if (ShenandoahCloneBarrier) {
364 ShenandoahBarrierSet::barrier_set()->clone_barrier_runtime(src);
365 }
366 Raw::clone(src, dst, size);
367 }
368
369 template <DecoratorSet decorators, typename BarrierSetT>
370 template <typename T>
371 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
372 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
373 size_t length) {
374 T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
375 T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
376
377 ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
378 bs->arraycopy_barrier(arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw),
379 arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw),
380 length);
381 Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
382 if (ShenandoahCardBarrier) {
383 bs->write_ref_array((HeapWord*) dst, length);
384 }
385 }
386
387 template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE>
388 void ShenandoahBarrierSet::arraycopy_work(T* src, size_t count) {
389 // Young cycles are allowed to run when old marking is in progress. When old marking is in progress,
390 // this barrier will be called with ENQUEUE=true and HAS_FWD=false, even though the young generation
391 // may have forwarded objects. In this case, the `arraycopy_work` is first called with HAS_FWD=true and
392 // ENQUEUE=false.
393 assert(HAS_FWD == _heap->has_forwarded_objects() || _heap->is_concurrent_old_mark_in_progress(),
394 "Forwarded object status is sane");
395 // This function cannot be called to handle marking and evacuation at the same time (they operate on
396 // different sides of the copy).
397 assert((HAS_FWD || EVAC) != ENQUEUE, "Cannot evacuate and mark both sides of copy.");
398
399 Thread* thread = Thread::current();
400 SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue(thread);
401 ShenandoahMarkingContext* ctx = _heap->marking_context();
402 const ShenandoahCollectionSet* const cset = _heap->collection_set();
403 T* end = src + count;
404 for (T* elem_ptr = src; elem_ptr < end; elem_ptr++) {
|