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