mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-03 18:25:30 +00:00
8288497: add support for JavaThread::is_oop_safe()
Reviewed-by: pchilanomate, dholmes, rehn, eosterlund
This commit is contained in:
parent
c74a9235fc
commit
e26d3b3c01
@ -3599,6 +3599,12 @@ void Threads::remove(JavaThread* p, bool is_daemon) {
|
||||
// StackWatermarkSet::on_safepoint(), which performs GC processing,
|
||||
// requiring the GC state to be alive.
|
||||
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");
|
||||
|
||||
|
||||
@ -904,8 +904,9 @@ class JavaThread: public Thread {
|
||||
// JavaThread termination support
|
||||
public:
|
||||
enum TerminatedTypes {
|
||||
_not_terminated = 0xDEAD - 2,
|
||||
_not_terminated = 0xDEAD - 3,
|
||||
_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
|
||||
_vm_exited // JavaThread is still executing native code, but VM is terminated
|
||||
// only VM_Exit can set _vm_exited
|
||||
@ -914,10 +915,14 @@ class JavaThread: public Thread {
|
||||
private:
|
||||
// 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
|
||||
// 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;
|
||||
|
||||
jint _in_deopt_handler; // count of deoptimization
|
||||
@ -1172,13 +1177,17 @@ private:
|
||||
bool on_thread_list() const { return _on_thread_list; }
|
||||
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;
|
||||
// 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
|
||||
// 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.
|
||||
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;
|
||||
void set_terminated(TerminatedTypes t);
|
||||
|
||||
@ -260,21 +260,24 @@ inline void JavaThread::set_done_attaching_via_jni() {
|
||||
}
|
||||
|
||||
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);
|
||||
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 {
|
||||
// Use load-acquire so that setting of _terminated by
|
||||
// JavaThread::exit() is seen more quickly.
|
||||
TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
|
||||
return check_is_terminated(l_terminated);
|
||||
}
|
||||
|
||||
inline void JavaThread::set_terminated(TerminatedTypes t) {
|
||||
// use release-store so the setting of _terminated is seen more quickly
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user