1 /*
  2  * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #ifndef SHARE_RUNTIME_JAVATHREAD_INLINE_HPP
 27 #define SHARE_RUNTIME_JAVATHREAD_INLINE_HPP
 28 
 29 #include "runtime/javaThread.hpp"
 30 
 31 #include "classfile/javaClasses.hpp"
 32 #include "gc/shared/tlab_globals.hpp"
 33 #include "memory/universe.hpp"
 34 #include "oops/instanceKlass.hpp"
 35 #include "oops/oopHandle.inline.hpp"
 36 #include "prims/jvmtiThreadState.hpp"
 37 #include "runtime/atomic.hpp"
 38 #include "runtime/continuation.hpp"
 39 #include "runtime/continuationEntry.inline.hpp"
 40 #include "runtime/nonJavaThread.hpp"
 41 #include "runtime/orderAccess.hpp"
 42 #include "runtime/safepoint.hpp"
 43 
 44 inline void JavaThread::set_suspend_flag(SuspendFlags f) {
 45   uint32_t flags;
 46   do {
 47     flags = _suspend_flags;
 48   }
 49   while (Atomic::cmpxchg(&_suspend_flags, flags, (flags | f)) != flags);
 50 }
 51 inline void JavaThread::clear_suspend_flag(SuspendFlags f) {
 52   uint32_t flags;
 53   do {
 54     flags = _suspend_flags;
 55   }
 56   while (Atomic::cmpxchg(&_suspend_flags, flags, (flags & ~f)) != flags);
 57 }
 58 
 59 inline void JavaThread::set_trace_flag() {
 60   set_suspend_flag(_trace_flag);
 61 }
 62 inline void JavaThread::clear_trace_flag() {
 63   clear_suspend_flag(_trace_flag);
 64 }
 65 inline void JavaThread::set_obj_deopt_flag() {
 66   set_suspend_flag(_obj_deopt);
 67 }
 68 inline void JavaThread::clear_obj_deopt_flag() {
 69   clear_suspend_flag(_obj_deopt);
 70 }
 71 
 72 #if INCLUDE_JVMTI
 73 inline void JavaThread::set_carrier_thread_suspended() {
 74   _carrier_thread_suspended = true;
 75 }
 76 inline void JavaThread::clear_carrier_thread_suspended() {
 77   _carrier_thread_suspended = false;
 78 }
 79 #endif
 80 
 81 class AsyncExceptionHandshake : public AsyncHandshakeClosure {
 82   OopHandle _exception;
 83  public:
 84   AsyncExceptionHandshake(OopHandle& o, const char* name = "AsyncExceptionHandshake")
 85   : AsyncHandshakeClosure(name), _exception(o) { }
 86 
 87   ~AsyncExceptionHandshake() {
 88     Thread* current = Thread::current();
 89     // Can get here from the VMThread via install_async_exception() bail out.
 90     if (current->is_Java_thread()) {
 91       guarantee(JavaThread::cast(current)->is_oop_safe(),
 92                 "JavaThread cannot touch oops after its GC barrier is detached.");
 93     }
 94     assert(!_exception.is_empty(), "invariant");
 95     _exception.release(Universe::vm_global());
 96   }
 97 
 98   void do_thread(Thread* thr) {
 99     JavaThread* self = JavaThread::cast(thr);
100     assert(self == JavaThread::current(), "must be");
101 
102     self->handle_async_exception(exception());
103   }
104   oop exception() {
105     assert(!_exception.is_empty(), "invariant");
106     return _exception.resolve();
107   }
108   bool is_async_exception()   { return true; }
109 };
110 
111 class UnsafeAccessErrorHandshake : public AsyncHandshakeClosure {
112  public:
113   UnsafeAccessErrorHandshake() : AsyncHandshakeClosure("UnsafeAccessErrorHandshake") {}
114   void do_thread(Thread* thr) {
115     JavaThread* self = JavaThread::cast(thr);
116     assert(self == JavaThread::current(), "must be");
117 
118     self->handshake_state()->handle_unsafe_access_error();
119   }
120   bool is_async_exception()   { return true; }
121 };
122 
123 inline void JavaThread::set_pending_unsafe_access_error() {
124   if (!has_async_exception_condition()) {
125     Handshake::execute(new UnsafeAccessErrorHandshake(), this);
126   }
127 }
128 
129 inline bool JavaThread::has_async_exception_condition() {
130   return handshake_state()->has_async_exception_operation();
131 }
132 
133 inline JavaThread::NoAsyncExceptionDeliveryMark::NoAsyncExceptionDeliveryMark(JavaThread *t) : _target(t) {
134   assert(!_target->handshake_state()->async_exceptions_blocked(), "Nesting is not supported");
135   _target->handshake_state()->set_async_exceptions_blocked(true);
136 }
137 inline JavaThread::NoAsyncExceptionDeliveryMark::~NoAsyncExceptionDeliveryMark() {
138   _target->handshake_state()->set_async_exceptions_blocked(false);
139 }
140 
141 inline JavaThreadState JavaThread::thread_state() const    {
142 #if defined(PPC64) || defined (AARCH64) || defined(RISCV64)
143   // Use membars when accessing volatile _thread_state. See
144   // Threads::create_vm() for size checks.
145   return Atomic::load_acquire(&_thread_state);
146 #else
147   return Atomic::load(&_thread_state);
148 #endif
149 }
150 
151 inline void JavaThread::set_thread_state(JavaThreadState s) {
152   assert(current_or_null() == nullptr || current_or_null() == this,
153          "state change should only be called by the current thread");
154 #if defined(PPC64) || defined (AARCH64) || defined(RISCV64)
155   // Use membars when accessing volatile _thread_state. See
156   // Threads::create_vm() for size checks.
157   Atomic::release_store(&_thread_state, s);
158 #else
159   Atomic::store(&_thread_state, s);
160 #endif
161 }
162 
163 inline void JavaThread::set_thread_state_fence(JavaThreadState s) {
164   set_thread_state(s);
165   OrderAccess::fence();
166 }
167 
168 ThreadSafepointState* JavaThread::safepoint_state() const  {
169   return _safepoint_state;
170 }
171 
172 void JavaThread::set_safepoint_state(ThreadSafepointState *state) {
173   _safepoint_state = state;
174 }
175 
176 bool JavaThread::is_at_poll_safepoint() {
177   return _safepoint_state->is_at_poll_safepoint();
178 }
179 
180 bool JavaThread::is_vthread_mounted() const {
181   return vthread_continuation() != nullptr;
182 }
183 
184 const ContinuationEntry* JavaThread::vthread_continuation() const {
185   for (ContinuationEntry* c = last_continuation(); c != nullptr; c = c->parent()) {
186     if (c->is_virtual_thread())
187       return c;
188   }
189   return nullptr;
190 }
191 
192 void JavaThread::enter_critical() {
193   assert(Thread::current() == this ||
194          (Thread::current()->is_VM_thread() &&
195          SafepointSynchronize::is_synchronizing()),
196          "this must be current thread or synchronizing");
197   _jni_active_critical++;
198 }
199 
200 inline void JavaThread::set_done_attaching_via_jni() {
201   _jni_attach_state = _attached_via_jni;
202   OrderAccess::fence();
203 }
204 
205 inline bool JavaThread::is_exiting() const {
206   TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
207   return l_terminated == _thread_exiting ||
208          l_terminated == _thread_gc_barrier_detached ||
209          check_is_terminated(l_terminated);
210 }
211 
212 inline bool JavaThread::is_oop_safe() const {
213   TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
214   return l_terminated != _thread_gc_barrier_detached &&
215          !check_is_terminated(l_terminated);
216 }
217 
218 inline bool JavaThread::is_terminated() const {
219   TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
220   return check_is_terminated(l_terminated);
221 }
222 
223 inline void JavaThread::set_terminated(TerminatedTypes t) {
224   Atomic::release_store(&_terminated, t);
225 }
226 
227 inline bool JavaThread::is_active_Java_thread() const {
228   return on_thread_list() && !is_terminated();
229 }
230 
231 // Allow tracking of class initialization monitor use
232 inline void JavaThread::set_class_to_be_initialized(InstanceKlass* k) {
233   assert((k == nullptr && _class_to_be_initialized != nullptr) ||
234          (k != nullptr && _class_to_be_initialized == nullptr), "incorrect usage");
235   assert(this == Thread::current(), "Only the current thread can set this field");
236   _class_to_be_initialized = k;
237 }
238 
239 inline InstanceKlass* JavaThread::class_to_be_initialized() const {
240   return _class_to_be_initialized;
241 }
242 
243 #endif // SHARE_RUNTIME_JAVATHREAD_INLINE_HPP