src/hotspot/share/jvmci/jvmciRuntime.hpp
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File
*** old/src/hotspot/share/jvmci/jvmciRuntime.hpp Thu Mar 28 11:22:54 2019
--- new/src/hotspot/share/jvmci/jvmciRuntime.hpp Thu Mar 28 11:22:54 2019
*** 23,48 ****
--- 23,94 ----
#ifndef SHARE_JVMCI_JVMCIRUNTIME_HPP
#define SHARE_JVMCI_JVMCIRUNTIME_HPP
#include "interpreter/interpreter.hpp"
+ #include "jvmci/jvmci.hpp"
#include "memory/allocation.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#define JVMCI_ERROR(...) \
{ Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::jdk_vm_ci_common_JVMCIError(), __VA_ARGS__); return; }
+ class JVMCIObject;
+ class JVMCIEnv;
+ class JVMCICompileState;
+
+ // Encapsulates the JVMCI metadata for an nmethod.
+ // JVMCINMethodData objects are inlined into nmethods
+ // at nmethod::_jvmci_data_offset.
+ class JVMCINMethodData {
+ // 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;
+
+ // Is HotSpotNmethod.name non-null? If so, the value is
+ // embedded in the end of this object.
+ bool _has_name;
+
+ // Address of the failed speculations list to which a speculation
+ // is appended when it causes a deoptimization.
+ FailedSpeculation** _failed_speculations;
+
+ public:
+ // Computes the size of a JVMCINMethodData object
+ static int compute_size(const char* nmethod_mirror_name) {
+ int size = sizeof(JVMCINMethodData);
+ if (nmethod_mirror_name != NULL) {
+ size += (int) strlen(nmethod_mirror_name) + 1;
+ }
+ return size;
+ }
+
+ void initialize(int nmethod_mirror_index,
+ const char* name,
+ FailedSpeculation** failed_speculations);
+
+ // 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)) : NULL; }
#define JVMCI_ERROR_(ret, ...) \
{ Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::jdk_vm_ci_common_JVMCIError(), __VA_ARGS__); return ret; }
+ // 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);
#define JVMCI_ERROR_0(...) JVMCI_ERROR_(0, __VA_ARGS__)
#define JVMCI_ERROR_NULL(...) JVMCI_ERROR_(NULL, __VA_ARGS__)
#define JVMCI_ERROR_OK(...) JVMCI_ERROR_(JVMCIEnv::ok, __VA_ARGS__)
#define CHECK_OK CHECK_(JVMCIEnv::ok)
+ // Gets the mirror from nm's oops table.
+ oop get_nmethod_mirror(nmethod* nm);
class JVMCIRuntime: public AllStatic {
+ // Sets the mirror in nm's oops table.
+ void set_nmethod_mirror(nmethod* nm, oop mirror);
+
+ // Clears the mirror in nm's oops table.
+ void clear_nmethod_mirror(nmethod* nm);
+ };
+
+ // A top level class that represents an initialized JVMCI runtime.
+ // There is one instance of this class per HotSpotJVMCIRuntime object.
+ class JVMCIRuntime: public CHeapObj<mtCompiler> {
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 {
*** 50,113 ****
--- 96,175 ----
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:
! static jobject _HotSpotJVMCIRuntime_instance;
! static bool _HotSpotJVMCIRuntime_initialized;
static bool _well_known_classes_initialized;
! volatile bool _being_initialized;
! volatile bool _initialized;
+
+ JVMCIObject _HotSpotJVMCIRuntime_instance;
- static CompLevelAdjustment _comp_level_adjustment;
- static bool _shutdown_called;
! static CompLevel adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread);
! CompLevel adjust_comp_level_inner(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
+
+ 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);
+ static methodHandle 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 methodHandle lookup_method(InstanceKlass* accessor,
+ Klass* holder,
+ Symbol* name,
+ Symbol* sig,
+ Bytecodes::Code bc,
+ constantTag tag);
public:
! static bool is_HotSpotJVMCIRuntime_initialized() {
! return _HotSpotJVMCIRuntime_initialized;
! _comp_level_adjustment = JVMCIRuntime::none;
+ _initialized = false;
+ _being_initialized = false;
+ _shutdown_called = false;
}
/**
* Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary
+ * Compute offsets and construct any state required before executing JVMCI code.
*/
! static Handle get_HotSpotJVMCIRuntime(TRAPS);
static jobject get_HotSpotJVMCIRuntime_jobject(TRAPS) {
initialize_JVMCI(CHECK_NULL);
assert(_HotSpotJVMCIRuntime_initialized, "must be");
return _HotSpotJVMCIRuntime_instance;
}
static Handle callStatic(const char* className, const char* methodName, const char* returnType, JavaCallArguments* args, TRAPS);
! void initialize(JVMCIEnv* jvmciEnv);
/**
* Determines if the VM is sufficiently booted to initialize JVMCI.
+ * Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary
*/
! static bool can_initialize_JVMCI();
! JVMCIObject get_HotSpotJVMCIRuntime(JVMCI_TRAPS);
+
+ bool is_HotSpotJVMCIRuntime_initialized() {
+ return _HotSpotJVMCIRuntime_instance.is_non_null();
+ }
/**
* Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime()
*/
! static void initialize_JVMCI(TRAPS);
! void initialize_JVMCI(JVMCI_TRAPS);
/**
* Explicitly initialize HotSpotJVMCIRuntime itself
*/
! static void initialize_HotSpotJVMCIRuntime(TRAPS);
static void initialize_well_known_classes(TRAPS);
! void initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS);
! static void metadata_do(void f(Metadata*));
static void shutdown(TRAPS);
static void bootstrap_finished(TRAPS);
static bool shutdown_called() {
return _shutdown_called;
}
! void call_getCompiler(TRAPS);
/**
* Lets JVMCI modify the compilation level currently selected for a method by
* the VM compilation policy.
*
*** 115,125 ****
--- 177,301 ----
* @param is_osr specifies if the compilation is an OSR compilation
* @param level the compilation level currently selected by the VM compilation policy
* @param thread the current thread
* @return the compilation level to use for the compilation
*/
! static CompLevel adjust_comp_level(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread);
! CompLevel adjust_comp_level(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
+
+ void shutdown();
+
+ bool shutdown_called() {
+ return _shutdown_called;
+ }
+
+ 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);
+ static methodHandle 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);
+
+ // Compiles `target` with the JVMCI compiler.
+ void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci);
+
+ // 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,
+ AbstractCompiler* compiler,
+ DebugInformationRecorder* debug_info,
+ Dependencies* dependencies,
+ int compile_id,
+ bool has_unsafe_access,
+ bool has_wide_vector,
+ JVMCIObject compiled_code,
+ JVMCIObject nmethod_mirror,
+ FailedSpeculation** failed_speculations,
+ char* speculations,
+ int speculations_len);
+
+ /**
+ * Exits the VM due to an unexpected exception.
+ */
+ static void exit_on_pending_exception(JVMCIEnv* JVMCIENV, const char* message);
+
+ static void describe_pending_hotspot_exception(JavaThread* THREAD, bool clear);
+
+ #define CHECK_EXIT THREAD); \
+ if (HAS_PENDING_EXCEPTION) { \
+ char buf[256]; \
+ jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
+ JVMCIRuntime::exit_on_pending_exception(NULL, 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::exit_on_pending_exception(NULL, 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::exit_on_pending_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::exit_on_pending_exception(JVMCIENV, buf); \
+ return result; \
+ } \
+ (void)(0
static BasicType kindToBasicType(Handle kind, TRAPS);
static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail);
static void new_array_common(JavaThread* thread, Klass* klass, jint length, bool null_on_fail);
*** 177,203 ****
--- 353,376 ----
static void throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message);
// helper methods to throw exception with complex messages
static void throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass);
static void throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass);
// Forces initialization of the JVMCI runtime.
static void force_initialization(TRAPS);
// Test only function
! static jint test_deoptimize_call_int(JavaThread* thread, int value);
};
// Tracing macros.
#define IF_TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1)) ; else
#define IF_TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2)) ; else
#define IF_TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3)) ; else
#define IF_TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4)) ; else
#define IF_TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5)) ; else
! #define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print("JVMCITrace-1: "), true))) ; else tty->print_cr
! #define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(" JVMCITrace-2: "), true))) ; else tty->print_cr
! #define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(" JVMCITrace-3: "), true))) ; else tty->print_cr
! #define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(" JVMCITrace-4: "), true))) ; else tty->print_cr
! #define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(" JVMCITrace-5: "), true))) ; else tty->print_cr
! #define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print(PTR_FORMAT " JVMCITrace-1: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
! #define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(PTR_FORMAT " JVMCITrace-2: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
! #define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(PTR_FORMAT " JVMCITrace-3: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
! #define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(PTR_FORMAT " JVMCITrace-4: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
! #define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(PTR_FORMAT " JVMCITrace-5: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
#endif // SHARE_JVMCI_JVMCIRUNTIME_HPP
src/hotspot/share/jvmci/jvmciRuntime.hpp
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File