< prev index next >

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

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

@@ -26,22 +26,44 @@
 #define SHARE_GC_SHENANDOAH_SHENANDOAHFORWARDING_INLINE_HPP
 
 #include "gc/shenandoah/shenandoahAsserts.hpp"
 #include "gc/shenandoah/shenandoahForwarding.hpp"
 #include "oops/markWord.inline.hpp"
+#include "runtime/thread.hpp"
 
 inline HeapWord* ShenandoahForwarding::get_forwardee_raw(oop obj) {
   shenandoah_assert_in_heap(NULL, obj);
   return get_forwardee_raw_unchecked(obj);
 }
 
 inline HeapWord* ShenandoahForwarding::get_forwardee_raw_unchecked(oop obj) {
+  // JVMTI and JFR code use mark words for marking objects for their needs.
+  // On this path, we can encounter the "marked" object, but with NULL
+  // fwdptr. That object is still not forwarded, and we need to return
+  // the object itself.
   markWord mark = obj->mark_raw();
   if (mark.is_marked()) {
-    return (HeapWord*) mark.clear_lock_bits().to_pointer();
-  } else {
+    HeapWord* fwdptr = (HeapWord*) mark.clear_lock_bits().to_pointer();
+    if (fwdptr != NULL) {
+      return fwdptr;
+    }
+  }
     return cast_from_oop<HeapWord*>(obj);
+}
+
+inline oop ShenandoahForwarding::get_forwardee_mutator(oop obj) {
+  // Same as above, but mutator thread cannot ever see NULL forwardee.
+  shenandoah_assert_correct(NULL, obj);
+  assert(Thread::current()->is_Java_thread(), "Must be a mutator thread");
+
+  markWord mark = obj->mark_raw();
+  if (mark.is_marked()) {
+    HeapWord* fwdptr = (HeapWord*) mark.clear_lock_bits().to_pointer();
+    assert(fwdptr != NULL, "Forwarding pointer is never null here");
+    return cast_to_oop(fwdptr);
+  } else {
+    return obj;
   }
 }
 
 inline oop ShenandoahForwarding::get_forwardee(oop obj) {
   shenandoah_assert_correct(NULL, obj);
< prev index next >