Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8248359: Update JVMCI
Reviewed-by: kvn, never
  • Loading branch information
Doug Simon committed Jul 1, 2020
1 parent eb78035 commit 03d47d58d658bef5fe9095c120c9d83eb3936e84
Show file tree
Hide file tree
Showing 16 changed files with 798 additions and 504 deletions.
@@ -1201,7 +1201,7 @@ void CompileBroker::compile_method_base(const methodHandle& method,
// Don't allow blocking compilation requests if we are in JVMCIRuntime::shutdown
// to avoid deadlock between compiler thread(s) and threads run at shutdown
// such as the DestroyJavaVM thread.
if (JVMCI::shutdown_called()) {
if (JVMCI::in_shutdown()) {
blocking = false;
}
}
@@ -2150,16 +2150,22 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
TraceTime t1("compilation", &time);
EventCompilation event;
JVMCICompileState compile_state(task);
JVMCIRuntime *runtime = NULL;

// Skip redefined methods
if (compile_state.target_method_is_old()) {
if (JVMCI::in_shutdown()) {
failure_reason = "in JVMCI shutdown";
retry_message = "not retryable";
compilable = ciEnv::MethodCompilable_never;
} else if (compile_state.target_method_is_old()) {
// Skip redefined methods
failure_reason = "redefined method";
retry_message = "not retryable";
compilable = ciEnv::MethodCompilable_never;
} else {
JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
methodHandle method(thread, target_handle);
env.runtime()->compile_method(&env, jvmci, method, osr_bci);
runtime = env.runtime();
runtime->compile_method(&env, jvmci, method, osr_bci);

failure_reason = compile_state.failure_reason();
failure_reason_on_C_heap = compile_state.failure_reason_on_C_heap();
@@ -35,12 +35,12 @@
// to a GC in the shared library).
class JNIAccessMark : public StackObj {
private:
ThreadToNativeFromVM ttnfv;
HandleMark hm;
ThreadToNativeFromVM _ttnfv;
HandleMark _hm;
JNIEnv* _env;
public:
inline JNIAccessMark(JVMCIEnv* jvmci_env) :
ttnfv(JavaThread::current()), hm(JavaThread::current()) {
inline JNIAccessMark(JVMCIEnv* jvmci_env, JavaThread* thread=JavaThread::current()) :
_ttnfv(thread), _hm(thread) {
_env = jvmci_env->_env;
}
JNIEnv* env() const { return _env; }
@@ -24,17 +24,19 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/oopStorage.hpp"
#include "gc/shared/oopStorageSet.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/metadataHandleBlock.hpp"
#include "jvmci/metadataHandles.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"

MetadataHandleBlock* JVMCI::_metadata_handles = NULL;
JVMCIRuntime* JVMCI::_compiler_runtime = NULL;
JVMCIRuntime* JVMCI::_java_runtime = NULL;
volatile bool JVMCI::_is_initialized = false;
void* JVMCI::_shared_library_handle = NULL;
char* JVMCI::_shared_library_path = NULL;
volatile bool JVMCI::_in_shutdown = false;

void jvmci_vmStructs_init() NOT_DEBUG_RETURN;

@@ -50,6 +52,40 @@ bool JVMCI::can_initialize_JVMCI() {
return true;
}

void* JVMCI::get_shared_library(char*& path, bool load) {
void* sl_handle = _shared_library_handle;
if (sl_handle != NULL || !load) {
path = _shared_library_path;
return sl_handle;
}
assert(JVMCI_lock->owner() == Thread::current(), "must be");
path = NULL;
if (_shared_library_handle == NULL) {
char path[JVM_MAXPATHLEN];
char ebuf[1024];
if (JVMCILibPath != NULL) {
if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
vm_exit_during_initialization("Unable to locate JVMCI shared library in path specified by -XX:JVMCILibPath value", JVMCILibPath);
}
} else {
if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
vm_exit_during_initialization("Unable to create path to JVMCI shared library");
}
}

void* handle = os::dll_load(path, ebuf, sizeof ebuf);
if (handle == NULL) {
vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf);
}
_shared_library_handle = handle;
_shared_library_path = strdup(path);

TRACE_jvmci_1("loaded JVMCI shared library from %s", path);
}
path = _shared_library_path;
return _shared_library_handle;
}

void JVMCI::initialize_compiler(TRAPS) {
if (JVMCILibDumpJNIConfig) {
JNIJVMCI::initialize_ids(NULL);
@@ -61,93 +97,57 @@ void JVMCI::initialize_compiler(TRAPS) {

void JVMCI::initialize_globals() {
jvmci_vmStructs_init();
_metadata_handles = MetadataHandleBlock::allocate_block();
if (UseJVMCINativeLibrary) {
// There are two runtimes.
_compiler_runtime = new JVMCIRuntime();
_java_runtime = new JVMCIRuntime();
_compiler_runtime = new JVMCIRuntime(0);
_java_runtime = new JVMCIRuntime(-1);
} else {
// There is only a single runtime
_java_runtime = _compiler_runtime = new JVMCIRuntime();
}
}

// Handles to objects in the Hotspot heap.
static OopStorage* object_handles() {
return OopStorageSet::vm_global();
}

jobject JVMCI::make_global(const Handle& obj) {
assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
assert(oopDesc::is_oop(obj()), "not an oop");
oop* ptr = object_handles()->allocate();
jobject res = NULL;
if (ptr != NULL) {
assert(*ptr == NULL, "invariant");
NativeAccess<>::oop_store(ptr, obj());
res = reinterpret_cast<jobject>(ptr);
} else {
vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
"Cannot create JVMCI oop handle");
_java_runtime = _compiler_runtime = new JVMCIRuntime(0);
}
return res;
}

void JVMCI::destroy_global(jobject handle) {
// Assert before nulling out, for better debugging.
assert(is_global_handle(handle), "precondition");
oop* oop_ptr = reinterpret_cast<oop*>(handle);
NativeAccess<>::oop_store(oop_ptr, (oop)NULL);
object_handles()->release(oop_ptr);
}

bool JVMCI::is_global_handle(jobject handle) {
const oop* ptr = reinterpret_cast<oop*>(handle);
return object_handles()->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
}

jmetadata JVMCI::allocate_handle(const methodHandle& handle) {
assert(_metadata_handles != NULL, "uninitialized");
MutexLocker ml(JVMCI_lock);
return _metadata_handles->allocate_handle(handle);
}

jmetadata JVMCI::allocate_handle(const constantPoolHandle& handle) {
assert(_metadata_handles != NULL, "uninitialized");
MutexLocker ml(JVMCI_lock);
return _metadata_handles->allocate_handle(handle);
}

void JVMCI::release_handle(jmetadata handle) {
MutexLocker ml(JVMCI_lock);
_metadata_handles->chain_free_list(handle);
}

void JVMCI::metadata_do(void f(Metadata*)) {
if (_metadata_handles != NULL) {
_metadata_handles->metadata_do(f);
if (_java_runtime != NULL) {
_java_runtime->_metadata_handles->metadata_do(f);
}
if (_compiler_runtime != NULL && _compiler_runtime != _java_runtime) {
_compiler_runtime->_metadata_handles->metadata_do(f);
}
}

void JVMCI::do_unloading(bool unloading_occurred) {
if (_metadata_handles != NULL && unloading_occurred) {
_metadata_handles->do_unloading();
if (unloading_occurred) {
if (_java_runtime != NULL) {
_java_runtime->_metadata_handles->do_unloading();
}
if (_compiler_runtime != NULL && _compiler_runtime != _java_runtime) {
_compiler_runtime->_metadata_handles->do_unloading();
}
}
}

bool JVMCI::is_compiler_initialized() {
return compiler_runtime()->is_HotSpotJVMCIRuntime_initialized();
return _is_initialized;
}

void JVMCI::shutdown() {
ResourceMark rm;
{
MutexLocker locker(JVMCI_lock);
_in_shutdown = true;
TRACE_jvmci_1("shutting down JVMCI");
}
JVMCIRuntime* java_runtime = _java_runtime;
if (java_runtime != compiler_runtime()) {
java_runtime->shutdown();
}
if (compiler_runtime() != NULL) {
compiler_runtime()->shutdown();
}
}

bool JVMCI::shutdown_called() {
if (compiler_runtime() != NULL) {
return compiler_runtime()->shutdown_called();
}
return false;
bool JVMCI::in_shutdown() {
return _in_shutdown;
}
@@ -45,15 +45,24 @@ class JVMCI : public AllStatic {
friend class JVMCIEnv;

private:
// Handles to Metadata objects.
static MetadataHandleBlock* _metadata_handles;

// Access to the HotSpotJVMCIRuntime used by the CompileBroker.
static JVMCIRuntime* _compiler_runtime;

// Access to the HotSpotJVMCIRuntime used by Java code running on the
// HotSpot heap. It will be the same as _compiler_runtime if
// UseJVMCINativeLibrary is false
// True when at least one JVMCIRuntime::initialize_HotSpotJVMCIRuntime()
// execution has completed successfully.
static volatile bool _is_initialized;

// Handle created when loading the JVMCI shared library with os::dll_load.
// Must hold JVMCI_lock when initializing.
static void* _shared_library_handle;

// Argument to os::dll_load when loading JVMCI shared library
static char* _shared_library_path;

// Records whether JVMCI::shutdown has been called.
static volatile bool _in_shutdown;

// Access to the HotSpot heap based JVMCIRuntime
static JVMCIRuntime* _java_runtime;

public:
@@ -64,13 +73,20 @@ class JVMCI : public AllStatic {
code_too_large
};

// 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`. If
// `load` is true then JVMCI_lock must be locked.
static void* get_shared_library(char*& path, bool load);

static void do_unloading(bool unloading_occurred);

static void metadata_do(void f(Metadata*));

static void shutdown();

static bool shutdown_called();
// Returns whether JVMCI::shutdown has been called.
static bool in_shutdown();

static bool is_compiler_initialized();

@@ -83,16 +99,9 @@ class JVMCI : public AllStatic {

static void initialize_compiler(TRAPS);

static jobject make_global(const Handle& obj);
static void destroy_global(jobject handle);
static bool is_global_handle(jobject handle);

static jmetadata allocate_handle(const methodHandle& handle);
static jmetadata allocate_handle(const constantPoolHandle& handle);

static void release_handle(jmetadata handle);

static JVMCIRuntime* compiler_runtime() { return _compiler_runtime; }
// 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; }
};

@@ -99,39 +99,39 @@ void JVMCICompiler::bootstrap(TRAPS) {
(jlong)nanos_to_millis(os::javaTimeNanos() - start), _methods_compiled);
}
_bootstrapping = false;
JVMCI::compiler_runtime()->bootstrap_finished(CHECK);
JVMCI::java_runtime()->bootstrap_finished(CHECK);
}

bool JVMCICompiler::force_comp_at_level_simple(const methodHandle& method) {
if (UseJVMCINativeLibrary) {
// This mechanism exists to force compilation of a JVMCI compiler by C1
// to reduces the compilation time spent on the JVMCI compiler itself. In
// +UseJVMCINativeLibrary mode, the JVMCI compiler is AOT compiled.
return false;
}

if (_bootstrapping) {
// When bootstrapping, the JVMCI compiler can compile its own methods.
return false;
}

JVMCIRuntime* runtime = JVMCI::compiler_runtime();
if (runtime != NULL && runtime->is_HotSpotJVMCIRuntime_initialized()) {
JavaThread* thread = JavaThread::current();
HandleMark hm(thread);
THREAD_JVMCIENV(thread);
JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(JVMCIENV);
objArrayHandle excludeModules(thread, HotSpotJVMCI::HotSpotJVMCIRuntime::excludeFromJVMCICompilation(JVMCIENV, HotSpotJVMCI::resolve(receiver)));
if (excludeModules.not_null()) {
ModuleEntry* moduleEntry = method->method_holder()->module();
for (int i = 0; i < excludeModules->length(); i++) {
if (excludeModules->obj_at(i) == moduleEntry->module()) {
return true;
if (UseJVMCINativeLibrary) {
// This mechanism exists to force compilation of a JVMCI compiler by C1
// to reduce the compilation time spent on the JVMCI compiler itself. In
// +UseJVMCINativeLibrary mode, the JVMCI compiler is AOT compiled.
return false;
} else {
JVMCIRuntime* runtime = JVMCI::java_runtime();
if (runtime != NULL) {
JVMCIObject receiver = runtime->probe_HotSpotJVMCIRuntime();
if (receiver.is_null()) {
return false;
}
JVMCIEnv* ignored_env = NULL;
objArrayHandle excludeModules(JavaThread::current(), HotSpotJVMCI::HotSpotJVMCIRuntime::excludeFromJVMCICompilation(ignored_env, HotSpotJVMCI::resolve(receiver)));
if (excludeModules.not_null()) {
ModuleEntry* moduleEntry = method->method_holder()->module();
for (int i = 0; i < excludeModules->length(); i++) {
if (excludeModules->obj_at(i) == moduleEntry->module()) {
return true;
}
}
}
}
return false;
}
return false;
}

// Compilation entry point for methods

0 comments on commit 03d47d5

Please sign in to comment.