8229839: Break circular dependency between oop.inline.hpp and markWord.inline.hpp

Reviewed-by: pliden, tonyp
This commit is contained in:
Stefan Karlsson 2019-08-19 12:40:27 +02:00
parent a3d6be2b2d
commit ebf98ac78c
12 changed files with 91 additions and 88 deletions

View File

@ -8008,14 +8008,14 @@ void CMSCollector::preserve_mark_work(oop p, markWord m) {
// Single threaded // Single threaded
void CMSCollector::preserve_mark_if_necessary(oop p) { void CMSCollector::preserve_mark_if_necessary(oop p) {
markWord m = p->mark_raw(); markWord m = p->mark_raw();
if (m.must_be_preserved(p)) { if (p->mark_must_be_preserved(m)) {
preserve_mark_work(p, m); preserve_mark_work(p, m);
} }
} }
void CMSCollector::par_preserve_mark_if_necessary(oop p) { void CMSCollector::par_preserve_mark_if_necessary(oop p) {
markWord m = p->mark_raw(); markWord m = p->mark_raw();
if (m.must_be_preserved(p)) { if (p->mark_must_be_preserved(m)) {
MutexLocker x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); MutexLocker x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
// Even though we read the mark word without holding // Even though we read the mark word without holding
// the lock, we are assured that it will not change // the lock, we are assured that it will not change

View File

@ -28,7 +28,7 @@
#include "gc/shared/genOopClosures.hpp" #include "gc/shared/genOopClosures.hpp"
#include "oops/compressedOops.inline.hpp" #include "oops/compressedOops.inline.hpp"
#include "oops/markWord.inline.hpp" #include "oops/markWord.inline.hpp"
#include "oops/oop.hpp" #include "oops/oop.inline.hpp"
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
//// PromotionInfo //// PromotionInfo

View File

@ -116,11 +116,11 @@ void G1FullGCCompactionPoint::forward(oop object, size_t size) {
} else { } else {
// Make sure object has the correct mark-word set or that it will be // Make sure object has the correct mark-word set or that it will be
// fixed when restoring the preserved marks. // fixed when restoring the preserved marks.
assert(object->mark_raw() == markWord::prototype_for_object(object) || // Correct mark assert(object->mark_raw() == markWord::prototype_for_klass(object->klass()) || // Correct mark
object->mark_raw().must_be_preserved(object) || // Will be restored by PreservedMarksSet object->mark_must_be_preserved() || // Will be restored by PreservedMarksSet
(UseBiasedLocking && object->has_bias_pattern_raw()), // Will be restored by BiasedLocking (UseBiasedLocking && object->has_bias_pattern_raw()), // Will be restored by BiasedLocking
"should have correct prototype obj: " PTR_FORMAT " mark: " PTR_FORMAT " prototype: " PTR_FORMAT, "should have correct prototype obj: " PTR_FORMAT " mark: " PTR_FORMAT " prototype: " PTR_FORMAT,
p2i(object), object->mark_raw().value(), markWord::prototype_for_object(object).value()); p2i(object), object->mark_raw().value(), markWord::prototype_for_klass(object->klass()).value());
} }
assert(object->forwardee() == NULL, "should be forwarded to NULL"); assert(object->forwardee() == NULL, "should be forwarded to NULL");
} }

View File

