--- old/src/hotspot/share/oops/oop.inline.hpp 2018-10-23 12:02:55.440437679 +0200 +++ new/src/hotspot/share/oops/oop.inline.hpp 2018-10-23 12:02:55.026424787 +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.