Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions make/conf/module-loader-map.conf
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -79,6 +78,7 @@ PLATFORM_MODULES= \
jdk.crypto.cryptoki \
jdk.dynalink \
jdk.httpserver \
jdk.internal.vm.ci \
jdk.jsobject \
jdk.localedata \
jdk.naming.dns \
Expand Down
8 changes: 5 additions & 3 deletions src/hotspot/share/jvmci/jvmciJavaClasses.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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) { \
Expand Down Expand Up @@ -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<Method*>* methods = iklass->methods(); \
for (int i = 0; i < methods->length(); i++) { \
Expand Down
19 changes: 16 additions & 3 deletions src/hotspot/share/prims/nativeLookup.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions src/java.base/share/lib/security/default.policy
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ grant codeBase "jrt:/jdk.internal.le" {
permission java.security.AllPermission;
};

grant codeBase "jrt:/jdk.internal.vm.ci" {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required as JVMCI is no longer loaded by the boot loader but should retain all permissions.

permission java.security.AllPermission;
};

grant codeBase "jrt:/jdk.graal.compiler" {
permission java.security.AllPermission;
};
Expand Down
96 changes: 96 additions & 0 deletions test/hotspot/jtreg/compiler/jvmci/LoadAlternativeJVMCI.java
Original file line number Diff line number Diff line change
@@ -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();
Copy link
Contributor

@AlanBateman AlanBateman Jan 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be cp[i] = file.toURI().toURL() as a file path needs encoding to be URI path component.

}

ClassLoader pcl = ClassLoader.getPlatformClassLoader();
URLClassLoader ucl = new URLClassLoader(cp, null);
Comment on lines +53 to +54
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am missing something here, a URLClassLoader first delegates to its parent before searching its URLs, so how does this not find the platform loader versions of the JVMCI classes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With new URLClassLoader(cp, null), the URL loader delegates directly to the boot loader, by-passing the platform loader.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<face-palm>

Thanks Doug.


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());
}
}
}
}
}
}
37 changes: 37 additions & 0 deletions test/hotspot/jtreg/compiler/jvmci/alt/CompilerToVM.java
Original file line number Diff line number Diff line change
@@ -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();
}

}
30 changes: 30 additions & 0 deletions test/hotspot/jtreg/compiler/jvmci/alt/HotSpotJVMCIRuntime.java
Original file line number Diff line number Diff line change
@@ -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 {
}
30 changes: 30 additions & 0 deletions test/hotspot/jtreg/compiler/jvmci/alt/ResolvedJavaType.java
Original file line number Diff line number Diff line change
@@ -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 {
}