Skip to content

Commit 0895366

Browse files
author
Christian Wimmer
committed
[GR-41998] Support JNI_VERSION_19.
PullRequest: graal/12995
2 parents 5fa7da8 + abd31e9 commit 0895366

File tree

9 files changed

+233
-5
lines changed

9 files changed

+233
-5
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionTables.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package com.oracle.svm.core.jni.functions;
2626

27+
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
2728
import org.graalvm.compiler.word.Word;
2829
import org.graalvm.nativeimage.CurrentIsolate;
2930
import org.graalvm.nativeimage.ImageSingletons;
@@ -42,6 +43,7 @@
4243
import com.oracle.svm.core.jni.headers.JNIInvokeInterface;
4344
import com.oracle.svm.core.jni.headers.JNIJavaVM;
4445
import com.oracle.svm.core.jni.headers.JNINativeInterface;
46+
import com.oracle.svm.core.jni.headers.JNINativeInterfaceJDK19OrLater;
4547
import com.oracle.svm.core.util.VMError;
4648

4749
/**
@@ -71,7 +73,7 @@ private JNIFunctionTables() {
7173
javaVMData = new WordBase[wordArrayLength(SizeOf.get(JNIJavaVM.class))];
7274
invokeInterfaceDataMutable = new WordBase[wordArrayLength(SizeOf.get(JNIInvokeInterface.class))];
7375
invokeInterfaceDataPrototype = new CFunctionPointer[wordArrayLength(SizeOf.get(JNIInvokeInterface.class))];
74-
functionTableData = new CFunctionPointer[wordArrayLength(SizeOf.get(JNINativeInterface.class))];
76+
functionTableData = new CFunctionPointer[wordArrayLength(JavaVersionUtil.JAVA_SPEC <= 17 ? SizeOf.get(JNINativeInterface.class) : SizeOf.get(JNINativeInterfaceJDK19OrLater.class))];
7577
}
7678

7779
@Platforms(Platform.HOSTED_ONLY.class)

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctions.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
import org.graalvm.compiler.core.common.SuppressFBWarnings;
3939
import org.graalvm.compiler.nodes.java.ArrayLengthNode;
40+
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
4041
import org.graalvm.nativeimage.ImageSingletons;
4142
import org.graalvm.nativeimage.IsolateThread;
4243
import org.graalvm.nativeimage.LogHandler;
@@ -102,6 +103,7 @@
102103
import com.oracle.svm.core.jni.headers.JNIObjectRefType;
103104
import com.oracle.svm.core.jni.headers.JNIValue;
104105
import com.oracle.svm.core.jni.headers.JNIVersion;
106+
import com.oracle.svm.core.jni.headers.JNIVersionJDK19OrLater;
105107
import com.oracle.svm.core.log.Log;
106108
import com.oracle.svm.core.monitor.MonitorSupport;
107109
import com.oracle.svm.core.snippets.KnownIntrinsics;
@@ -151,7 +153,7 @@ public final class JNIFunctions {
151153
@CEntryPointOptions(prologue = CEntryPointOptions.NoPrologue.class, epilogue = CEntryPointOptions.NoEpilogue.class)
152154
@Uninterruptible(reason = "No need to enter the isolate and also no way to report errors if unable to.")
153155
static int GetVersion(JNIEnvironment env) {
154-
return JNIVersion.JNI_VERSION_10();
156+
return JavaVersionUtil.JAVA_SPEC <= 17 ? JNIVersion.JNI_VERSION_10() : JNIVersionJDK19OrLater.JNI_VERSION_19();
155157
}
156158

157159
/*
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.jni.functions;
26+
27+
import org.graalvm.nativeimage.c.function.CEntryPoint;
28+
import org.graalvm.nativeimage.c.function.CEntryPoint.Publish;
29+
30+
import com.oracle.svm.core.c.function.CEntryPointOptions;
31+
import com.oracle.svm.core.jni.JNIObjectHandles;
32+
import com.oracle.svm.core.jni.functions.JNIFunctions.Support.JNIEnvEnterFatalOnFailurePrologue;
33+
import com.oracle.svm.core.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnFalse;
34+
import com.oracle.svm.core.jni.headers.JNIEnvironment;
35+
import com.oracle.svm.core.jni.headers.JNIObjectHandle;
36+
import com.oracle.svm.core.thread.Target_java_lang_BaseVirtualThread;
37+
38+
@SuppressWarnings("unused")
39+
public final class JNIFunctionsJDK19OrLater {
40+
41+
// Checkstyle: stop
42+
43+
/*
44+
* jboolean (JNICALL *IsVirtualThread) (JNIEnv *env, jobject obj);
45+
*/
46+
@CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnFalse.class, include = CEntryPoint.NotIncludedAutomatically.class, publishAs = Publish.NotPublished)
47+
@CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class)
48+
static boolean IsVirtualThread(JNIEnvironment env, JNIObjectHandle handle) {
49+
Object obj = JNIObjectHandles.getObject(handle);
50+
return obj instanceof Target_java_lang_BaseVirtualThread;
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.jni.headers;
26+
27+
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
28+
29+
public class JNIHeaderDirectivesJDK19OrLater extends JNIHeaderDirectives {
30+
31+
@Override
32+
public boolean isInConfiguration() {
33+
return JavaVersionUtil.JAVA_SPEC >= 19;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.jni.headers;
26+
27+
import org.graalvm.nativeimage.c.CContext;
28+
import org.graalvm.nativeimage.c.function.CFunctionPointer;
29+
import org.graalvm.nativeimage.c.struct.CField;
30+
import org.graalvm.nativeimage.c.struct.CStruct;
31+
32+
@CContext(JNIHeaderDirectivesJDK19OrLater.class)
33+
@CStruct(value = "JNINativeInterface_", addStructKeyword = true)
34+
public interface JNINativeInterfaceJDK19OrLater extends JNINativeInterface {
35+
36+
// Virtual threads
37+
38+
@CField
39+
void setIsVirtualThread(CFunctionPointer p);
40+
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package com.oracle.svm.core.jni.headers;
2626

27+
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
2728
import org.graalvm.nativeimage.c.CContext;
2829
import org.graalvm.nativeimage.c.constant.CConstant;
2930

@@ -33,8 +34,14 @@
3334
public final class JNIVersion {
3435
@Uninterruptible(reason = "Called from uninterruptible code.")
3536
public static boolean isSupported(int version) {
36-
return version == JNI_VERSION_10() || version == JNI_VERSION_9() || version == JNI_VERSION_1_8() || version == JNI_VERSION_1_6() ||
37-
version == JNI_VERSION_1_4() || version == JNI_VERSION_1_2() || version == JNI_VERSION_1_1();
37+
return (JavaVersionUtil.JAVA_SPEC > 17 && version == JNIVersionJDK19OrLater.JNI_VERSION_19()) ||
38+
version == JNI_VERSION_10() ||
39+
version == JNI_VERSION_9() ||
40+
version == JNI_VERSION_1_8() ||
41+
version == JNI_VERSION_1_6() ||
42+
version == JNI_VERSION_1_4() ||
43+
version == JNI_VERSION_1_2() ||
44+
version == JNI_VERSION_1_1();
3845
}
3946

4047
// Checkstyle: stop
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.jni.headers;
26+
27+
import org.graalvm.nativeimage.c.CContext;
28+
import org.graalvm.nativeimage.c.constant.CConstant;
29+
30+
@CContext(JNIHeaderDirectivesJDK19OrLater.class)
31+
public final class JNIVersionJDK19OrLater {
32+
33+
// Checkstyle: stop
34+
35+
@CConstant
36+
public static native int JNI_VERSION_19();
37+
38+
// Checkstyle: resume
39+
40+
private JNIVersionJDK19OrLater() {
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.thread;
26+
27+
import com.oracle.svm.core.annotate.TargetClass;
28+
import com.oracle.svm.core.jdk.JDK19OrLater;
29+
30+
@TargetClass(className = "java.lang.BaseVirtualThread", onlyWith = JDK19OrLater.class)
31+
public final class Target_java_lang_BaseVirtualThread {
32+
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFunctionTablesFeature.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.List;
3131
import java.util.stream.Stream;
3232

33+
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
3334
import org.graalvm.nativeimage.AnnotationAccess;
3435
import org.graalvm.nativeimage.ImageSingletons;
3536
import org.graalvm.nativeimage.c.function.CEntryPoint;
@@ -46,9 +47,11 @@
4647
import com.oracle.svm.core.jni.functions.JNIFunctions;
4748
import com.oracle.svm.core.jni.functions.JNIFunctions.UnimplementedWithJNIEnvArgument;
4849
import com.oracle.svm.core.jni.functions.JNIFunctions.UnimplementedWithJavaVMArgument;
50+
import com.oracle.svm.core.jni.functions.JNIFunctionsJDK19OrLater;
4951
import com.oracle.svm.core.jni.functions.JNIInvocationInterface;
5052
import com.oracle.svm.core.jni.headers.JNIInvokeInterface;
5153
import com.oracle.svm.core.jni.headers.JNINativeInterface;
54+
import com.oracle.svm.core.jni.headers.JNINativeInterfaceJDK19OrLater;
5255
import com.oracle.svm.core.meta.MethodPointer;
5356
import com.oracle.svm.core.util.VMError;
5457
import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl;
@@ -87,6 +90,7 @@ public class JNIFunctionTablesFeature implements Feature {
8790
* for the Interface Function Table</a>
8891
*/
8992
private StructInfo functionTableMetadata;
93+
private StructInfo functionTableMetadataJDK19OrLater;
9094

9195
/**
9296
* Metadata about the table pointed to by the {@code JavaVM*} C pointer.
@@ -116,12 +120,16 @@ public void beforeAnalysis(BeforeAnalysisAccess arg) {
116120
invokeInterfaceMetadata = (StructInfo) nativeLibraries.findElementInfo(invokeInterface);
117121
AnalysisType functionTable = metaAccess.lookupJavaType(JNINativeInterface.class);
118122
functionTableMetadata = (StructInfo) nativeLibraries.findElementInfo(functionTable);
123+
if (JavaVersionUtil.JAVA_SPEC > 17) {
124+
functionTableMetadataJDK19OrLater = (StructInfo) nativeLibraries.findElementInfo(metaAccess.lookupJavaType(JNINativeInterfaceJDK19OrLater.class));
125+
}
119126

120127
// Manually add functions as entry points so this is only done when JNI features are enabled
121128
AnalysisType invokes = metaAccess.lookupJavaType(JNIInvocationInterface.class);
122129
AnalysisType exports = metaAccess.lookupJavaType(JNIInvocationInterface.Exports.class);
123130
AnalysisType functions = metaAccess.lookupJavaType(JNIFunctions.class);
124-
Stream<AnalysisMethod> analysisMethods = Stream.of(invokes, functions, exports).flatMap(type -> Stream.of(type.getDeclaredMethods()));
131+
AnalysisType functionsJDK19OrLater = JavaVersionUtil.JAVA_SPEC <= 17 ? null : metaAccess.lookupJavaType(JNIFunctionsJDK19OrLater.class);
132+
Stream<AnalysisMethod> analysisMethods = Stream.of(invokes, functions, functionsJDK19OrLater, exports).filter(type -> type != null).flatMap(type -> Stream.of(type.getDeclaredMethods()));
125133
Stream<AnalysisMethod> unimplementedMethods = Stream.of((AnalysisMethod) getSingleMethod(metaAccess, UnimplementedWithJNIEnvArgument.class),
126134
(AnalysisMethod) getSingleMethod(metaAccess, UnimplementedWithJavaVMArgument.class));
127135
Stream.concat(analysisMethods, unimplementedMethods).forEach(method -> {
@@ -220,6 +228,14 @@ private void fillJNIFunctionsTable(CompilationAccessImpl access) {
220228
int offset = field.getOffsetInfo().getProperty();
221229
tables.initFunctionEntry(offset, getStubFunctionPointer(access, method));
222230
}
231+
if (JavaVersionUtil.JAVA_SPEC > 17) {
232+
HostedType functionsJDK19OrLater = access.getMetaAccess().lookupJavaType(JNIFunctionsJDK19OrLater.class);
233+
for (HostedMethod method : functionsJDK19OrLater.getDeclaredMethods()) {
234+
StructFieldInfo field = findFieldFor(functionTableMetadataJDK19OrLater, method.getName());
235+
int offset = field.getOffsetInfo().getProperty();
236+
tables.initFunctionEntry(offset, getStubFunctionPointer(access, method));
237+
}
238+
}
223239
for (ResolvedJavaMethod accessor : generatedMethods) {
224240
StructFieldInfo field = findFieldFor(functionTableMetadata, accessor.getName());
225241

0 commit comments

Comments
 (0)