< prev index next >

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

Print this page
rev 57589 : 8237632: Shenandoah fails some vmTestbase_nsk_jvmti tests with "Forwardee must point to a heap address"


  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
  25 #define SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
  26 
  27 #include "gc/shared/barrierSet.hpp"
  28 #include "gc/shenandoah/shenandoahAsserts.hpp"
  29 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  30 #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
  31 #include "gc/shenandoah/shenandoahForwarding.inline.hpp"
  32 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  33 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  34 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"

  35 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
  36 #include "memory/iterator.inline.hpp"
  37 #include "oops/oop.inline.hpp"
  38 
  39 inline oop ShenandoahBarrierSet::resolve_forwarded_not_null(oop p) {



  40   return ShenandoahForwarding::get_forwardee(p);
  41 }
  42 
  43 inline oop ShenandoahBarrierSet::resolve_forwarded(oop p) {
  44   if (((HeapWord*) p) != NULL) {
  45     return resolve_forwarded_not_null(p);
  46   } else {
  47     return p;
  48   }
  49 }
  50 











  51 inline void ShenandoahBarrierSet::enqueue(oop obj) {
  52   shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_traversal_in_progress());
  53   assert(_satb_mark_queue_set.is_active(), "only get here when SATB active");
  54 
  55   // Filter marked objects before hitting the SATB queues. The same predicate would
  56   // be used by SATBMQ::filter to eliminate already marked objects downstream, but
  57   // filtering here helps to avoid wasteful SATB queueing work to begin with.
  58   if (!_heap->requires_marking<false>(obj)) return;
  59 
  60   ShenandoahThreadLocalData::satb_mark_queue(Thread::current()).enqueue_known_active(obj);
  61 }
  62 
  63 template <DecoratorSet decorators, typename T>
  64 inline void ShenandoahBarrierSet::satb_barrier(T *field) {
  65   if (HasDecorator<decorators, IS_DEST_UNINITIALIZED>::value ||
  66       HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
  67     return;
  68   }
  69   if (ShenandoahSATBBarrier && _heap->is_concurrent_mark_in_progress()) {
  70     T heap_oop = RawAccess<>::oop_load(field);


 102     keep_alive_barrier(value);
 103   }
 104 }
 105 
 106 template <DecoratorSet decorators>
 107 inline void ShenandoahBarrierSet::keep_alive_if_weak(oop value) {
 108   assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known");
 109   if (!HasDecorator<decorators, ON_STRONG_OOP_REF>::value &&
 110       !HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
 111     keep_alive_barrier(value);
 112   }
 113 }
 114 
 115 template <DecoratorSet decorators, typename BarrierSetT>
 116 template <typename T>
 117 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_not_in_heap(T* addr) {
 118   oop value = Raw::oop_load_not_in_heap(addr);
 119   if (value != NULL) {
 120     ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();
 121     value = bs->load_reference_barrier_native(value, addr);

 122     bs->keep_alive_if_weak<decorators>(value);
 123   }

 124   return value;
 125 }
 126 
 127 template <DecoratorSet decorators, typename BarrierSetT>
 128 template <typename T>
 129 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap(T* addr) {
 130   oop value = Raw::oop_load_in_heap(addr);
 131   if (value != NULL) {
 132     ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();
 133     value = bs->load_reference_barrier_not_null(value);
 134     bs->keep_alive_if_weak<decorators>(value);
 135   }
 136   return value;
 137 }
 138 
 139 template <DecoratorSet decorators, typename BarrierSetT>
 140 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap_at(oop base, ptrdiff_t offset) {
 141   oop value = Raw::oop_load_in_heap_at(base, offset);
 142   if (value != NULL) {
 143     ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();


 168   oop_store_not_in_heap(addr, value);
 169 }
 170 
 171 template <DecoratorSet decorators, typename BarrierSetT>
 172 inline void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) {
 173   oop_store_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), value);
 174 }
 175 
 176 template <DecoratorSet decorators, typename BarrierSetT>
 177 template <typename T>
 178 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_not_in_heap(T* addr, oop compare_value, oop new_value) {
 179   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
 180   bs->storeval_barrier(new_value);
 181 
 182   oop res;
 183   oop expected = compare_value;
 184   do {
 185     compare_value = expected;
 186     res = Raw::oop_atomic_cmpxchg(addr, compare_value, new_value);
 187     expected = res;
 188   } while ((compare_value != expected) && (resolve_forwarded(compare_value) == resolve_forwarded(expected)));
 189 
 190   // Note: We don't need a keep-alive-barrier here. We already enqueue any loaded reference for SATB anyway,
 191   // because it must be the previous value.
 192   if (res != NULL) {
 193     res = ShenandoahBarrierSet::barrier_set()->load_reference_barrier_not_null(res);
 194     bs->satb_enqueue(res);
 195   }
 196   return res;
 197 }
 198 
 199 template <DecoratorSet decorators, typename BarrierSetT>
 200 template <typename T>
 201 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value) {
 202   return oop_atomic_cmpxchg_not_in_heap(addr, compare_value, new_value);
 203 }
 204 
 205 template <DecoratorSet decorators, typename BarrierSetT>
 206 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap_at(oop base, ptrdiff_t offset, oop compare_value, oop new_value) {
 207   return oop_atomic_cmpxchg_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), compare_value, new_value);
 208 }




  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
  25 #define SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
  26 
  27 #include "gc/shared/barrierSet.hpp"
  28 #include "gc/shenandoah/shenandoahAsserts.hpp"
  29 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  30 #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
  31 #include "gc/shenandoah/shenandoahForwarding.inline.hpp"
  32 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  33 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  34 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  35 #include "gc/shenandoah/shenandoahSafepoint.hpp"
  36 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
  37 #include "memory/iterator.inline.hpp"
  38 #include "oops/oop.inline.hpp"
  39 
  40 inline oop ShenandoahBarrierSet::resolve_forwarded_not_null(oop p) {
  41   assert(ShenandoahHeap::heap()->in_collection_set(p) ||
  42          ShenandoahSafepoint::is_at_shenandoah_safepoint(),
  43          "No forwarding oops outside cset");
  44   return ShenandoahForwarding::get_forwardee(p);
  45 }
  46 
  47 inline oop ShenandoahBarrierSet::resolve_forwarded(oop p) {
  48   if (((HeapWord*) p) != NULL) {
  49     return resolve_forwarded_not_null(p);
  50   } else {
  51     return p;
  52   }
  53 }
  54 
  55 inline oop ShenandoahBarrierSet::resolve_forwarded_checked(oop p) {
  56   if (p == NULL) return p;
  57   ShenandoahHeap* const heap = ShenandoahHeap::heap();
  58   if (heap->in_collection_set(p) ||
  59      (heap->is_concurrent_traversal_in_progress() && heap->is_degenerated_gc_in_progress())) {
  60     return resolve_forwarded_not_null(p);
  61   } else {
  62     return p;
  63   }
  64 }
  65 
  66 inline void ShenandoahBarrierSet::enqueue(oop obj) {
  67   shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_traversal_in_progress());
  68   assert(_satb_mark_queue_set.is_active(), "only get here when SATB active");
  69 
  70   // Filter marked objects before hitting the SATB queues. The same predicate would
  71   // be used by SATBMQ::filter to eliminate already marked objects downstream, but
  72   // filtering here helps to avoid wasteful SATB queueing work to begin with.
  73   if (!_heap->requires_marking<false>(obj)) return;
  74 
  75   ShenandoahThreadLocalData::satb_mark_queue(Thread::current()).enqueue_known_active(obj);
  76 }
  77 
  78 template <DecoratorSet decorators, typename T>
  79 inline void ShenandoahBarrierSet::satb_barrier(T *field) {
  80   if (HasDecorator<decorators, IS_DEST_UNINITIALIZED>::value ||
  81       HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
  82     return;
  83   }
  84   if (ShenandoahSATBBarrier && _heap->is_concurrent_mark_in_progress()) {
  85     T heap_oop = RawAccess<>::oop_load(field);


 117     keep_alive_barrier(value);
 118   }
 119 }
 120 
 121 template <DecoratorSet decorators>
 122 inline void ShenandoahBarrierSet::keep_alive_if_weak(oop value) {
 123   assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known");
 124   if (!HasDecorator<decorators, ON_STRONG_OOP_REF>::value &&
 125       !HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
 126     keep_alive_barrier(value);
 127   }
 128 }
 129 
 130 template <DecoratorSet decorators, typename BarrierSetT>
 131 template <typename T>
 132 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_not_in_heap(T* addr) {
 133   oop value = Raw::oop_load_not_in_heap(addr);
 134   if (value != NULL) {
 135     ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();
 136     value = bs->load_reference_barrier_native(value, addr);
 137     if (value != NULL) {
 138       bs->keep_alive_if_weak<decorators>(value);
 139     }
 140   }
 141   return value;
 142 }
 143 
 144 template <DecoratorSet decorators, typename BarrierSetT>
 145 template <typename T>
 146 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap(T* addr) {
 147   oop value = Raw::oop_load_in_heap(addr);
 148   if (value != NULL) {
 149     ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();
 150     value = bs->load_reference_barrier_not_null(value);
 151     bs->keep_alive_if_weak<decorators>(value);
 152   }
 153   return value;
 154 }
 155 
 156 template <DecoratorSet decorators, typename BarrierSetT>
 157 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap_at(oop base, ptrdiff_t offset) {
 158   oop value = Raw::oop_load_in_heap_at(base, offset);
 159   if (value != NULL) {
 160     ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();


 185   oop_store_not_in_heap(addr, value);
 186 }
 187 
 188 template <DecoratorSet decorators, typename BarrierSetT>
 189 inline void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) {
 190   oop_store_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), value);
 191 }
 192 
 193 template <DecoratorSet decorators, typename BarrierSetT>
 194 template <typename T>
 195 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_not_in_heap(T* addr, oop compare_value, oop new_value) {
 196   ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
 197   bs->storeval_barrier(new_value);
 198 
 199   oop res;
 200   oop expected = compare_value;
 201   do {
 202     compare_value = expected;
 203     res = Raw::oop_atomic_cmpxchg(addr, compare_value, new_value);
 204     expected = res;
 205   } while ((compare_value != expected) && (resolve_forwarded_checked(compare_value) == resolve_forwarded_checked(expected)));
 206 
 207   // Note: We don't need a keep-alive-barrier here. We already enqueue any loaded reference for SATB anyway,
 208   // because it must be the previous value.
 209   if (res != NULL) {
 210     res = ShenandoahBarrierSet::barrier_set()->load_reference_barrier_not_null(res);
 211     bs->satb_enqueue(res);
 212   }
 213   return res;
 214 }
 215 
 216 template <DecoratorSet decorators, typename BarrierSetT>
 217 template <typename T>
 218 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value) {
 219   return oop_atomic_cmpxchg_not_in_heap(addr, compare_value, new_value);
 220 }
 221 
 222 template <DecoratorSet decorators, typename BarrierSetT>
 223 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap_at(oop base, ptrdiff_t offset, oop compare_value, oop new_value) {
 224   return oop_atomic_cmpxchg_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), compare_value, new_value);
 225 }


< prev index next >