< 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 >