< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp

Print this page

355   if (ShenandoahCardBarrier) {
356     bs->write_ref_field_post<decorators>(addr);
357   }
358   return result;
359 }
360 
361 template <DecoratorSet decorators, typename BarrierSetT>
362 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value) {
363   assert((decorators & AS_NO_KEEPALIVE) == 0, "must be absent");
364   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
365   DecoratorSet resolved_decorators = AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);
366   auto addr = AccessInternal::oop_field_addr<decorators>(base, offset);
367   oop result = bs->oop_xchg(resolved_decorators, addr, new_value);
368   if (ShenandoahCardBarrier) {
369     bs->write_ref_field_post<decorators>(addr);
370   }
371   return result;
372 }
373 
374 // Clone barrier support



















































375 template <DecoratorSet decorators, typename BarrierSetT>
376 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
377   if (ShenandoahCloneBarrier) {
378     ShenandoahBarrierSet::barrier_set()->clone_barrier_runtime(src);









379   }
380   Raw::clone(src, dst, size);




381 }
382 
383 template <DecoratorSet decorators, typename BarrierSetT>
384 template <typename T>
385 OopCopyResult ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
386                                                                                                   arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
387                                                                                                   size_t length) {
388   T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
389   T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
390 
391   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
392   bs->arraycopy_barrier(src, dst, length);
393   OopCopyResult result = Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
394   if (ShenandoahCardBarrier) {
395     bs->write_ref_array((HeapWord*) dst, length);
396   }
397   return result;
398 }
399 
400 template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE>

355   if (ShenandoahCardBarrier) {
356     bs->write_ref_field_post<decorators>(addr);
357   }
358   return result;
359 }
360 
361 template <DecoratorSet decorators, typename BarrierSetT>
362 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value) {
363   assert((decorators & AS_NO_KEEPALIVE) == 0, "must be absent");
364   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
365   DecoratorSet resolved_decorators = AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);
366   auto addr = AccessInternal::oop_field_addr<decorators>(base, offset);
367   oop result = bs->oop_xchg(resolved_decorators, addr, new_value);
368   if (ShenandoahCardBarrier) {
369     bs->write_ref_field_post<decorators>(addr);
370   }
371   return result;
372 }
373 
374 // Clone barrier support
375 template <bool EVAC>
376 class ShenandoahUpdateEvacForCloneOopClosure : public BasicOopIterateClosure {
377 private:
378   ShenandoahHeap* const _heap;
379   const ShenandoahCollectionSet* const _cset;
380   Thread* const _thread;
381 
382   template <class T>
383   inline void do_oop_work(T* p) {
384     T o = RawAccess<>::oop_load(p);
385     if (!CompressedOops::is_null(o)) {
386       oop obj = CompressedOops::decode_not_null(o);
387       if (_cset->is_in(obj)) {
388         oop fwd = ShenandoahForwarding::get_forwardee(obj);
389         if (EVAC && obj == fwd) {
390           fwd = _heap->evacuate_object(obj, _thread);
391         }
392         shenandoah_assert_forwarded_except(p, obj, _heap->cancelled_gc());
393         ShenandoahHeap::atomic_update_oop(fwd, p, o);
394         obj = fwd;
395       }
396     }
397   }
398 
399 public:
400   ShenandoahUpdateEvacForCloneOopClosure() :
401           _heap(ShenandoahHeap::heap()),
402           _cset(_heap->collection_set()),
403           _thread(Thread::current()) {}
404 
405   virtual void do_oop(oop* p)       { do_oop_work(p); }
406   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
407 };
408 
409 void ShenandoahBarrierSet::clone_evacuation(oop obj) {
410   assert(_heap->is_evacuation_in_progress(), "only during evacuation");
411   if (need_bulk_update(cast_from_oop<HeapWord*>(obj))) {
412     ShenandoahEvacOOMScope oom_evac_scope;
413     ShenandoahUpdateEvacForCloneOopClosure<true> cl;
414     obj->oop_iterate(&cl);
415   }
416 }
417 
418 void ShenandoahBarrierSet::clone_update(oop obj) {
419   assert(_heap->is_update_refs_in_progress(), "only during update-refs");
420   if (need_bulk_update(cast_from_oop<HeapWord*>(obj))) {
421     ShenandoahUpdateEvacForCloneOopClosure<false> cl;
422     obj->oop_iterate(&cl);
423   }
424 }
425 
426 template <DecoratorSet decorators, typename BarrierSetT>
427 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t count) {
428   // Hot code path, called from compiler/runtime. Make sure fast path is fast.
429 
430   // Fix up src before doing the copy, if needed.
431   const char gc_state = ShenandoahThreadLocalData::gc_state(Thread::current());
432   if (gc_state > 0 && ShenandoahCloneBarrier) {
433     ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
434     if ((gc_state & ShenandoahHeap::EVACUATION) != 0) {
435       bs->clone_evacuation(src);
436     } else if ((gc_state & ShenandoahHeap::UPDATE_REFS) != 0) {
437       bs->clone_update(src);
438     }
439   }
440 
441   Raw::clone(src, dst, count);
442 
443   // Safety: clone destination must be in young, otherwise we need card barriers.
444   shenandoah_assert_in_young_if(nullptr, dst, ShenandoahCardBarrier);
445 }
446 
447 template <DecoratorSet decorators, typename BarrierSetT>
448 template <typename T>
449 OopCopyResult ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
450                                                                                                   arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
451                                                                                                   size_t length) {
452   T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
453   T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
454 
455   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
456   bs->arraycopy_barrier(src, dst, length);
457   OopCopyResult result = Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
458   if (ShenandoahCardBarrier) {
459     bs->write_ref_array((HeapWord*) dst, length);
460   }
461   return result;
462 }
463 
464 template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE>
< prev index next >