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