< prev index next >
src/hotspot/share/jvmci/jvmciRuntime.cpp
Print this page
*** 21,41 ****
--- 21,44 ----
* questions.
*/
#include "precompiled.hpp"
#include "compiler/compileBroker.hpp"
+ #include "gc/shared/oopStorage.inline.hpp"
#include "jvmci/jniAccessMark.inline.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciRuntime.hpp"
+ #include "jvmci/metadataHandles.hpp"
#include "logging/log.hpp"
#include "memory/oopFactory.hpp"
#include "oops/constantPool.inline.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
+ #include "runtime/jniHandles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#if INCLUDE_G1GC
#include "gc/g1/g1ThreadLocalData.hpp"
#endif // INCLUDE_G1GC
*** 711,720 ****
--- 714,875 ----
HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
}
}
}
+ OopStorage* JVMCIRuntime::create_object_handles(int id) {
+ FormatBuffer<> name("JVMCI %s Runtime %d Global Oop Handles", id == -1 ? "Java" : "Shared Library", id);
+ return new OopStorage(name, JVMCIGlobalAlloc_lock, JVMCIGlobalActive_lock);
+ }
+
+ JVMCIRuntime::JVMCIRuntime(int id) {
+ _init_state = uninitialized;
+ _shared_library_javavm = NULL;
+ _id = id;
+ _object_handles = new OopStorage(id == -1 ? "JVMCI Java Runtime Global Oop Handles" :
+ "JVMCI Shared Library Runtime Global Oop Handles",
+ JVMCIGlobalAlloc_lock,
+ JVMCIGlobalActive_lock);
+ _metadata_handles = new MetadataHandles();
+ TRACE_jvmci_1("created new JVMCI runtime %d (" PTR_FORMAT ")", id, p2i(this));
+ }
+
+ jobject JVMCIRuntime::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");
+ }
+ return res;
+ }
+
+ void JVMCIRuntime::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 JVMCIRuntime::is_global_handle(jobject handle) {
+ const oop* ptr = reinterpret_cast<oop*>(handle);
+ return _object_handles->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
+ }
+
+ jmetadata JVMCIRuntime::allocate_handle(const methodHandle& handle) {
+ MutexLocker ml(JVMCI_lock);
+ return _metadata_handles->allocate_handle(handle);
+ }
+
+ jmetadata JVMCIRuntime::allocate_handle(const constantPoolHandle& handle) {
+ MutexLocker ml(JVMCI_lock);
+ return _metadata_handles->allocate_handle(handle);
+ }
+
+ void JVMCIRuntime::release_handle(jmetadata handle) {
+ MutexLocker ml(JVMCI_lock);
+ _metadata_handles->chain_free_list(handle);
+ }
+
+ JNIEnv* JVMCIRuntime::init_shared_library_javavm() {
+ JavaVM* javaVM = (JavaVM*) _shared_library_javavm;
+ if (javaVM == NULL) {
+ MutexLocker locker(JVMCI_lock);
+ // Check again under JVMCI_lock
+ javaVM = (JavaVM*) _shared_library_javavm;
+ if (javaVM != NULL) {
+ return NULL;
+ }
+ char* sl_path;
+ void* sl_handle = JVMCI::get_shared_library(sl_path, true);
+
+ jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
+ typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
+
+ JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(sl_handle, "JNI_CreateJavaVM"));
+ if (JNI_CreateJavaVM == NULL) {
+ vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", sl_path);
+ }
+
+ ResourceMark rm;
+ JavaVMInitArgs vm_args;
+ vm_args.version = JNI_VERSION_1_2;
+ vm_args.ignoreUnrecognized = JNI_TRUE;
+ JavaVMOption options[1];
+ jlong javaVM_id = 0;
+
+ // Protocol: JVMCI shared library JavaVM should support a non-standard "_javavm_id"
+ // option whose extraInfo info field is a pointer to which a unique id for the
+ // JavaVM should be written.
+ options[0].optionString = (char*) "_javavm_id";
+ options[0].extraInfo = &javaVM_id;
+
+ vm_args.version = JNI_VERSION_1_2;
+ vm_args.options = options;
+ vm_args.nOptions = sizeof(options) / sizeof(JavaVMOption);
+
+ JNIEnv* env = NULL;
+ int result = (*JNI_CreateJavaVM)(&javaVM, (void**) &env, &vm_args);
+ if (result == JNI_OK) {
+ guarantee(env != NULL, "missing env");
+ _shared_library_javavm = javaVM;
+ TRACE_jvmci_1("created JavaVM[%ld]@" PTR_FORMAT " for JVMCI runtime %d", javaVM_id, p2i(javaVM), _id);
+ return env;
+ } else {
+ vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), sl_path);
+ }
+ }
+ return NULL;
+ }
+
+ void JVMCIRuntime::init_JavaVM_info(jlongArray info, JVMCI_TRAPS) {
+ if (info != NULL) {
+ typeArrayOop info_oop = (typeArrayOop) JNIHandles::resolve(info);
+ if (info_oop->length() < 4) {
+ JVMCI_THROW_MSG(ArrayIndexOutOfBoundsException, err_msg("%d < 4", info_oop->length()));
+ }
+ JavaVM* javaVM = (JavaVM*) _shared_library_javavm;
+ info_oop->long_at_put(0, (jlong) (address) javaVM);
+ info_oop->long_at_put(1, (jlong) (address) javaVM->functions->reserved0);
+ info_oop->long_at_put(2, (jlong) (address) javaVM->functions->reserved1);
+ info_oop->long_at_put(3, (jlong) (address) javaVM->functions->reserved2);
+ }
+ }
+
+ #define JAVAVM_CALL_BLOCK \
+ guarantee(thread != NULL && _shared_library_javavm != NULL, "npe"); \
+ ThreadToNativeFromVM ttnfv(thread); \
+ JavaVM* javavm = (JavaVM*) _shared_library_javavm;
+
+ jint JVMCIRuntime::AttachCurrentThread(JavaThread* thread, void **penv, void *args) {
+ JAVAVM_CALL_BLOCK
+ return javavm->AttachCurrentThread(penv, args);
+ }
+
+ jint JVMCIRuntime::AttachCurrentThreadAsDaemon(JavaThread* thread, void **penv, void *args) {
+ JAVAVM_CALL_BLOCK
+ return javavm->AttachCurrentThreadAsDaemon(penv, args);
+ }
+
+ jint JVMCIRuntime::DetachCurrentThread(JavaThread* thread) {
+ JAVAVM_CALL_BLOCK
+ return javavm->DetachCurrentThread();
+ }
+
+ jint JVMCIRuntime::GetEnv(JavaThread* thread, void **penv, jint version) {
+ JAVAVM_CALL_BLOCK
+ return javavm->GetEnv(penv, version);
+ }
+ #undef JAVAVM_CALL_BLOCK \
+
void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS) {
if (is_HotSpotJVMCIRuntime_initialized()) {
if (JVMCIENV->is_hotspot() && UseJVMCINativeLibrary) {
JVMCI_THROW_MSG(InternalError, "JVMCI has already been enabled in the JVMCI shared library");
}
*** 724,756 ****
// This should only be called in the context of the JVMCI class being initialized
JVMCIObject result = JVMCIENV->call_HotSpotJVMCIRuntime_runtime(JVMCI_CHECK);
_HotSpotJVMCIRuntime_instance = JVMCIENV->make_global(result);
}
void JVMCIRuntime::initialize(JVMCIEnv* JVMCIENV) {
- assert(this != NULL, "sanity");
// Check first without JVMCI_lock
! if (_initialized) {
return;
}
MutexLocker locker(JVMCI_lock);
// Check again under JVMCI_lock
! if (_initialized) {
return;
}
! while (_being_initialized) {
JVMCI_lock->wait();
! if (_initialized) {
return;
}
}
! _being_initialized = true;
{
MutexUnlocker unlock(JVMCI_lock);
HandleMark hm;
--- 879,914 ----
// This should only be called in the context of the JVMCI class being initialized
JVMCIObject result = JVMCIENV->call_HotSpotJVMCIRuntime_runtime(JVMCI_CHECK);
_HotSpotJVMCIRuntime_instance = JVMCIENV->make_global(result);
+ JVMCI::_is_initialized = true;
}
void JVMCIRuntime::initialize(JVMCIEnv* JVMCIENV) {
// Check first without JVMCI_lock
! if (_init_state == fully_initialized) {
return;
}
MutexLocker locker(JVMCI_lock);
// Check again under JVMCI_lock
! if (_init_state == fully_initialized) {
return;
}
! while (_init_state == being_initialized) {
! TRACE_jvmci_1("waiting for initialization of JVMCI runtime %d", _id);
JVMCI_lock->wait();
! if (_init_state == fully_initialized) {
! TRACE_jvmci_1("done waiting for initialization of JVMCI runtime %d", _id);
return;
}
}
! TRACE_jvmci_1("initializing JVMCI runtime %d", _id);
! _init_state = being_initialized;
{
MutexUnlocker unlock(JVMCI_lock);
HandleMark hm;
*** 765,774 ****
--- 923,937 ----
if (jni()->ExceptionCheck()) {
jni()->ExceptionDescribe();
fatal("JNI exception during init");
}
}
+
+ if (!JVMCIENV->is_hotspot()) {
+ JNIAccessMark jni(JVMCIENV, THREAD);
+ JNIJVMCI::register_natives(jni.env());
+ }
create_jvmci_primitive_type(T_BOOLEAN, JVMCI_CHECK_EXIT_((void)0));
create_jvmci_primitive_type(T_BYTE, JVMCI_CHECK_EXIT_((void)0));
create_jvmci_primitive_type(T_CHAR, JVMCI_CHECK_EXIT_((void)0));
create_jvmci_primitive_type(T_SHORT, JVMCI_CHECK_EXIT_((void)0));
create_jvmci_primitive_type(T_INT, JVMCI_CHECK_EXIT_((void)0));
*** 780,791 ****
if (!JVMCIENV->is_hotspot()) {
JVMCIENV->copy_saved_properties();
}
}
! _initialized = true;
! _being_initialized = false;
JVMCI_lock->notify_all();
}
JVMCIObject JVMCIRuntime::create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS) {
Thread* THREAD = Thread::current();
--- 943,954 ----
if (!JVMCIENV->is_hotspot()) {
JVMCIENV->copy_saved_properties();
}
}
! _init_state = fully_initialized;
! TRACE_jvmci_1("initialized JVMCI runtime %d", _id);
JVMCI_lock->notify_all();
}
JVMCIObject JVMCIRuntime::create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS) {
Thread* THREAD = Thread::current();
*** 823,834 ****
initialize(JVMCIENV);
initialize_JVMCI(JVMCI_CHECK_(JVMCIObject()));
return _HotSpotJVMCIRuntime_instance;
}
!
! // private void CompilerToVM.registerNatives()
JVM_ENTRY_NO_ENV(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass))
#ifdef _LP64
#ifndef TARGET_ARCH_sparc
uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
--- 986,996 ----
initialize(JVMCIENV);
initialize_JVMCI(JVMCI_CHECK_(JVMCIObject()));
return _HotSpotJVMCIRuntime_instance;
}
! // private static void CompilerToVM.registerNatives()
JVM_ENTRY_NO_ENV(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass))
#ifdef _LP64
#ifndef TARGET_ARCH_sparc
uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
*** 871,890 ****
}
JVM_END
void JVMCIRuntime::shutdown() {
! if (is_HotSpotJVMCIRuntime_initialized()) {
! _shutdown_called = true;
!
! THREAD_JVMCIENV(JavaThread::current());
JVMCIENV->call_HotSpotJVMCIRuntime_shutdown(_HotSpotJVMCIRuntime_instance);
}
}
void JVMCIRuntime::bootstrap_finished(TRAPS) {
! if (is_HotSpotJVMCIRuntime_initialized()) {
THREAD_JVMCIENV(JavaThread::current());
JVMCIENV->call_HotSpotJVMCIRuntime_bootstrapFinished(_HotSpotJVMCIRuntime_instance, JVMCIENV);
}
}
--- 1033,1053 ----
}
JVM_END
void JVMCIRuntime::shutdown() {
! if (_HotSpotJVMCIRuntime_instance.is_non_null()) {
! TRACE_jvmci_1("shutting down HotSpotJVMCIRuntime for JVMCI runtime %d", _id);
! JVMCIEnv __stack_jvmci_env__(JavaThread::current(), _HotSpotJVMCIRuntime_instance.is_hotspot(), __FILE__, __LINE__);
! JVMCIEnv* JVMCIENV = &__stack_jvmci_env__;
JVMCIENV->call_HotSpotJVMCIRuntime_shutdown(_HotSpotJVMCIRuntime_instance);
+ TRACE_jvmci_1("shut down HotSpotJVMCIRuntime for JVMCI runtime %d", _id);
}
}
void JVMCIRuntime::bootstrap_finished(TRAPS) {
! if (_HotSpotJVMCIRuntime_instance.is_non_null()) {
THREAD_JVMCIENV(JavaThread::current());
JVMCIENV->call_HotSpotJVMCIRuntime_bootstrapFinished(_HotSpotJVMCIRuntime_instance, JVMCIENV);
}
}
*** 1320,1333 ****
bool is_osr = entry_bci != InvocationEntryBci;
if (compiler->is_bootstrapping() && is_osr) {
// no OSR compilations during bootstrap - the compiler is just too slow at this point,
// and we know that there are no endless loops
! compile_state->set_failure(true, "No OSR during boostrap");
return;
}
! if (JVMCI::shutdown_called()) {
compile_state->set_failure(false, "Avoiding compilation during shutdown");
return;
}
HandleMark hm;
--- 1483,1496 ----
bool is_osr = entry_bci != InvocationEntryBci;
if (compiler->is_bootstrapping() && is_osr) {
// no OSR compilations during bootstrap - the compiler is just too slow at this point,
// and we know that there are no endless loops
! compile_state->set_failure(true, "No OSR during bootstrap");
return;
}
! if (JVMCI::in_shutdown()) {
compile_state->set_failure(false, "Avoiding compilation during shutdown");
return;
}
HandleMark hm;
*** 1548,1552 ****
--- 1711,1726 ----
nm->post_compiled_method_load_event();
}
return result;
}
+
+ bool JVMCIRuntime::trace_prefix(int level) {
+ Thread* thread = Thread::current_or_null_safe();
+ if (thread != NULL) {
+ ResourceMark rm;
+ tty->print("JVMCITrace-%d[%s]:%*c", level, thread == NULL ? "?" : thread->name(), level, ' ');
+ } else {
+ tty->print("JVMCITrace-%d[?]:%*c", level, level, ' ');
+ }
+ return true;
+ }
< prev index next >