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