< prev index next > src/hotspot/share/runtime/objectMonitorTable.cpp
Print this page
#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"
// 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;
_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 (;;) {
_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 (;;) {
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;
}
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;
}
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);
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);
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");
}
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 >