--- old/src/hotspot/share/oops/oop.inline.hpp 2019-08-20 10:52:35.900905175 +0200 +++ new/src/hotspot/share/oops/oop.inline.hpp 2019-08-20 10:52:35.676901720 +0200 @@ -82,11 +82,11 @@ } void oopDesc::init_mark() { - set_mark(markWord::prototype_for_object(this)); + set_mark(markWord::prototype_for_klass(klass())); } void oopDesc::init_mark_raw() { - set_mark_raw(markWord::prototype_for_object(this)); + set_mark_raw(markWord::prototype_for_klass(klass())); } Klass* oopDesc::klass() const { @@ -483,4 +483,34 @@ mark_raw().set_displaced_mark_helper(m); } +// Supports deferred calling of obj->klass(). +class DeferredObjectToKlass { + const oopDesc* _obj; + +public: + DeferredObjectToKlass(const oopDesc* obj) : _obj(obj) {} + + // Implicitly convertible to const Klass*. + operator const Klass*() const { + return _obj->klass(); + } +}; + +bool oopDesc::mark_must_be_preserved() const { + return mark_must_be_preserved(mark_raw()); +} + +bool oopDesc::mark_must_be_preserved(markWord m) const { + // There's a circular dependency between oop.inline.hpp and + // markWord.inline.hpp because markWord::must_be_preserved wants to call + // oopDesc::klass(). This could be solved by calling klass() here. However, + // not all paths inside must_be_preserved calls klass(). Defer the call until + // the klass is actually needed. + return m.must_be_preserved(DeferredObjectToKlass(this)); +} + +bool oopDesc::mark_must_be_preserved_for_promotion_failure(markWord m) const { + return m.must_be_preserved_for_promotion_failure(DeferredObjectToKlass(this)); +} + #endif // SHARE_OOPS_OOP_INLINE_HPP