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 "logging/log.hpp"
 34 #include "memory/resourceArea.hpp"
 35 #include "memory/universe.hpp"
 36 #include "oops/instanceKlass.hpp"
 37 #include "oops/oopHandle.inline.hpp"
 38 #include "runtime/atomic.hpp"
 39 #include "runtime/continuation.hpp"
 40 #include "runtime/continuationEntry.inline.hpp"
 41 #include "runtime/nonJavaThread.hpp"
 42 #include "runtime/objectMonitor.inline.hpp"
 43 #include "runtime/orderAccess.hpp"
 44 #include "runtime/safepoint.hpp"
 45 #include "runtime/synchronizer.hpp"
 46 #include "utilities/globalDefinitions.hpp"
 47 #include "utilities/sizes.hpp"
 48 
 49 inline void JavaThread::set_suspend_flag(SuspendFlags f) {
 50   uint32_t flags;
 51   do {
 52     flags = _suspend_flags;
 53   }
 54   while (Atomic::cmpxchg(&_suspend_flags, flags, (flags | f)) != flags);
 55 }
 56 inline void JavaThread::clear_suspend_flag(SuspendFlags f) {
 57   uint32_t flags;
 58   do {
 59     flags = _suspend_flags;
 60   }
 61   while (Atomic::cmpxchg(&_suspend_flags, flags, (flags & ~f)) != flags);
 62 }
 63 
 64 inline void JavaThread::set_trace_flag() {
 65   set_suspend_flag(_trace_flag);
 66 }
 67 inline void JavaThread::clear_trace_flag() {
 68   clear_suspend_flag(_trace_flag);
 69 }
 70 inline void JavaThread::set_obj_deopt_flag() {
 71   set_suspend_flag(_obj_deopt);
 72 }
 73 inline void JavaThread::clear_obj_deopt_flag() {
 74   clear_suspend_flag(_obj_deopt);
 75 }
 76 
 77 #if INCLUDE_JVMTI
 78 inline void JavaThread::set_carrier_thread_suspended() {
 79   _carrier_thread_suspended = true;
 80 }
 81 inline void JavaThread::clear_carrier_thread_suspended() {
 82   _carrier_thread_suspended = false;
 83 }
 84 #endif
 85 
 86 class AsyncExceptionHandshake : public AsyncHandshakeClosure {
 87   OopHandle _exception;
 88  public:
 89   AsyncExceptionHandshake(OopHandle& o, const char* name = "AsyncExceptionHandshake")
 90   : AsyncHandshakeClosure(name), _exception(o) { }
 91 
 92   ~AsyncExceptionHandshake() {
 93     Thread* current = Thread::current();
 94     // Can get here from the VMThread via install_async_exception() bail out.
 95     if (current->is_Java_thread()) {
 96       guarantee(JavaThread::cast(current)->is_oop_safe(),
 97                 "JavaThread cannot touch oops after its GC barrier is detached.");
 98     }
 99     assert(!_exception.is_empty(), "invariant");
100     _exception.release(Universe::vm_global());
101   }
102 
103   void do_thread(Thread* thr) {
104     JavaThread* self = JavaThread::cast(thr);
105     assert(self == JavaThread::current(), "must be");
106 
107     self->handle_async_exception(exception());
108   }
109   oop exception() {
110     assert(!_exception.is_empty(), "invariant");
111     return _exception.resolve();
112   }
113   bool is_async_exception()   { return true; }
114 };
115 
116 class UnsafeAccessErrorHandshake : public AsyncHandshakeClosure {
117  public:
118   UnsafeAccessErrorHandshake() : AsyncHandshakeClosure("UnsafeAccessErrorHandshake") {}
119   void do_thread(Thread* thr) {
120     JavaThread* self = JavaThread::cast(thr);
121     assert(self == JavaThread::current(), "must be");
122 
123     self->handshake_state()->handle_unsafe_access_error();
124   }
125   bool is_async_exception()   { return true; }
126 };
127 
128 inline void JavaThread::set_pending_unsafe_access_error() {
129   if (!has_async_exception_condition()) {
130     Handshake::execute(new UnsafeAccessErrorHandshake(), this);
131   }
132 }
133 
134 inline bool JavaThread::has_async_exception_condition() {
135   return handshake_state()->has_async_exception_operation();
136 }
137 
138 inline JavaThread::NoAsyncExceptionDeliveryMark::NoAsyncExceptionDeliveryMark(JavaThread *t) : _target(t) {
139   assert(!_target->handshake_state()->async_exceptions_blocked(), "Nesting is not supported");
140   _target->handshake_state()->set_async_exceptions_blocked(true);
141 }
142 inline JavaThread::NoAsyncExceptionDeliveryMark::~NoAsyncExceptionDeliveryMark() {
143   _target->handshake_state()->set_async_exceptions_blocked(false);
144 }
145 
146 inline JavaThreadState JavaThread::thread_state() const    {
147 #if defined(PPC64) || defined (AARCH64) || defined(RISCV64)
148   // Use membars when accessing volatile _thread_state. See
149   // Threads::create_vm() for size checks.
150   return Atomic::load_acquire(&_thread_state);
151 #else
152   return Atomic::load(&_thread_state);
153 #endif
154 }
155 
156 inline void JavaThread::set_thread_state(JavaThreadState s) {
157   assert(current_or_null() == nullptr || current_or_null() == this,
158          "state change should only be called by the current thread");
159 #if defined(PPC64) || defined (AARCH64) || defined(RISCV64)
160   // Use membars when accessing volatile _thread_state. See
161   // Threads::create_vm() for size checks.
162   Atomic::release_store(&_thread_state, s);
163 #else
164   Atomic::store(&_thread_state, s);
165 #endif
166 }
167 
168 inline void JavaThread::set_thread_state_fence(JavaThreadState s) {
169   set_thread_state(s);
170   OrderAccess::fence();
171 }
172 
173 ThreadSafepointState* JavaThread::safepoint_state() const  {
174   return _safepoint_state;
175 }
176 
177 void JavaThread::set_safepoint_state(ThreadSafepointState *state) {
178   _safepoint_state = state;
179 }
180 
181 bool JavaThread::is_at_poll_safepoint() {
182   return _safepoint_state->is_at_poll_safepoint();
183 }
184 
185 bool JavaThread::is_vthread_mounted() const {
186   return vthread_continuation() != nullptr;
187 }
188 
189 const ContinuationEntry* JavaThread::vthread_continuation() const {
190   for (ContinuationEntry* c = last_continuation(); c != nullptr; c = c->parent()) {
191     if (c->is_virtual_thread())
192       return c;
193   }
194   return nullptr;
195 }
196 
197 void JavaThread::enter_critical() {
198   assert(Thread::current() == this ||
199          (Thread::current()->is_VM_thread() &&
200          SafepointSynchronize::is_synchronizing()),
201          "this must be current thread or synchronizing");
202   _jni_active_critical++;
203 }
204 
205 inline void JavaThread::set_done_attaching_via_jni() {
206   _jni_attach_state = _attached_via_jni;
207   OrderAccess::fence();
208 }
209 
210 inline bool JavaThread::is_exiting() const {
211   TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
212   return l_terminated == _thread_exiting ||
213          l_terminated == _thread_gc_barrier_detached ||
214          check_is_terminated(l_terminated);
215 }
216 
217 inline bool JavaThread::is_oop_safe() const {
218   TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
219   return l_terminated != _thread_gc_barrier_detached &&
220          !check_is_terminated(l_terminated);
221 }
222 
223 inline bool JavaThread::is_terminated() const {
224   TerminatedTypes l_terminated = Atomic::load_acquire(&_terminated);
225   return check_is_terminated(l_terminated);
226 }
227 
228 inline void JavaThread::set_terminated(TerminatedTypes t) {
229   Atomic::release_store(&_terminated, t);
230 }
231 
232 inline bool JavaThread::is_active_Java_thread() const {
233   return on_thread_list() && !is_terminated();
234 }
235 
236 // Allow tracking of class initialization monitor use
237 inline void JavaThread::set_class_to_be_initialized(InstanceKlass* k) {
238   assert((k == nullptr && _class_to_be_initialized != nullptr) ||
239          (k != nullptr && _class_to_be_initialized == nullptr), "incorrect usage");
240   assert(this == Thread::current(), "Only the current thread can set this field");
241   _class_to_be_initialized = k;
242 }
243 
244 inline InstanceKlass* JavaThread::class_to_be_initialized() const {
245   return _class_to_be_initialized;
246 }
247 
248 inline void JavaThread::om_set_monitor_cache(ObjectMonitor* monitor) {
249   assert(LockingMode == LM_LIGHTWEIGHT, "must be");
250   assert(monitor != nullptr, "use om_clear_monitor_cache to clear");
251   assert(this == current() || monitor->owner_raw() == this, "only add owned monitors for other threads");
252   assert(this == current() || is_obj_deopt_suspend(), "thread must not run concurrently");
253 
254   _om_cache.set_monitor(monitor);
255 }
256 
257 inline void JavaThread::om_clear_monitor_cache() {
258   if (LockingMode != LM_LIGHTWEIGHT) {
259     return;
260   }
261 
262   _om_cache.clear();
263 
264   LogTarget(Info, monitorinflation, thread) lt;
265   if (!lt.is_enabled()) {
266     return;
267   }
268 
269   ResourceMark rm;
270 
271   if (_unlocked_inflation != 0 ||
272       _recursive_inflation != 0 ||
273       _contended_recursive_inflation != 0 ||
274       _contended_inflation != 0 ||
275       _wait_inflation != 0 ||
276       _lock_stack_inflation != 0) {
277     lt.print("Mon: %8zu Rec: %8zu CRec: %8zu Cont: %8zu Wait: %8zu Stack: %8zu Thread: %s",
278              _unlocked_inflation,
279              _recursive_inflation,
280              _contended_recursive_inflation,
281              _contended_inflation,
282              _wait_inflation,
283              _lock_stack_inflation,
284              name());
285   }
286   _unlocked_inflation            = 0;
287   _recursive_inflation           = 0;
288   _contended_recursive_inflation = 0;
289   _contended_inflation           = 0;
290   _wait_inflation                = 0;
291   _lock_stack_inflation          = 0;
292 
293   if (_lock_lookup != 0 ||
294       _unlock_lookup != 0) {
295     const double lock_hit_rate = (double)_lock_hit / (double)_lock_lookup * 100;
296     const double unlock_hit_rate = (double)_unlock_hit / (double)_unlock_lookup * 100;
297     lt.print("Lock: %3.2lf %% [%6zu / %6zu] Unlock: %3.2lf %% [%6zu / %6zu] Thread: %s",
298              lock_hit_rate, _lock_hit, _lock_lookup,
299              unlock_hit_rate, _unlock_hit, _unlock_lookup,
300              name());
301   }
302   _lock_hit = 0;
303   _lock_lookup = 0;
304   _unlock_hit = 0;
305   _unlock_lookup = 0;
306 }
307 
308 inline ObjectMonitor* JavaThread::om_get_from_monitor_cache(oop obj) {
309   assert(obj != nullptr, "do not look for null objects");
310   assert(this == current(), "only get own thread locals");
311   return _om_cache.get_monitor(obj);
312 }
313 
314 #endif // SHARE_RUNTIME_JAVATHREAD_INLINE_HPP