- Notifications
You must be signed in to change notification settings - Fork 5.8k
/
Copy pathjvmci.hpp
237 lines (188 loc) · 8.84 KB
/
jvmci.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_JVMCI_JVMCI_HPP
#defineSHARE_JVMCI_JVMCI_HPP
#include"compiler/compiler_globals.hpp"
#include"compiler/compilerDefinitions.hpp"
#include"utilities/exceptions.hpp"
classBoolObjectClosure;
classCompilerThread;
classconstantPoolHandle;
classJavaThread;
classJVMCIEnv;
classJVMCIRuntime;
classMetadata;
classMetadataHandleBlock;
classOopClosure;
classOopStorage;
template <size_t>
classFormatStringEventLog;
typedef FormatStringEventLog<256> StringEventLog;
struct_jmetadata;
typedefstruct_jmetadata *jmetadata;
// A stack object that manages a scope in which the current thread, if
// it's a CompilerThread, can have its CompilerThread::_can_call_java
// field changed. This allows restricting libjvmci better in terms
// of when it can make Java calls. If a Java call on a CompilerThread
// reaches a clinit, there's a risk of dead-lock when async compilation
// is disabled (e.g. -Xbatch or -Xcomp) as the non-CompilerThread thread
// waiting for the blocking compilation may hold the clinit lock.
//
// This scope is primarily used to disable Java calls when libjvmci enters
// the VM via a C2V (i.e. CompilerToVM) native method.
classCompilerThreadCanCallJava : StackObj {
private:
CompilerThread* _current; // Only non-null if state of thread changed
public:
// If the current thread is a CompilerThread associated with
// a JVMCI compiler where CompilerThread::_can_call_java != new_state,
// then _can_call_java is set to `new_state`
// Returns nullptr if no change was made, otherwise the current CompilerThread
static CompilerThread* update(JavaThread* current, bool new_state);
CompilerThreadCanCallJava(JavaThread* current, bool new_state);
// Resets CompilerThread::_can_call_java of the current thread if the
// constructor changed it.
~CompilerThreadCanCallJava();
};
classJVMCI : publicAllStatic {
friendclassJVMCIRuntime;
friendclassJVMCIEnv;
private:
// List of libjvmci based JVMCIRuntimes.
// Should only be accessed under JVMCI_lock.
static JVMCIRuntime* _compiler_runtimes;
// Special libjvmci based JVMCIRuntime reserved for
// threads trying to attach when in JVMCI shutdown.
// This preserves the invariant that JVMCIRuntime::for_thread()
// never returns null.
static JVMCIRuntime* _shutdown_compiler_runtime;
// True when at least one JVMCIRuntime::initialize_HotSpotJVMCIRuntime()
// execution has completed successfully.
staticvolatilebool _is_initialized;
// True once boxing cache classes are guaranteed to be initialized.
staticbool _box_caches_initialized;
// Handle created when loading the JVMCI shared library with os::dll_load.
// Must hold JVMCI_lock when initializing.
staticvoid* _shared_library_handle;
// Argument to os::dll_load when loading JVMCI shared library
staticchar* _shared_library_path;
// Records whether JVMCI::shutdown has been called.
staticvolatilebool _in_shutdown;
// Access to the HotSpot heap based JVMCIRuntime
static JVMCIRuntime* _java_runtime;
// The file descriptor to which fatal_log() writes. Initialized on
// first call to fatal_log().
staticvolatileint _fatal_log_fd;
// The path of the file underlying _fatal_log_fd if it is a normal file.
staticconstchar* _fatal_log_filename;
// Thread id of the first thread reporting a libjvmci error.
staticvolatile intx _first_error_tid;
// JVMCI event log (shows up in hs_err crash logs).
static StringEventLog* _events;
static StringEventLog* _verbose_events;
enum {
max_EventLog_level = 4
};
// Gets the Thread* value for the current thread or null if it's not available.
static Thread* current_thread_or_null();
// Writes into `pathbuf` the path to the existing JVMCI shared library file.
// If the file cannot be found and `fail_is_fatal` is true, then
// a fatal error occurs.
// Returns whether the path to an existing file was written into `pathbuf`.
staticboolget_shared_library_path(char* pathbuf, size_t pathlen, bool fail_is_fatal);
public:
enum CodeInstallResult {
ok,
dependencies_failed,
cache_full,
nmethod_reclaimed,
code_too_large,
first_permanent_bailout = code_too_large
};
// Returns true iff JVMCIThreadsPerNativeLibraryRuntime == 0.
staticboolusing_singleton_shared_library_runtime() {
return JVMCIThreadsPerNativeLibraryRuntime == 0;
}
// Returns true iff there is a new shared library JavaVM per compilation.
staticboolone_shared_library_javavm_per_compilation() {
return JVMCIThreadsPerNativeLibraryRuntime == 1 && JVMCICompilerIdleDelay == 0;
}
// Determines if the JVMCI shared library exists. This does not
// take into account whether loading the library would succeed
// if it's not already loaded.
staticboolshared_library_exists();
// Gets the handle to the loaded JVMCI shared library, loading it
// first if not yet loaded and `load` is true. The path from
// which the library is loaded is returned in `path`.
staticvoid* get_shared_library(char*& path, bool load);
// Logs the fatal crash data in `buf` to the appropriate stream.
staticvoidfatal_log(constchar* buf, size_t count);
// Gets the name of the opened JVMCI shared library crash data file or null
// if this file has not been created.
staticconstchar* fatal_log_filename() { return _fatal_log_filename; }
staticvoiddo_unloading(bool unloading_occurred);
staticvoidmetadata_do(voidf(Metadata*));
staticvoidshutdown(JavaThread* thread);
// Returns whether JVMCI::shutdown has been called.
staticboolin_shutdown();
staticboolis_compiler_initialized();
/**
* Determines if the VM is sufficiently booted to initialize JVMCI.
*/
staticboolcan_initialize_JVMCI();
staticvoidinitialize_globals();
// Called to force initialization of the JVMCI compiler
// early in VM startup.
staticvoidinitialize_compiler(TRAPS);
// Ensures the boxing cache classes (e.g., java.lang.Integer.IntegerCache) are initialized.
staticvoidensure_box_caches_initialized(TRAPS);
// Increments a value indicating some JVMCI compilation activity
// happened on `thread` if it is a CompilerThread.
// Returns `thread`.
static JavaThread* compilation_tick(JavaThread* thread);
// Gets the single runtime for JVMCI on the Java heap. This is the only
// JVMCI runtime available when !UseJVMCINativeLibrary.
static JVMCIRuntime* java_runtime() { return _java_runtime; }
// Gets the JVMCI shared library runtime associated with `thread`.
// This must only be called when UseJVMCINativeLibrary is true.
// If `create` is true and there is no runtime currently associated with
// `thread`, this method creates one.
static JVMCIRuntime* compiler_runtime(JavaThread* thread, bool create=true);
// Appends an event to the JVMCI event log if JVMCIEventLogLevel >= `level`
staticvoidvlog(int level, constchar* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
// Traces an event to tty if JVMCITraceLevel >= `level`
staticvoidvtrace(int level, constchar* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
public:
// Log/trace a JVMCI event
staticvoidevent(int level, constchar* format, ...) ATTRIBUTE_PRINTF(2, 3);
staticvoidevent1(constchar* format, ...) ATTRIBUTE_PRINTF(1, 2);
staticvoidevent2(constchar* format, ...) ATTRIBUTE_PRINTF(1, 2);
staticvoidevent3(constchar* format, ...) ATTRIBUTE_PRINTF(1, 2);
staticvoidevent4(constchar* format, ...) ATTRIBUTE_PRINTF(1, 2);
};
// JVMCI event macros.
#defineJVMCI_event_1if (JVMCITraceLevel < 1 && JVMCIEventLogLevel < 1) ; else ::JVMCI::event1
#defineJVMCI_event_2if (JVMCITraceLevel < 2 && JVMCIEventLogLevel < 2) ; else ::JVMCI::event2
#defineJVMCI_event_3if (JVMCITraceLevel < 3 && JVMCIEventLogLevel < 3) ; else ::JVMCI::event3
#defineJVMCI_event_4if (JVMCITraceLevel < 4 && JVMCIEventLogLevel < 4) ; else ::JVMCI::event4
#endif // SHARE_JVMCI_JVMCI_HPP