8256302: releasing oopStorage when deflating allows for faster deleting
Reviewed-by: dholmes, rehn, coleenp
This commit is contained in:
parent
02bce0b145
commit
6402004852
src/hotspot/share
@ -54,6 +54,7 @@ class WeakHandle {
|
||||
inline oop peek() const;
|
||||
void release(OopStorage* storage) const;
|
||||
bool is_null() const { return _obj == nullptr; }
|
||||
void set_null() { _obj = nullptr; }
|
||||
|
||||
void replace(oop with_obj);
|
||||
|
||||
|
@ -276,7 +276,10 @@ ObjectMonitor::ObjectMonitor(oop object) :
|
||||
{ }
|
||||
|
||||
ObjectMonitor::~ObjectMonitor() {
|
||||
_object.release(_oop_storage);
|
||||
if (!_object.is_null()) {
|
||||
// Release object's oop storage if it hasn't already been done.
|
||||
release_object();
|
||||
}
|
||||
}
|
||||
|
||||
oop ObjectMonitor::object() const {
|
||||
@ -595,6 +598,9 @@ bool ObjectMonitor::deflate_monitor() {
|
||||
install_displaced_markword_in_object(obj);
|
||||
}
|
||||
|
||||
// Release object's oop storage since the ObjectMonitor has been deflated:
|
||||
release_object();
|
||||
|
||||
// We leave owner == DEFLATER_MARKER and contentions < 0
|
||||
// to force any racing threads to retry.
|
||||
return true; // Success, ObjectMonitor has been deflated.
|
||||
|
@ -363,6 +363,7 @@ private:
|
||||
// Deflation support
|
||||
bool deflate_monitor();
|
||||
void install_displaced_markword_in_object(const oop obj);
|
||||
void release_object() { _object.release(_oop_storage); _object.set_null(); }
|
||||
};
|
||||
|
||||
#endif // SHARE_RUNTIME_OBJECTMONITOR_HPP
|
||||
|
@ -1645,6 +1645,15 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
static size_t delete_monitors(GrowableArray<ObjectMonitor*>* delete_list) {
|
||||
size_t count = 0;
|
||||
for (ObjectMonitor* monitor: *delete_list) {
|
||||
delete monitor;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// This function is called by the MonitorDeflationThread to deflate
|
||||
// ObjectMonitors. It is also called via do_final_audit_and_print_stats()
|
||||
// and VM_ThreadDump::doit() by the VMThread.
|
||||
@ -1719,16 +1728,30 @@ size_t ObjectSynchronizer::deflate_idle_monitors(ObjectMonitorsHashtable* table)
|
||||
}
|
||||
|
||||
// After the handshake, safely free the ObjectMonitors that were
|
||||
// deflated in this cycle.
|
||||
for (ObjectMonitor* monitor: delete_list) {
|
||||
delete monitor;
|
||||
deleted_count++;
|
||||
|
||||
if (current->is_Java_thread()) {
|
||||
// A JavaThread must check for a safepoint/handshake and honor it.
|
||||
chk_for_block_req(JavaThread::cast(current), "deletion", "deleted_count",
|
||||
deleted_count, ls, &timer);
|
||||
// deflated and unlinked in this cycle.
|
||||
if (current->is_Java_thread()) {
|
||||
if (ls != NULL) {
|
||||
timer.stop();
|
||||
ls->print_cr("before setting blocked: unlinked_count=" SIZE_FORMAT
|
||||
", in_use_list stats: ceiling=" SIZE_FORMAT ", count="
|
||||
SIZE_FORMAT ", max=" SIZE_FORMAT,
|
||||
unlinked_count, in_use_list_ceiling(),
|
||||
_in_use_list.count(), _in_use_list.max());
|
||||
}
|
||||
// Mark the calling JavaThread blocked (safepoint safe) while we free
|
||||
// the ObjectMonitors so we don't delay safepoints whilst doing that.
|
||||
ThreadBlockInVM tbivm(JavaThread::cast(current));
|
||||
if (ls != NULL) {
|
||||
ls->print_cr("after setting blocked: in_use_list stats: ceiling="
|
||||
SIZE_FORMAT ", count=" SIZE_FORMAT ", max=" SIZE_FORMAT,
|
||||
in_use_list_ceiling(), _in_use_list.count(), _in_use_list.max());
|
||||
timer.start();
|
||||
}
|
||||
deleted_count = delete_monitors(&delete_list);
|
||||
// ThreadBlockInVM is destroyed here
|
||||
} else {
|
||||
// A non-JavaThread can just free the ObjectMonitors:
|
||||
deleted_count = delete_monitors(&delete_list);
|
||||
}
|
||||
assert(unlinked_count == deleted_count, "must be");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user