< prev index next >

src/hotspot/share/runtime/objectMonitor.hpp

Print this page
@@ -142,12 +142,20 @@
    // have busy multi-threaded access. _header and _object are set at initial
    // inflation. The _object does not change, so it is a good choice to share
    // its cache line with _header.
    DEFINE_PAD_MINUS_SIZE(0, OM_CACHE_LINE_SIZE, sizeof(volatile markWord) +
                          sizeof(WeakHandle));
-   // Used by async deflation as a marker in the _owner field:
-   #define DEFLATER_MARKER reinterpret_cast<void*>(-1)
+   // Used by async deflation as a marker in the _owner field.
+   // Note that the choice of the two markers is peculiar:
+   // - They need to represent values that cannot be pointers. In particular,
+   //   we achieve this by using the lowest two bits
+   // - ANONYMOUS_OWNER should be a small value, it is used in generated code
+   //   and small values encode much better
+   // - We test for anonymous owner by testing for the lowest bit, therefore
+   //   DEFLATER_MARKER must *not* have that bit set.
+   #define DEFLATER_MARKER reinterpret_cast<void*>(2)
+   #define ANONYMOUS_OWNER reinterpret_cast<void*>(1)
    void* volatile _owner;            // pointer to owning thread OR BasicLock
    volatile uint64_t _previous_owner_tid;  // thread id of the previous owner of the monitor
    // Separate _owner and _next_om on different cache lines since
    // both can have busy multi-threaded access. _previous_owner_tid is only
    // changed by ObjectMonitor::exit() so it is a good choice to share the

@@ -202,10 +210,11 @@
  
    static int Knob_SpinLimit;
  
    // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
    // ByteSize would also be an appropriate type.
+   static int header_offset_in_bytes()      { return offset_of(ObjectMonitor, _header); }
    static int owner_offset_in_bytes()       { return offset_of(ObjectMonitor, _owner); }
    static int recursions_offset_in_bytes()  { return offset_of(ObjectMonitor, _recursions); }
    static int cxq_offset_in_bytes()         { return offset_of(ObjectMonitor, _cxq); }
    static int succ_offset_in_bytes()        { return offset_of(ObjectMonitor, _succ); }
    static int EntryList_offset_in_bytes()   { return offset_of(ObjectMonitor, _EntryList); }

@@ -261,10 +270,22 @@
    // Try to set _owner field to new_value if the current value matches
    // old_value, using Atomic::cmpxchg(). Otherwise, does not change the
    // _owner field. Returns the prior value of the _owner field.
    void*     try_set_owner_from(void* old_value, void* new_value);
  
+   void set_owner_anonymous() {
+     set_owner_from(NULL, ANONYMOUS_OWNER);
+   }
+ 
+   bool is_owner_anonymous() const {
+     return owner_raw() == ANONYMOUS_OWNER;
+   }
+ 
+   void set_owner_from_anonymous(Thread* owner) {
+     set_owner_from(ANONYMOUS_OWNER, owner);
+   }
+ 
    // Simply get _next_om field.
    ObjectMonitor* next_om() const;
    // Simply set _next_om field to new_value.
    void set_next_om(ObjectMonitor* new_value);
  

@@ -321,10 +342,12 @@
  
    // Use the following at your own risk
    intx      complete_exit(JavaThread* current);
    bool      reenter(intx recursions, JavaThread* current);
  
+   static void maybe_deflate_dead(oop* p);
+ 
   private:
    void      AddWaiter(ObjectWaiter* waiter);
    void      INotify(JavaThread* current);
    ObjectWaiter* DequeueWaiter();
    void      DequeueSpecificWaiter(ObjectWaiter* waiter);
< prev index next >