< prev index next >

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

Print this page

 39 #include "gc/shenandoah/shenandoahGeneration.hpp"
 40 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 41 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
 42 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
 43 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
 44 #include "memory/iterator.inline.hpp"
 45 #include "oops/oop.inline.hpp"
 46 
 47 inline oop ShenandoahBarrierSet::resolve_forwarded_not_null(oop p) {
 48   return ShenandoahForwarding::get_forwardee(p);
 49 }
 50 
 51 inline oop ShenandoahBarrierSet::resolve_forwarded(oop p) {
 52   if (p != nullptr) {
 53     return resolve_forwarded_not_null(p);
 54   } else {
 55     return p;
 56   }
 57 }
 58 
 59 inline oop ShenandoahBarrierSet::resolve_forwarded_not_null_mutator(oop p) {
 60   return ShenandoahForwarding::get_forwardee_mutator(p);
 61 }
 62 
 63 template <class T>
 64 inline oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj, T* load_addr) {
 65   assert(ShenandoahLoadRefBarrier, "should be enabled");
 66   shenandoah_assert_in_cset(load_addr, obj);





































 67 
 68   oop fwd = resolve_forwarded_not_null_mutator(obj);
 69   if (obj == fwd) {
 70     assert(_heap->is_evacuation_in_progress(), "evac should be in progress");
 71     Thread* const t = Thread::current();
 72     ShenandoahEvacOOMScope scope(t);
 73     fwd = _heap->evacuate_object(obj, t);
 74   }
 75 
 76   if (load_addr != nullptr && fwd != obj) {
 77     // Since we are here and we know the load address, update the reference.
 78     ShenandoahHeap::atomic_update_oop(fwd, load_addr, obj);
 79   }
 80 
 81   return fwd;
 82 }
 83 
 84 inline oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
 85   if (!ShenandoahLoadRefBarrier) {
 86     return obj;
 87   }
 88   if (_heap->has_forwarded_objects() && _heap->in_collection_set(obj)) {

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>

 39 #include "gc/shenandoah/shenandoahGeneration.hpp"
 40 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 41 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
 42 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
 43 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
 44 #include "memory/iterator.inline.hpp"
 45 #include "oops/oop.inline.hpp"
 46 
 47 inline oop ShenandoahBarrierSet::resolve_forwarded_not_null(oop p) {
 48   return ShenandoahForwarding::get_forwardee(p);
 49 }
 50 
 51 inline oop ShenandoahBarrierSet::resolve_forwarded(oop p) {
 52   if (p != nullptr) {
 53     return resolve_forwarded_not_null(p);
 54   } else {
 55     return p;
 56   }
 57 }
 58 
 59 template <DecoratorSet decorators, class T>




 60 inline oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj, T* load_addr) {
 61   assert(ShenandoahLoadRefBarrier, "Should be enabled");
 62 
 63   bool on_weak    = HasDecorator<decorators, ON_WEAK_OOP_REF>::value;
 64   bool on_phantom = HasDecorator<decorators, ON_PHANTOM_OOP_REF>::value;
 65 
 66   // Handle nulls. Strong loads filtered nulls with cset checks.
 67   // Weak/phantom loads need to check for nulls here.
 68   if (on_weak || on_phantom) {
 69     if (obj == nullptr) {
 70       return nullptr;
 71     }
 72   } else {
 73     assert(obj != nullptr, "Should have been filtered before");
 74   }
 75 
 76   // Prevent resurrection of unreachable phantom (i.e. weak-native) references.
 77   if (on_phantom &&
 78       _heap->is_concurrent_weak_root_in_progress() &&
 79       _heap->is_in_active_generation(obj) &&
 80       !_heap->marking_context()->is_marked(obj)) {
 81     return nullptr;
 82   }
 83 
 84   // Prevent resurrection of unreachable weak references.
 85   if (on_weak &&
 86       _heap->is_concurrent_weak_root_in_progress() &&
 87       _heap->is_in_active_generation(obj) &&
 88       !_heap->marking_context()->is_marked_strong(obj)) {
 89     return nullptr;
 90   }
 91 
 92   // Weak/phantom loads need additional cset check.
 93   if (on_phantom || on_weak) {
 94     if (!_heap->has_forwarded_objects() || !_heap->in_collection_set(obj)) {
 95       return obj;
 96     }
 97   } else {
 98     shenandoah_assert_in_cset(load_addr, obj);
 99   }
100 
101   oop fwd = ShenandoahForwarding::get_forwardee_mutator(obj);
102   if (obj == fwd) {
103     assert(_heap->is_evacuation_in_progress(), "evac should be in progress");
104     Thread* const t = Thread::current();
105     ShenandoahEvacOOMScope scope(t);
106     fwd = _heap->evacuate_object(obj, t);
107   }
108 
109   if (load_addr != nullptr && fwd != obj) {
110     // Since we are here and we know the load address, update the reference.
111     ShenandoahHeap::atomic_update_oop(fwd, load_addr, obj);
112   }
113 
114   return fwd;
115 }
116 
117 inline oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
118   if (!ShenandoahLoadRefBarrier) {
119     return obj;
120   }
121   if (_heap->has_forwarded_objects() && _heap->in_collection_set(obj)) {

388   if (ShenandoahCardBarrier) {
389     bs->write_ref_field_post<decorators>(addr);
390   }
391   return result;
392 }
393 
394 template <DecoratorSet decorators, typename BarrierSetT>
395 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value) {
396   assert((decorators & AS_NO_KEEPALIVE) == 0, "must be absent");
397   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
398   DecoratorSet resolved_decorators = AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);
399   auto addr = AccessInternal::oop_field_addr<decorators>(base, offset);
400   oop result = bs->oop_xchg(resolved_decorators, addr, new_value);
401   if (ShenandoahCardBarrier) {
402     bs->write_ref_field_post<decorators>(addr);
403   }
404   return result;
405 }
406 
407 // Clone barrier support
408 template <bool EVAC>
409 class ShenandoahUpdateEvacForCloneOopClosure : public BasicOopIterateClosure {
410 private:
411   ShenandoahHeap* const _heap;
412   const ShenandoahCollectionSet* const _cset;
413   Thread* const _thread;
414 
415   template <class T>
416   inline void do_oop_work(T* p) {
417     T o = RawAccess<>::oop_load(p);
418     if (!CompressedOops::is_null(o)) {
419       oop obj = CompressedOops::decode_not_null(o);
420       if (_cset->is_in(obj)) {
421         oop fwd = ShenandoahForwarding::get_forwardee(obj);
422         if (EVAC && obj == fwd) {
423           fwd = _heap->evacuate_object(obj, _thread);
424         }
425         shenandoah_assert_forwarded_except(p, obj, _heap->cancelled_gc());
426         ShenandoahHeap::atomic_update_oop(fwd, p, o);
427         obj = fwd;
428       }
429     }
430   }
431 
432 public:
433   ShenandoahUpdateEvacForCloneOopClosure() :
434           _heap(ShenandoahHeap::heap()),
435           _cset(_heap->collection_set()),
436           _thread(Thread::current()) {}
437 
438   virtual void do_oop(oop* p)       { do_oop_work(p); }
439   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
440 };
441 
442 void ShenandoahBarrierSet::clone_evacuation(oop obj) {
443   assert(_heap->is_evacuation_in_progress(), "only during evacuation");
444   if (need_bulk_update(cast_from_oop<HeapWord*>(obj))) {
445     ShenandoahEvacOOMScope oom_evac_scope;
446     ShenandoahUpdateEvacForCloneOopClosure<true> cl;
447     obj->oop_iterate(&cl);
448   }
449 }
450 
451 void ShenandoahBarrierSet::clone_update(oop obj) {
452   assert(_heap->is_update_refs_in_progress(), "only during update-refs");
453   if (need_bulk_update(cast_from_oop<HeapWord*>(obj))) {
454     ShenandoahUpdateEvacForCloneOopClosure<false> cl;
455     obj->oop_iterate(&cl);
456   }
457 }
458 
459 template <DecoratorSet decorators, typename BarrierSetT>
460 void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t count) {
461   // Hot code path, called from compiler/runtime. Make sure fast path is fast.
462 
463   // Fix up src before doing the copy, if needed.
464   const char gc_state = ShenandoahThreadLocalData::gc_state(Thread::current());
465   if (gc_state > 0 && ShenandoahCloneBarrier) {
466     ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
467     if ((gc_state & ShenandoahHeap::EVACUATION) != 0) {
468       bs->clone_evacuation(src);
469     } else if ((gc_state & ShenandoahHeap::UPDATE_REFS) != 0) {
470       bs->clone_update(src);
471     }
472   }
473 
474   Raw::clone(src, dst, count);
475 
476   // Safety: clone destination must be in young, otherwise we need card barriers.
477   shenandoah_assert_in_young_if(nullptr, dst, ShenandoahCardBarrier);
478 }
479 
480 template <DecoratorSet decorators, typename BarrierSetT>
481 template <typename T>
482 OopCopyResult ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
483                                                                                                   arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
484                                                                                                   size_t length) {
485   T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
486   T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
487 
488   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
489   bs->arraycopy_barrier(src, dst, length);
490   OopCopyResult result = Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
491   if (ShenandoahCardBarrier) {
492     bs->write_ref_array((HeapWord*) dst, length);
493   }
494   return result;
495 }
496 
497 template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE>
< prev index next >