Skip to content

Commit

Permalink
8307068: store a JavaThread* in the java.lang.Thread object after the…
Browse files Browse the repository at this point in the history
… JavaThread* is added to the main ThreadsList

Reviewed-by: phh
Backport-of: ceca198ef21b9003492b456d87180d2f48774f73
  • Loading branch information
GoeLin committed Jul 19, 2023
1 parent 494cf45 commit 86e8887
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/hotspot/share/classfile/javaClasses.cpp
Expand Up @@ -1793,11 +1793,18 @@ JavaThread* java_lang_Thread::thread(oop java_thread) {
return (JavaThread*)java_thread->address_field(_eetop_offset);
}

JavaThread* java_lang_Thread::thread_acquire(oop java_thread) {
return reinterpret_cast<JavaThread*>(java_thread->address_field_acquire(_eetop_offset));
}

void java_lang_Thread::set_thread(oop java_thread, JavaThread* thread) {
java_thread->address_field_put(_eetop_offset, (address)thread);
}

void java_lang_Thread::release_set_thread(oop java_thread, JavaThread* thread) {
java_thread->release_address_field_put(_eetop_offset, (address)thread);
}

bool java_lang_Thread::interrupted(oop java_thread) {
// Make sure the caller can safely access oops.
assert(Thread::current()->is_VM_thread() ||
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/classfile/javaClasses.hpp
Expand Up @@ -420,8 +420,10 @@ class java_lang_Thread : AllStatic {

// Returns the JavaThread associated with the thread obj
static JavaThread* thread(oop java_thread);
static JavaThread* thread_acquire(oop java_thread);
// Set JavaThread for instance
static void set_thread(oop java_thread, JavaThread* thread);
static void release_set_thread(oop java_thread, JavaThread* thread);
// Interrupted status
static bool interrupted(oop java_thread);
static void set_interrupted(oop java_thread, bool val);
Expand Down
17 changes: 11 additions & 6 deletions src/hotspot/share/runtime/thread.cpp
Expand Up @@ -1341,8 +1341,7 @@ static void ensure_join(JavaThread* thread) {
// Clear the native thread instance - this makes isAlive return false and allows the join()
// to complete once we've done the notify_all below. Needs a release() to obey Java Memory Model
// requirements.
OrderAccess::release();
java_lang_Thread::set_thread(threadObj(), NULL);
java_lang_Thread::release_set_thread(threadObj(), NULL);
lock.notify_all(thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
Expand Down Expand Up @@ -2261,7 +2260,6 @@ void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
assert(InstanceKlass::cast(thread_oop->klass())->is_linked(),
"must be initialized");
set_threadObj(thread_oop());
java_lang_Thread::set_thread(thread_oop(), this);

if (prio == NoPriority) {
prio = java_lang_Thread::priority(thread_oop());
Expand All @@ -2277,6 +2275,11 @@ void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
// added to the Threads list for if a GC happens, then the java_thread oop
// will not be visited by GC.
Threads::add(this);
// Publish the JavaThread* in java.lang.Thread after the JavaThread* is
// on a ThreadsList. We don't want to wait for the release when the
// Theads_lock is dropped somewhere in the caller since the JavaThread*
// is already visible to JVM/TI via the ThreadsList.
java_lang_Thread::release_set_thread(thread_oop(), this);
}

oop JavaThread::current_park_blocker() {
Expand Down Expand Up @@ -4007,9 +4010,6 @@ void JavaThread::start_internal_daemon(JavaThread* current, JavaThread* target,
MutexLocker mu(current, Threads_lock);

// Initialize the fields of the thread_oop first.

java_lang_Thread::set_thread(thread_oop(), target); // isAlive == true now

if (prio != NoPriority) {
java_lang_Thread::set_priority(thread_oop(), prio);
// Note: we don't call os::set_priority here. Possibly we should,
Expand All @@ -4022,6 +4022,11 @@ void JavaThread::start_internal_daemon(JavaThread* current, JavaThread* target,
target->set_threadObj(thread_oop());

Threads::add(target); // target is now visible for safepoint/handshake
// Publish the JavaThread* in java.lang.Thread after the JavaThread* is
// on a ThreadsList. We don't want to wait for the release when the
// Theads_lock is dropped when the 'mu' destructor is run since the
// JavaThread* is already visible to JVM/TI via the ThreadsList.
java_lang_Thread::release_set_thread(thread_oop(), target); // isAlive == true now
Thread::start(target);
}

Expand Down
7 changes: 4 additions & 3 deletions src/hotspot/share/runtime/threadSMR.cpp
Expand Up @@ -792,10 +792,11 @@ bool ThreadsListHandle::cv_internal_thread_to_JavaThread(jobject jthread,
*thread_oop_p = thread_oop;
}

JavaThread *java_thread = java_lang_Thread::thread(thread_oop);
JavaThread *java_thread = java_lang_Thread::thread_acquire(thread_oop);
if (java_thread == NULL) {
// The java.lang.Thread does not contain a JavaThread * so it has
// not yet run or it has died.
// The java.lang.Thread does not contain a JavaThread* so it has not
// run enough to be put on a ThreadsList or it has exited enough to
// make it past ensure_join() where the JavaThread* is cleared.
return false;
}
// Looks like a live JavaThread at this point.
Expand Down

1 comment on commit 86e8887

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.