diff --git a/make/conf/module-loader-map.conf b/make/conf/module-loader-map.conf index ca09d23b02b18..d36e30e33f140 100644 --- a/make/conf/module-loader-map.conf +++ b/make/conf/module-loader-map.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,6 @@ BOOT_MODULES= \ java.security.sasl \ java.xml \ jdk.incubator.vector \ - jdk.internal.vm.ci \ jdk.jfr \ jdk.management \ jdk.management.jfr \ @@ -79,6 +78,7 @@ PLATFORM_MODULES= \ jdk.crypto.cryptoki \ jdk.dynalink \ jdk.httpserver \ + jdk.internal.vm.ci \ jdk.jsobject \ jdk.localedata \ jdk.naming.dns \ diff --git a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp index 8bec6aa37db9b..e35af58fa35bf 100644 --- a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp +++ b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -126,7 +126,8 @@ jmethodID JNIJVMCI::_HotSpotResolvedObjectTypeImpl_fromMetaspace_method; jmethodID JNIJVMCI::_HotSpotResolvedPrimitiveType_fromMetaspace_method; #define START_CLASS(className, fullClassName) { \ - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::fullClassName(), true, CHECK); \ + Handle cl = Handle(THREAD, SystemDictionary::java_platform_loader()); \ + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::fullClassName(), cl, Handle(), true, CHECK); \ InstanceKlass* current = className::_klass; \ if (current != InstanceKlass::cast(k)) { \ if (current != nullptr) { \ @@ -515,7 +516,8 @@ void JNIJVMCI::initialize_ids(JNIEnv* env) { #define DUMP_ALL_NATIVE_METHODS(class_symbol) do { \ current_class_name = class_symbol->as_C_string(); \ - Klass* k = SystemDictionary::resolve_or_fail(class_symbol, true, CHECK_EXIT); \ + Handle cl = Handle(THREAD, SystemDictionary::java_platform_loader()); \ + Klass* k = SystemDictionary::resolve_or_fail(class_symbol, cl, Handle(), true, CHECK_EXIT); \ InstanceKlass* iklass = InstanceKlass::cast(k); \ Array* methods = iklass->methods(); \ for (int i = 0; i < methods->length(); i++) { \ diff --git a/src/hotspot/share/prims/nativeLookup.cpp b/src/hotspot/share/prims/nativeLookup.cpp index e838c831ff1ab..fa2e94ec5bf10 100644 --- a/src/hotspot/share/prims/nativeLookup.cpp +++ b/src/hotspot/share/prims/nativeLookup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -260,8 +260,8 @@ address NativeLookup::lookup_style(const methodHandle& method, char* pure_name, // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_findNative // gets found the first time around - otherwise an infinite loop can occur. This is // another VM/library dependency - Handle loader(THREAD, method->method_holder()->class_loader()); - if (loader.is_null()) { + ClassLoaderData* cld = method->method_holder()->class_loader_data(); + if (cld->is_boot_class_loader_data()) { entry = lookup_special_native(jni_name); if (entry == nullptr) { entry = (address) os::dll_lookup(os::native_java_library(), jni_name); @@ -271,10 +271,23 @@ address NativeLookup::lookup_style(const methodHandle& method, char* pure_name, } } +#if INCLUDE_JVMCI + // Look for JVMCI natives if the method is loaded by the platform class loader + // and the JNI name denotes a JVMCI class. JVMCI native methods loaded + // by any other class loader will fail to link. + if (cld->is_platform_class_loader_data() && strncmp("Java_jdk_vm_ci_", jni_name, strlen("Java_jdk_vm_ci_")) == 0) { + entry = lookup_special_native(jni_name); + if (entry != nullptr) { + return entry; + } + } +#endif + // Otherwise call static method findNative in ClassLoader Klass* klass = vmClasses::ClassLoader_klass(); Handle name_arg = java_lang_String::create_from_str(jni_name, CHECK_NULL); + Handle loader(THREAD, cld->class_loader()); JavaValue result(T_LONG); JavaCalls::call_static(&result, klass, diff --git a/src/java.base/share/lib/security/default.policy b/src/java.base/share/lib/security/default.policy index aa67bd6b53e66..c2b7fdd080831 100644 --- a/src/java.base/share/lib/security/default.policy +++ b/src/java.base/share/lib/security/default.policy @@ -163,6 +163,10 @@ grant codeBase "jrt:/jdk.internal.le" { permission java.security.AllPermission; }; +grant codeBase "jrt:/jdk.internal.vm.ci" { + permission java.security.AllPermission; +}; + grant codeBase "jrt:/jdk.graal.compiler" { permission java.security.AllPermission; }; diff --git a/test/hotspot/jtreg/compiler/jvmci/LoadAlternativeJVMCI.java b/test/hotspot/jtreg/compiler/jvmci/LoadAlternativeJVMCI.java new file mode 100644 index 0000000000000..dd63867e7c239 --- /dev/null +++ b/test/hotspot/jtreg/compiler/jvmci/LoadAlternativeJVMCI.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Tests that it is possible to load JVMCI classes from a custom class loader and + * that the loaded class is different than the classes loaded by the platform loader. + * This test also ensures that only JVMCI classes loaded by the platform loader + * will have their native methods linked to implementations in the JVM. + * @modules java.base/jdk.internal.loader:+open + * @compile alt/ResolvedJavaType.java + * @compile alt/HotSpotJVMCIRuntime.java + * @compile alt/CompilerToVM.java + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI LoadAlternativeJVMCI + */ +import java.io.File; +import java.net.URL; +import java.net.URI; +import java.net.URLClassLoader; + +public class LoadAlternativeJVMCI { + public static void main(String[] args) throws Exception { + String[] testClasses = System.getProperty("test.classes").split(File.pathSeparator); + URL[] cp = new URL[testClasses.length]; + for (int i = 0; i < testClasses.length; i++) { + String e = testClasses[i]; + if (new File(e).isDirectory()) { + e = e + File.separator; + } + cp[i] = new URI("file:" + e).toURL(); + } + + ClassLoader pcl = ClassLoader.getPlatformClassLoader(); + URLClassLoader ucl = new URLClassLoader(cp, null); + + String[] names = { + "jdk.vm.ci.meta.ResolvedJavaType", + "jdk.vm.ci.hotspot.CompilerToVM", + "jdk.vm.ci.hotspot.HotSpotJVMCIRuntime" + }; + for (String name : names) { + Class customClass = ucl.loadClass(name); + Class platformClass = pcl.loadClass(name); + if (customClass.equals(platformClass)) { + throw new AssertionError(String.format("%s loaded by %s should be distinct from version loaded by %s", + name, ucl, pcl)); + } + Class customClassAgain = ucl.loadClass(name); + if (!customClassAgain.equals(customClass)) { + throw new AssertionError(String.format("%s loaded twice by %s should produce the same class", + name, ucl)); + } + + if (name.equals("jdk.vm.ci.hotspot.CompilerToVM")) { + // Detect refactoring of CompilerToVM.registerNatives so that alt/CompilerToVM.java + // can be adjusted accordingly. + try { + platformClass.getDeclaredMethod("registerNatives"); + } catch (NoSuchMethodException e) { + throw new AssertionError("missing method in platform JVMCI class: " + e); + } + + // Only JVMCI classes loaded by the platform class loader can link to native + // method implementations in HotSpot. + try { + Class.forName(name, true, ucl); + throw new AssertionError("expected UnsatisfiedLinkError"); + } catch (UnsatisfiedLinkError e) { + if (!e.getMessage().contains(name + ".registerNatives")) { + throw new AssertionError("unexpected message: " + e.getMessage()); + } + } + } + } + } +} diff --git a/test/hotspot/jtreg/compiler/jvmci/alt/CompilerToVM.java b/test/hotspot/jtreg/compiler/jvmci/alt/CompilerToVM.java new file mode 100644 index 0000000000000..59e08fb7257e3 --- /dev/null +++ b/test/hotspot/jtreg/compiler/jvmci/alt/CompilerToVM.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * Alternative version of CompilerToVM + * @see LoadAlternativeJVMCI + */ +public class CompilerToVM { + + private static native void registerNatives(); + + static { + registerNatives(); + } + +} diff --git a/test/hotspot/jtreg/compiler/jvmci/alt/HotSpotJVMCIRuntime.java b/test/hotspot/jtreg/compiler/jvmci/alt/HotSpotJVMCIRuntime.java new file mode 100644 index 0000000000000..0006d28cd4d67 --- /dev/null +++ b/test/hotspot/jtreg/compiler/jvmci/alt/HotSpotJVMCIRuntime.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +/** + * Alternative version of HotSpotJVMCIRuntime + * @see LoadAlternativeJVMCI + */ +public class HotSpotJVMCIRuntime { +} diff --git a/test/hotspot/jtreg/compiler/jvmci/alt/ResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/alt/ResolvedJavaType.java new file mode 100644 index 0000000000000..04a7b3e0ed295 --- /dev/null +++ b/test/hotspot/jtreg/compiler/jvmci/alt/ResolvedJavaType.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Alternative version of HotSpotJVMCIRuntime + * @see LoadAlternativeJVMCI + */ +public class ResolvedJavaType { +}