1 | /* |
2 | * Copyright (c) 2012, 2019, 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 | #ifndef SHARE_JVMCI_JVMCIRUNTIME_HPP |
25 | #define SHARE_JVMCI_JVMCIRUNTIME_HPP |
26 | |
27 | #include "code/nmethod.hpp" |
28 | #include "jvmci/jvmci.hpp" |
29 | #include "jvmci/jvmciExceptions.hpp" |
30 | #include "jvmci/jvmciObject.hpp" |
31 | |
32 | class JVMCIEnv; |
33 | class JVMCICompiler; |
34 | class JVMCICompileState; |
35 | |
36 | // Encapsulates the JVMCI metadata for an nmethod. |
37 | // JVMCINMethodData objects are inlined into nmethods |
38 | // at nmethod::_jvmci_data_offset. |
39 | class JVMCINMethodData { |
40 | // Index for the HotSpotNmethod mirror in the nmethod's oops table. |
41 | // This is -1 if there is no mirror in the oops table. |
42 | int _nmethod_mirror_index; |
43 | |
44 | // Is HotSpotNmethod.name non-null? If so, the value is |
45 | // embedded in the end of this object. |
46 | bool _has_name; |
47 | |
48 | // Address of the failed speculations list to which a speculation |
49 | // is appended when it causes a deoptimization. |
50 | FailedSpeculation** _failed_speculations; |
51 | |
52 | public: |
53 | // Computes the size of a JVMCINMethodData object |
54 | static int compute_size(const char* nmethod_mirror_name) { |
55 | int size = sizeof(JVMCINMethodData); |
56 | if (nmethod_mirror_name != NULL) { |
57 | size += (int) strlen(nmethod_mirror_name) + 1; |
58 | } |
59 | return size; |
60 | } |
61 | |
62 | void initialize(int nmethod_mirror_index, |
63 | const char* name, |
64 | FailedSpeculation** failed_speculations); |
65 | |
66 | // Adds `speculation` to the failed speculations list. |
67 | void add_failed_speculation(nmethod* nm, jlong speculation); |
68 | |
69 | // Gets the JVMCI name of the nmethod (which may be NULL). |
70 | const char* name() { return _has_name ? (char*)(((address) this) + sizeof(JVMCINMethodData)) : NULL; } |
71 | |
72 | // Clears the HotSpotNmethod.address field in the mirror. If nm |
73 | // is dead, the HotSpotNmethod.entryPoint field is also cleared. |
74 | void invalidate_nmethod_mirror(nmethod* nm); |
75 | |
76 | // Gets the mirror from nm's oops table. |
77 | oop get_nmethod_mirror(nmethod* nm, bool phantom_ref); |
78 | |
79 | // Sets the mirror in nm's oops table. |
80 | void set_nmethod_mirror(nmethod* nm, oop mirror); |
81 | |
82 | // Clears the mirror in nm's oops table. |
83 | void clear_nmethod_mirror(nmethod* nm); |
84 | }; |
85 | |
86 | // A top level class that represents an initialized JVMCI runtime. |
87 | // There is one instance of this class per HotSpotJVMCIRuntime object. |
88 | class JVMCIRuntime: public CHeapObj<mtJVMCI> { |
89 | public: |
90 | // Constants describing whether JVMCI wants to be able to adjust the compilation |
91 | // level selected for a method by the VM compilation policy and if so, based on |
92 | // what information about the method being schedule for compilation. |
93 | enum CompLevelAdjustment { |
94 | none = 0, // no adjustment |
95 | by_holder = 1, // adjust based on declaring class of method |
96 | by_full_signature = 2 // adjust based on declaring class, name and signature of method |
97 | }; |
98 | |
99 | private: |
100 | volatile bool _being_initialized; |
101 | volatile bool _initialized; |
102 | |
103 | JVMCIObject _HotSpotJVMCIRuntime_instance; |
104 | |
105 | bool _shutdown_called; |
106 | |
107 | JVMCIObject create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS); |
108 | |
109 | // Implementation methods for loading and constant pool access. |
110 | static Klass* get_klass_by_name_impl(Klass*& accessing_klass, |
111 | const constantPoolHandle& cpool, |
112 | Symbol* klass_name, |
113 | bool require_local); |
114 | static Klass* get_klass_by_index_impl(const constantPoolHandle& cpool, |
115 | int klass_index, |
116 | bool& is_accessible, |
117 | Klass* loading_klass); |
118 | static void get_field_by_index_impl(InstanceKlass* loading_klass, fieldDescriptor& fd, |
119 | int field_index); |
120 | static methodHandle get_method_by_index_impl(const constantPoolHandle& cpool, |
121 | int method_index, Bytecodes::Code bc, |
122 | InstanceKlass* loading_klass); |
123 | |
124 | // Helper methods |
125 | static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass); |
126 | static methodHandle lookup_method(InstanceKlass* accessor, |
127 | Klass* holder, |
128 | Symbol* name, |
129 | Symbol* sig, |
130 | Bytecodes::Code bc, |
131 | constantTag tag); |
132 | |
133 | public: |
134 | JVMCIRuntime() { |
135 | _initialized = false; |
136 | _being_initialized = false; |
137 | _shutdown_called = false; |
138 | } |
139 | |
140 | /** |
141 | * Compute offsets and construct any state required before executing JVMCI code. |
142 | */ |
143 | void initialize(JVMCIEnv* jvmciEnv); |
144 | |
145 | /** |
146 | * Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary |
147 | */ |
148 | JVMCIObject get_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
149 | |
150 | bool is_HotSpotJVMCIRuntime_initialized() { |
151 | return _HotSpotJVMCIRuntime_instance.is_non_null(); |
152 | } |
153 | |
154 | /** |
155 | * Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime() |
156 | */ |
157 | void initialize_JVMCI(JVMCI_TRAPS); |
158 | |
159 | /** |
160 | * Explicitly initialize HotSpotJVMCIRuntime itself |
161 | */ |
162 | void initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
163 | |
164 | void call_getCompiler(TRAPS); |
165 | |
166 | void shutdown(); |
167 | |
168 | bool shutdown_called() { |
169 | return _shutdown_called; |
170 | } |
171 | |
172 | void bootstrap_finished(TRAPS); |
173 | |
174 | // Look up a klass by name from a particular class loader (the accessor's). |
175 | // If require_local, result must be defined in that class loader, or NULL. |
176 | // If !require_local, a result from remote class loader may be reported, |
177 | // if sufficient class loader constraints exist such that initiating |
178 | // a class loading request from the given loader is bound to return |
179 | // the class defined in the remote loader (or throw an error). |
180 | // |
181 | // Return an unloaded klass if !require_local and no class at all is found. |
182 | // |
183 | // The CI treats a klass as loaded if it is consistently defined in |
184 | // another loader, even if it hasn't yet been loaded in all loaders |
185 | // that could potentially see it via delegation. |
186 | static Klass* get_klass_by_name(Klass* accessing_klass, |
187 | Symbol* klass_name, |
188 | bool require_local); |
189 | |
190 | // Constant pool access. |
191 | static Klass* get_klass_by_index(const constantPoolHandle& cpool, |
192 | int klass_index, |
193 | bool& is_accessible, |
194 | Klass* loading_klass); |
195 | static void get_field_by_index(InstanceKlass* loading_klass, fieldDescriptor& fd, |
196 | int field_index); |
197 | static methodHandle get_method_by_index(const constantPoolHandle& cpool, |
198 | int method_index, Bytecodes::Code bc, |
199 | InstanceKlass* loading_klass); |
200 | |
201 | // converts the Klass* representing the holder of a method into a |
202 | // InstanceKlass*. This is needed since the holder of a method in |
203 | // the bytecodes could be an array type. Basically this converts |
204 | // array types into java/lang/Object and other types stay as they are. |
205 | static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass); |
206 | |
207 | // Helper routine for determining the validity of a compilation |
208 | // with respect to concurrent class loading. |
209 | static JVMCI::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, JVMCICompileState* task, char** failure_detail); |
210 | |
211 | // Compiles `target` with the JVMCI compiler. |
212 | void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci); |
213 | |
214 | // Register the result of a compilation. |
215 | JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV, |
216 | const methodHandle& target, |
217 | nmethod*& nm, |
218 | int entry_bci, |
219 | CodeOffsets* offsets, |
220 | int orig_pc_offset, |
221 | CodeBuffer* code_buffer, |
222 | int frame_words, |
223 | OopMapSet* oop_map_set, |
224 | ExceptionHandlerTable* handler_table, |
225 | ImplicitExceptionTable* implicit_exception_table, |
226 | AbstractCompiler* compiler, |
227 | DebugInformationRecorder* debug_info, |
228 | Dependencies* dependencies, |
229 | int compile_id, |
230 | bool has_unsafe_access, |
231 | bool has_wide_vector, |
232 | JVMCIObject compiled_code, |
233 | JVMCIObject nmethod_mirror, |
234 | FailedSpeculation** failed_speculations, |
235 | char* speculations, |
236 | int speculations_len); |
237 | |
238 | /** |
239 | * Exits the VM due to an unexpected exception. |
240 | */ |
241 | static void exit_on_pending_exception(JVMCIEnv* JVMCIENV, const char* message); |
242 | |
243 | static void describe_pending_hotspot_exception(JavaThread* THREAD, bool clear); |
244 | |
245 | #define CHECK_EXIT THREAD); \ |
246 | if (HAS_PENDING_EXCEPTION) { \ |
247 | char buf[256]; \ |
248 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
249 | JVMCIRuntime::exit_on_pending_exception(NULL, buf); \ |
250 | return; \ |
251 | } \ |
252 | (void)(0 |
253 | |
254 | #define CHECK_EXIT_(v) THREAD); \ |
255 | if (HAS_PENDING_EXCEPTION) { \ |
256 | char buf[256]; \ |
257 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
258 | JVMCIRuntime::exit_on_pending_exception(NULL, buf); \ |
259 | return v; \ |
260 | } \ |
261 | (void)(0 |
262 | |
263 | #define JVMCI_CHECK_EXIT JVMCIENV); \ |
264 | if (JVMCIENV->has_pending_exception()) { \ |
265 | char buf[256]; \ |
266 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
267 | JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \ |
268 | return; \ |
269 | } \ |
270 | (void)(0 |
271 | |
272 | #define JVMCI_CHECK_EXIT_(result) JVMCIENV); \ |
273 | if (JVMCIENV->has_pending_exception()) { \ |
274 | char buf[256]; \ |
275 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
276 | JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \ |
277 | return result; \ |
278 | } \ |
279 | (void)(0 |
280 | |
281 | static BasicType kindToBasicType(const Handle& kind, TRAPS); |
282 | |
283 | static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail); |
284 | static void new_array_common(JavaThread* thread, Klass* klass, jint length, bool null_on_fail); |
285 | static void new_multi_array_common(JavaThread* thread, Klass* klass, int rank, jint* dims, bool null_on_fail); |
286 | static void dynamic_new_array_common(JavaThread* thread, oopDesc* element_mirror, jint length, bool null_on_fail); |
287 | static void dynamic_new_instance_common(JavaThread* thread, oopDesc* type_mirror, bool null_on_fail); |
288 | |
289 | // The following routines are called from compiled JVMCI code |
290 | |
291 | // When allocation fails, these stubs: |
292 | // 1. Exercise -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError handling and also |
293 | // post a JVMTI_EVENT_RESOURCE_EXHAUSTED event if the failure is an OutOfMemroyError |
294 | // 2. Return NULL with a pending exception. |
295 | // Compiled code must ensure these stubs are not called twice for the same allocation |
296 | // site due to the non-repeatable side effects in the case of OOME. |
297 | static void new_instance(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, false); } |
298 | static void new_array(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, false); } |
299 | static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, false); } |
300 | static void dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, false); } |
301 | static void dynamic_new_instance(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, false); } |
302 | |
303 | // When allocation fails, these stubs return NULL and have no pending exception. Compiled code |
304 | // can use these stubs if a failed allocation will be retried (e.g., by deoptimizing and |
305 | // re-executing in the interpreter). |
306 | static void new_instance_or_null(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, true); } |
307 | static void new_array_or_null(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, true); } |
308 | static void new_multi_array_or_null(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, true); } |
309 | static void dynamic_new_array_or_null(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, true); } |
310 | static void dynamic_new_instance_or_null(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, true); } |
311 | |
312 | static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupted); |
313 | static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3); |
314 | static jint identity_hash_code(JavaThread* thread, oopDesc* obj); |
315 | static address exception_handler_for_pc(JavaThread* thread); |
316 | static void monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock); |
317 | static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock); |
318 | static jboolean object_notify(JavaThread* thread, oopDesc* obj); |
319 | static jboolean object_notifyAll(JavaThread* thread, oopDesc* obj); |
320 | static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value); |
321 | static oopDesc* load_and_clear_exception(JavaThread* thread); |
322 | static void log_printf(JavaThread* thread, const char* format, jlong v1, jlong v2, jlong v3); |
323 | static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline); |
324 | // Print the passed in object, optionally followed by a newline. If |
325 | // as_string is true and the object is a java.lang.String then it |
326 | // printed as a string, otherwise the type of the object is printed |
327 | // followed by its address. |
328 | static void log_object(JavaThread* thread, oopDesc* object, bool as_string, bool newline); |
329 | #if INCLUDE_G1GC |
330 | static void write_barrier_pre(JavaThread* thread, oopDesc* obj); |
331 | static void write_barrier_post(JavaThread* thread, void* card); |
332 | #endif |
333 | static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child); |
334 | |
335 | // used to throw exceptions from compiled JVMCI code |
336 | static void throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message); |
337 | // helper methods to throw exception with complex messages |
338 | static void throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass); |
339 | static void throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass); |
340 | |
341 | // Test only function |
342 | static jint test_deoptimize_call_int(JavaThread* thread, int value); |
343 | }; |
344 | |
345 | // Tracing macros. |
346 | |
347 | #define IF_TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1)) ; else |
348 | #define IF_TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2)) ; else |
349 | #define IF_TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3)) ; else |
350 | #define IF_TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4)) ; else |
351 | #define IF_TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5)) ; else |
352 | |
353 | #define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print(PTR_FORMAT " JVMCITrace-1: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
354 | #define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(PTR_FORMAT " JVMCITrace-2: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
355 | #define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(PTR_FORMAT " JVMCITrace-3: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
356 | #define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(PTR_FORMAT " JVMCITrace-4: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
357 | #define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(PTR_FORMAT " JVMCITrace-5: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
358 | |
359 | #endif // SHARE_JVMCI_JVMCIRUNTIME_HPP |
360 | |