< prev index next >

src/hotspot/share/runtime/objectMonitorTable.cpp

Print this page
*** 24,12 ***
--- 24,14 ---
  
  #include "logging/log.hpp"
  #include "runtime/interfaceSupport.inline.hpp"
  #include "runtime/javaThread.hpp"
  #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.inline.hpp"
  #include "runtime/objectMonitorTable.hpp"
  #include "runtime/safepoint.hpp"
+ #include "runtime/synchronizer.hpp"
  #include "runtime/thread.hpp"
  #include "runtime/timerTrace.hpp"
  #include "runtime/trimNativeHeap.hpp"
  #include "utilities/debug.hpp"
  #include "utilities/globalDefinitions.hpp"

*** 116,10 ***
--- 118,25 ---
  // searching for at the hash index, without needing further linear searching.
  // The grow load factor is set to 12.5%, which satisfies the above
  // requirements. Don't change it for fun, it might backfire.
  // -----------------------------------------------------------------------------
  
+ // Get the identity hash from an oop, handling both compact and legacy headers.
+ // Returns 0 if the object has not been hashed yet (meaning no monitor exists
+ // for it in the table).
+ static intptr_t object_hash(oop obj) {
+   markWord mark = obj->mark();
+   if (UseCompactObjectHeaders) {
+     if (!mark.is_hashed()) {
+       return 0;
+     }
+     return static_cast<intptr_t>(ObjectSynchronizer::get_hash(mark, obj));
+   } else {
+     return mark.hash();
+   }
+ }
+ 
  Atomic<ObjectMonitorTable::Table*> ObjectMonitorTable::_curr;
  
  class ObjectMonitorTable::Table : public CHeapObj<mtObjectMonitor> {
    friend class ObjectMonitorTable;
  

*** 400,11 ***
        _prev.load_relaxed()->remove(obj, old_monitor, hash);
      }
    }
  
    void reinsert(oop obj, Entry new_monitor) {
!     intptr_t hash = obj->mark().hash();
  
      const size_t start_index = size_t(hash) & _capacity_mask;
      size_t index = start_index;
  
      for (;;) {
--- 417,11 ---
        _prev.load_relaxed()->remove(obj, old_monitor, hash);
      }
    }
  
    void reinsert(oop obj, Entry new_monitor) {
!     intptr_t hash = as_monitor(new_monitor)->hash();
  
      const size_t start_index = size_t(hash) & _capacity_mask;
      size_t index = start_index;
  
      for (;;) {

*** 516,11 ***
  void ObjectMonitorTable::create() {
    _curr.store_relaxed(new Table(128, nullptr));
  }
  
  ObjectMonitor* ObjectMonitorTable::monitor_get(oop obj) {
!   const intptr_t hash = obj->mark().hash();
    Table* curr = _curr.load_acquire();
    ObjectMonitor* monitor = curr->get(obj, hash);
    return monitor;
  }
  
--- 533,12 ---
  void ObjectMonitorTable::create() {
    _curr.store_relaxed(new Table(128, nullptr));
  }
  
  ObjectMonitor* ObjectMonitorTable::monitor_get(oop obj) {
!   const intptr_t hash = object_hash(obj);
+   if (hash == 0) return nullptr;
    Table* curr = _curr.load_acquire();
    ObjectMonitor* monitor = curr->get(obj, hash);
    return monitor;
  }
  

*** 563,11 ***
  
    return result;
  }
  
  ObjectMonitor* ObjectMonitorTable::monitor_put_get(ObjectMonitor* monitor, oop obj) {
!   const intptr_t hash = obj->mark().hash();
    Table* curr =  _curr.load_acquire();
  
    for (;;) {
      // Curr is the latest table and is reasonably loaded.
      ObjectMonitor* result = curr->get_set(obj, curr->as_entry(monitor), hash);
--- 581,11 ---
  
    return result;
  }
  
  ObjectMonitor* ObjectMonitorTable::monitor_put_get(ObjectMonitor* monitor, oop obj) {
!   const intptr_t hash = monitor->hash();
    Table* curr =  _curr.load_acquire();
  
    for (;;) {
      // Curr is the latest table and is reasonably loaded.
      ObjectMonitor* result = curr->get_set(obj, curr->as_entry(monitor), hash);

*** 583,11 ***
    oop obj = monitor->object_peek();
    if (obj == nullptr) {
      // Defer removal until subsequent rebuilding.
      return;
    }
!   const intptr_t hash = obj->mark().hash();
    Table* curr =  _curr.load_acquire();
    curr->remove(obj, curr->as_entry(monitor), hash);
    assert(monitor_get(obj) != monitor, "should have been removed");
  }
  
--- 601,11 ---
    oop obj = monitor->object_peek();
    if (obj == nullptr) {
      // Defer removal until subsequent rebuilding.
      return;
    }
!   const intptr_t hash = monitor->hash();
    Table* curr =  _curr.load_acquire();
    curr->remove(obj, curr->as_entry(monitor), hash);
    assert(monitor_get(obj) != monitor, "should have been removed");
  }
  
< prev index next >