8319137: release _object in ObjectMonitor dtor to avoid races
Reviewed-by: stefank, aboldtch, shade, dcubed, eosterlund
This commit is contained in:
parent
8b47a14958
commit
c39d001c7a
@ -276,24 +276,15 @@ ObjectMonitor::ObjectMonitor(oop object) :
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
ObjectMonitor::~ObjectMonitor() {
|
ObjectMonitor::~ObjectMonitor() {
|
||||||
if (!_object.is_null()) {
|
_object.release(_oop_storage);
|
||||||
// Release object's oop storage if it hasn't already been done.
|
|
||||||
release_object();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
oop ObjectMonitor::object() const {
|
oop ObjectMonitor::object() const {
|
||||||
check_object_context();
|
check_object_context();
|
||||||
if (_object.is_null()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return _object.resolve();
|
return _object.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
oop ObjectMonitor::object_peek() const {
|
oop ObjectMonitor::object_peek() const {
|
||||||
if (_object.is_null()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return _object.peek();
|
return _object.peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,9 +579,6 @@ bool ObjectMonitor::deflate_monitor() {
|
|||||||
install_displaced_markword_in_object(obj);
|
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
|
// We leave owner == DEFLATER_MARKER and contentions < 0
|
||||||
// to force any racing threads to retry.
|
// to force any racing threads to retry.
|
||||||
return true; // Success, ObjectMonitor has been deflated.
|
return true; // Success, ObjectMonitor has been deflated.
|
||||||
|
@ -364,7 +364,6 @@ private:
|
|||||||
// Deflation support
|
// Deflation support
|
||||||
bool deflate_monitor();
|
bool deflate_monitor();
|
||||||
void install_displaced_markword_in_object(const oop obj);
|
void install_displaced_markword_in_object(const oop obj);
|
||||||
void release_object() { _object.release(_oop_storage); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_RUNTIME_OBJECTMONITOR_HPP
|
#endif // SHARE_RUNTIME_OBJECTMONITOR_HPP
|
||||||
|
@ -1581,14 +1581,18 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t delete_monitors(GrowableArray<ObjectMonitor*>* delete_list) {
|
static size_t delete_monitors(JavaThread* current, GrowableArray<ObjectMonitor*>* delete_list,
|
||||||
|
LogStream* ls, elapsedTimer* timer_p) {
|
||||||
NativeHeapTrimmer::SuspendMark sm("monitor deletion");
|
NativeHeapTrimmer::SuspendMark sm("monitor deletion");
|
||||||
size_t count = 0;
|
size_t deleted_count = 0;
|
||||||
for (ObjectMonitor* monitor: *delete_list) {
|
for (ObjectMonitor* monitor: *delete_list) {
|
||||||
delete monitor;
|
delete monitor;
|
||||||
count++;
|
deleted_count++;
|
||||||
|
// A JavaThread must check for a safepoint/handshake and honor it.
|
||||||
|
ObjectSynchronizer::chk_for_block_req(current, "deletion", "deleted_count",
|
||||||
|
deleted_count, ls, timer_p);
|
||||||
}
|
}
|
||||||
return count;
|
return deleted_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is called by the MonitorDeflationThread to deflate
|
// This function is called by the MonitorDeflationThread to deflate
|
||||||
@ -1662,30 +1666,7 @@ size_t ObjectSynchronizer::deflate_idle_monitors() {
|
|||||||
|
|
||||||
// After the handshake, safely free the ObjectMonitors that were
|
// After the handshake, safely free the ObjectMonitors that were
|
||||||
// deflated and unlinked in this cycle.
|
// deflated and unlinked in this cycle.
|
||||||
if (current->is_Java_thread()) {
|
deleted_count = delete_monitors(JavaThread::cast(current), &delete_list, ls, &timer);
|
||||||
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");
|
assert(unlinked_count == deleted_count, "must be");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user