1 /* 2 * Copyright (c) 1997, 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_INTERFACESUPPORT_INLINE_HPP 27 #define SHARE_RUNTIME_INTERFACESUPPORT_INLINE_HPP 28 29 // No interfaceSupport.hpp 30 31 #include "gc/shared/gc_globals.hpp" 32 #include "runtime/globals.hpp" 33 #include "runtime/handles.inline.hpp" 34 #include "runtime/javaThread.inline.hpp" 35 #include "runtime/mutexLocker.hpp" 36 #include "runtime/orderAccess.hpp" 37 #include "runtime/os.hpp" 38 #include "runtime/perfData.hpp" 39 #include "runtime/safepointMechanism.inline.hpp" 40 #include "runtime/safepointVerifiers.hpp" 41 #include "runtime/threadWXSetters.inline.hpp" 42 #include "runtime/vmOperations.hpp" 43 #include "utilities/globalDefinitions.hpp" 44 #include "utilities/macros.hpp" 45 #include "utilities/preserveException.hpp" 46 47 // Wrapper for all entry points to the virtual machine. 48 49 // InterfaceSupport provides functionality used by the VM_LEAF_BASE and 50 // VM_ENTRY_BASE macros. These macros are used to guard entry points into 51 // the VM and perform checks upon leave of the VM. 52 53 54 class InterfaceSupport: AllStatic { 55 # ifdef ASSERT 56 public: 57 static unsigned int _scavenge_alot_counter; 58 static unsigned int _fullgc_alot_counter; 59 static intx _fullgc_alot_invocation; 60 61 // Helper methods used to implement +ScavengeALot and +FullGCALot 62 static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); } 63 static void gc_alot(); 64 65 static void walk_stack_from(vframe* start_vf); 66 static void walk_stack(); 67 68 static void zombieAll(); 69 static void deoptimizeAll(); 70 static void verify_stack(); 71 static void verify_last_frame(); 72 # endif 73 }; 74 75 76 // Basic class for all thread transition classes. 77 78 class ThreadStateTransition : public StackObj { 79 protected: 80 JavaThread* _thread; 81 82 public: 83 ThreadStateTransition(JavaThread *thread) : _thread(thread) { 84 assert(thread != nullptr, "must be active Java thread"); 85 assert(thread == Thread::current(), "must be current thread"); 86 } 87 88 static inline void transition_from_java(JavaThread *thread, JavaThreadState to) { 89 assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state"); 90 assert(to == _thread_in_vm || to == _thread_in_native, "invalid transition"); 91 thread->set_thread_state(to); 92 } 93 94 // We never install asynchronous exceptions when coming (back) in to the runtime 95 // from native code because the runtime is not set up to handle exceptions floating 96 // around at arbitrary points. 97 static inline void transition_from_native(JavaThread *thread, JavaThreadState to, bool check_asyncs = true) { 98 assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state"); 99 assert(to == _thread_in_vm || to == _thread_in_Java, "invalid transition"); 100 assert(!thread->has_last_Java_frame() || thread->frame_anchor()->walkable(), "Unwalkable stack in native transition"); 101 102 if (!UseSystemMemoryBarrier) { 103 thread->set_thread_state_fence(_thread_in_vm); 104 } else { 105 thread->set_thread_state(_thread_in_vm); 106 } 107 SafepointMechanism::process_if_requested_with_exit_check(thread, to != _thread_in_Java ? false : check_asyncs); 108 thread->set_thread_state(to); 109 } 110 111 static inline void transition_from_vm(JavaThread *thread, JavaThreadState to, bool check_asyncs = true) { 112 assert(thread->thread_state() == _thread_in_vm, "coming from wrong thread state"); 113 if (to == _thread_in_Java) { 114 SafepointMechanism::process_if_requested_with_exit_check(thread, check_asyncs); 115 thread->set_thread_state(to); 116 } else { 117 assert(to == _thread_in_native || to == _thread_blocked, "invalid transition"); 118 // Check NoSafepointVerifier. This also clears unhandled oops if CheckUnhandledOops is used. 119 thread->check_possible_safepoint(); 120 121 // Once we are in native/blocked vm expects stack to be walkable 122 thread->frame_anchor()->make_walkable(); 123 OrderAccess::storestore(); // Keep thread_state change and make_walkable() separate. 124 thread->set_thread_state(to); 125 } 126 } 127 }; 128 129 class ThreadInVMfromJava : public ThreadStateTransition { 130 bool _check_asyncs; 131 public: 132 ThreadInVMfromJava(JavaThread* thread, bool check_asyncs = true) : ThreadStateTransition(thread), _check_asyncs(check_asyncs) { 133 transition_from_java(thread, _thread_in_vm); 134 } 135 ~ThreadInVMfromJava() { 136 if (_thread->stack_overflow_state()->stack_yellow_reserved_zone_disabled()) { 137 _thread->stack_overflow_state()->enable_stack_yellow_reserved_zone(); 138 } 139 // We prevent asynchronous exceptions from being installed on return to Java in situations 140 // where we can't tolerate them. See bugs: 4324348, 4854693, 4998314, 5040492, 5050705. 141 transition_from_vm(_thread, _thread_in_Java, _check_asyncs); 142 } 143 }; 144 145 146 class ThreadInVMfromUnknown { 147 JavaThread* _thread; 148 public: 149 ThreadInVMfromUnknown() : _thread(nullptr) { 150 Thread* t = Thread::current(); 151 if (t->is_Java_thread()) { 152 JavaThread* t2 = JavaThread::cast(t); 153 if (t2->thread_state() == _thread_in_native) { 154 _thread = t2; 155 ThreadStateTransition::transition_from_native(t2, _thread_in_vm); 156 // Used to have a HandleMarkCleaner but that is dangerous as 157 // it could free a handle in our (indirect, nested) caller. 158 // We expect any handles will be short lived and figure we 159 // don't need an actual HandleMark. 160 } 161 } 162 } 163 ~ThreadInVMfromUnknown() { 164 if (_thread) { 165 ThreadStateTransition::transition_from_vm(_thread, _thread_in_native); 166 } 167 } 168 }; 169 170 171 class ThreadInVMfromNative : public ThreadStateTransition { 172 ResetNoHandleMark __rnhm; 173 public: 174 ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) { 175 transition_from_native(thread, _thread_in_vm); 176 } 177 ~ThreadInVMfromNative() { 178 // We cannot assert !_thread->owns_locks() since we have valid cases where 179 // we call known native code using this wrapper holding locks. 180 transition_from_vm(_thread, _thread_in_native); 181 } 182 }; 183 184 185 class ThreadToNativeFromVM : public ThreadStateTransition { 186 public: 187 ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) { 188 assert(!thread->owns_locks(), "must release all locks when leaving VM"); 189 transition_from_vm(thread, _thread_in_native); 190 } 191 ~ThreadToNativeFromVM() { 192 transition_from_native(_thread, _thread_in_vm); 193 assert(!_thread->is_pending_jni_exception_check(), "Pending JNI Exception Check"); 194 // We don't need to clear_walkable because it will happen automagically when we return to java 195 } 196 }; 197 198 // Perform a transition to _thread_blocked and take a call-back to be executed before 199 // SafepointMechanism::process_if_requested when returning to the VM. This allows us 200 // to perform an "undo" action if we might block processing a safepoint/handshake operation 201 // (such as thread suspension). 202 template <typename PRE_PROC = void(JavaThread*)> 203 class ThreadBlockInVMPreprocess : public ThreadStateTransition { 204 private: 205 PRE_PROC& _pr; 206 bool _allow_suspend; 207 public: 208 ThreadBlockInVMPreprocess(JavaThread* thread, PRE_PROC& pr, bool allow_suspend = false) 209 : ThreadStateTransition(thread), _pr(pr), _allow_suspend(allow_suspend) { 210 transition_from_vm(thread, _thread_blocked); 211 } 212 ~ThreadBlockInVMPreprocess() { 213 assert(_thread->thread_state() == _thread_blocked, "coming from wrong thread state"); 214 // Change back to _thread_in_vm and ensure it is seen by the VM thread. 215 _thread->set_thread_state_fence(_thread_in_vm); 216 217 if (SafepointMechanism::should_process(_thread, _allow_suspend)) { 218 _pr(_thread); 219 SafepointMechanism::process_if_requested(_thread, _allow_suspend, false /* check_async_exception */); 220 } 221 } 222 }; 223 224 class ThreadBlockInVM : public ThreadBlockInVMPreprocess<> { 225 public: 226 ThreadBlockInVM(JavaThread* thread, bool allow_suspend = false) 227 : ThreadBlockInVMPreprocess(thread, emptyOp, allow_suspend) {} 228 private: 229 static void emptyOp(JavaThread* current) {} 230 }; 231 232 233 // Debug class instantiated in JRT_ENTRY macro. 234 // Can be used to verify properties on enter/exit of the VM. 235 236 #ifdef ASSERT 237 class VMEntryWrapper { 238 public: 239 VMEntryWrapper(); 240 ~VMEntryWrapper(); 241 }; 242 243 244 class VMNativeEntryWrapper { 245 public: 246 VMNativeEntryWrapper(); 247 ~VMNativeEntryWrapper(); 248 }; 249 250 #endif // ASSERT 251 252 // LEAF routines do not lock, GC or throw exceptions 253 254 // On macos/aarch64 we need to maintain the W^X state of the thread. So we 255 // take WXWrite on the enter to VM from the "outside" world, so the rest of JVM 256 // code can assume writing (but not executing) codecache is always possible 257 // without preliminary actions. 258 // JavaThread state should be changed only after taking WXWrite. The state 259 // change may trigger a safepoint, that would need WXWrite to do bookkeeping 260 // in the codecache. 261 262 #define VM_LEAF_BASE(result_type, header) \ 263 debug_only(NoHandleMark __hm;) \ 264 os::verify_stack_alignment(); \ 265 /* begin of body */ 266 267 #define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \ 268 debug_only(ResetNoHandleMark __rnhm;) \ 269 HandleMarkCleaner __hm(thread); \ 270 JavaThread* THREAD = thread; /* For exception macros. */ \ 271 os::verify_stack_alignment(); \ 272 /* begin of body */ 273 274 275 // ENTRY routines may lock, GC and throw exceptions 276 277 #define VM_ENTRY_BASE(result_type, header, thread) \ 278 HandleMarkCleaner __hm(thread); \ 279 JavaThread* THREAD = thread; /* For exception macros. */ \ 280 os::verify_stack_alignment(); \ 281 /* begin of body */ 282 283 284 #define JRT_ENTRY(result_type, header) \ 285 result_type header { \ 286 assert(current == JavaThread::current(), "Must be"); \ 287 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current)); \ 288 ThreadInVMfromJava __tiv(current); \ 289 VM_ENTRY_BASE(result_type, header, current) \ 290 debug_only(VMEntryWrapper __vew;) 291 292 // JRT_LEAF currently can be called from either _thread_in_Java or 293 // _thread_in_native mode. 294 // 295 // JRT_LEAF rules: 296 // A JRT_LEAF method may not interfere with safepointing by 297 // 1) acquiring or blocking on a Mutex or JavaLock - checked 298 // 2) allocating heap memory - checked 299 // 3) executing a VM operation - checked 300 // 4) executing a system call (including malloc) that could block or grab a lock 301 // 5) invoking GC 302 // 6) reaching a safepoint 303 // 7) running too long 304 // Nor may any method it calls. 305 306 #define JRT_LEAF(result_type, header) \ 307 result_type header { \ 308 VM_LEAF_BASE(result_type, header) \ 309 debug_only(NoSafepointVerifier __nsv;) 310 311 312 #define JRT_ENTRY_NO_ASYNC(result_type, header) \ 313 result_type header { \ 314 assert(current == JavaThread::current(), "Must be"); \ 315 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current)); \ 316 ThreadInVMfromJava __tiv(current, false /* check asyncs */); \ 317 VM_ENTRY_BASE(result_type, header, current) \ 318 debug_only(VMEntryWrapper __vew;) 319 320 // Same as JRT Entry but allows for return value after the safepoint 321 // to get back into Java from the VM 322 #define JRT_BLOCK_ENTRY(result_type, header) \ 323 result_type header { \ 324 assert(current == JavaThread::current(), "Must be"); \ 325 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current)); \ 326 HandleMarkCleaner __hm(current); 327 328 #define JRT_BLOCK \ 329 { \ 330 assert(current == JavaThread::current(), "Must be"); \ 331 ThreadInVMfromJava __tiv(current); \ 332 JavaThread* THREAD = current; /* For exception macros. */ \ 333 debug_only(VMEntryWrapper __vew;) 334 335 #define JRT_BLOCK_NO_ASYNC \ 336 { \ 337 assert(current == JavaThread::current(), "Must be"); \ 338 ThreadInVMfromJava __tiv(current, false /* check asyncs */); \ 339 JavaThread* THREAD = current; /* For exception macros. */ \ 340 debug_only(VMEntryWrapper __vew;) 341 342 #define JRT_ENTRY_PROF(result_type, sub, name, header) \ 343 PerfTickCounters* _perf_##sub##_##name##_timer = nullptr; \ 344 PerfCounter* _perf_##sub##_##name##_count = nullptr; \ 345 result_type header { \ 346 assert(current == JavaThread::current(), "Must be"); \ 347 PerfTraceTimedEvent perf_##sub##_##name(_perf_##sub##_##name##_timer, _perf_##sub##_##name##_count, current->do_profile_rt_call()); \ 348 ProfileVMCallContext pctx(current, &(perf_##sub##_##name), current->do_profile_rt_call()); \ 349 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current)); \ 350 ThreadInVMfromJava __tiv(current); \ 351 VM_ENTRY_BASE(result_type, header, current) \ 352 debug_only(VMEntryWrapper __vew;) 353 354 #define JRT_LEAF_PROF(result_type, sub, name, header) \ 355 PerfTickCounters* _perf_##sub##_##name##_timer = nullptr; \ 356 PerfCounter* _perf_##sub##_##name##_count = nullptr; \ 357 result_type header { \ 358 PerfTraceTimedEvent perf_##sub##_##name(_perf_##sub##_##name##_timer, _perf_##sub##_##name##_count, \ 359 current->do_profile_rt_call()); \ 360 ProfileVMCallContext pctx(current, &(perf_##sub##_##name), current->do_profile_rt_call()); \ 361 VM_LEAF_BASE(result_type, header) \ 362 debug_only(NoSafepointVerifier __nsv;) 363 364 #define JRT_LEAF_PROF_NO_THREAD(result_type, sub, name, header) \ 365 PerfTickCounters* _perf_##sub##_##name##_timer = nullptr; \ 366 PerfCounter* _perf_##sub##_##name##_count = nullptr; \ 367 result_type header { \ 368 Thread* current = Thread::current(); \ 369 PerfTraceTimedEvent perf_##sub##_##name(_perf_##sub##_##name##_timer, _perf_##sub##_##name##_count, \ 370 current->do_profile_rt_call()); \ 371 ProfileVMCallContext pctx(current, &(perf_##sub##_##name), current->do_profile_rt_call()); \ 372 VM_LEAF_BASE(result_type, header) \ 373 debug_only(NoSafepointVerifier __nsv;) 374 375 #define JRT_ENTRY_NO_ASYNC_PROF(result_type, sub, name, header) \ 376 PerfTickCounters* _perf_##sub##_##name##_timer = nullptr; \ 377 PerfCounter* _perf_##sub##_##name##_count = nullptr; \ 378 result_type header { \ 379 assert(current == JavaThread::current(), "Must be"); \ 380 PerfTraceTimedEvent perf_##sub##_##name(_perf_##sub##_##name##_timer, _perf_##sub##_##name##_count, current->do_profile_rt_call()); \ 381 ProfileVMCallContext pctx(current, &(perf_##sub##_##name), current->do_profile_rt_call()); \ 382 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current)); \ 383 ThreadInVMfromJava __tiv(current, false /* check asyncs */); \ 384 VM_ENTRY_BASE(result_type, header, current) \ 385 debug_only(VMEntryWrapper __vew;) 386 387 #define JRT_BLOCK_ENTRY_PROF(result_type, sub, name, header) \ 388 PerfTickCounters* _perf_##sub##_##name##_timer = nullptr; \ 389 PerfCounter* _perf_##sub##_##name##_count = nullptr; \ 390 result_type header { \ 391 assert(current == JavaThread::current(), "Must be"); \ 392 PerfTraceTimedEvent perf_##sub##_##name(_perf_##sub##_##name##_timer, _perf_##sub##_##name##_count, current->do_profile_rt_call()); \ 393 ProfileVMCallContext pctx(current, &(perf_##sub##_##name), current->do_profile_rt_call()); \ 394 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current)); \ 395 HandleMarkCleaner __hm(current); 396 397 #define PROF_ENTRY(result_type, sub, name, header) \ 398 PerfTickCounters* _perf_##sub##_##name##_timer = nullptr; \ 399 PerfCounter* _perf_##sub##_##name##_count = nullptr; \ 400 result_type header { \ 401 assert(current == JavaThread::current(), "must be"); \ 402 PerfTraceTimedEvent perf_##sub##_##name(_perf_##sub##_##name##_timer, _perf_##sub##_##name##_count, current->do_profile_rt_call()); \ 403 ProfileVMCallContext pctx(current, &(perf_##sub##_##name), current->do_profile_rt_call()); 404 405 #define JRT_BLOCK_END } 406 #define JRT_END } 407 #define PROF_END } 408 409 // Definitions for JNI 410 // 411 // As the JNIEnv can be passed from external native code we validate 412 // it in debug builds, primarily for our own testing. In general JNI 413 // does not attempt to detect programming errors and a bad JNIEnv may 414 // not even be readable. 415 416 #define JNI_ENTRY(result_type, header) \ 417 JNI_ENTRY_NO_PRESERVE(result_type, header) \ 418 WeakPreserveExceptionMark __wem(thread); 419 420 #define JNI_ENTRY_NO_PRESERVE(result_type, header) \ 421 extern "C" { \ 422 result_type JNICALL header { \ 423 JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ 424 assert(thread == Thread::current(), "JNIEnv is only valid in same thread"); \ 425 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ 426 ThreadInVMfromNative __tiv(thread); \ 427 debug_only(VMNativeEntryWrapper __vew;) \ 428 VM_ENTRY_BASE(result_type, header, thread) 429 430 431 #define JNI_LEAF(result_type, header) \ 432 extern "C" { \ 433 result_type JNICALL header { \ 434 JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ 435 assert(thread == Thread::current(), "JNIEnv is only valid in same thread"); \ 436 VM_LEAF_BASE(result_type, header) 437 438 439 // Close the routine and the extern "C" 440 #define JNI_END } } 441 442 443 444 // Definitions for JVM 445 446 #define JVM_ENTRY(result_type, header) \ 447 extern "C" { \ 448 result_type JNICALL header { \ 449 JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ 450 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ 451 ThreadInVMfromNative __tiv(thread); \ 452 debug_only(VMNativeEntryWrapper __vew;) \ 453 VM_ENTRY_BASE(result_type, header, thread) 454 455 456 #define JVM_ENTRY_NO_ENV(result_type, header) \ 457 extern "C" { \ 458 result_type JNICALL header { \ 459 JavaThread* thread = JavaThread::current(); \ 460 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ 461 ThreadInVMfromNative __tiv(thread); \ 462 debug_only(VMNativeEntryWrapper __vew;) \ 463 VM_ENTRY_BASE(result_type, header, thread) 464 465 466 #define JVM_LEAF(result_type, header) \ 467 extern "C" { \ 468 result_type JNICALL header { \ 469 VM_Exit::block_if_vm_exited(); \ 470 VM_LEAF_BASE(result_type, header) 471 472 473 #define JVM_ENTRY_PROF(result_type, name, header) \ 474 PerfTickCounters* _perf_##name##_timer = nullptr; \ 475 PerfCounter* _perf_##name##_count = nullptr; \ 476 extern "C" { \ 477 result_type JNICALL header { \ 478 JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ 479 PerfTraceTimedEvent perf_##name(_perf_##name##_timer, _perf_##name##_count, thread->profile_vm_calls()); \ 480 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ 481 ThreadInVMfromNative __tiv(thread); \ 482 debug_only(VMNativeEntryWrapper __vew;) \ 483 VM_ENTRY_BASE(result_type, header, thread) 484 485 486 #define JVM_ENTRY_NO_ENV_PROF(result_type, name, header) \ 487 PerfTickCounters* _perf_##name##_timer = nullptr; \ 488 PerfCounter* _perf_##name##_count = nullptr; \ 489 extern "C" { \ 490 result_type JNICALL header { \ 491 JavaThread* thread = JavaThread::current(); \ 492 PerfTraceTimedEvent perf_##name(_perf_##name##_timer, _perf_##name##_count, thread->profile_vm_calls()); \ 493 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ 494 ThreadInVMfromNative __tiv(thread); \ 495 debug_only(VMNativeEntryWrapper __vew;) \ 496 VM_ENTRY_BASE(result_type, header, thread) 497 498 499 #define JVM_LEAF_PROF(result_type, name, header) \ 500 PerfTickCounters* _perf_##name##_timer = nullptr; \ 501 PerfCounter* _perf_##name##_count = nullptr; \ 502 extern "C" { \ 503 result_type JNICALL header { \ 504 PerfTraceTimedEvent perf_##name(_perf_##name##_timer, _perf_##name##_count, \ 505 ProfileVMCalls && Thread::current()->profile_vm_calls()); \ 506 VM_Exit::block_if_vm_exited(); \ 507 VM_LEAF_BASE(result_type, header) 508 509 #define JVM_END } } 510 511 #endif // SHARE_RUNTIME_INTERFACESUPPORT_INLINE_HPP