Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-aarch32-jdk8u
Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/runtime/interfaceSupport.hpp
48773 views
1
/*
2
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
26
#define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
27
28
#include "memory/gcLocker.hpp"
29
#include "runtime/handles.inline.hpp"
30
#include "runtime/mutexLocker.hpp"
31
#include "runtime/orderAccess.hpp"
32
#include "runtime/os.hpp"
33
#include "runtime/safepoint.hpp"
34
#include "runtime/thread.inline.hpp"
35
#include "runtime/vmThread.hpp"
36
#include "utilities/globalDefinitions.hpp"
37
#include "utilities/preserveException.hpp"
38
#include "utilities/top.hpp"
39
40
// Wrapper for all entry points to the virtual machine.
41
// The HandleMarkCleaner is a faster version of HandleMark.
42
// It relies on the fact that there is a HandleMark further
43
// down the stack (in JavaCalls::call_helper), and just resets
44
// to the saved values in that HandleMark.
45
46
class HandleMarkCleaner: public StackObj {
47
private:
48
Thread* _thread;
49
public:
50
HandleMarkCleaner(Thread* thread) {
51
_thread = thread;
52
_thread->last_handle_mark()->push();
53
}
54
~HandleMarkCleaner() {
55
_thread->last_handle_mark()->pop_and_restore();
56
}
57
58
private:
59
inline void* operator new(size_t size, void* ptr) throw() {
60
return ptr;
61
}
62
};
63
64
// InterfaceSupport provides functionality used by the VM_LEAF_BASE and
65
// VM_ENTRY_BASE macros. These macros are used to guard entry points into
66
// the VM and perform checks upon leave of the VM.
67
68
69
class InterfaceSupport: AllStatic {
70
# ifdef ASSERT
71
public:
72
static long _scavenge_alot_counter;
73
static long _fullgc_alot_counter;
74
static long _number_of_calls;
75
static long _fullgc_alot_invocation;
76
77
// tracing
78
static void trace(const char* result_type, const char* header);
79
80
// Helper methods used to implement +ScavengeALot and +FullGCALot
81
static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }
82
static void gc_alot();
83
84
static void walk_stack_from(vframe* start_vf);
85
static void walk_stack();
86
87
# ifdef ENABLE_ZAP_DEAD_LOCALS
88
static void zap_dead_locals_old();
89
# endif
90
91
static void zombieAll();
92
static void unlinkSymbols();
93
static void deoptimizeAll();
94
static void stress_derived_pointers();
95
static void verify_stack();
96
static void verify_last_frame();
97
# endif
98
99
public:
100
// OS dependent stuff
101
#ifdef TARGET_OS_FAMILY_linux
102
# include "interfaceSupport_linux.hpp"
103
#endif
104
#ifdef TARGET_OS_FAMILY_solaris
105
# include "interfaceSupport_solaris.hpp"
106
#endif
107
#ifdef TARGET_OS_FAMILY_windows
108
# include "interfaceSupport_windows.hpp"
109
#endif
110
#ifdef TARGET_OS_FAMILY_aix
111
# include "interfaceSupport_aix.hpp"
112
#endif
113
#ifdef TARGET_OS_FAMILY_bsd
114
# include "interfaceSupport_bsd.hpp"
115
#endif
116
117
};
118
119
120
// Basic class for all thread transition classes.
121
122
class ThreadStateTransition : public StackObj {
123
protected:
124
JavaThread* _thread;
125
public:
126
ThreadStateTransition(JavaThread *thread) {
127
_thread = thread;
128
assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
129
}
130
131
// Change threadstate in a manner, so safepoint can detect changes.
132
// Time-critical: called on exit from every runtime routine
133
static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
134
assert(from != _thread_in_Java, "use transition_from_java");
135
assert(from != _thread_in_native, "use transition_from_native");
136
assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
137
assert(thread->thread_state() == from, "coming from wrong thread state");
138
// Change to transition state (assumes total store ordering! -Urs)
139
thread->set_thread_state((JavaThreadState)(from + 1));
140
141
// Make sure new state is seen by VM thread
142
if (os::is_MP()) {
143
if (UseMembar) {
144
// Force a fence between the write above and read below
145
OrderAccess::fence();
146
} else {
147
// store to serialize page so VM thread can do pseudo remote membar
148
os::write_memory_serialize_page(thread);
149
}
150
}
151
152
if (SafepointSynchronize::do_call_back()) {
153
SafepointSynchronize::block(thread);
154
}
155
thread->set_thread_state(to);
156
157
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
158
}
159
160
// transition_and_fence must be used on any thread state transition
161
// where there might not be a Java call stub on the stack, in
162
// particular on Windows where the Structured Exception Handler is
163
// set up in the call stub. os::write_memory_serialize_page() can
164
// fault and we can't recover from it on Windows without a SEH in
165
// place.
166
static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
167
assert(thread->thread_state() == from, "coming from wrong thread state");
168
assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
169
// Change to transition state (assumes total store ordering! -Urs)
170
thread->set_thread_state((JavaThreadState)(from + 1));
171
172
// Make sure new state is seen by VM thread
173
if (os::is_MP()) {
174
if (UseMembar) {
175
// Force a fence between the write above and read below
176
OrderAccess::fence();
177
} else {
178
// Must use this rather than serialization page in particular on Windows
179
InterfaceSupport::serialize_memory(thread);
180
}
181
}
182
183
if (SafepointSynchronize::do_call_back()) {
184
SafepointSynchronize::block(thread);
185
}
186
thread->set_thread_state(to);
187
188
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
189
}
190
191
// Same as above, but assumes from = _thread_in_Java. This is simpler, since we
192
// never block on entry to the VM. This will break the code, since e.g. preserve arguments
193
// have not been setup.
194
static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
195
assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
196
thread->set_thread_state(to);
197
}
198
199
static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
200
assert((to & 1) == 0, "odd numbers are transitions states");
201
assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
202
// Change to transition state (assumes total store ordering! -Urs)
203
thread->set_thread_state(_thread_in_native_trans);
204
205
// Make sure new state is seen by GC thread
206
if (os::is_MP()) {
207
if (UseMembar) {
208
// Force a fence between the write above and read below
209
OrderAccess::fence();
210
} else {
211
// Must use this rather than serialization page in particular on Windows
212
InterfaceSupport::serialize_memory(thread);
213
}
214
}
215
216
// We never install asynchronous exceptions when coming (back) in
217
// to the runtime from native code because the runtime is not set
218
// up to handle exceptions floating around at arbitrary points.
219
if (SafepointSynchronize::do_call_back() || thread->is_suspend_after_native()) {
220
JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
221
222
// Clear unhandled oops anywhere where we could block, even if we don't.
223
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
224
}
225
226
thread->set_thread_state(to);
227
}
228
protected:
229
void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }
230
void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }
231
void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }
232
void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
233
};
234
235
236
class ThreadInVMfromJava : public ThreadStateTransition {
237
public:
238
ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
239
trans_from_java(_thread_in_vm);
240
}
241
~ThreadInVMfromJava() {
242
trans(_thread_in_vm, _thread_in_Java);
243
// Check for pending. async. exceptions or suspends.
244
if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
245
}
246
};
247
248
249
class ThreadInVMfromUnknown {
250
private:
251
JavaThread* _thread;
252
public:
253
ThreadInVMfromUnknown() : _thread(NULL) {
254
Thread* t = Thread::current();
255
if (t->is_Java_thread()) {
256
JavaThread* t2 = (JavaThread*) t;
257
if (t2->thread_state() == _thread_in_native) {
258
_thread = t2;
259
ThreadStateTransition::transition_from_native(t2, _thread_in_vm);
260
// Used to have a HandleMarkCleaner but that is dangerous as
261
// it could free a handle in our (indirect, nested) caller.
262
// We expect any handles will be short lived and figure we
263
// don't need an actual HandleMark.
264
}
265
}
266
}
267
~ThreadInVMfromUnknown() {
268
if (_thread) {
269
ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);
270
}
271
}
272
};
273
274
275
class ThreadInVMfromNative : public ThreadStateTransition {
276
public:
277
ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {
278
trans_from_native(_thread_in_vm);
279
}
280
~ThreadInVMfromNative() {
281
trans_and_fence(_thread_in_vm, _thread_in_native);
282
}
283
};
284
285
286
class ThreadToNativeFromVM : public ThreadStateTransition {
287
public:
288
ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) {
289
// We are leaving the VM at this point and going directly to native code.
290
// Block, if we are in the middle of a safepoint synchronization.
291
assert(!thread->owns_locks(), "must release all locks when leaving VM");
292
thread->frame_anchor()->make_walkable(thread);
293
trans_and_fence(_thread_in_vm, _thread_in_native);
294
// Check for pending. async. exceptions or suspends.
295
if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);
296
}
297
298
~ThreadToNativeFromVM() {
299
trans_from_native(_thread_in_vm);
300
// We don't need to clear_walkable because it will happen automagically when we return to java
301
}
302
};
303
304
305
class ThreadBlockInVM : public ThreadStateTransition {
306
public:
307
ThreadBlockInVM(JavaThread *thread)
308
: ThreadStateTransition(thread) {
309
// Once we are blocked vm expects stack to be walkable
310
thread->frame_anchor()->make_walkable(thread);
311
trans_and_fence(_thread_in_vm, _thread_blocked);
312
}
313
~ThreadBlockInVM() {
314
trans_and_fence(_thread_blocked, _thread_in_vm);
315
// We don't need to clear_walkable because it will happen automagically when we return to java
316
}
317
};
318
319
320
// This special transition class is only used to prevent asynchronous exceptions
321
// from being installed on vm exit in situations where we can't tolerate them.
322
// See bugs: 4324348, 4854693, 4998314, 5040492, 5050705.
323
class ThreadInVMfromJavaNoAsyncException : public ThreadStateTransition {
324
public:
325
ThreadInVMfromJavaNoAsyncException(JavaThread* thread) : ThreadStateTransition(thread) {
326
trans_from_java(_thread_in_vm);
327
}
328
~ThreadInVMfromJavaNoAsyncException() {
329
trans(_thread_in_vm, _thread_in_Java);
330
// NOTE: We do not check for pending. async. exceptions.
331
// If we did and moved the pending async exception over into the
332
// pending exception field, we would need to deopt (currently C2
333
// only). However, to do so would require that we transition back
334
// to the _thread_in_vm state. Instead we postpone the handling of
335
// the async exception.
336
337
// Check for pending. suspends only.
338
if (_thread->has_special_runtime_exit_condition())
339
_thread->handle_special_runtime_exit_condition(false);
340
}
341
};
342
343
// Debug class instantiated in JRT_ENTRY and ITR_ENTRY macro.
344
// Can be used to verify properties on enter/exit of the VM.
345
346
#ifdef ASSERT
347
class VMEntryWrapper {
348
public:
349
VMEntryWrapper() {
350
if (VerifyLastFrame) {
351
InterfaceSupport::verify_last_frame();
352
}
353
}
354
355
~VMEntryWrapper() {
356
InterfaceSupport::check_gc_alot();
357
if (WalkStackALot) {
358
InterfaceSupport::walk_stack();
359
}
360
#ifdef ENABLE_ZAP_DEAD_LOCALS
361
if (ZapDeadLocalsOld) {
362
InterfaceSupport::zap_dead_locals_old();
363
}
364
#endif
365
#ifdef COMPILER2
366
// This option is not used by Compiler 1
367
if (StressDerivedPointers) {
368
InterfaceSupport::stress_derived_pointers();
369
}
370
#endif
371
if (DeoptimizeALot || DeoptimizeRandom) {
372
InterfaceSupport::deoptimizeAll();
373
}
374
if (ZombieALot) {
375
InterfaceSupport::zombieAll();
376
}
377
if (UnlinkSymbolsALot) {
378
InterfaceSupport::unlinkSymbols();
379
}
380
// do verification AFTER potential deoptimization
381
if (VerifyStack) {
382
InterfaceSupport::verify_stack();
383
}
384
385
}
386
};
387
388
389
class VMNativeEntryWrapper {
390
public:
391
VMNativeEntryWrapper() {
392
if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
393
}
394
395
~VMNativeEntryWrapper() {
396
if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
397
}
398
};
399
400
#endif
401
402
403
// VM-internal runtime interface support
404
405
#ifdef ASSERT
406
407
class RuntimeHistogramElement : public HistogramElement {
408
public:
409
RuntimeHistogramElement(const char* name);
410
};
411
412
#define TRACE_CALL(result_type, header) \
413
InterfaceSupport::_number_of_calls++; \
414
if (TraceRuntimeCalls) \
415
InterfaceSupport::trace(#result_type, #header); \
416
if (CountRuntimeCalls) { \
417
static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \
418
if (e != NULL) e->increment_count(); \
419
}
420
#else
421
#define TRACE_CALL(result_type, header) \
422
/* do nothing */
423
#endif
424
425
426
// LEAF routines do not lock, GC or throw exceptions
427
428
#define VM_LEAF_BASE(result_type, header) \
429
TRACE_CALL(result_type, header) \
430
debug_only(NoHandleMark __hm;) \
431
os::verify_stack_alignment(); \
432
/* begin of body */
433
434
#define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \
435
TRACE_CALL(result_type, header) \
436
debug_only(ResetNoHandleMark __rnhm;) \
437
HandleMarkCleaner __hm(thread); \
438
Thread* THREAD = thread; \
439
os::verify_stack_alignment(); \
440
/* begin of body */
441
442
443
// ENTRY routines may lock, GC and throw exceptions
444
445
#define VM_ENTRY_BASE(result_type, header, thread) \
446
TRACE_CALL(result_type, header) \
447
HandleMarkCleaner __hm(thread); \
448
Thread* THREAD = thread; \
449
os::verify_stack_alignment(); \
450
/* begin of body */
451
452
453
// QUICK_ENTRY routines behave like ENTRY but without a handle mark
454
455
#define VM_QUICK_ENTRY_BASE(result_type, header, thread) \
456
TRACE_CALL(result_type, header) \
457
debug_only(NoHandleMark __hm;) \
458
Thread* THREAD = thread; \
459
os::verify_stack_alignment(); \
460
/* begin of body */
461
462
463
// Definitions for IRT (Interpreter Runtime)
464
// (thread is an argument passed in to all these routines)
465
466
#define IRT_ENTRY(result_type, header) \
467
result_type header { \
468
ThreadInVMfromJava __tiv(thread); \
469
VM_ENTRY_BASE(result_type, header, thread) \
470
debug_only(VMEntryWrapper __vew;)
471
472
473
#define IRT_LEAF(result_type, header) \
474
result_type header { \
475
VM_LEAF_BASE(result_type, header) \
476
debug_only(No_Safepoint_Verifier __nspv(true);)
477
478
479
#define IRT_ENTRY_NO_ASYNC(result_type, header) \
480
result_type header { \
481
ThreadInVMfromJavaNoAsyncException __tiv(thread); \
482
VM_ENTRY_BASE(result_type, header, thread) \
483
debug_only(VMEntryWrapper __vew;)
484
485
#define IRT_END }
486
487
488
// Definitions for JRT (Java (Compiler/Shared) Runtime)
489
490
#define JRT_ENTRY(result_type, header) \
491
result_type header { \
492
ThreadInVMfromJava __tiv(thread); \
493
VM_ENTRY_BASE(result_type, header, thread) \
494
debug_only(VMEntryWrapper __vew;)
495
496
497
#define JRT_LEAF(result_type, header) \
498
result_type header { \
499
VM_LEAF_BASE(result_type, header) \
500
debug_only(JRT_Leaf_Verifier __jlv;)
501
502
503
#define JRT_ENTRY_NO_ASYNC(result_type, header) \
504
result_type header { \
505
ThreadInVMfromJavaNoAsyncException __tiv(thread); \
506
VM_ENTRY_BASE(result_type, header, thread) \
507
debug_only(VMEntryWrapper __vew;)
508
509
// Same as JRT Entry but allows for return value after the safepoint
510
// to get back into Java from the VM
511
#define JRT_BLOCK_ENTRY(result_type, header) \
512
result_type header { \
513
TRACE_CALL(result_type, header) \
514
HandleMarkCleaner __hm(thread);
515
516
#define JRT_BLOCK \
517
{ \
518
ThreadInVMfromJava __tiv(thread); \
519
Thread* THREAD = thread; \
520
debug_only(VMEntryWrapper __vew;)
521
522
#define JRT_BLOCK_END }
523
524
#define JRT_END }
525
526
// Definitions for JNI
527
528
#define JNI_ENTRY(result_type, header) \
529
JNI_ENTRY_NO_PRESERVE(result_type, header) \
530
WeakPreserveExceptionMark __wem(thread);
531
532
#define JNI_ENTRY_NO_PRESERVE(result_type, header) \
533
extern "C" { \
534
result_type JNICALL header { \
535
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
536
assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
537
ThreadInVMfromNative __tiv(thread); \
538
debug_only(VMNativeEntryWrapper __vew;) \
539
VM_ENTRY_BASE(result_type, header, thread)
540
541
542
// Ensure that the VMNativeEntryWrapper constructor, which can cause
543
// a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE).
544
#define JNI_QUICK_ENTRY(result_type, header) \
545
extern "C" { \
546
result_type JNICALL header { \
547
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
548
assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
549
ThreadInVMfromNative __tiv(thread); \
550
debug_only(VMNativeEntryWrapper __vew;) \
551
VM_QUICK_ENTRY_BASE(result_type, header, thread)
552
553
554
#define JNI_LEAF(result_type, header) \
555
extern "C" { \
556
result_type JNICALL header { \
557
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
558
assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
559
VM_LEAF_BASE(result_type, header)
560
561
562
// Close the routine and the extern "C"
563
#define JNI_END } }
564
565
566
567
// Definitions for JVM
568
569
#define JVM_ENTRY(result_type, header) \
570
extern "C" { \
571
result_type JNICALL header { \
572
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
573
ThreadInVMfromNative __tiv(thread); \
574
debug_only(VMNativeEntryWrapper __vew;) \
575
VM_ENTRY_BASE(result_type, header, thread)
576
577
578
#define JVM_ENTRY_NO_ENV(result_type, header) \
579
extern "C" { \
580
result_type JNICALL header { \
581
JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); \
582
ThreadInVMfromNative __tiv(thread); \
583
debug_only(VMNativeEntryWrapper __vew;) \
584
VM_ENTRY_BASE(result_type, header, thread)
585
586
587
#define JVM_QUICK_ENTRY(result_type, header) \
588
extern "C" { \
589
result_type JNICALL header { \
590
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
591
ThreadInVMfromNative __tiv(thread); \
592
debug_only(VMNativeEntryWrapper __vew;) \
593
VM_QUICK_ENTRY_BASE(result_type, header, thread)
594
595
596
#define JVM_LEAF(result_type, header) \
597
extern "C" { \
598
result_type JNICALL header { \
599
VM_Exit::block_if_vm_exited(); \
600
VM_LEAF_BASE(result_type, header)
601
602
603
#define JVM_ENTRY_FROM_LEAF(env, result_type, header) \
604
{ { \
605
JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
606
ThreadInVMfromNative __tiv(thread); \
607
debug_only(VMNativeEntryWrapper __vew;) \
608
VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)
609
610
611
#define JVM_END } }
612
613
#endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
614
615