| /* |
| * Copyright (c) 2012, 2023, 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_JVMCIRUNTIME_HPP |
| #define SHARE_JVMCI_JVMCIRUNTIME_HPP |
| |
| #include "code/nmethod.hpp" |
| #include "gc/shared/collectedHeap.hpp" |
| #include "jvm_io.h" |
| #include "jvmci/jvmci.hpp" |
| #include "jvmci/jvmciExceptions.hpp" |
| #include "jvmci/jvmciObject.hpp" |
| #include "utilities/linkedlist.hpp" |
| #if INCLUDE_G1GC |
| #include "gc/g1/g1CardTable.hpp" |
| #endif // INCLUDE_G1GC |
| |
| class JVMCIEnv; |
| class JVMCICompiler; |
| class JVMCICompileState; |
| class MetadataHandles; |
| |
| // Encapsulates the JVMCI metadata for an nmethod. JVMCINMethodData objects are normally inlined |
| // into nmethods at nmethod::_jvmci_data_offset but during construction of the nmethod they are |
| // resource allocated so they can be passed into the nmethod constructor. |
| class JVMCINMethodData : public ResourceObj { |
| friend class JVMCIVMStructs; |
| |
| // Is HotSpotNmethod.name non-null? If so, the value is |
| // embedded in the end of this object. |
| bool _has_name; |
| |
| // Index for the HotSpotNmethod mirror in the nmethod's oops table. |
| // This is -1 if there is no mirror in the oops table. |
| int _nmethod_mirror_index; |
| |
| // This is the offset of the patchable part of the nmethod entry barrier sequence. The meaning is |
| // somewhat platform dependent as the way patching is done varies by architecture. Older JVMCI |
| // based compilers didn't emit the entry barrier so having a positive value for this offset |
| // confirms that the installed code supports the entry barrier. |
| int _nmethod_entry_patch_offset; |
| |
| // Address of the failed speculations list to which a speculation |
| // is appended when it causes a deoptimization. |
| FailedSpeculation** _failed_speculations; |
| |
| // A speculation id is a length (low 5 bits) and an index into |
| // a jbyte array (i.e. 31 bits for a positive Java int). |
| enum { |
| // Keep in sync with HotSpotSpeculationEncoding. |
| SPECULATION_LENGTH_BITS = 5, |
| SPECULATION_LENGTH_MASK = (1 << SPECULATION_LENGTH_BITS) - 1 |
| }; |
| |
| // Allocate a temporary data object for use during installation |
| void initialize(int nmethod_mirror_index, |
| int nmethod_entry_patch_offset, |
| const char* nmethod_mirror_name, |
| FailedSpeculation** failed_speculations); |
| |
| void* operator new(size_t size, const char* nmethod_mirror_name) { |
| assert(size == sizeof(JVMCINMethodData), "must agree"); |
| size_t total_size = compute_size(nmethod_mirror_name); |
| return (address)resource_allocate_bytes(total_size); |
| } |
| |
| public: |
| static JVMCINMethodData* create(int nmethod_mirror_index, |
| int nmethod_entry_patch_offset, |
| const char* nmethod_mirror_name, |
| FailedSpeculation** failed_speculations) { |
| JVMCINMethodData* result = new (nmethod_mirror_name) JVMCINMethodData(); |
| result->initialize(nmethod_mirror_index, |
| nmethod_entry_patch_offset, |
| nmethod_mirror_name, |
| failed_speculations); |
| return result; |
| } |
| |
| // Computes the size of a JVMCINMethodData object |
| static int compute_size(const char* nmethod_mirror_name) { |
| int size = sizeof(JVMCINMethodData); |
| if (nmethod_mirror_name != nullptr) { |
| size += (int) strlen(nmethod_mirror_name) + 1; |
| } |
| return size; |
| } |
| |
| int size() { |
| return compute_size(name()); |
| } |
| |
| // Copy the contents of this object into data which is normally the storage allocated in the nmethod. |
| void copy(JVMCINMethodData* data); |
| |
| // Adds `speculation` to the failed speculations list. |
| void add_failed_speculation(nmethod* nm, jlong speculation); |
| |
| // Gets the JVMCI name of the nmethod (which may be null). |
| const char* name() { return _has_name ? (char*)(((address) this) + sizeof(JVMCINMethodData)) : nullptr; } |
| |
| // Clears the HotSpotNmethod.address field in the mirror. If nm |
| // is dead, the HotSpotNmethod.entryPoint field is also cleared. |
| void invalidate_nmethod_mirror(nmethod* nm); |
| |
| // Gets the mirror from nm's oops table. |
| oop get_nmethod_mirror(nmethod* nm, bool phantom_ref); |
| |
| // Sets the mirror in nm's oops table. |
| void set_nmethod_mirror(nmethod* nm, oop mirror); |
| |
| bool has_entry_barrier() { |
| return _nmethod_entry_patch_offset != -1; |
| } |
| |
| int nmethod_entry_patch_offset() { |
| guarantee(_nmethod_entry_patch_offset != -1, "missing entry barrier"); |
| return _nmethod_entry_patch_offset; |
| } |
| }; |
| |
| // A top level class that represents an initialized JVMCI runtime. |
| // There is one instance of this class per HotSpotJVMCIRuntime object. |
| class JVMCIRuntime: public CHeapObj<mtJVMCI> { |
| friend class JVMCI; |
| friend class JavaVMRefsInitialization; |
| public: |
| // Constants describing whether JVMCI wants to be able to adjust the compilation |
| // level selected for a method by the VM compilation policy and if so, based on |
| // what information about the method being schedule for compilation. |
| enum CompLevelAdjustment { |
| none = 0, // no adjustment |
| by_holder = 1, // adjust based on declaring class of method |
| by_full_signature = 2 // adjust based on declaring class, name and signature of method |
| }; |
| |
| private: |
| |
| enum InitState { |
| uninitialized, |
| being_initialized, |
| fully_initialized |
| }; |
| |
| // Initialization state of this JVMCIRuntime. |
| InitState _init_state; |
| |
| // Initialization state of the references to classes, methods |
| // and fields in the JVMCI shared library. |
| static InitState _shared_library_javavm_refs_init_state; |
| |
| // Initialization state of the references to classes, methods |
| // and fields in HotSpot metadata. |
| static InitState _hotspot_javavm_refs_init_state; |
| |
| // A wrapper for a VM scoped JNI global handle (i.e. JVMCIEnv::make_global) |
| // to a HotSpotJVMCIRuntime instance. This JNI global handle must never |
| // be explicitly destroyed as it can be accessed in a racy way during |
| // JVMCI shutdown. Furthermore, it will be reclaimed when |
| // the VM or shared library JavaVM managing the handle dies. |
| JVMCIObject _HotSpotJVMCIRuntime_instance; |
| |
| // Lock for operations that may be performed by |
| // any thread attached this runtime. To avoid deadlock, |
| // this lock must always be acquired before JVMCI_lock. |
| Monitor* _lock; |
| |
| // Result of calling JNI_CreateJavaVM in the JVMCI shared library. |
| // Must only be mutated under _lock. |
| JavaVM* _shared_library_javavm; |
| |
| // Id for _shared_library_javavm. |
| int _shared_library_javavm_id; |
| |
| // Position and link in global list of JVMCI shared library runtimes. |
| // The HotSpot heap based runtime will have an id of -1 and the |
| // runtime reserved for threads attaching during JVMCI shutdown |
| // will have an id of -2. |
| int _id; |
| JVMCIRuntime* _next; |
| |
| // Handles to Metadata objects. |
| MetadataHandles* _metadata_handles; |
| |
| // List of oop handles allocated via make_oop_handle. This is to support |
| // destroying remaining oop handles when the JavaVM associated |
| // with this runtime is shutdown. |
| GrowableArray<oop*> _oop_handles; |
| |
| // Number of threads attached or about to be attached to this runtime. |
| // Must only be mutated under JVMCI_lock to facilitate safely moving |
| // threads between JVMCI runtimes. A value of -1 implies this runtime is |
| // not available to be attached to another thread because it is in the |
| // process of shutting down and destroying its JavaVM. |
| int _num_attached_threads; |
| static const int cannot_be_attached = -1; |
| |
| // Is this runtime for threads managed by the CompileBroker? |
| // Examples of non-CompileBroker threads are CompileTheWorld threads |
| // or Truffle compilation threads. |
| bool _for_compile_broker; |
| |
| JVMCIObject create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS); |
| |
| // Implementation methods for loading and constant pool access. |
| static Klass* get_klass_by_name_impl(Klass*& accessing_klass, |
| const constantPoolHandle& cpool, |
| Symbol* klass_name, |
| bool require_local); |
| static Klass* get_klass_by_index_impl(const constantPoolHandle& cpool, |
| int klass_index, |
| bool& is_accessible, |
| Klass* loading_klass); |
| static void get_field_by_index_impl(InstanceKlass* loading_klass, fieldDescriptor& fd, |
| int field_index, Bytecodes::Code bc); |
| static Method* get_method_by_index_impl(const constantPoolHandle& cpool, |
| int method_index, Bytecodes::Code bc, |
| InstanceKlass* loading_klass); |
| |
| // Helper methods |
| static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass); |
| static Method* lookup_method(InstanceKlass* accessor, |
| Klass* holder, |
| Symbol* name, |
| Symbol* sig, |
| Bytecodes::Code bc, |
| constantTag tag); |
| |
| // Helpers for `for_thread`. |
| |
| // Selects an existing runtime (except for `skip`) that has |
| // fewer than JVMCI::max_threads_per_runtime() attached threads. |
| // If such a runtime exists, its _num_attached_threads is incremented |
| // and the caller must subsequently attach `thread` to it. |
| // JVMCI_lock must be held by current thread. |
| // If null is returned, then `*count` contains the number of JVMCIRuntimes |
| // currently allocated. |
| static JVMCIRuntime* select_runtime(JavaThread* thread, JVMCIRuntime* skip, int* count); |
| |
| // Selects an existing runtime for `thread` or creates a new one if |
| // no applicable runtime exists. |
| // JVMCI_lock must be held by current thread |
| static JVMCIRuntime* select_or_create_runtime(JavaThread* thread); |
| |
| // Selects an existing runtime for `thread` when in JVMCI shutdown. |
| // JVMCI_lock must be held by current thread |
| static JVMCIRuntime* select_runtime_in_shutdown(JavaThread* thread); |
| |
| // Releases all the non-null entries in _oop_handles and then clears |
| // the list. Returns the number released handles. |
| int release_and_clear_oop_handles(); |
| |
| public: |
| JVMCIRuntime(JVMCIRuntime* next, int id, bool for_compile_broker); |
| |
| int id() const { return _id; } |
| Monitor* lock() const { return _lock; } |
| |
| // Ensures that a JVMCI shared library JavaVM exists for this runtime. |
| // If the JavaVM was created by this call, then the thread-local JNI |
| // interface pointer for the JavaVM is returned otherwise null is returned. |
| // If this method tried to create the JavaVM but failed, the error code returned |
| // by JNI_CreateJavaVM is returned in create_JavaVM_err. |
| JNIEnv* init_shared_library_javavm(int* create_JavaVM_err); |
| |
| // Determines if the JVMCI shared library JavaVM exists for this runtime. |
| bool has_shared_library_javavm() { return _shared_library_javavm != nullptr; } |
| |
| // Gets an ID for the JVMCI shared library JavaVM associated with this runtime. |
| int get_shared_library_javavm_id() { return _shared_library_javavm_id; } |
| |
| // Copies info about the JVMCI shared library JavaVM associated with this |
| // runtime into `info` as follows: |
| // { |
| // javaVM, // the {@code JavaVM*} value |
| // javaVM->functions->reserved0, |
| // javaVM->functions->reserved1, |
| // javaVM->functions->reserved2 |
| // } |
| void init_JavaVM_info(jlongArray info, JVMCI_TRAPS); |
| |
| // Wrappers for calling Invocation Interface functions on the |
| // JVMCI shared library JavaVM associated with this runtime. |
| // These wrappers ensure all required thread state transitions are performed. |
| jint AttachCurrentThread(JavaThread* thread, void **penv, void *args); |
| jint AttachCurrentThreadAsDaemon(JavaThread* thread, void **penv, void *args); |
| jint DetachCurrentThread(JavaThread* thread); |
| jint GetEnv(JavaThread* thread, void **penv, jint version); |
| |
| // Compute offsets and construct any state required before executing JVMCI code. |
| void initialize(JVMCIEnv* jvmciEnv); |
| |
| // Allocation and management of handles to HotSpot heap objects |
| // whose lifetime is scoped by this JVMCIRuntime. The max lifetime |
| // of these handles is the same as the JVMCI shared library JavaVM |
| // associated with this JVMCIRuntime. These JNI handles are |
| // used when creating an IndirectHotSpotObjectConstantImpl in the |
| // shared library JavaVM. |
| jlong make_oop_handle(const Handle& obj); |
| |
| // Releases all the non-null entries in _oop_handles whose referent is null. |
| // Returns the number of handles released by this call. |
| // The method also resets _last_found_oop_handle_index to -1 |
| // and _null_oop_handles to 0. |
| int release_cleared_oop_handles(); |
| |
| // Allocation and management of metadata handles. |
| jmetadata allocate_handle(const methodHandle& handle); |
| jmetadata allocate_handle(const constantPoolHandle& handle); |
| void release_handle(jmetadata handle); |
| |
| // Finds a JVMCI runtime for `thread`. A new JVMCI runtime is created if |
| // there are none currently available with JVMCI::max_threads_per_runtime() |
| // or fewer attached threads. |
| static JVMCIRuntime* for_thread(JavaThread* thread); |
| |
| // Finds the JVMCI runtime owning `javavm` and attaches `thread` to it. |
| // Returns an error message if attaching fails. |
| static const char* attach_shared_library_thread(JavaThread* thread, JavaVM* javaVM); |
| |
| // Reserves a slot in this runtime for `thread` to prevent it being |
| // shutdown before `thread` is attached. JVMCI_lock must be held |
| // and the caller must call `attach_thread` upon releasing it. |
| void pre_attach_thread(JavaThread* thread); |
| |
| // Attaches `thread` to this runtime. |
| void attach_thread(JavaThread* thread); |
| |
| // Detaches `thread` from this runtime. |
| // Returns whether DestroyJavaVM was called on the JavaVM associated |
| // with this runtime as a result of detaching. |
| // The `can_destroy_javavm` is false when in the scope of |
| // a down call from the JVMCI shared library JavaVM. Since the scope |
| // will return to the shared library JavaVM, the JavaVM must not be destroyed. |
| bool detach_thread(JavaThread* thread, const char* reason, bool can_destroy_javavm=true); |
| |
| // If `thread` is the last thread attached to this runtime, |
| // move it to another runtime with an existing JavaVM and available capacity |
| // if possible, thus allowing this runtime to release its JavaVM. |
| void repack(JavaThread* thread); |
| |
| // Gets the HotSpotJVMCIRuntime instance for this runtime, |
| // initializing it first if necessary. |
| JVMCIObject get_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
| |
| bool is_HotSpotJVMCIRuntime_initialized() { |
| return _HotSpotJVMCIRuntime_instance.is_non_null(); |
| } |
| |
| // Gets the current HotSpotJVMCIRuntime instance for this runtime which |
| // may be a "null" JVMCIObject value. |
| JVMCIObject probe_HotSpotJVMCIRuntime() { |
| return _HotSpotJVMCIRuntime_instance; |
| } |
| |
| // Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime() |
| void initialize_JVMCI(JVMCI_TRAPS); |
| |
| // Explicitly initialize HotSpotJVMCIRuntime itself |
| void initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
| |
| void call_getCompiler(TRAPS); |
| |
| // Shuts down this runtime by calling HotSpotJVMCIRuntime.shutdown(). |
| // If this is the last thread attached to this runtime, then |
| // `_HotSpotJVMCIRuntime_instance` is set to null and `_init_state` |
| // to uninitialized. |
| void shutdown(); |
| |
| // Destroys the JVMCI shared library JavaVM attached to this runtime. |
| // Return true iff DestroyJavaVM was called on the JavaVM. |
| bool destroy_shared_library_javavm(); |
| |
| void bootstrap_finished(TRAPS); |
| |
| // Look up a klass by name from a particular class loader (the accessor's). |
| // If require_local, result must be defined in that class loader, or null. |
| // If !require_local, a result from remote class loader may be reported, |
| // if sufficient class loader constraints exist such that initiating |
| // a class loading request from the given loader is bound to return |
| // the class defined in the remote loader (or throw an error). |
| // |
| // Return an unloaded klass if !require_local and no class at all is found. |
| // |
| // The CI treats a klass as loaded if it is consistently defined in |
| // another loader, even if it hasn't yet been loaded in all loaders |
| // that could potentially see it via delegation. |
| static Klass* get_klass_by_name(Klass* accessing_klass, |
| Symbol* klass_name, |
| bool require_local); |
| |
| // Constant pool access. |
| static Klass* get_klass_by_index(const constantPoolHandle& cpool, |
| int klass_index, |
| bool& is_accessible, |
| Klass* loading_klass); |
| static void get_field_by_index(InstanceKlass* loading_klass, fieldDescriptor& fd, |
| int field_index, Bytecodes::Code bc); |
| static Method* get_method_by_index(const constantPoolHandle& cpool, |
| int method_index, Bytecodes::Code bc, |
| InstanceKlass* loading_klass); |
| |
| // converts the Klass* representing the holder of a method into a |
| // InstanceKlass*. This is needed since the holder of a method in |
| // the bytecodes could be an array type. Basically this converts |
| // array types into java/lang/Object and other types stay as they are. |
| static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass); |
| |
| // Helper routine for determining the validity of a compilation |
| // with respect to concurrent class loading. |
| static JVMCI::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, |
| JVMCICompileState* task, |
| char** failure_detail, |
| bool& failing_dep_is_call_site); |
| |
| // Compiles `target` with the JVMCI compiler. |
| void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci); |
| |
| // Determines if the GC identified by `name` is supported by the JVMCI compiler. |
| bool is_gc_supported(JVMCIEnv* JVMCIENV, CollectedHeap::Name name); |
| |
| // Register the result of a compilation. |
| JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV, |
| const methodHandle& target, |
| nmethod*& nm, |
| int entry_bci, |
| CodeOffsets* offsets, |
| int orig_pc_offset, |
| CodeBuffer* code_buffer, |
| int frame_words, |
| OopMapSet* oop_map_set, |
| ExceptionHandlerTable* handler_table, |
| ImplicitExceptionTable* implicit_exception_table, |
| AbstractCompiler* compiler, |
| DebugInformationRecorder* debug_info, |
| Dependencies* dependencies, |
| int compile_id, |
| bool has_monitors, |
| bool has_unsafe_access, |
| bool has_wide_vector, |
| JVMCIObject compiled_code, |
| JVMCIObject nmethod_mirror, |
| FailedSpeculation** failed_speculations, |
| char* speculations, |
| int speculations_len, |
| int nmethod_entry_patch_offset); |
| |
| // Detach `thread` from this runtime and destroy this runtime's JavaVM |
| // if using one JavaVM per JVMCI compilation . |
| void post_compile(JavaThread* thread); |
| |
| // Reports an unexpected exception and exits the VM with a fatal error. |
| static void fatal_exception(JVMCIEnv* JVMCIENV, const char* message); |
| |
| static void describe_pending_hotspot_exception(JavaThread* THREAD); |
| |
| #define CHECK_EXIT THREAD); \ |
| if (HAS_PENDING_EXCEPTION) { \ |
| char buf[256]; \ |
| jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| JVMCIRuntime::fatal_exception(nullptr, buf); \ |
| return; \ |
| } \ |
| (void)(0 |
| |
| #define CHECK_EXIT_(v) THREAD); \ |
| if (HAS_PENDING_EXCEPTION) { \ |
| char buf[256]; \ |
| jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| JVMCIRuntime::fatal_exception(nullptr, buf); \ |
| return v; \ |
| } \ |
| (void)(0 |
| |
| #define JVMCI_CHECK_EXIT JVMCIENV); \ |
| if (JVMCIENV->has_pending_exception()) { \ |
| char buf[256]; \ |
| jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| JVMCIRuntime::fatal_exception(JVMCIENV, buf); \ |
| return; \ |
| } \ |
| (void)(0 |
| |
| #define JVMCI_CHECK_EXIT_(result) JVMCIENV); \ |
| if (JVMCIENV->has_pending_exception()) { \ |
| char buf[256]; \ |
| jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| JVMCIRuntime::fatal_exception(JVMCIENV, buf); \ |
| return result; \ |
| } \ |
| (void)(0 |
| |
| static BasicType kindToBasicType(const Handle& kind, TRAPS); |
| |
| static void new_instance_common(JavaThread* current, Klass* klass, bool null_on_fail); |
| static void new_array_common(JavaThread* current, Klass* klass, jint length, bool null_on_fail); |
| static void new_multi_array_common(JavaThread* current, Klass* klass, int rank, jint* dims, bool null_on_fail); |
| static void dynamic_new_array_common(JavaThread* current, oopDesc* element_mirror, jint length, bool null_on_fail); |
| static void dynamic_new_instance_common(JavaThread* current, oopDesc* type_mirror, bool null_on_fail); |
| |
| // The following routines are called from compiled JVMCI code |
| |
| // When allocation fails, these stubs: |
| // 1. Exercise -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError handling and also |
| // post a JVMTI_EVENT_RESOURCE_EXHAUSTED event if the failure is an OutOfMemroyError |
| // 2. Return null with a pending exception. |
| // Compiled code must ensure these stubs are not called twice for the same allocation |
| // site due to the non-repeatable side effects in the case of OOME. |
| static void new_instance(JavaThread* current, Klass* klass) { new_instance_common(current, klass, false); } |
| static void new_array(JavaThread* current, Klass* klass, jint length) { new_array_common(current, klass, length, false); } |
| static void new_multi_array(JavaThread* current, Klass* klass, int rank, jint* dims) { new_multi_array_common(current, klass, rank, dims, false); } |
| static void dynamic_new_array(JavaThread* current, oopDesc* element_mirror, jint length) { dynamic_new_array_common(current, element_mirror, length, false); } |
| static void dynamic_new_instance(JavaThread* current, oopDesc* type_mirror) { dynamic_new_instance_common(current, type_mirror, false); } |
| |
| // When allocation fails, these stubs return null and have no pending exception. Compiled code |
| // can use these stubs if a failed allocation will be retried (e.g., by deoptimizing and |
| // re-executing in the interpreter). |
| static void new_instance_or_null(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, true); } |
| static void new_array_or_null(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, true); } |
| static void new_multi_array_or_null(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, true); } |
| static void dynamic_new_array_or_null(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, true); } |
| static void dynamic_new_instance_or_null(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, true); } |
| |
| static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3); |
| static jint identity_hash_code(JavaThread* current, oopDesc* obj); |
| static address exception_handler_for_pc(JavaThread* current); |
| static void monitorenter(JavaThread* current, oopDesc* obj, BasicLock* lock); |
| static void monitorexit (JavaThread* current, oopDesc* obj, BasicLock* lock); |
| static jboolean object_notify(JavaThread* current, oopDesc* obj); |
| static jboolean object_notifyAll(JavaThread* current, oopDesc* obj); |
| static void vm_error(JavaThread* current, jlong where, jlong format, jlong value); |
| static oopDesc* load_and_clear_exception(JavaThread* thread); |
| static void log_printf(JavaThread* thread, const char* format, jlong v1, jlong v2, jlong v3); |
| static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline); |
| // Print the passed in object, optionally followed by a newline. If |
| // as_string is true and the object is a java.lang.String then it |
| // printed as a string, otherwise the type of the object is printed |
| // followed by its address. |
| static void log_object(JavaThread* thread, oopDesc* object, bool as_string, bool newline); |
| #if INCLUDE_G1GC |
| using CardValue = G1CardTable::CardValue; |
| static void write_barrier_pre(JavaThread* thread, oopDesc* obj); |
| static void write_barrier_post(JavaThread* thread, volatile CardValue* card); |
| #endif |
| static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child); |
| |
| // used to throw exceptions from compiled JVMCI code |
| static int throw_and_post_jvmti_exception(JavaThread* current, const char* exception, const char* message); |
| // helper methods to throw exception with complex messages |
| static int throw_klass_external_name_exception(JavaThread* current, const char* exception, Klass* klass); |
| static int throw_class_cast_exception(JavaThread* current, const char* exception, Klass* caster_klass, Klass* target_klass); |
| |
| // A helper to allow invocation of an arbitrary Java method. For simplicity the method is |
| // restricted to a static method that takes at most one argument. For calling convention |
| // simplicity all types are passed by being converted into a jlong |
| static jlong invoke_static_method_one_arg(JavaThread* current, Method* method, jlong argument); |
| |
| // Test only function |
| static jint test_deoptimize_call_int(JavaThread* current, int value); |
| }; |
| #endif // SHARE_JVMCI_JVMCIRUNTIME_HPP |