diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 941d0c0511e..e9e61e3a3de 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -2373,11 +2373,8 @@ void MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) { assert(source() != destination(), "inv"); assert(FullGCForwarding::is_forwarded(cast_to_oop(source())), "inv"); assert(FullGCForwarding::forwardee(cast_to_oop(source())) == cast_to_oop(destination()), "inv"); - // Read the klass before the copying, since it might destroy the klass (i.e. overlapping copy) - // and if partial copy, the destination klass may not be copied yet - Klass* klass = cast_to_oop(source())->klass(); Copy::aligned_conjoint_words(source(), copy_destination(), words); - cast_to_oop(copy_destination())->set_mark(Klass::default_prototype_header(klass)); + cast_to_oop(copy_destination())->reinit_mark(); } update_state(words); diff --git a/src/hotspot/share/gc/shared/memAllocator.cpp b/src/hotspot/share/gc/shared/memAllocator.cpp index 1ef0633b243..4b0f34fe7ad 100644 --- a/src/hotspot/share/gc/shared/memAllocator.cpp +++ b/src/hotspot/share/gc/shared/memAllocator.cpp @@ -383,10 +383,10 @@ oop MemAllocator::finish(HeapWord* mem) const { // object zeroing are visible before setting the klass non-null, for // concurrent collectors. if (UseCompactObjectHeaders) { - oopDesc::release_set_mark(mem, Klass::default_prototype_header(_klass)); + oopDesc::release_set_mark(mem, _klass->prototype_header()); } else { if (EnableValhalla) { - oopDesc::set_mark(mem, Klass::default_prototype_header(_klass)); + oopDesc::set_mark(mem, _klass->prototype_header()); } else { oopDesc::set_mark(mem, markWord::prototype()); } diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index c9d807b2022..b9ad1423fd8 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -742,7 +742,6 @@ class Klass : public Metadata { inline markWord prototype_header() const; inline void set_prototype_header(markWord header); static ByteSize prototype_header_offset() { return in_ByteSize(offset_of(Klass, _prototype_header)); } - static inline markWord default_prototype_header(Klass* k); inline void set_prototype_header_klass(narrowKlass klass); JFR_ONLY(DEFINE_TRACE_ID_METHODS;) diff --git a/src/hotspot/share/oops/klass.inline.hpp b/src/hotspot/share/oops/klass.inline.hpp index ab23b965574..51e6933eb14 100644 --- a/src/hotspot/share/oops/klass.inline.hpp +++ b/src/hotspot/share/oops/klass.inline.hpp @@ -90,11 +90,6 @@ inline markWord Klass::prototype_header() const { return _prototype_header; } -// May no longer be required (was used to avoid a bootstrapping problem... -inline markWord Klass::default_prototype_header(Klass* k) { - return (k == nullptr) ? markWord::prototype() : k->prototype_header(); -} - inline void Klass::set_prototype_header_klass(narrowKlass klass) { // Merge narrowKlass in existing prototype header. _prototype_header = _prototype_header.set_narrow_klass(klass); diff --git a/src/hotspot/share/oops/markWord.hpp b/src/hotspot/share/oops/markWord.hpp index 7a6660c90b0..b4c3b87511c 100644 --- a/src/hotspot/share/oops/markWord.hpp +++ b/src/hotspot/share/oops/markWord.hpp @@ -306,7 +306,8 @@ class markWord { // Should this header be preserved during GC? bool must_be_preserved() const { - return (!is_unlocked() || !has_no_hash() || (EnableValhalla && is_larval_state())); + return (!is_unlocked() || !has_no_hash() || + (EnableValhalla && (is_larval_state() || is_inline_type() || is_flat_array() || is_null_free_array()))); } // WARNING: The following routines are used EXCLUSIVELY by @@ -411,26 +412,23 @@ class markWord { return (mask_bits(value(), larval_mask_in_place) == larval_pattern); } -#ifdef _LP64 // 64 bit encodings only bool is_flat_array() const { +#ifdef _LP64 // 64 bit encodings only return (mask_bits(value(), flat_array_mask_in_place) == null_free_flat_array_pattern) || (mask_bits(value(), flat_array_mask_in_place) == nullable_flat_array_pattern); +#else + return false; +#endif } bool is_null_free_array() const { +#ifdef _LP64 // 64 bit encodings only return (mask_bits(value(), null_free_array_mask_in_place) == null_free_array_pattern); - } #else - bool is_flat_array() const { - fatal("Should not ask this for mark word, ask oopDesc"); return false; +#endif } - bool is_null_free_array() const { - fatal("Should not ask this for mark word, ask oopDesc"); - return false; - } -#endif inline Klass* klass() const; inline Klass* klass_or_null() const; inline Klass* klass_without_asserts() const; diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp index ceb568b0d4a..84d436f6047 100644 --- a/src/hotspot/share/oops/oop.hpp +++ b/src/hotspot/share/oops/oop.hpp @@ -93,6 +93,7 @@ class oopDesc { // Used only to re-initialize the mark word (e.g., of promoted // objects during a GC) -- requires a valid klass pointer inline void init_mark(); + inline void reinit_mark(); // special for parallelGC inline Klass* klass() const; inline Klass* klass_or_null() const; diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp index 0e1c9f64cb3..5e9cc8bce2e 100644 --- a/src/hotspot/share/oops/oop.inline.hpp +++ b/src/hotspot/share/oops/oop.inline.hpp @@ -95,6 +95,17 @@ void oopDesc::init_mark() { set_mark(prototype_mark()); } +// This is for parallel gc, which doesn't always have the klass. +// markWord::must_be_preserved preserves the original prototype header bits for EnableValhalla, +// I don't know why serial gc doesn't work the same. +void oopDesc::reinit_mark() { + if (UseCompactObjectHeaders) { + set_mark(klass()->prototype_header()); + } else { + set_mark(markWord::prototype()); + } +} + Klass* oopDesc::klass() const { switch (ObjLayout::klass_mode()) { case ObjLayout::Compact: