src/hotspot/share/oops/oop.inline.hpp
changeset 52271 1587306fe23f
parent 52119 88916200bdd7
child 53244 9807daeb47c4
--- a/src/hotspot/share/oops/oop.inline.hpp	Wed Oct 24 14:59:21 2018 +0200
+++ b/src/hotspot/share/oops/oop.inline.hpp	Wed Oct 24 16:22:34 2018 +0200
@@ -370,26 +370,21 @@
   return cas_set_mark_raw(m, compare, order) == compare;
 }
 
-oop oopDesc::forward_to_atomic(oop p, atomic_memory_order order) {
-  markOop oldMark = mark_raw();
-  markOop forwardPtrMark = markOopDesc::encode_pointer_as_mark(p);
-  markOop curMark;
-
-  assert(forwardPtrMark->decode_pointer() == p, "encoding must be reversable");
-  assert(sizeof(markOop) == sizeof(intptr_t), "CAS below requires this.");
-
-  while (!oldMark->is_marked()) {
-    curMark = cas_set_mark_raw(forwardPtrMark, oldMark, order);
-    assert(is_forwarded(), "object should have been forwarded");
-    if (curMark == oldMark) {
-      return NULL;
-    }
-    // If the CAS was unsuccessful then curMark->is_marked()
-    // should return true as another thread has CAS'd in another
-    // forwarding pointer.
-    oldMark = curMark;
+oop oopDesc::forward_to_atomic(oop p, markOop compare, atomic_memory_order order) {
+  // CMS forwards some non-heap value into the mark oop to reserve oops during
+  // promotion, so the next two asserts do not hold.
+  assert(UseConcMarkSweepGC || check_obj_alignment(p),
+         "forwarding to something not aligned");
+  assert(UseConcMarkSweepGC || Universe::heap()->is_in_reserved(p),
+         "forwarding to something not in heap");
+  markOop m = markOopDesc::encode_pointer_as_mark(p);
+  assert(m->decode_pointer() == p, "encoding must be reversable");
+  markOop old_mark = cas_set_mark_raw(m, compare, order);
+  if (old_mark == compare) {
+    return NULL;
+  } else {
+    return (oop)old_mark->decode_pointer();
   }
-  return forwardee();
 }
 
 // Note that the forwardee is not the same thing as the displaced_mark.