@ -51,7 +51,7 @@ inline bool G1FullGCMarker::mark_object(oop obj) {
// Marked by us, preserve if needed. // Marked by us, preserve if needed.
markWord mark = obj->mark_raw(); markWord mark = obj->mark_raw();
if (mark.must_be_preserved(obj) && if (obj->mark_must_be_preserved(mark) &&
!G1ArchiveAllocator::is_open_archive_object(obj)) { !G1ArchiveAllocator::is_open_archive_object(obj)) {
preserved_stack()->push(obj, mark); preserved_stack()->push(obj, mark);
} }

View File

@ -77,11 +77,11 @@ template <class T> inline void G1AdjustClosure::adjust_pointer(T* p) {
oop forwardee = obj->forwardee(); oop forwardee = obj->forwardee();
if (forwardee == NULL) { if (forwardee == NULL) {
// Not forwarded, return current reference. // Not forwarded, return current reference.
assert(obj->mark_raw() == markWord::prototype_for_object(obj) || // Correct mark assert(obj->mark_raw() == markWord::prototype_for_klass(obj->klass()) || // Correct mark
obj->mark_raw().must_be_preserved(obj) || // Will be restored by PreservedMarksSet obj->mark_must_be_preserved() || // Will be restored by PreservedMarksSet
(UseBiasedLocking && obj->has_bias_pattern_raw()), // Will be restored by BiasedLocking (UseBiasedLocking && obj->has_bias_pattern_raw()), // Will be restored by BiasedLocking
"Must have correct prototype or be preserved, obj: " PTR_FORMAT ", mark: " PTR_FORMAT ", prototype: " PTR_FORMAT, "Must have correct prototype or be preserved, obj: " PTR_FORMAT ", mark: " PTR_FORMAT ", prototype: " PTR_FORMAT,
p2i(obj), obj->mark_raw().value(), markWord::prototype_for_object(obj).value()); p2i(obj), obj->mark_raw().value(), markWord::prototype_for_klass(obj->klass()).value());
return; return;
} }

View File

@ -40,7 +40,7 @@ inline void MarkSweep::mark_object(oop obj) {
markWord mark = obj->mark_raw(); markWord mark = obj->mark_raw();
obj->set_mark_raw(markWord::prototype().set_marked()); obj->set_mark_raw(markWord::prototype().set_marked());
if (mark.must_be_preserved(obj)) { if (obj->mark_must_be_preserved(mark)) {
preserve_mark(obj, mark); preserve_mark(obj, mark);
} }
} }

View File

