mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +02:00
8288497: add support for JavaThread::is_oop_safe()
Reviewed-by: pchilanomate, dholmes, rehn, eosterlund
This commit is contained in:
parent
c74a9235fc
commit
e26d3b3c01
4 changed files with 31 additions and 12 deletions
|
@ -3599,6 +3599,12 @@ void Threads::remove(JavaThread* p, bool is_daemon) {
|
||||||
// StackWatermarkSet::on_safepoint(), which performs GC processing,
|
// StackWatermarkSet::on_safepoint(), which performs GC processing,
|
||||||
// requiring the GC state to be alive.
|
// requiring the GC state to be alive.
|
||||||
BarrierSet::barrier_set()->on_thread_detach(p);
|
BarrierSet::barrier_set()->on_thread_detach(p);
|
||||||
|
if (p->is_exiting()) {
|
||||||
|
// If we got here via JavaThread::exit(), then we remember that the
|
||||||
|
// thread's GC barrier has been detached. We don't do this when we get
|
||||||
|
// here from another path, e.g., cleanup_failed_attach_current_thread().
|
||||||
|
p->set_terminated(JavaThread::_thread_gc_barrier_detached);
|
||||||
|
}
|
||||||
|
|
||||||
assert(ThreadsSMRSupport::get_java_thread_list()->includes(p), "p must be present");
|
assert(ThreadsSMRSupport::get_java_thread_list()->includes(p), "p must be present");
|
||||||
|
|
||||||
|
|
|
@ -904,8 +904,9 @@ class JavaThread: public Thread {
|
||||||
// JavaThread termination support
|
// JavaThread termination support
|
||||||
public:
|
public:
|
||||||
enum TerminatedTypes {
|
enum TerminatedTypes {
|
||||||
_not_terminated = 0xDEAD - 2,
|
_not_terminated = 0xDEAD - 3,
|
||||||
_thread_exiting, // JavaThread::exit() has been called for this thread
|
_thread_exiting, // JavaThread::exit() has been called for this thread
|
||||||
|
_thread_gc_barrier_detached, // thread's GC barrier has been detached
|
||||||
_thread_terminated, // JavaThread is removed from thread list
|
_thread_terminated, // JavaThread is removed from thread list
|
||||||
_vm_exited // JavaThread is still executing native code, but VM is terminated
|
_vm_exited // JavaThread is still executing native code, but VM is terminated
|
||||||
// only VM_Exit can set _vm_exited
|
// only VM_Exit can set _vm_exited
|
||||||
|
@ -914,10 +915,14 @@ class JavaThread: public Thread {
|
||||||
private:
|
private:
|
||||||
// In general a JavaThread's _terminated field transitions as follows:
|
// In general a JavaThread's _terminated field transitions as follows:
|
||||||
//
|
//
|
||||||
// _not_terminated => _thread_exiting => _thread_terminated
|
// _not_terminated => _thread_exiting => _thread_gc_barrier_detached => _thread_terminated
|
||||||
//
|
//
|
||||||
// _vm_exited is a special value to cover the case of a JavaThread
|
// _vm_exited is a special value to cover the case of a JavaThread
|
||||||
// executing native code after the VM itself is terminated.
|
// executing native code after the VM itself is terminated.
|
||||||
|
//
|
||||||
|
// A JavaThread that fails to JNI attach has these _terminated field transitions:
|
||||||
|
// _not_terminated => _thread_terminated
|
||||||
|
//
|
||||||
volatile TerminatedTypes _terminated;
|
volatile TerminatedTypes _terminated;
|
||||||
|
|
||||||
jint _in_deopt_handler; // count of deoptimization
|
jint _in_deopt_handler; // count of deoptimization
|
||||||
|
@ -1172,13 +1177,17 @@ private:
|
||||||
bool on_thread_list() const { return _on_thread_list; }
|
bool on_thread_list() const { return _on_thread_list; }
|
||||||
void set_on_thread_list() { _on_thread_list = true; }
|
void set_on_thread_list() { _on_thread_list = true; }
|
||||||
|
|
||||||
// thread has called JavaThread::exit() or is terminated
|
// thread has called JavaThread::exit(), thread's GC barrier is detached
|
||||||
|
// or thread is terminated
|
||||||
bool is_exiting() const;
|
bool is_exiting() const;
|
||||||
|
// thread's GC barrier is NOT detached and thread is NOT terminated
|
||||||
|
bool is_oop_safe() const;
|
||||||
// thread is terminated (no longer on the threads list); we compare
|
// thread is terminated (no longer on the threads list); we compare
|
||||||
// against the two non-terminated values so that a freed JavaThread
|
// against the three non-terminated values so that a freed JavaThread
|
||||||
// will also be considered terminated.
|
// will also be considered terminated.
|
||||||
bool check_is_terminated(TerminatedTypes l_terminated) const {
|
bool check_is_terminated(TerminatedTypes l_terminated) const {
|
||||||
return l_terminated != _not_terminated && l_terminated != _thread_exiting;
|
return l_terminated != _not_terminated && l_terminated != _thread_exiting &&
|
||||||
|
l_terminated != _thread_gc_barrier_detached;
|
||||||
}
|
}
|
||||||
bool is_terminated() const;
|
bool is_terminated() const;
|
||||||
void set_terminated(TerminatedTypes t);
|
void set_terminated(TerminatedTypes t);
|
||||||
|
|
|
@ -260,21 +260,24 @@ inline void JavaThread::set_done_attaching_via_jni() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool JavaThread::is_exiting() const {
|
inline bool JavaThread::is_exiting() const {
|
||||||
// Use load-acquire so that setting of _terminated by
|
|
||||||
// JavaThread::exit() is seen more quickly.
|
|
||||||
TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
|
TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
|
||||||
return l_terminated == _thread_exiting || check_is_terminated(l_terminated);
|
return l_terminated == _thread_exiting ||
|
||||||
|
l_terminated == _thread_gc_barrier_detached ||
|
||||||
|
check_is_terminated(l_terminated);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool JavaThread::is_oop_safe() const {
|
||||||
|
TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
|
||||||
|
return l_terminated != _thread_gc_barrier_detached &&
|
||||||
|
!check_is_terminated(l_terminated);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool JavaThread::is_terminated() const {
|
inline bool JavaThread::is_terminated() const {
|
||||||
// Use load-acquire so that setting of _terminated by
|
|
||||||
// JavaThread::exit() is seen more quickly.
|
|
||||||
TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
|
TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
|
||||||
return check_is_terminated(l_terminated);
|
return check_is_terminated(l_terminated);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void JavaThread::set_terminated(TerminatedTypes t) {
|
inline void JavaThread::set_terminated(TerminatedTypes t) {
|
||||||
// use release-store so the setting of _terminated is seen more quickly
|
|
||||||
Atomic::release_store(&_terminated, t);
|
Atomic::release_store(&_terminated, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,8 @@ void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
|
||||||
|
|
||||||
assert(!thread->is_terminated(), "must not be terminated");
|
assert(!thread->is_terminated(), "must not be terminated");
|
||||||
if (!thread->is_exiting()) {
|
if (!thread->is_exiting()) {
|
||||||
// JavaThread::exit() skipped calling current_thread_exiting()
|
// We did not get here via JavaThread::exit() so current_thread_exiting()
|
||||||
|
// was not called, e.g., JavaThread::cleanup_failed_attach_current_thread().
|
||||||
decrement_thread_counts(thread, daemon);
|
decrement_thread_counts(thread, daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue