Skip to content

Commit a6c418e

Browse files
author
David Holmes
committed
8297168: Provide a bulk OopHandle release mechanism with the ServiceThread
Reviewed-by: rehn, coleenp
1 parent 4a544bb commit a6c418e

File tree

4 files changed

+78
-45
lines changed

4 files changed

+78
-45
lines changed

src/hotspot/share/runtime/javaThread.cpp

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -599,11 +599,8 @@ JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) : JavaThread
599599

600600
JavaThread::~JavaThread() {
601601

602-
// Ask ServiceThread to release the OopHandles
603-
ServiceThread::add_oop_handle_release(_threadObj);
604-
ServiceThread::add_oop_handle_release(_vthread);
605-
ServiceThread::add_oop_handle_release(_jvmti_vthread);
606-
ServiceThread::add_oop_handle_release(_extentLocalCache);
602+
// Enqueue OopHandles for release by the service thread.
603+
add_oop_handles_for_release();
607604

608605
// Return the sleep event to the free list
609606
ParkEvent::Release(_SleepEvent);
@@ -2073,3 +2070,57 @@ void JavaThread::vm_exit_on_osthread_failure(JavaThread* thread) {
20732070
os::native_thread_creation_failed_msg());
20742071
}
20752072
}
2073+
2074+
// Deferred OopHandle release support.
2075+
2076+
class OopHandleList : public CHeapObj<mtInternal> {
2077+
static const int _count = 4;
2078+
OopHandle _handles[_count];
2079+
OopHandleList* _next;
2080+
int _index;
2081+
public:
2082+
OopHandleList(OopHandleList* next) : _next(next), _index(0) {}
2083+
void add(OopHandle h) {
2084+
assert(_index < _count, "too many additions");
2085+
_handles[_index++] = h;
2086+
}
2087+
~OopHandleList() {
2088+
assert(_index == _count, "usage error");
2089+
for (int i = 0; i < _index; i++) {
2090+
_handles[i].release(JavaThread::thread_oop_storage());
2091+
}
2092+
}
2093+
OopHandleList* next() const { return _next; }
2094+
};
2095+
2096+
OopHandleList* JavaThread::_oop_handle_list = nullptr;
2097+
2098+
// Called by the ServiceThread to do the work of releasing
2099+
// the OopHandles.
2100+
void JavaThread::release_oop_handles() {
2101+
OopHandleList* list;
2102+
{
2103+
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
2104+
list = _oop_handle_list;
2105+
_oop_handle_list = nullptr;
2106+
}
2107+
assert(!SafepointSynchronize::is_at_safepoint(), "cannot be called at a safepoint");
2108+
2109+
while (list != nullptr) {
2110+
OopHandleList* l = list;
2111+
list = l->next();
2112+
delete l;
2113+
}
2114+
}
2115+
2116+
// Add our OopHandles for later release.
2117+
void JavaThread::add_oop_handles_for_release() {
2118+
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
2119+
OopHandleList* new_head = new OopHandleList(_oop_handle_list);
2120+
new_head->add(_threadObj);
2121+
new_head->add(_vthread);
2122+
new_head->add(_jvmti_vthread);
2123+
new_head->add(_extentLocalCache);
2124+
_oop_handle_list = new_head;
2125+
Service_lock->notify_all();
2126+
}

src/hotspot/share/runtime/javaThread.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class JvmtiSampledObjectAllocEventCollector;
5959
class JvmtiThreadState;
6060

6161
class Metadata;
62+
class OopHandleList;
6263
class OopStorage;
6364
class OSThread;
6465