@ -31,7 +31,7 @@
#include "utilities/stack.inline.hpp" #include "utilities/stack.inline.hpp"
inline bool PreservedMarks::should_preserve_mark(oop obj, markWord m) const { inline bool PreservedMarks::should_preserve_mark(oop obj, markWord m) const {
return m.must_be_preserved_for_promotion_failure(obj); return obj->mark_must_be_preserved_for_promotion_failure(m);
} }
inline void PreservedMarks::push(oop obj, markWord m) { inline void PreservedMarks::push(oop obj, markWord m) {

View File

@ -252,8 +252,8 @@ class markWord {
static markWord INFLATING() { return zero(); } // inflate-in-progress static markWord INFLATING() { return zero(); } // inflate-in-progress
// Should this header be preserved during GC? // Should this header be preserved during GC?
inline bool must_be_preserved(oop obj_containing_mark) const; template <typename KlassProxy>
inline bool must_be_preserved_with_bias(oop obj_containing_mark) const; inline bool must_be_preserved(KlassProxy klass) const;
// Should this header (including its age bits) be preserved in the // Should this header (including its age bits) be preserved in the
// case of a promotion failure during scavenge? // case of a promotion failure during scavenge?
@ -272,15 +272,14 @@ class markWord {
// observation is that promotion failures are quite rare and // observation is that promotion failures are quite rare and
// reducing the number of mark words preserved during them isn't a // reducing the number of mark words preserved during them isn't a
// high priority. // high priority.
inline bool must_be_preserved_for_promotion_failure(oop obj_containing_mark) const; template <typename KlassProxy>
inline bool must_be_preserved_with_bias_for_promotion_failure(oop obj_containing_mark) const; inline bool must_be_preserved_for_promotion_failure(KlassProxy klass) const;
// Should this header be preserved during a scavenge where CMS is // Should this header be preserved during a scavenge where CMS is
// the old generation? // the old generation?
// (This is basically the same body as must_be_preserved_for_promotion_failure(), // (This is basically the same body as must_be_preserved_for_promotion_failure(),
// but takes the Klass* as argument instead) // but takes the Klass* as argument instead)
inline bool must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const; inline bool must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const;
inline bool must_be_preserved_with_bias_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const;
// WARNING: The following routines are used EXCLUSIVELY by // WARNING: The following routines are used EXCLUSIVELY by
// synchronization functions. They are not really gc safe. // synchronization functions. They are not really gc safe.
@ -372,7 +371,7 @@ class markWord {
} }
// Helper function for restoration of unmarked mark oops during GC // Helper function for restoration of unmarked mark oops during GC
static inline markWord prototype_for_object(oop obj); static inline markWord prototype_for_klass(const Klass* klass);
// Debugging // Debugging
void print_on(outputStream* st) const; void print_on(outputStream* st) const;

View File

@ -27,88 +27,57 @@
#include "oops/klass.hpp" #include "oops/klass.hpp"
#include "oops/markWord.hpp" #include "oops/markWord.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/globals.hpp" #include "runtime/globals.hpp"
// Should this header be preserved during GC (when biased locking is enabled)?
inline bool markWord::must_be_preserved_with_bias(oop obj_containing_mark) const {
assert(UseBiasedLocking, "unexpected");
if (has_bias_pattern()) {
// Will reset bias at end of collection
// Mark words of biased and currently locked objects are preserved separately
return false;
}
markWord prototype_header = prototype_for_object(obj_containing_mark);
if (prototype_header.has_bias_pattern()) {
// Individual instance which has its bias revoked; must return
// true for correctness
return true;
}
return (!is_unlocked() || !has_no_hash());
}
// Should this header be preserved during GC? // Should this header be preserved during GC?
inline bool markWord::must_be_preserved(oop obj_containing_mark) const { template <typename KlassProxy>
if (!UseBiasedLocking) inline bool markWord::must_be_preserved(KlassProxy klass) const {
return (!is_unlocked() || !has_no_hash()); if (UseBiasedLocking) {
return must_be_preserved_with_bias(obj_containing_mark); if (has_bias_pattern()) {
} // Will reset bias at end of collection
// Mark words of biased and currently locked objects are preserved separately
// Should this header be preserved in the case of a promotion failure return false;
// during scavenge (when biased locking is enabled)? }
inline bool markWord::must_be_preserved_with_bias_for_promotion_failure(oop obj_containing_mark) const { markWord prototype_header = prototype_for_klass(klass);
assert(UseBiasedLocking, "unexpected"); if (prototype_header.has_bias_pattern()) {
// We don't explicitly save off the mark words of biased and // Individual instance which has its bias revoked; must return
// currently-locked objects during scavenges, so if during a // true for correctness
// promotion failure we encounter either a biased mark word or a return true;
// klass which still has a biasable prototype header, we have to }
// preserve the mark word. This results in oversaving, but promotion
// failures are rare, and this avoids adding more complex logic to
// the scavengers to call new variants of
// BiasedLocking::preserve_marks() / restore_marks() in the middle
// of a scavenge when a promotion failure has first been detected.
if (has_bias_pattern() ||
prototype_for_object(obj_containing_mark).has_bias_pattern()) {
return true;
} }
return (!is_unlocked() || !has_no_hash()); return (!is_unlocked() || !has_no_hash());
} }
// Should this header be preserved in the case of a promotion failure // Should this header be preserved in the case of a promotion failure during scavenge?
// during scavenge? template <typename KlassProxy>
inline bool markWord::must_be_preserved_for_promotion_failure(oop obj_containing_mark) const { inline bool markWord::must_be_preserved_for_promotion_failure(KlassProxy klass) const {
if (!UseBiasedLocking) if (UseBiasedLocking) {
return (!is_unlocked() || !has_no_hash()); // We don't explicitly save off the mark words of biased and
return must_be_preserved_with_bias_for_promotion_failure(obj_containing_mark); // currently-locked objects during scavenges, so if during a
} // promotion failure we encounter either a biased mark word or a
// klass which still has a biasable prototype header, we have to
// preserve the mark word. This results in oversaving, but promotion
// Same as must_be_preserved_with_bias_for_promotion_failure() except that // failures are rare, and this avoids adding more complex logic to
// it takes a Klass* argument, instead of the object of which this is the mark word. // the scavengers to call new variants of
inline bool markWord::must_be_preserved_with_bias_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const { // BiasedLocking::preserve_marks() / restore_marks() in the middle
assert(UseBiasedLocking, "unexpected"); // of a scavenge when a promotion failure has first been detected.
// CMS scavenges preserve mark words in similar fashion to promotion failures; see above if (has_bias_pattern() || prototype_for_klass(klass).has_bias_pattern()) {
if (has_bias_pattern() || return true;
klass_of_obj_containing_mark->prototype_header().has_bias_pattern()) { }
return true;
} }
return (!is_unlocked() || !has_no_hash()); return (!is_unlocked() || !has_no_hash());
} }
// Same as must_be_preserved_for_promotion_failure() except that // Same as must_be_preserved_for_promotion_failure().
// it takes a Klass* argument, instead of the object of which this is the mark word.
inline bool markWord::must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const { inline bool markWord::must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const {
if (!UseBiasedLocking) return must_be_preserved_for_promotion_failure(klass_of_obj_containing_mark);
return (!is_unlocked() || !has_no_hash());
return must_be_preserved_with_bias_for_cms_scavenge(klass_of_obj_containing_mark);
} }
inline markWord markWord::prototype_for_object(oop obj) { inline markWord markWord::prototype_for_klass(const Klass* klass) {
#ifdef ASSERT markWord prototype_header = klass->prototype_header();
markWord prototype_header = obj->klass()->prototype_header();
assert(prototype_header == prototype() || prototype_header.has_bias_pattern(), "corrupt prototype header"); assert(prototype_header == prototype() || prototype_header.has_bias_pattern(), "corrupt prototype header");
#endif
return obj->klass()->prototype_header(); return prototype_header;
} }
#endif // SHARE_OOPS_MARKWORD_INLINE_HPP #endif // SHARE_OOPS_MARKWORD_INLINE_HPP

View File

@ -313,6 +313,11 @@ class oopDesc {
inline markWord displaced_mark_raw() const; inline markWord displaced_mark_raw() const;
inline void set_displaced_mark_raw(markWord m); inline void set_displaced_mark_raw(markWord m);
// Checks if the mark word needs to be preserved
inline bool mark_must_be_preserved() const;
inline bool mark_must_be_preserved(markWord m) const;
inline bool mark_must_be_preserved_for_promotion_failure(markWord m) const;
static bool has_klass_gap(); static bool has_klass_gap();
// for code generation // for code generation

View File

@ -82,11 +82,11 @@ markWord oopDesc::cas_set_mark_raw(markWord new_mark, markWord old_mark, atomic_
} }
void oopDesc::init_mark() { void oopDesc::init_mark() {
set_mark(markWord::prototype_for_object(this)); set_mark(markWord::prototype_for_klass(klass()));
} }
void oopDesc::init_mark_raw() { 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 { Klass* oopDesc::klass() const {
@ -483,4 +483,34 @@ void oopDesc::set_displaced_mark_raw(markWord m) {
mark_raw().set_displaced_mark_helper(m); 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 #endif // SHARE_OOPS_OOP_INLINE_HPP

View File

@ -1712,7 +1712,7 @@ inline void ObjectMarker::mark(oop o) {
// object's mark word // object's mark word
markWord mark = o->mark(); markWord mark = o->mark();
if (mark.must_be_preserved(o)) { if (o->mark_must_be_preserved(mark)) {
_saved_mark_stack->push(mark); _saved_mark_stack->push(mark);
_saved_oop_stack->push(o); _saved_oop_stack->push(o);
} }