< 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"

@@ -30,15 +30,19 @@
 #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
 #include "gc/shenandoah/shenandoahForwarding.inline.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
+#include "gc/shenandoah/shenandoahSafepoint.hpp"
 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
 #include "memory/iterator.inline.hpp"
 #include "oops/oop.inline.hpp"
 
 inline oop ShenandoahBarrierSet::resolve_forwarded_not_null(oop p) {
+  assert(ShenandoahHeap::heap()->in_collection_set(p) ||
+         ShenandoahSafepoint::is_at_shenandoah_safepoint(),
+         "No forwarding oops outside cset");
   return ShenandoahForwarding::get_forwardee(p);
 }
 
 inline oop ShenandoahBarrierSet::resolve_forwarded(oop p) {
   if (((HeapWord*) p) != NULL) {

@@ -46,10 +50,21 @@
   } else {
     return p;
   }
 }
 
+inline oop ShenandoahBarrierSet::resolve_forwarded_checked(oop p) {
+  if (p == NULL) return p;
+  ShenandoahHeap* const heap = ShenandoahHeap::heap();
+  if (heap->in_collection_set(p) ||
+     (heap->is_concurrent_traversal_in_progress() && heap->is_degenerated_gc_in_progress())) {
+    return resolve_forwarded_not_null(p);
+  } else {
+    return p;
+  }
+}
+
 inline void ShenandoahBarrierSet::enqueue(oop obj) {
   shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_traversal_in_progress());
   assert(_satb_mark_queue_set.is_active(), "only get here when SATB active");
 
   // Filter marked objects before hitting the SATB queues. The same predicate would

@@ -117,12 +132,14 @@
 inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_not_in_heap(T* addr) {
   oop value = Raw::oop_load_not_in_heap(addr);
   if (value != NULL) {
     ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();
     value = bs->load_reference_barrier_native(value, addr);
+    if (value != NULL) {
     bs->keep_alive_if_weak<decorators>(value);
   }
+  }
   return value;
 }
 
 template <DecoratorSet decorators, typename BarrierSetT>
 template <typename T>

@@ -183,11 +200,11 @@
   oop expected = compare_value;
   do {
     compare_value = expected;
     res = Raw::oop_atomic_cmpxchg(addr, compare_value, new_value);
     expected = res;
-  } while ((compare_value != expected) && (resolve_forwarded(compare_value) == resolve_forwarded(expected)));
+  } while ((compare_value != expected) && (resolve_forwarded_checked(compare_value) == resolve_forwarded_checked(expected)));
 
   // Note: We don't need a keep-alive-barrier here. We already enqueue any loaded reference for SATB anyway,
   // because it must be the previous value.
   if (res != NULL) {
     res = ShenandoahBarrierSet::barrier_set()->load_reference_barrier_not_null(res);
< prev index next >