< prev index next > src/hotspot/share/oops/oop.hpp
Print this page
// There may be ordering constraints on the initialization of fields that
// make use of the C++ copy/assign incorrect.
NONCOPYABLE(oopDesc);
+ inline oop cas_set_forwardee(markWord new_mark, markWord old_mark, atomic_memory_order order);
+
public:
// Must be trivial; see verifying static assert after the class.
oopDesc() = default;
inline markWord mark() const;
inline void release_set_mark(markWord m);
inline markWord cas_set_mark(markWord new_mark, markWord old_mark);
inline markWord cas_set_mark(markWord new_mark, markWord old_mark, atomic_memory_order order);
+ inline markWord resolve_mark() const;
+
+ // Returns the prototype mark that should be used for this object.
+ inline markWord prototype_mark() const;
+
// 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 Klass* klass() const;
// For klass field compression
static inline void set_klass_gap(HeapWord* mem, int z);
// size of object header, aligned to platform wordSize
! static constexpr int header_size() { return sizeof(oopDesc)/HeapWordSize; }
// Returns whether this is an instance of k or an instance of a subclass of k
inline bool is_a(Klass* k) const;
// Returns the actual oop size of the object in machine words
// For klass field compression
static inline void set_klass_gap(HeapWord* mem, int z);
// size of object header, aligned to platform wordSize
! static int header_size() {
+ if (UseCompactObjectHeaders) {
+ return sizeof(markWord) / HeapWordSize;
+ } else {
+ return sizeof(oopDesc)/HeapWordSize;
+ }
+ }
// Returns whether this is an instance of k or an instance of a subclass of k
inline bool is_a(Klass* k) const;
// Returns the actual oop size of the object in machine words
// Sometimes (for complicated concurrency-related reasons), it is useful
// to be able to figure out the size of an object knowing its klass.
inline size_t size_given_klass(Klass* klass);
+ // The following set of methods is used to access the mark-word and related
+ // properties when the object may be forwarded. Be careful where and when
+ // using this method. It assumes that the forwardee is installed in
+ // the header as a plain pointer (or self-forwarded). In particular,
+ // those methods can not deal with the sliding-forwarding that is used
+ // in Serial, G1 and Shenandoah full-GCs.
+ private:
+ inline Klass* forward_safe_klass_impl(markWord m) const;
+ public:
+ inline Klass* forward_safe_klass() const;
+ inline Klass* forward_safe_klass(markWord m) const;
+ inline size_t forward_safe_size();
+ inline void forward_safe_init_mark();
+
// type test operations (inlined in oop.inline.hpp)
inline bool is_instance() const;
inline bool is_instanceRef() const;
inline bool is_stackChunk() const;
inline bool is_array() const;
// garbage collection
inline bool is_gc_marked() const;
// Forward pointer operations for scavenge
inline bool is_forwarded() const;
+ inline bool is_self_forwarded() const;
inline void forward_to(oop p);
+ inline void forward_to_self();
// Like "forward_to", but inserts the forwarding pointer atomically.
// Exactly one thread succeeds in inserting the forwarding pointer, and
// this call returns null for that thread; any other thread has the
// value of the forwarding pointer returned and does not modify "this".
inline oop forward_to_atomic(oop p, markWord compare, atomic_memory_order order = memory_order_conservative);
+ inline oop forward_to_self_atomic(markWord compare, atomic_memory_order order = memory_order_conservative);
inline oop forwardee() const;
+ inline oop forwardee(markWord header) const;
+
+ inline void unset_self_forwarded();
// Age of object during scavenge
inline uint age() const;
inline void incr_age();
static bool has_klass_gap();
// for code generation
static int mark_offset_in_bytes() { return (int)offset_of(oopDesc, _mark); }
! static int klass_offset_in_bytes() { return (int)offset_of(oopDesc, _metadata._klass); }
static int klass_gap_offset_in_bytes() {
assert(has_klass_gap(), "only applicable to compressed klass pointers");
return klass_offset_in_bytes() + sizeof(narrowKlass);
}
// for error reporting
static void* load_oop_raw(oop obj, int offset);
! DEBUG_ONLY(bool size_might_change();)
};
// An oopDesc is not initialized via a constructor. Space is allocated in
// the Java heap, and static functions provided here on HeapWord* are used
// to fill in certain parts of that memory. The allocated memory is then
static bool has_klass_gap();
// for code generation
static int mark_offset_in_bytes() { return (int)offset_of(oopDesc, _mark); }
! static int klass_offset_in_bytes() {
+ #ifdef _LP64
+ if (UseCompactObjectHeaders) {
+ constexpr int load_shift = markWord::klass_load_shift;
+ STATIC_ASSERT(load_shift % 8 == 0);
+ return mark_offset_in_bytes() + load_shift / 8;
+ } else
+ #endif
+ {
+ return (int)offset_of(oopDesc, _metadata._klass);
+ }
+ }
static int klass_gap_offset_in_bytes() {
assert(has_klass_gap(), "only applicable to compressed klass pointers");
+ assert(!UseCompactObjectHeaders, "don't use klass_offset_in_bytes() with compact headers");
return klass_offset_in_bytes() + sizeof(narrowKlass);
}
+ static int base_offset_in_bytes() {
+ #ifdef _LP64
+ if (UseCompactObjectHeaders) {
+ // With compact headers, the Klass* field is not used for the Klass*
+ // and is used for the object fields instead.
+ STATIC_ASSERT(sizeof(markWord) == 8);
+ return sizeof(markWord);
+ } else if (UseCompressedClassPointers) {
+ return sizeof(markWord) + sizeof(narrowKlass);
+ } else
+ #endif
+ {
+ return sizeof(oopDesc);
+ }
+ }
+
// for error reporting
static void* load_oop_raw(oop obj, int offset);
! DEBUG_ONLY(bool size_might_change(Klass* klass);)
};
// An oopDesc is not initialized via a constructor. Space is allocated in
// the Java heap, and static functions provided here on HeapWord* are used
// to fill in certain parts of that memory. The allocated memory is then
< prev index next >