@@ -81,9 +82,14 @@ class JavaThread: public Thread {
8182
friend class HandshakeState;
8283
friend class Continuation;
8384
friend class Threads;
85+
friend class ServiceThread; // for deferred OopHandle release access
8486
private:
8587
bool _in_asgct; // Is set when this JavaThread is handling ASGCT call
8688
bool _on_thread_list; // Is set when this JavaThread is added to the Threads list
89+
90+
// All references to Java objects managed via OopHandles. These
91+
// have to be released by the ServiceThread after the JavaThread has
92+
// terminated - see add_oop_handles_for_release().
8793
OopHandle _threadObj; // The Java level thread object
8894
OopHandle _vthread; // the value returned by Thread.currentThread(): the virtual thread, if mounted, otherwise _threadObj
8995
OopHandle _jvmti_vthread;
@@ -1168,6 +1174,20 @@ class JavaThread: public Thread {
11681174
// AsyncGetCallTrace support
11691175
inline bool in_asgct(void) {return _in_asgct;}
11701176
inline void set_in_asgct(bool value) {_in_asgct = value;}
1177+
1178+
// Deferred OopHandle release support
1179+
private:
1180+
// List of OopHandles to be released - guarded by the Service_lock.
1181+
static OopHandleList* _oop_handle_list;
1182+
// Add our OopHandles to the list for the service thread to release.
1183+
void add_oop_handles_for_release();
1184+
// Called by the ServiceThread to release the OopHandles.
1185+
static void release_oop_handles();
1186+
// Called by the ServiceThread to poll if there are any OopHandles to release.
1187+
// Called when holding the Service_lock.
1188+
static bool has_oop_handles_to_release() {
1189+
return _oop_handle_list != nullptr;
1190+
}
11711191
};
11721192

11731193
inline JavaThread* JavaThread::current_or_null() {

src/hotspot/share/runtime/serviceThread.cpp

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -59,36 +59,6 @@ JvmtiDeferredEvent* ServiceThread::_jvmti_event = NULL;
5959
// to add this field to the per-JavaThread event queue. TODO: fix this sometime later
6060
JvmtiDeferredEventQueue ServiceThread::_jvmti_service_queue;
6161

62-
// Defer releasing JavaThread OopHandle to the ServiceThread
63-
class OopHandleList : public CHeapObj<mtInternal> {
64-
OopHandle _handle;
65-
OopHandleList* _next;
66-
public:
67-
OopHandleList(OopHandle h, OopHandleList* next) : _handle(h), _next(next) {}
68-
~OopHandleList() {
69-
_handle.release(JavaThread::thread_oop_storage());
70-
}
71-
OopHandleList* next() const { return _next; }
72-
};
73-
74-
static OopHandleList* _oop_handle_list = NULL;
75-
76-
static void release_oop_handles() {
77-
OopHandleList* list;
78-
{
79-
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
80-
list = _oop_handle_list;
81-
_oop_handle_list = NULL;
82-
}
83-
assert(!SafepointSynchronize::is_at_safepoint(), "cannot be called at a safepoint");
84-
85-
while (list != NULL) {
86-
OopHandleList* l = list;
87-
list = l->next();
88-
delete l;
89-
}
90-
}
91-
9262
void ServiceThread::initialize() {
9363
EXCEPTION_MARK;
9464

@@ -152,7 +122,7 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
152122
(thread_id_table_work = ThreadIdTable::has_work()) |
153123
(protection_domain_table_work = ProtectionDomainCacheTable::has_work()) |
154124
(oopstorage_work = OopStorage::has_cleanup_work_and_reset()) |
155-
(oop_handles_to_release = (_oop_handle_list != NULL)) |
125+
(oop_handles_to_release = JavaThread::has_oop_handles_to_release()) |
156126
(cldg_cleanup_work = ClassLoaderDataGraph::should_clean_metaspaces_and_reset()) |
157127
(jvmti_tagmap_work = JvmtiTagMap::has_object_free_events_and_reset())
158128
) == 0) {
@@ -215,7 +185,7 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
215185
}
216186

217187
if (oop_handles_to_release) {
218-
release_oop_handles();
188+
JavaThread::release_oop_handles();
219189
}
220190

221191
if (cldg_cleanup_work) {
@@ -261,10 +231,3 @@ void ServiceThread::nmethods_do(CodeBlobClosure* cf) {
261231
_jvmti_service_queue.nmethods_do(cf);
262232
}
263233
}
264-
265-
void ServiceThread::add_oop_handle_release(OopHandle handle) {
266-
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
267-
OopHandleList* new_head = new OopHandleList(handle, _oop_handle_list);
268-
_oop_handle_list = new_head;
269-
Service_lock->notify_all();
270-
}

src/hotspot/share/runtime/serviceThread.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ class ServiceThread : public JavaThread {
5252

5353
// Add event to the service thread event queue.
5454
static void enqueue_deferred_event(JvmtiDeferredEvent* event);
55-
static void add_oop_handle_release(OopHandle handle);
5655

5756
// GC support
5857
void oops_do_no_frames(OopClosure* f, CodeBlobClosure* cf);

0 commit comments

Comments
 (0)