@@ -1001,8 +1001,10 @@ JavaThread::JavaThread() :
10011001 _monitor_chunks(nullptr ),
10021002
10031003 _suspend_flags(0 ),
1004- _async_exception_condition(_no_async_condition),
10051004 _pending_async_exception(nullptr ),
1005+ #ifdef ASSERT
1006+ _is_unsafe_access_error (false ),
1007+ #endif
10061008
10071009 _thread_state (_thread_new),
10081010 _saved_exception_pc(nullptr ),
@@ -1572,9 +1574,6 @@ void JavaThread::remove_monitor_chunk(MonitorChunk* chunk) {
15721574
15731575// Asynchronous exceptions support
15741576//
1575- // Note: this function shouldn't block if it's called in
1576- // _thread_in_native_trans state (such as from
1577- // check_special_condition_for_native_trans()).
15781577void JavaThread::check_and_handle_async_exceptions () {
15791578 if (has_last_Java_frame () && has_async_exception_condition ()) {
15801579 // If we are at a polling page safepoint (not a poll return)
@@ -1600,21 +1599,12 @@ void JavaThread::check_and_handle_async_exceptions() {
16001599 }
16011600 }
16021601
1603- AsyncExceptionCondition condition = clear_async_exception_condition ();
1604- if (condition == _no_async_condition) {
1605- // Conditions have changed since has_special_runtime_exit_condition()
1606- // was called:
1607- // - if we were here only because of an external suspend request,
1608- // then that was taken care of above (or cancelled) so we are done
1609- // - if we were here because of another async request, then it has
1610- // been cleared between the has_special_runtime_exit_condition()
1611- // and now so again we are done
1602+ if (!clear_async_exception_condition ()) {
16121603 return ;
16131604 }
16141605
1615- // Check for pending async. exception
16161606 if (_pending_async_exception != NULL ) {
1617- // Only overwrite an already pending exception, if it is not a threadDeath.
1607+ // Only overwrite an already pending exception if it is not a threadDeath.
16181608 if (!has_pending_exception () || !pending_exception ()->is_a (vmClasses::ThreadDeath_klass ())) {
16191609
16201610 // We cannot call Exceptions::_throw(...) here because we cannot block
@@ -1631,25 +1621,23 @@ void JavaThread::check_and_handle_async_exceptions() {
16311621 }
16321622 ls.print_cr (" of type: %s" , _pending_async_exception->klass ()->external_name ());
16331623 }
1634- _pending_async_exception = NULL ;
1635- // Clear condition from _suspend_flags since we have finished processing it.
1636- clear_suspend_flag (_has_async_exception);
16371624 }
1638- }
1625+ // Always null out the _pending_async_exception oop here since the async condition was
1626+ // already cleared above and thus considered handled.
1627+ _pending_async_exception = NULL ;
1628+ } else {
1629+ assert (_is_unsafe_access_error, " must be" );
1630+ DEBUG_ONLY (_is_unsafe_access_error = false );
16391631
1640- if (condition == _async_unsafe_access_error && !has_pending_exception ()) {
16411632 // We may be at method entry which requires we save the do-not-unlock flag.
16421633 UnlockFlagSaver fs (this );
16431634 switch (thread_state ()) {
16441635 case _thread_in_vm: {
16451636 JavaThread* THREAD = this ;
16461637 Exceptions::throw_unsafe_access_internal_error (THREAD, __FILE__, __LINE__, " a fault occurred in an unsafe memory access operation" );
1647- return ;
1648- }
1649- case _thread_in_native: {
1650- ThreadInVMfromNative tiv (this );
1651- JavaThread* THREAD = this ;
1652- Exceptions::throw_unsafe_access_internal_error (THREAD, __FILE__, __LINE__, " a fault occurred in an unsafe memory access operation" );
1638+ // We might have blocked in a ThreadBlockInVM wrapper in the call above so make sure we process pending
1639+ // suspend requests and object reallocation operations if any since we might be going to Java after this.
1640+ SafepointMechanism::process_if_requested_with_exit_check (this , true /* check asyncs */ );
16531641 return ;
16541642 }
16551643 case _thread_in_Java: {
@@ -1662,8 +1650,6 @@ void JavaThread::check_and_handle_async_exceptions() {
16621650 ShouldNotReachHere ();
16631651 }
16641652 }
1665-
1666- assert (has_pending_exception (), " must have handled the async condition if no exception" );
16671653}
16681654
16691655void JavaThread::handle_special_runtime_exit_condition (bool check_asyncs) {
@@ -1696,9 +1682,8 @@ class InstallAsyncExceptionClosure : public HandshakeClosure {
16961682 }
16971683};
16981684
1699- void JavaThread::send_async_exception (oop java_thread , oop java_throwable) {
1685+ void JavaThread::send_async_exception (JavaThread* target , oop java_throwable) {
17001686 Handle throwable (Thread::current (), java_throwable);
1701- JavaThread* target = java_lang_Thread::thread (java_thread);
17021687 InstallAsyncExceptionClosure vm_stop (throwable);
17031688 Handshake::execute (&vm_stop, target);
17041689}
@@ -1847,21 +1832,17 @@ void JavaThread::check_special_condition_for_native_trans(JavaThread *thread) {
18471832 assert (thread->thread_state () == _thread_in_native_trans, " wrong state" );
18481833 assert (!thread->has_last_Java_frame () || thread->frame_anchor ()->walkable (), " Unwalkable stack in native->Java transition" );
18491834
1835+ thread->set_thread_state (_thread_in_vm);
1836+
18501837 // Enable WXWrite: called directly from interpreter native wrapper.
18511838 MACOS_AARCH64_ONLY (ThreadWXEnable wx (WXWrite, thread));
18521839
1853- SafepointMechanism::process_if_requested_with_exit_check (thread, false /* check asyncs */ );
1840+ SafepointMechanism::process_if_requested_with_exit_check (thread, true /* check asyncs */ );
18541841
18551842 // After returning from native, it could be that the stack frames are not
18561843 // yet safe to use. We catch such situations in the subsequent stack watermark
18571844 // barrier, which will trap unsafe stack frames.
18581845 StackWatermarkSet::before_unwind (thread);
1859-
1860- if (thread->has_async_exception_condition (false /* check unsafe access error */ )) {
1861- // We are in _thread_in_native_trans state, don't handle unsafe
1862- // access error since that may block.
1863- thread->check_and_handle_async_exceptions ();
1864- }
18651846}
18661847
18671848#ifndef PRODUCT
0 commit comments