< prev index next >

src/hotspot/share/oops/oop.hpp

Print this page
*** 76,10 ***
--- 76,15 ---
  
    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;

*** 94,11 ***
  
    // 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
--- 99,17 ---
  
    // 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

*** 106,10 ***
--- 117,24 ---
  
    // 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;

*** 256,18 ***
--- 281,21 ---
  
    // Forward pointer operations for scavenge
    inline bool is_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;
  
    // Age of object during scavenge
    inline uint age() const;
    inline void incr_age();
  

*** 307,16 ***
  
    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_klass_raw(oop obj);
    static void* load_oop_raw(oop obj, int offset);
  
    DEBUG_ONLY(bool size_might_change();)
--- 335,43 ---
  
    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) {
+       STATIC_ASSERT(markWord::klass_shift % 8 == 0);
+       return mark_offset_in_bytes() + markWord::klass_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.
+       assert(sizeof(markWord) == 8, "sanity");
+       return sizeof(markWord);
+     } else if (UseCompressedClassPointers) {
+       return sizeof(markWord) + sizeof(narrowKlass);
+     } else
+ #endif
+     {
+       return sizeof(oopDesc);
+     }
+   }
+ 
    // for error reporting
    static void* load_klass_raw(oop obj);
    static void* load_oop_raw(oop obj, int offset);
  
    DEBUG_ONLY(bool size_might_change();)
< prev index next >