diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp index 774406c515068..b653a06b8774d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -327,8 +327,11 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure { */ void verify_oops_from(oop obj) { _loc = obj; - Klass* klass = ShenandoahForwarding::klass(obj); - obj->oop_iterate_backwards(this, klass); + // oop_iterate() can not deal with forwarded objects, because + // it needs to load klass(), which may be overridden by the + // forwarding pointer. + oop fwd = ShenandoahForwarding::get_forwardee_raw(obj); + fwd->oop_iterate(this); _loc = nullptr; } diff --git a/src/hotspot/share/oops/oop.cpp b/src/hotspot/share/oops/oop.cpp index ef5e4db815a64..71c8aa406635c 100644 --- a/src/hotspot/share/oops/oop.cpp +++ b/src/hotspot/share/oops/oop.cpp @@ -153,8 +153,8 @@ bool oopDesc::is_objArray_noinline() const { return is_objArray(); } bool oopDesc::is_typeArray_noinline() const { return is_typeArray(); } bool oopDesc::has_klass_gap() { - // Only has a klass gap when compressed class pointers are used. - // Except when using compact headers. + // Only has a klass gap when compressed class pointers are used and not + // using compact headers. return UseCompressedClassPointers && !UseCompactObjectHeaders; } diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp index 7d69a1f961fb7..1bacec7f9a3b7 100644 --- a/src/hotspot/share/oops/oop.hpp +++ b/src/hotspot/share/oops/oop.hpp @@ -100,12 +100,12 @@ class oopDesc { // For klass field compression static inline void set_klass_gap(HeapWord* mem, int z); - // size of object header, aligned to platform wordSize + // Size of object header, aligned to platform wordSize static int header_size() { if (UseCompactObjectHeaders) { return sizeof(markWord) / HeapWordSize; } else { - return sizeof(oopDesc) / HeapWordSize; + return sizeof(oopDesc) / HeapWordSize; } } @@ -337,7 +337,7 @@ class oopDesc { // of LoadNKlass instructions. This value could be any value that is not a valid // field offset. Use an offset halfway into the markWord, as the markWord is never // partially loaded from C2. - return mark_offset_in_bytes() + sizeof(markWord) / 2; + return 4; } else #endif { diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp index 63ba2fdc1a87c..2c0cf87ad7992 100644 --- a/src/hotspot/share/oops/oop.inline.hpp +++ b/src/hotspot/share/oops/oop.inline.hpp @@ -292,6 +292,8 @@ bool oopDesc::is_self_forwarded() const { // Used by scavengers void oopDesc::forward_to(oop p) { + assert(cast_from_oop(p) != this, + "must not be used for self-forwarding, use forward_to_self() instead"); markWord m = markWord::encode_pointer_as_mark(p); assert(m.decode_pointer() == p, "encoding must be reversible"); set_mark(m); @@ -312,6 +314,8 @@ oop oopDesc::cas_set_forwardee(markWord new_mark, markWord compare, atomic_memor } oop oopDesc::forward_to_atomic(oop p, markWord compare, atomic_memory_order order) { + assert(cast_from_oop(p) != this, + "must not be used for self-forwarding, use forward_to_self_atomic() instead"); markWord m = markWord::encode_pointer_as_mark(p); assert(forwardee(m) == p, "encoding must be reversible"); return cas_set_forwardee(m, compare, order); @@ -398,7 +402,7 @@ void oopDesc::oop_iterate_backwards(OopClosureType* cl) { template void oopDesc::oop_iterate_backwards(OopClosureType* cl, Klass* k) { // In this assert, we cannot safely access the Klass* with compact headers. - assert(UseCompactObjectHeaders || k == klass(), "wrong klass"); + assert(k == klass(), "wrong klass"); OopIteratorClosureDispatch::oop_oop_iterate_backwards(cl, this, k); }