1 /*
2 * Copyright (c) 2012, 2024, 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 "gc/shared/collectedHeap.hpp"
29 #include "jvm_io.h"
30 #include "jvmci/jvmci.hpp"
31 #include "jvmci/jvmciExceptions.hpp"
32 #include "jvmci/jvmciObject.hpp"
33 #include "utilities/linkedlist.hpp"
34 #if INCLUDE_G1GC
35 #include "gc/g1/g1CardTable.hpp"
36 #endif // INCLUDE_G1GC
37
38 #define JVMCI_NOT_ENABLED_ERROR_MESSAGE "JVMCI is not enabled. Must specify '-XX:+EnableJVMCI' or '--add-modules=jdk.internal.vm.ci' to the java launcher."
39
40 class JVMCIEnv;
41 class JVMCICompiler;
42 class JVMCICompileState;
43 class MetadataHandles;
44
45 // Encapsulates the JVMCI metadata for an nmethod. JVMCINMethodData objects are normally inlined
46 // into nmethods at nmethod::_jvmci_data_offset but during construction of the nmethod they are
47 // resource allocated so they can be passed into the nmethod constructor.
48 class JVMCINMethodData : public ResourceObj {
49 friend class JVMCIVMStructs;
50
51 // Is HotSpotNmethod.name non-null? If so, the value is
52 // embedded in the end of this object.
53 bool _has_name;
54
55 // Index for the HotSpotNmethod mirror in the nmethod's oops table.
56 // This is -1 if there is no mirror in the oops table.
57 int _nmethod_mirror_index;
58
59 // This is the offset of the patchable part of the nmethod entry barrier sequence. The meaning is
60 // somewhat platform dependent as the way patching is done varies by architecture.
61 int _nmethod_entry_patch_offset;
62
63 // Address of the failed speculations list to which a speculation
64 // is appended when it causes a deoptimization.
65 FailedSpeculation** _failed_speculations;
66
67 // A speculation id is a length (low 5 bits) and an index into
68 // a jbyte array (i.e. 31 bits for a positive Java int).
69 enum {
70 // Keep in sync with HotSpotSpeculationEncoding.
71 SPECULATION_LENGTH_BITS = 5,
72 SPECULATION_LENGTH_MASK = (1 << SPECULATION_LENGTH_BITS) - 1
73 };
74
75 // Allocate a temporary data object for use during installation
76 void initialize(int nmethod_mirror_index,
77 int nmethod_entry_patch_offset,
78 const char* nmethod_mirror_name,
79 FailedSpeculation** failed_speculations);
80
81 void* operator new(size_t size, const char* nmethod_mirror_name) {
82 assert(size == sizeof(JVMCINMethodData), "must agree");
83 size_t total_size = compute_size(nmethod_mirror_name);
84 return (address)resource_allocate_bytes(total_size);
85 }
86
87 public:
88 static JVMCINMethodData* create(int nmethod_mirror_index,
89 int nmethod_entry_patch_offset,
90 const char* nmethod_mirror_name,
91 FailedSpeculation** failed_speculations) {
92 JVMCINMethodData* result = new (nmethod_mirror_name) JVMCINMethodData();
93 result->initialize(nmethod_mirror_index,
94 nmethod_entry_patch_offset,
95 nmethod_mirror_name,
96 failed_speculations);
97 return result;
98 }
99
100 // Computes the size of a JVMCINMethodData object
101 static int compute_size(const char* nmethod_mirror_name) {
102 int size = sizeof(JVMCINMethodData);
103 if (nmethod_mirror_name != nullptr) {
104 size += (int) strlen(nmethod_mirror_name) + 1;
105 }
106 return size;
107 }
108
109 int size() {
110 return compute_size(name());
111 }
112
113 // Copy the contents of this object into data which is normally the storage allocated in the nmethod.
114 void copy(JVMCINMethodData* data);
115
116 // Adds `speculation` to the failed speculations list.
117 void add_failed_speculation(nmethod* nm, jlong speculation);
118
119 // Gets the JVMCI name of the nmethod (which may be null).
120 const char* name() { return _has_name ? (char*)(((address) this) + sizeof(JVMCINMethodData)) : nullptr; }
121
122 // Clears the HotSpotNmethod.address field in the mirror. If nm
123 // is dead, the HotSpotNmethod.entryPoint field is also cleared.
124 void invalidate_nmethod_mirror(nmethod* nm, nmethod::InvalidationReason invalidation_reason);
125
126 // Gets the mirror from nm's oops table.
127 oop get_nmethod_mirror(nmethod* nm);
128
129 // Sets the mirror in nm's oops table.
130 void set_nmethod_mirror(nmethod* nm, oop mirror);
131
132 int nmethod_entry_patch_offset() {
133 return _nmethod_entry_patch_offset;
134 }
135 };
136
137 // A top level class that represents an initialized JVMCI runtime.
138 // There is one instance of this class per HotSpotJVMCIRuntime object.
139 class JVMCIRuntime: public CHeapObj<mtJVMCI> {
140 friend class JVMCI;
141 friend class JavaVMRefsInitialization;
142 public:
143 // Constants describing whether JVMCI wants to be able to adjust the compilation
144 // level selected for a method by the VM compilation policy and if so, based on
145 // what information about the method being schedule for compilation.
146 enum CompLevelAdjustment {
147 none = 0, // no adjustment
148 by_holder = 1, // adjust based on declaring class of method
149 by_full_signature = 2 // adjust based on declaring class, name and signature of method
150 };
151
152 private:
153
154 enum InitState {
155 uninitialized,
156 being_initialized,
157 fully_initialized
158 };
159
160 // Initialization state of this JVMCIRuntime.
161 InitState _init_state;
162
163 // Initialization state of the references to classes, methods
164 // and fields in the JVMCI shared library.
165 static InitState _shared_library_javavm_refs_init_state;
166
167 // Initialization state of the references to classes, methods
168 // and fields in HotSpot metadata.
169 static InitState _hotspot_javavm_refs_init_state;
170
171 // A wrapper for a VM scoped JNI global handle (i.e. JVMCIEnv::make_global)
172 // to a HotSpotJVMCIRuntime instance. This JNI global handle must never
173 // be explicitly destroyed as it can be accessed in a racy way during
174 // JVMCI shutdown. Furthermore, it will be reclaimed when
175 // the VM or shared library JavaVM managing the handle dies.
176 JVMCIObject _HotSpotJVMCIRuntime_instance;
177
178 // Lock for operations that may be performed by
179 // any thread attached this runtime. To avoid deadlock,
180 // this lock must always be acquired before JVMCI_lock.
181 Monitor* _lock;
182
183 // Result of calling JNI_CreateJavaVM in the JVMCI shared library.
184 // Must only be mutated under _lock.
185 JavaVM* _shared_library_javavm;
186
187 // Id for _shared_library_javavm.
188 jlong _shared_library_javavm_id;
189
190 // Position and link in global list of JVMCI shared library runtimes.
191 // The HotSpot heap based runtime will have an id of -1 and the
192 // runtime reserved for threads attaching during JVMCI shutdown
193 // will have an id of -2.
194 int _id;
195 JVMCIRuntime* _next;
196
197 // Handles to Metadata objects.
198 MetadataHandles* _metadata_handles;
199
200 // List of oop handles allocated via make_oop_handle. This is to support
201 // destroying remaining oop handles when the JavaVM associated
202 // with this runtime is shutdown.
203 GrowableArray<oop*> _oop_handles;
204
205 // Number of threads attached or about to be attached to this runtime.
206 // Must only be mutated under JVMCI_lock to facilitate safely moving
207 // threads between JVMCI runtimes. A value of -1 implies this runtime is
208 // not available to be attached to another thread because it is in the
209 // process of shutting down and destroying its JavaVM.
210 int _num_attached_threads;
211 static const int cannot_be_attached = -1;
212
213 // Is this runtime for threads managed by the CompileBroker?
214 // Examples of non-CompileBroker threads are CompileTheWorld threads
215 // or Truffle compilation threads.
216 bool _for_compile_broker;
217
218 JVMCIObject create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS);
219
220 // Implementation methods for loading and constant pool access.
221 static Klass* get_klass_by_name_impl(Klass*& accessing_klass,
222 const constantPoolHandle& cpool,
223 Symbol* klass_name,
224 bool require_local);
225 static Klass* get_klass_by_index_impl(const constantPoolHandle& cpool,
226 int klass_index,
227 bool& is_accessible,
228 Klass* loading_klass);
229 static Method* get_method_by_index_impl(const constantPoolHandle& cpool,
230 int method_index, Bytecodes::Code bc,
231 InstanceKlass* loading_klass);
232
233 // Helper methods
234 static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass);
235 static Method* lookup_method(InstanceKlass* accessor,
236 Klass* holder,
237 Symbol* name,
238 Symbol* sig,
239 Bytecodes::Code bc,
240 constantTag tag);
241
242 // Helpers for `for_thread`.
243
244 // Selects an existing runtime (except for `skip`) that has
245 // fewer than JVMCI::max_threads_per_runtime() attached threads.
246 // If such a runtime exists, its _num_attached_threads is incremented
247 // and the caller must subsequently attach `thread` to it.
248 // JVMCI_lock must be held by current thread.
249 // If null is returned, then `*count` contains the number of JVMCIRuntimes
250 // currently allocated.
251 static JVMCIRuntime* select_runtime(JavaThread* thread, JVMCIRuntime* skip, int* count);
252
253 // Selects an existing runtime for `thread` or creates a new one if
254 // no applicable runtime exists.
255 // JVMCI_lock must be held by current thread
256 static JVMCIRuntime* select_or_create_runtime(JavaThread* thread);
257
258 // Selects an existing runtime for `thread` when in JVMCI shutdown.
259 // JVMCI_lock must be held by current thread
260 static JVMCIRuntime* select_runtime_in_shutdown(JavaThread* thread);
261
262 // Releases all the non-null entries in _oop_handles and then clears
263 // the list. Returns the number released handles.
264 int release_and_clear_oop_handles();
265
266 public:
267 JVMCIRuntime(JVMCIRuntime* next, int id, bool for_compile_broker);
268
269 int id() const { return _id; }
270 Monitor* lock() const { return _lock; }
271
272 // Ensures that a JVMCI shared library JavaVM exists for this runtime.
273 // If the JavaVM was created by this call, then the thread-local JNI
274 // interface pointer for the JavaVM is returned otherwise null is returned.
275 // If this method tried to create the JavaVM but failed, the error code returned
276 // by JNI_CreateJavaVM is returned in create_JavaVM_err and, if available, an
277 // error message is malloc'ed and assigned to err_msg. The caller is responsible
278 // for freeing err_msg.
279 JNIEnv* init_shared_library_javavm(int* create_JavaVM_err, const char** err_msg);
280
281 // Determines if the JVMCI shared library JavaVM exists for this runtime.
282 bool has_shared_library_javavm() { return _shared_library_javavm != nullptr; }
283
284 // Gets an ID for the JVMCI shared library JavaVM associated with this runtime.
285 jlong get_shared_library_javavm_id() { return _shared_library_javavm_id; }
286
287 // Copies info about the JVMCI shared library JavaVM associated with this
288 // runtime into `info` as follows:
289 // {
290 // javaVM, // the {@code JavaVM*} value
291 // javaVM->functions->reserved0,
292 // javaVM->functions->reserved1,
293 // javaVM->functions->reserved2
294 // }
295 void init_JavaVM_info(jlongArray info, JVMCI_TRAPS);
296
297 // Wrappers for calling Invocation Interface functions on the
298 // JVMCI shared library JavaVM associated with this runtime.
299 // These wrappers ensure all required thread state transitions are performed.
300 jint AttachCurrentThread(JavaThread* thread, void **penv, void *args);
301 jint AttachCurrentThreadAsDaemon(JavaThread* thread, void **penv, void *args);
302 jint DetachCurrentThread(JavaThread* thread);
303 jint GetEnv(JavaThread* thread, void **penv, jint version);
304
305 // Compute offsets and construct any state required before executing JVMCI code.
306 void initialize(JVMCIEnv* jvmciEnv);
307
308 // Allocation and management of handles to HotSpot heap objects
309 // whose lifetime is scoped by this JVMCIRuntime. The max lifetime
310 // of these handles is the same as the JVMCI shared library JavaVM
311 // associated with this JVMCIRuntime. These JNI handles are
312 // used when creating an IndirectHotSpotObjectConstantImpl in the
313 // shared library JavaVM.
314 jlong make_oop_handle(const Handle& obj);
315 #ifdef ASSERT
316 static bool is_oop_handle(jlong handle);
317 #endif
318
319 // Releases all the non-null entries in _oop_handles whose referent is null.
320 // Returns the number of handles released by this call.
321 int release_cleared_oop_handles();
322
323 // Allocation and management of metadata handles.
324 jmetadata allocate_handle(const methodHandle& handle);
325 jmetadata allocate_handle(const constantPoolHandle& handle);
326 void release_handle(jmetadata handle);
327
328 // Finds a JVMCI runtime for `thread`. A new JVMCI runtime is created if
329 // there are none currently available with JVMCI::max_threads_per_runtime()
330 // or fewer attached threads.
331 static JVMCIRuntime* for_thread(JavaThread* thread);
332
333 // Finds the JVMCI runtime owning `javavm` and attaches `thread` to it.
334 // Returns an error message if attaching fails.
335 static const char* attach_shared_library_thread(JavaThread* thread, JavaVM* javaVM);
336
337 // Reserves a slot in this runtime for `thread` to prevent it being
338 // shutdown before `thread` is attached. JVMCI_lock must be held
339 // and the caller must call `attach_thread` upon releasing it.
340 void pre_attach_thread(JavaThread* thread);
341
342 // Attaches `thread` to this runtime.
343 void attach_thread(JavaThread* thread);
344
345 // Detaches `thread` from this runtime.
346 // Returns whether DestroyJavaVM was called on the JavaVM associated
347 // with this runtime as a result of detaching.
348 // The `can_destroy_javavm` is false when in the scope of
349 // a down call from the JVMCI shared library JavaVM. Since the scope
350 // will return to the shared library JavaVM, the JavaVM must not be destroyed.
351 bool detach_thread(JavaThread* thread, const char* reason, bool can_destroy_javavm=true);
352
353 // If `thread` is the last thread attached to this runtime,
354 // move it to another runtime with an existing JavaVM and available capacity
355 // if possible, thus allowing this runtime to release its JavaVM.
356 void repack(JavaThread* thread);
357
358 // Gets the HotSpotJVMCIRuntime instance for this runtime,
359 // initializing it first if necessary.
360 JVMCIObject get_HotSpotJVMCIRuntime(JVMCI_TRAPS);
361
362 bool is_HotSpotJVMCIRuntime_initialized() {
363 return _HotSpotJVMCIRuntime_instance.is_non_null();
364 }
365
366 // Gets the current HotSpotJVMCIRuntime instance for this runtime which
367 // may be a "null" JVMCIObject value.
368 JVMCIObject probe_HotSpotJVMCIRuntime() {
369 return _HotSpotJVMCIRuntime_instance;
370 }
371
372 // Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime()
373 void initialize_JVMCI(JVMCI_TRAPS);
374
375 // Explicitly initialize HotSpotJVMCIRuntime itself
376 void initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS);
377
378 // Shuts down this runtime by calling HotSpotJVMCIRuntime.shutdown().
379 // If this is the last thread attached to this runtime, then
380 // `_HotSpotJVMCIRuntime_instance` is set to null and `_init_state`
381 // to uninitialized.
382 void shutdown();
383
384 // Destroys the JVMCI shared library JavaVM attached to this runtime.
385 // Return true iff DestroyJavaVM was called on the JavaVM.
386 bool destroy_shared_library_javavm();
387
388 void bootstrap_finished(TRAPS);
389
390 // Look up a klass by name from a particular class loader (the accessor's).
391 // If require_local, result must be defined in that class loader, or null.
392 // If !require_local, a result from remote class loader may be reported,
393 // if sufficient class loader constraints exist such that initiating
394 // a class loading request from the given loader is bound to return
395 // the class defined in the remote loader (or throw an error).
396 //
397 // Return an unloaded klass if !require_local and no class at all is found.
398 //
399 // The CI treats a klass as loaded if it is consistently defined in
400 // another loader, even if it hasn't yet been loaded in all loaders
401 // that could potentially see it via delegation.
402 static Klass* get_klass_by_name(Klass* accessing_klass,
403 Symbol* klass_name,
404 bool require_local);
405
406 // Constant pool access.
407 static Klass* get_klass_by_index(const constantPoolHandle& cpool,
408 int klass_index,
409 bool& is_accessible,
410 Klass* loading_klass);
411 static Method* get_method_by_index(const constantPoolHandle& cpool,
412 int method_index, Bytecodes::Code bc,
413 InstanceKlass* loading_klass);
414
415 // converts the Klass* representing the holder of a method into a
416 // InstanceKlass*. This is needed since the holder of a method in
417 // the bytecodes could be an array type. Basically this converts
418 // array types into java/lang/Object and other types stay as they are.
419 static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass);
420
421 // Helper routine for determining the validity of a compilation
422 // with respect to concurrent class loading.
423 static JVMCI::CodeInstallResult validate_compile_task_dependencies(Dependencies* target,
424 JVMCICompileState* task,
425 char** failure_detail,
426 bool& failing_dep_is_call_site);
427
428 // Compiles `target` with the JVMCI compiler.
429 void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci);
430
431 // Determines if the GC identified by `name` is supported by the JVMCI compiler.
432 bool is_gc_supported(JVMCIEnv* JVMCIENV, CollectedHeap::Name name);
433
434 // Determines if the intrinsic identified by `id` is supported by the JVMCI compiler.
435 bool is_intrinsic_supported(JVMCIEnv* JVMCIENV, jint id);
436
437 // Register the result of a compilation.
438 JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV,
439 const methodHandle& target,
440 nmethod*& nm,
441 int entry_bci,
442 CodeOffsets* offsets,
443 int orig_pc_offset,
444 CodeBuffer* code_buffer,
445 int frame_words,
446 OopMapSet* oop_map_set,
447 ExceptionHandlerTable* handler_table,
448 ImplicitExceptionTable* implicit_exception_table,
449 AbstractCompiler* compiler,
450 DebugInformationRecorder* debug_info,
451 Dependencies* dependencies,
452 int compile_id,
453 bool has_monitors,
454 bool has_unsafe_access,
455 bool has_scoped_access,
456 bool has_wide_vector,
457 JVMCIObject compiled_code,
458 JVMCIObject nmethod_mirror,
459 FailedSpeculation** failed_speculations,
460 char* speculations,
461 int speculations_len,
462 int nmethod_entry_patch_offset);
463
464 // Detach `thread` from this runtime and destroy this runtime's JavaVM
465 // if using one JavaVM per JVMCI compilation .
466 void post_compile(JavaThread* thread);
467
468 // Reports an unexpected exception and exits the VM with a fatal error.
469 static void fatal_exception(JVMCIEnv* JVMCIENV, const char* message);
470
471 static void describe_pending_hotspot_exception(JavaThread* THREAD);
472
473 #define CHECK_EXIT THREAD); \
474 if (HAS_PENDING_EXCEPTION) { \
475 char buf[256]; \
476 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
477 JVMCIRuntime::fatal_exception(nullptr, buf); \
478 return; \
479 } \
480 (void)(0
481
482 #define CHECK_EXIT_(v) THREAD); \
483 if (HAS_PENDING_EXCEPTION) { \
484 char buf[256]; \
485 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
486 JVMCIRuntime::fatal_exception(nullptr, buf); \
487 return v; \
488 } \
489 (void)(0
490
491 #define JVMCI_CHECK_EXIT JVMCIENV); \
492 if (JVMCIENV->has_pending_exception()) { \
493 char buf[256]; \
494 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
495 JVMCIRuntime::fatal_exception(JVMCIENV, buf); \
496 return; \
497 } \
498 (void)(0
499
500 #define JVMCI_CHECK_EXIT_(result) JVMCIENV); \
501 if (JVMCIENV->has_pending_exception()) { \
502 char buf[256]; \
503 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
504 JVMCIRuntime::fatal_exception(JVMCIENV, buf); \
505 return result; \
506 } \
507 (void)(0
508
509 static BasicType kindToBasicType(const Handle& kind, TRAPS);
510
511 // The following routines are called from compiled JVMCI code
512
513 // When allocation fails, these stubs return null and have no pending OutOfMemoryError exception.
514 // Compiled code can use these stubs if a failed allocation will be retried (e.g., by deoptimizing
515 // and re-executing in the interpreter).
516 static void new_instance_or_null(JavaThread* thread, Klass* klass);
517 static void new_array_or_null(JavaThread* thread, Klass* klass, jint length);
518 static void new_multi_array_or_null(JavaThread* thread, Klass* klass, int rank, jint* dims);
519 static void dynamic_new_array_or_null(JavaThread* thread, oopDesc* element_mirror, jint length);
520 static void dynamic_new_instance_or_null(JavaThread* thread, oopDesc* type_mirror);
521
522 static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3);
523 static jint identity_hash_code(JavaThread* current, oopDesc* obj);
524 static address exception_handler_for_pc(JavaThread* current);
525 static void monitorenter(JavaThread* current, oopDesc* obj, BasicLock* lock);
526 static void monitorexit (JavaThread* current, oopDesc* obj, BasicLock* lock);
527 static jboolean object_notify(JavaThread* current, oopDesc* obj);
528 static jboolean object_notifyAll(JavaThread* current, oopDesc* obj);
529 static void vm_error(JavaThread* current, jlong where, jlong format, jlong value);
530 static oopDesc* load_and_clear_exception(JavaThread* thread);
531 static void log_printf(JavaThread* thread, const char* format, jlong v1, jlong v2, jlong v3);
532 static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
533 // Print the passed in object, optionally followed by a newline. If
534 // as_string is true and the object is a java.lang.String then it
535 // printed as a string, otherwise the type of the object is printed
536 // followed by its address.
537 static void log_object(JavaThread* thread, oopDesc* object, bool as_string, bool newline);
538 #if INCLUDE_G1GC
539 using CardValue = G1CardTable::CardValue;
540 static void write_barrier_pre(JavaThread* thread, oopDesc* obj);
541 static void write_barrier_post(JavaThread* thread, volatile CardValue* card);
542 #endif
543 static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child);
544
545 // used to throw exceptions from compiled JVMCI code
546 static int throw_and_post_jvmti_exception(JavaThread* current, const char* exception, const char* message);
547 // helper methods to throw exception with complex messages
548 static int throw_klass_external_name_exception(JavaThread* current, const char* exception, Klass* klass);
549 static int throw_class_cast_exception(JavaThread* current, const char* exception, Klass* caster_klass, Klass* target_klass);
550
551 // A helper to allow invocation of an arbitrary Java method. For simplicity the method is
552 // restricted to a static method that takes at most one argument. For calling convention
553 // simplicity all types are passed by being converted into a jlong
554 static jlong invoke_static_method_one_arg(JavaThread* current, Method* method, jlong argument);
555
556 // Test only function
557 static jint test_deoptimize_call_int(JavaThread* current, int value);
558 };
559 #endif // SHARE_JVMCI_JVMCIRUNTIME_HPP