6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include "precompiled.hpp"
25 #include "compiler/compileBroker.hpp"
26 #include "jvmci/jniAccessMark.inline.hpp"
27 #include "jvmci/jvmciCompilerToVM.hpp"
28 #include "jvmci/jvmciRuntime.hpp"
29 #include "logging/log.hpp"
30 #include "memory/oopFactory.hpp"
31 #include "oops/constantPool.inline.hpp"
32 #include "oops/method.inline.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/biasedLocking.hpp"
35 #include "runtime/deoptimization.hpp"
36 #include "runtime/frame.inline.hpp"
37 #include "runtime/sharedRuntime.hpp"
38 #if INCLUDE_G1GC
39 #include "gc/g1/g1ThreadLocalData.hpp"
40 #endif // INCLUDE_G1GC
41
42 // Simple helper to see if the caller of a runtime stub which
43 // entered the VM has been deoptimized
44
45 static bool caller_is_deopted() {
46 JavaThread* thread = JavaThread::current();
47 RegisterMap reg_map(thread, false);
48 frame runtime_frame = thread->last_frame();
49 frame caller_frame = runtime_frame.sender(®_map);
50 assert(caller_frame.is_compiled_frame(), "must be compiled");
51 return caller_frame.is_deoptimized_frame();
52 }
53
54 // Stress deoptimization
55 static void deopt_caller() {
56 if ( !caller_is_deopted()) {
696 // We cannot use JVMCIObject to wrap the mirror as this is called
697 // during GC, forbidding the creation of JNIHandles.
698 JVMCIEnv* jvmciEnv = NULL;
699 nmethod* current = (nmethod*) HotSpotJVMCI::InstalledCode::address(jvmciEnv, nmethod_mirror);
700 if (nm == current) {
701 if (!nm->is_alive()) {
702 // Break the link from the mirror to nm such that
703 // future invocations via the mirror will result in
704 // an InvalidInstalledCodeException.
705 HotSpotJVMCI::InstalledCode::set_address(jvmciEnv, nmethod_mirror, 0);
706 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
707 } else if (nm->is_not_entrant()) {
708 // Zero the entry point so any new invocation will fail but keep
709 // the address link around that so that existing activations can
710 // be deoptimized via the mirror (i.e. JVMCIEnv::invalidate_installed_code).
711 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
712 }
713 }
714 }
715
716 void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS) {
717 if (is_HotSpotJVMCIRuntime_initialized()) {
718 if (JVMCIENV->is_hotspot() && UseJVMCINativeLibrary) {
719 JVMCI_THROW_MSG(InternalError, "JVMCI has already been enabled in the JVMCI shared library");
720 }
721 }
722
723 initialize(JVMCIENV);
724
725 // This should only be called in the context of the JVMCI class being initialized
726 JVMCIObject result = JVMCIENV->call_HotSpotJVMCIRuntime_runtime(JVMCI_CHECK);
727
728 _HotSpotJVMCIRuntime_instance = JVMCIENV->make_global(result);
729 }
730
731 void JVMCIRuntime::initialize(JVMCIEnv* JVMCIENV) {
732 assert(this != NULL, "sanity");
733 // Check first without JVMCI_lock
734 if (_initialized) {
735 return;
736 }
737
738 MutexLocker locker(JVMCI_lock);
739 // Check again under JVMCI_lock
740 if (_initialized) {
741 return;
742 }
743
744 while (_being_initialized) {
745 JVMCI_lock->wait();
746 if (_initialized) {
747 return;
748 }
749 }
750
751 _being_initialized = true;
752
753 {
754 MutexUnlocker unlock(JVMCI_lock);
755
756 HandleMark hm;
757 ResourceMark rm;
758 JavaThread* THREAD = JavaThread::current();
759 if (JVMCIENV->is_hotspot()) {
760 HotSpotJVMCI::compute_offsets(CHECK_EXIT);
761 } else {
762 JNIAccessMark jni(JVMCIENV);
763
764 JNIJVMCI::initialize_ids(jni.env());
765 if (jni()->ExceptionCheck()) {
766 jni()->ExceptionDescribe();
767 fatal("JNI exception during init");
768 }
769 }
770 create_jvmci_primitive_type(T_BOOLEAN, JVMCI_CHECK_EXIT_((void)0));
771 create_jvmci_primitive_type(T_BYTE, JVMCI_CHECK_EXIT_((void)0));
772 create_jvmci_primitive_type(T_CHAR, JVMCI_CHECK_EXIT_((void)0));
773 create_jvmci_primitive_type(T_SHORT, JVMCI_CHECK_EXIT_((void)0));
774 create_jvmci_primitive_type(T_INT, JVMCI_CHECK_EXIT_((void)0));
775 create_jvmci_primitive_type(T_LONG, JVMCI_CHECK_EXIT_((void)0));
776 create_jvmci_primitive_type(T_FLOAT, JVMCI_CHECK_EXIT_((void)0));
777 create_jvmci_primitive_type(T_DOUBLE, JVMCI_CHECK_EXIT_((void)0));
778 create_jvmci_primitive_type(T_VOID, JVMCI_CHECK_EXIT_((void)0));
779
780 if (!JVMCIENV->is_hotspot()) {
781 JVMCIENV->copy_saved_properties();
782 }
783 }
784
785 _initialized = true;
786 _being_initialized = false;
787 JVMCI_lock->notify_all();
788 }
789
790 JVMCIObject JVMCIRuntime::create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS) {
791 Thread* THREAD = Thread::current();
792 // These primitive types are long lived and are created before the runtime is fully set up
793 // so skip registering them for scanning.
794 JVMCIObject mirror = JVMCIENV->get_object_constant(java_lang_Class::primitive_mirror(type), false, true);
795 if (JVMCIENV->is_hotspot()) {
796 JavaValue result(T_OBJECT);
797 JavaCallArguments args;
798 args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(mirror)));
799 args.push_int(type2char(type));
800 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedPrimitiveType::klass(), vmSymbols::fromMetaspace_name(), vmSymbols::primitive_fromMetaspace_signature(), &args, CHECK_(JVMCIObject()));
801
802 return JVMCIENV->wrap(JNIHandles::make_local((oop)result.get_jobject()));
803 } else {
804 JNIAccessMark jni(JVMCIENV);
805 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedPrimitiveType::clazz(),
806 JNIJVMCI::HotSpotResolvedPrimitiveType_fromMetaspace_method(),
808 if (jni()->ExceptionCheck()) {
809 return JVMCIObject();
810 }
811 return JVMCIENV->wrap(result);
812 }
813 }
814
815 void JVMCIRuntime::initialize_JVMCI(JVMCI_TRAPS) {
816 if (!is_HotSpotJVMCIRuntime_initialized()) {
817 initialize(JVMCI_CHECK);
818 JVMCIENV->call_JVMCI_getRuntime(JVMCI_CHECK);
819 }
820 }
821
822 JVMCIObject JVMCIRuntime::get_HotSpotJVMCIRuntime(JVMCI_TRAPS) {
823 initialize(JVMCIENV);
824 initialize_JVMCI(JVMCI_CHECK_(JVMCIObject()));
825 return _HotSpotJVMCIRuntime_instance;
826 }
827
828
829 // private void CompilerToVM.registerNatives()
830 JVM_ENTRY_NO_ENV(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass))
831
832 #ifdef _LP64
833 #ifndef TARGET_ARCH_sparc
834 uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
835 uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
836 guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)");
837 #endif // TARGET_ARCH_sparc
838 #else
839 fatal("check TLAB allocation code for address space conflicts");
840 #endif
841
842 JNI_JVMCIENV(thread, env);
843
844 if (!EnableJVMCI) {
845 JVMCI_THROW_MSG(InternalError, "JVMCI is not enabled");
846 }
847
848 JVMCIENV->runtime()->initialize(JVMCIENV);
849
856 Universe::non_oop_word();
857
858 if (JNI_OK != env->RegisterNatives(c2vmClass, CompilerToVM::methods, CompilerToVM::methods_count())) {
859 if (!env->ExceptionCheck()) {
860 for (int i = 0; i < CompilerToVM::methods_count(); i++) {
861 if (JNI_OK != env->RegisterNatives(c2vmClass, CompilerToVM::methods + i, 1)) {
862 guarantee(false, "Error registering JNI method %s%s", CompilerToVM::methods[i].name, CompilerToVM::methods[i].signature);
863 break;
864 }
865 }
866 } else {
867 env->ExceptionDescribe();
868 }
869 guarantee(false, "Failed registering CompilerToVM native methods");
870 }
871 }
872 JVM_END
873
874
875 void JVMCIRuntime::shutdown() {
876 if (is_HotSpotJVMCIRuntime_initialized()) {
877 _shutdown_called = true;
878
879 THREAD_JVMCIENV(JavaThread::current());
880 JVMCIENV->call_HotSpotJVMCIRuntime_shutdown(_HotSpotJVMCIRuntime_instance);
881 }
882 }
883
884 void JVMCIRuntime::bootstrap_finished(TRAPS) {
885 if (is_HotSpotJVMCIRuntime_initialized()) {
886 THREAD_JVMCIENV(JavaThread::current());
887 JVMCIENV->call_HotSpotJVMCIRuntime_bootstrapFinished(_HotSpotJVMCIRuntime_instance, JVMCIENV);
888 }
889 }
890
891 void JVMCIRuntime::describe_pending_hotspot_exception(JavaThread* THREAD, bool clear) {
892 if (HAS_PENDING_EXCEPTION) {
893 Handle exception(THREAD, PENDING_EXCEPTION);
894 const char* exception_file = THREAD->exception_file();
895 int exception_line = THREAD->exception_line();
896 CLEAR_PENDING_EXCEPTION;
897 if (exception->is_a(SystemDictionary::ThreadDeath_klass())) {
898 // Don't print anything if we are being killed.
899 } else {
900 java_lang_Throwable::print_stack_trace(exception, tty);
901
902 // Clear and ignore any exceptions raised during printing
903 CLEAR_PENDING_EXCEPTION;
904 }
905 if (!clear) {
1305 // Only report a fatal JVMCI compilation exception once
1306 static volatile int report_init_failure = 0;
1307 if (!report_init_failure && Atomic::cmpxchg(1, &report_init_failure, 0) == 0) {
1308 tty->print_cr("%s:", msg);
1309 JVMCIENV->describe_pending_exception(true);
1310 }
1311 JVMCIENV->clear_pending_exception();
1312 before_exit(thread);
1313 vm_exit(-1);
1314 }
1315
1316 void JVMCIRuntime::compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& method, int entry_bci) {
1317 JVMCI_EXCEPTION_CONTEXT
1318
1319 JVMCICompileState* compile_state = JVMCIENV->compile_state();
1320
1321 bool is_osr = entry_bci != InvocationEntryBci;
1322 if (compiler->is_bootstrapping() && is_osr) {
1323 // no OSR compilations during bootstrap - the compiler is just too slow at this point,
1324 // and we know that there are no endless loops
1325 compile_state->set_failure(true, "No OSR during boostrap");
1326 return;
1327 }
1328 if (JVMCI::shutdown_called()) {
1329 compile_state->set_failure(false, "Avoiding compilation during shutdown");
1330 return;
1331 }
1332
1333 HandleMark hm;
1334 JVMCIObject receiver = get_HotSpotJVMCIRuntime(JVMCIENV);
1335 if (JVMCIENV->has_pending_exception()) {
1336 fatal_exception_in_compile(JVMCIENV, thread, "Exception during HotSpotJVMCIRuntime initialization");
1337 }
1338 JVMCIObject jvmci_method = JVMCIENV->get_jvmci_method(method, JVMCIENV);
1339 if (JVMCIENV->has_pending_exception()) {
1340 JVMCIENV->describe_pending_exception(true);
1341 compile_state->set_failure(false, "exception getting JVMCI wrapper method");
1342 return;
1343 }
1344
1345 JVMCIObject result_object = JVMCIENV->call_HotSpotJVMCIRuntime_compileMethod(receiver, jvmci_method, entry_bci,
1346 (jlong) compile_state, compile_state->task()->compile_id());
1347 if (!JVMCIENV->has_pending_exception()) {
1348 if (result_object.is_non_null()) {
1533 nm->make_in_use();
1534 }
1535 result = nm != NULL ? JVMCI::ok :JVMCI::cache_full;
1536 }
1537 }
1538
1539 // String creation must be done outside lock
1540 if (failure_detail != NULL) {
1541 // A failure to allocate the string is silently ignored.
1542 JVMCIObject message = JVMCIENV->create_string(failure_detail, JVMCIENV);
1543 JVMCIENV->set_HotSpotCompiledNmethod_installationFailureMessage(compiled_code, message);
1544 }
1545
1546 // JVMTI -- compiled method notification (must be done outside lock)
1547 if (nm != NULL) {
1548 nm->post_compiled_method_load_event();
1549 }
1550
1551 return result;
1552 }
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include "precompiled.hpp"
25 #include "compiler/compileBroker.hpp"
26 #include "gc/shared/oopStorage.inline.hpp"
27 #include "jvmci/jniAccessMark.inline.hpp"
28 #include "jvmci/jvmciCompilerToVM.hpp"
29 #include "jvmci/jvmciRuntime.hpp"
30 #include "jvmci/metadataHandles.hpp"
31 #include "logging/log.hpp"
32 #include "memory/oopFactory.hpp"
33 #include "oops/constantPool.inline.hpp"
34 #include "oops/method.inline.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "runtime/biasedLocking.hpp"
37 #include "runtime/deoptimization.hpp"
38 #include "runtime/frame.inline.hpp"
39 #include "runtime/jniHandles.inline.hpp"
40 #include "runtime/sharedRuntime.hpp"
41 #if INCLUDE_G1GC
42 #include "gc/g1/g1ThreadLocalData.hpp"
43 #endif // INCLUDE_G1GC
44
45 // Simple helper to see if the caller of a runtime stub which
46 // entered the VM has been deoptimized
47
48 static bool caller_is_deopted() {
49 JavaThread* thread = JavaThread::current();
50 RegisterMap reg_map(thread, false);
51 frame runtime_frame = thread->last_frame();
52 frame caller_frame = runtime_frame.sender(®_map);
53 assert(caller_frame.is_compiled_frame(), "must be compiled");
54 return caller_frame.is_deoptimized_frame();
55 }
56
57 // Stress deoptimization
58 static void deopt_caller() {
59 if ( !caller_is_deopted()) {
699 // We cannot use JVMCIObject to wrap the mirror as this is called
700 // during GC, forbidding the creation of JNIHandles.
701 JVMCIEnv* jvmciEnv = NULL;
702 nmethod* current = (nmethod*) HotSpotJVMCI::InstalledCode::address(jvmciEnv, nmethod_mirror);
703 if (nm == current) {
704 if (!nm->is_alive()) {
705 // Break the link from the mirror to nm such that
706 // future invocations via the mirror will result in
707 // an InvalidInstalledCodeException.
708 HotSpotJVMCI::InstalledCode::set_address(jvmciEnv, nmethod_mirror, 0);
709 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
710 } else if (nm->is_not_entrant()) {
711 // Zero the entry point so any new invocation will fail but keep
712 // the address link around that so that existing activations can
713 // be deoptimized via the mirror (i.e. JVMCIEnv::invalidate_installed_code).
714 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
715 }
716 }
717 }
718
719 OopStorage* JVMCIRuntime::create_object_handles(int id) {
720 FormatBuffer<> name("JVMCI %s Runtime %d Global Oop Handles", id == -1 ? "Java" : "Shared Library", id);
721 return new OopStorage(name, JVMCIGlobalAlloc_lock, JVMCIGlobalActive_lock);
722 }
723
724 JVMCIRuntime::JVMCIRuntime(int id) {
725 _init_state = uninitialized;
726 _shared_library_javavm = NULL;
727 _id = id;
728 _object_handles = new OopStorage(id == -1 ? "JVMCI Java Runtime Global Oop Handles" :
729 "JVMCI Shared Library Runtime Global Oop Handles",
730 JVMCIGlobalAlloc_lock,
731 JVMCIGlobalActive_lock);
732 _metadata_handles = new MetadataHandles();
733 TRACE_jvmci_1("created new JVMCI runtime %d (" PTR_FORMAT ")", id, p2i(this));
734 }
735
736 jobject JVMCIRuntime::make_global(const Handle& obj) {
737 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
738 assert(oopDesc::is_oop(obj()), "not an oop");
739 oop* ptr = _object_handles->allocate();
740 jobject res = NULL;
741 if (ptr != NULL) {
742 assert(*ptr == NULL, "invariant");
743 NativeAccess<>::oop_store(ptr, obj());
744 res = reinterpret_cast<jobject>(ptr);
745 } else {
746 vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
747 "Cannot create JVMCI oop handle");
748 }
749 return res;
750 }
751
752 void JVMCIRuntime::destroy_global(jobject handle) {
753 // Assert before nulling out, for better debugging.
754 assert(is_global_handle(handle), "precondition");
755 oop* oop_ptr = reinterpret_cast<oop*>(handle);
756 NativeAccess<>::oop_store(oop_ptr, (oop)NULL);
757 _object_handles->release(oop_ptr);
758 }
759
760 bool JVMCIRuntime::is_global_handle(jobject handle) {
761 const oop* ptr = reinterpret_cast<oop*>(handle);
762 return _object_handles->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
763 }
764
765 jmetadata JVMCIRuntime::allocate_handle(const methodHandle& handle) {
766 MutexLocker ml(JVMCI_lock);
767 return _metadata_handles->allocate_handle(handle);
768 }
769
770 jmetadata JVMCIRuntime::allocate_handle(const constantPoolHandle& handle) {
771 MutexLocker ml(JVMCI_lock);
772 return _metadata_handles->allocate_handle(handle);
773 }
774
775 void JVMCIRuntime::release_handle(jmetadata handle) {
776 MutexLocker ml(JVMCI_lock);
777 _metadata_handles->chain_free_list(handle);
778 }
779
780 JNIEnv* JVMCIRuntime::init_shared_library_javavm() {
781 JavaVM* javaVM = (JavaVM*) _shared_library_javavm;
782 if (javaVM == NULL) {
783 MutexLocker locker(JVMCI_lock);
784 // Check again under JVMCI_lock
785 javaVM = (JavaVM*) _shared_library_javavm;
786 if (javaVM != NULL) {
787 return NULL;
788 }
789 char* sl_path;
790 void* sl_handle = JVMCI::get_shared_library(sl_path, true);
791
792 jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
793 typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
794
795 JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(sl_handle, "JNI_CreateJavaVM"));
796 if (JNI_CreateJavaVM == NULL) {
797 vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", sl_path);
798 }
799
800 ResourceMark rm;
801 JavaVMInitArgs vm_args;
802 vm_args.version = JNI_VERSION_1_2;
803 vm_args.ignoreUnrecognized = JNI_TRUE;
804 JavaVMOption options[1];
805 jlong javaVM_id = 0;
806
807 // Protocol: JVMCI shared library JavaVM should support a non-standard "_javavm_id"
808 // option whose extraInfo info field is a pointer to which a unique id for the
809 // JavaVM should be written.
810 options[0].optionString = (char*) "_javavm_id";
811 options[0].extraInfo = &javaVM_id;
812
813 vm_args.version = JNI_VERSION_1_2;
814 vm_args.options = options;
815 vm_args.nOptions = sizeof(options) / sizeof(JavaVMOption);
816
817 JNIEnv* env = NULL;
818 int result = (*JNI_CreateJavaVM)(&javaVM, (void**) &env, &vm_args);
819 if (result == JNI_OK) {
820 guarantee(env != NULL, "missing env");
821 _shared_library_javavm = javaVM;
822 TRACE_jvmci_1("created JavaVM[%ld]@" PTR_FORMAT " for JVMCI runtime %d", javaVM_id, p2i(javaVM), _id);
823 return env;
824 } else {
825 vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), sl_path);
826 }
827 }
828 return NULL;
829 }
830
831 void JVMCIRuntime::init_JavaVM_info(jlongArray info, JVMCI_TRAPS) {
832 if (info != NULL) {
833 typeArrayOop info_oop = (typeArrayOop) JNIHandles::resolve(info);
834 if (info_oop->length() < 4) {
835 JVMCI_THROW_MSG(ArrayIndexOutOfBoundsException, err_msg("%d < 4", info_oop->length()));
836 }
837 JavaVM* javaVM = (JavaVM*) _shared_library_javavm;
838 info_oop->long_at_put(0, (jlong) (address) javaVM);
839 info_oop->long_at_put(1, (jlong) (address) javaVM->functions->reserved0);
840 info_oop->long_at_put(2, (jlong) (address) javaVM->functions->reserved1);
841 info_oop->long_at_put(3, (jlong) (address) javaVM->functions->reserved2);
842 }
843 }
844
845 #define JAVAVM_CALL_BLOCK \
846 guarantee(thread != NULL && _shared_library_javavm != NULL, "npe"); \
847 ThreadToNativeFromVM ttnfv(thread); \
848 JavaVM* javavm = (JavaVM*) _shared_library_javavm;
849
850 jint JVMCIRuntime::AttachCurrentThread(JavaThread* thread, void **penv, void *args) {
851 JAVAVM_CALL_BLOCK
852 return javavm->AttachCurrentThread(penv, args);
853 }
854
855 jint JVMCIRuntime::AttachCurrentThreadAsDaemon(JavaThread* thread, void **penv, void *args) {
856 JAVAVM_CALL_BLOCK
857 return javavm->AttachCurrentThreadAsDaemon(penv, args);
858 }
859
860 jint JVMCIRuntime::DetachCurrentThread(JavaThread* thread) {
861 JAVAVM_CALL_BLOCK
862 return javavm->DetachCurrentThread();
863 }
864
865 jint JVMCIRuntime::GetEnv(JavaThread* thread, void **penv, jint version) {
866 JAVAVM_CALL_BLOCK
867 return javavm->GetEnv(penv, version);
868 }
869 #undef JAVAVM_CALL_BLOCK \
870
871 void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS) {
872 if (is_HotSpotJVMCIRuntime_initialized()) {
873 if (JVMCIENV->is_hotspot() && UseJVMCINativeLibrary) {
874 JVMCI_THROW_MSG(InternalError, "JVMCI has already been enabled in the JVMCI shared library");
875 }
876 }
877
878 initialize(JVMCIENV);
879
880 // This should only be called in the context of the JVMCI class being initialized
881 JVMCIObject result = JVMCIENV->call_HotSpotJVMCIRuntime_runtime(JVMCI_CHECK);
882
883 _HotSpotJVMCIRuntime_instance = JVMCIENV->make_global(result);
884 JVMCI::_is_initialized = true;
885 }
886
887 void JVMCIRuntime::initialize(JVMCIEnv* JVMCIENV) {
888 // Check first without JVMCI_lock
889 if (_init_state == fully_initialized) {
890 return;
891 }
892
893 MutexLocker locker(JVMCI_lock);
894 // Check again under JVMCI_lock
895 if (_init_state == fully_initialized) {
896 return;
897 }
898
899 while (_init_state == being_initialized) {
900 TRACE_jvmci_1("waiting for initialization of JVMCI runtime %d", _id);
901 JVMCI_lock->wait();
902 if (_init_state == fully_initialized) {
903 TRACE_jvmci_1("done waiting for initialization of JVMCI runtime %d", _id);
904 return;
905 }
906 }
907
908 TRACE_jvmci_1("initializing JVMCI runtime %d", _id);
909 _init_state = being_initialized;
910
911 {
912 MutexUnlocker unlock(JVMCI_lock);
913
914 HandleMark hm;
915 ResourceMark rm;
916 JavaThread* THREAD = JavaThread::current();
917 if (JVMCIENV->is_hotspot()) {
918 HotSpotJVMCI::compute_offsets(CHECK_EXIT);
919 } else {
920 JNIAccessMark jni(JVMCIENV);
921
922 JNIJVMCI::initialize_ids(jni.env());
923 if (jni()->ExceptionCheck()) {
924 jni()->ExceptionDescribe();
925 fatal("JNI exception during init");
926 }
927 }
928
929 if (!JVMCIENV->is_hotspot()) {
930 JNIAccessMark jni(JVMCIENV, THREAD);
931 JNIJVMCI::register_natives(jni.env());
932 }
933 create_jvmci_primitive_type(T_BOOLEAN, JVMCI_CHECK_EXIT_((void)0));
934 create_jvmci_primitive_type(T_BYTE, JVMCI_CHECK_EXIT_((void)0));
935 create_jvmci_primitive_type(T_CHAR, JVMCI_CHECK_EXIT_((void)0));
936 create_jvmci_primitive_type(T_SHORT, JVMCI_CHECK_EXIT_((void)0));
937 create_jvmci_primitive_type(T_INT, JVMCI_CHECK_EXIT_((void)0));
938 create_jvmci_primitive_type(T_LONG, JVMCI_CHECK_EXIT_((void)0));
939 create_jvmci_primitive_type(T_FLOAT, JVMCI_CHECK_EXIT_((void)0));
940 create_jvmci_primitive_type(T_DOUBLE, JVMCI_CHECK_EXIT_((void)0));
941 create_jvmci_primitive_type(T_VOID, JVMCI_CHECK_EXIT_((void)0));
942
943 if (!JVMCIENV->is_hotspot()) {
944 JVMCIENV->copy_saved_properties();
945 }
946 }
947
948 _init_state = fully_initialized;
949 TRACE_jvmci_1("initialized JVMCI runtime %d", _id);
950 JVMCI_lock->notify_all();
951 }
952
953 JVMCIObject JVMCIRuntime::create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS) {
954 Thread* THREAD = Thread::current();
955 // These primitive types are long lived and are created before the runtime is fully set up
956 // so skip registering them for scanning.
957 JVMCIObject mirror = JVMCIENV->get_object_constant(java_lang_Class::primitive_mirror(type), false, true);
958 if (JVMCIENV->is_hotspot()) {
959 JavaValue result(T_OBJECT);
960 JavaCallArguments args;
961 args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(mirror)));
962 args.push_int(type2char(type));
963 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedPrimitiveType::klass(), vmSymbols::fromMetaspace_name(), vmSymbols::primitive_fromMetaspace_signature(), &args, CHECK_(JVMCIObject()));
964
965 return JVMCIENV->wrap(JNIHandles::make_local((oop)result.get_jobject()));
966 } else {
967 JNIAccessMark jni(JVMCIENV);
968 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedPrimitiveType::clazz(),
969 JNIJVMCI::HotSpotResolvedPrimitiveType_fromMetaspace_method(),
971 if (jni()->ExceptionCheck()) {
972 return JVMCIObject();
973 }
974 return JVMCIENV->wrap(result);
975 }
976 }
977
978 void JVMCIRuntime::initialize_JVMCI(JVMCI_TRAPS) {
979 if (!is_HotSpotJVMCIRuntime_initialized()) {
980 initialize(JVMCI_CHECK);
981 JVMCIENV->call_JVMCI_getRuntime(JVMCI_CHECK);
982 }
983 }
984
985 JVMCIObject JVMCIRuntime::get_HotSpotJVMCIRuntime(JVMCI_TRAPS) {
986 initialize(JVMCIENV);
987 initialize_JVMCI(JVMCI_CHECK_(JVMCIObject()));
988 return _HotSpotJVMCIRuntime_instance;
989 }
990
991 // private static void CompilerToVM.registerNatives()
992 JVM_ENTRY_NO_ENV(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass))
993
994 #ifdef _LP64
995 #ifndef TARGET_ARCH_sparc
996 uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
997 uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
998 guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)");
999 #endif // TARGET_ARCH_sparc
1000 #else
1001 fatal("check TLAB allocation code for address space conflicts");
1002 #endif
1003
1004 JNI_JVMCIENV(thread, env);
1005
1006 if (!EnableJVMCI) {
1007 JVMCI_THROW_MSG(InternalError, "JVMCI is not enabled");
1008 }
1009
1010 JVMCIENV->runtime()->initialize(JVMCIENV);
1011
1018 Universe::non_oop_word();
1019
1020 if (JNI_OK != env->RegisterNatives(c2vmClass, CompilerToVM::methods, CompilerToVM::methods_count())) {
1021 if (!env->ExceptionCheck()) {
1022 for (int i = 0; i < CompilerToVM::methods_count(); i++) {
1023 if (JNI_OK != env->RegisterNatives(c2vmClass, CompilerToVM::methods + i, 1)) {
1024 guarantee(false, "Error registering JNI method %s%s", CompilerToVM::methods[i].name, CompilerToVM::methods[i].signature);
1025 break;
1026 }
1027 }
1028 } else {
1029 env->ExceptionDescribe();
1030 }
1031 guarantee(false, "Failed registering CompilerToVM native methods");
1032 }
1033 }
1034 JVM_END
1035
1036
1037 void JVMCIRuntime::shutdown() {
1038 if (_HotSpotJVMCIRuntime_instance.is_non_null()) {
1039 TRACE_jvmci_1("shutting down HotSpotJVMCIRuntime for JVMCI runtime %d", _id);
1040 JVMCIEnv __stack_jvmci_env__(JavaThread::current(), _HotSpotJVMCIRuntime_instance.is_hotspot(), __FILE__, __LINE__);
1041 JVMCIEnv* JVMCIENV = &__stack_jvmci_env__;
1042 JVMCIENV->call_HotSpotJVMCIRuntime_shutdown(_HotSpotJVMCIRuntime_instance);
1043 TRACE_jvmci_1("shut down HotSpotJVMCIRuntime for JVMCI runtime %d", _id);
1044 }
1045 }
1046
1047 void JVMCIRuntime::bootstrap_finished(TRAPS) {
1048 if (_HotSpotJVMCIRuntime_instance.is_non_null()) {
1049 THREAD_JVMCIENV(JavaThread::current());
1050 JVMCIENV->call_HotSpotJVMCIRuntime_bootstrapFinished(_HotSpotJVMCIRuntime_instance, JVMCIENV);
1051 }
1052 }
1053
1054 void JVMCIRuntime::describe_pending_hotspot_exception(JavaThread* THREAD, bool clear) {
1055 if (HAS_PENDING_EXCEPTION) {
1056 Handle exception(THREAD, PENDING_EXCEPTION);
1057 const char* exception_file = THREAD->exception_file();
1058 int exception_line = THREAD->exception_line();
1059 CLEAR_PENDING_EXCEPTION;
1060 if (exception->is_a(SystemDictionary::ThreadDeath_klass())) {
1061 // Don't print anything if we are being killed.
1062 } else {
1063 java_lang_Throwable::print_stack_trace(exception, tty);
1064
1065 // Clear and ignore any exceptions raised during printing
1066 CLEAR_PENDING_EXCEPTION;
1067 }
1068 if (!clear) {
1468 // Only report a fatal JVMCI compilation exception once
1469 static volatile int report_init_failure = 0;
1470 if (!report_init_failure && Atomic::cmpxchg(1, &report_init_failure, 0) == 0) {
1471 tty->print_cr("%s:", msg);
1472 JVMCIENV->describe_pending_exception(true);
1473 }
1474 JVMCIENV->clear_pending_exception();
1475 before_exit(thread);
1476 vm_exit(-1);
1477 }
1478
1479 void JVMCIRuntime::compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& method, int entry_bci) {
1480 JVMCI_EXCEPTION_CONTEXT
1481
1482 JVMCICompileState* compile_state = JVMCIENV->compile_state();
1483
1484 bool is_osr = entry_bci != InvocationEntryBci;
1485 if (compiler->is_bootstrapping() && is_osr) {
1486 // no OSR compilations during bootstrap - the compiler is just too slow at this point,
1487 // and we know that there are no endless loops
1488 compile_state->set_failure(true, "No OSR during bootstrap");
1489 return;
1490 }
1491 if (JVMCI::in_shutdown()) {
1492 compile_state->set_failure(false, "Avoiding compilation during shutdown");
1493 return;
1494 }
1495
1496 HandleMark hm;
1497 JVMCIObject receiver = get_HotSpotJVMCIRuntime(JVMCIENV);
1498 if (JVMCIENV->has_pending_exception()) {
1499 fatal_exception_in_compile(JVMCIENV, thread, "Exception during HotSpotJVMCIRuntime initialization");
1500 }
1501 JVMCIObject jvmci_method = JVMCIENV->get_jvmci_method(method, JVMCIENV);
1502 if (JVMCIENV->has_pending_exception()) {
1503 JVMCIENV->describe_pending_exception(true);
1504 compile_state->set_failure(false, "exception getting JVMCI wrapper method");
1505 return;
1506 }
1507
1508 JVMCIObject result_object = JVMCIENV->call_HotSpotJVMCIRuntime_compileMethod(receiver, jvmci_method, entry_bci,
1509 (jlong) compile_state, compile_state->task()->compile_id());
1510 if (!JVMCIENV->has_pending_exception()) {
1511 if (result_object.is_non_null()) {
1696 nm->make_in_use();
1697 }
1698 result = nm != NULL ? JVMCI::ok :JVMCI::cache_full;
1699 }
1700 }
1701
1702 // String creation must be done outside lock
1703 if (failure_detail != NULL) {
1704 // A failure to allocate the string is silently ignored.
1705 JVMCIObject message = JVMCIENV->create_string(failure_detail, JVMCIENV);
1706 JVMCIENV->set_HotSpotCompiledNmethod_installationFailureMessage(compiled_code, message);
1707 }
1708
1709 // JVMTI -- compiled method notification (must be done outside lock)
1710 if (nm != NULL) {
1711 nm->post_compiled_method_load_event();
1712 }
1713
1714 return result;
1715 }
1716
1717 bool JVMCIRuntime::trace_prefix(int level) {
1718 Thread* thread = Thread::current_or_null_safe();
1719 if (thread != NULL) {
1720 ResourceMark rm;
1721 tty->print("JVMCITrace-%d[%s]:%*c", level, thread == NULL ? "?" : thread->name(), level, ' ');
1722 } else {
1723 tty->print("JVMCITrace-%d[?]:%*c", level, level, ' ');
1724 }
1725 return true;
1726 }
|