Skip to content

Commit 1892b1b

Browse files
committed
[GR-62284] Introduce AccessCondition and TypeReachabilityCondition
PullRequest: graal/20164
2 parents d8af05b + dcb65b1 commit 1892b1b

File tree

91 files changed

+900
-748
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+900
-748
lines changed

sdk/mx.sdk/suite.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,7 @@ class UniversalDetector {
976976
"exports" : [
977977
"com.oracle.svm.core.annotate",
978978
"org.graalvm.nativeimage.hosted",
979+
"org.graalvm.nativeimage.dynamicaccess",
979980
"org.graalvm.nativeimage.c.function",
980981
"org.graalvm.nativeimage.c.struct",
981982
"org.graalvm.nativeimage.c.type",

sdk/src/org.graalvm.nativeimage/snapshot.sigtest

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,10 @@ CLSS public abstract interface org.graalvm.nativeimage.hosted.FieldValueTransfor
10991099
meth public abstract java.lang.Object transform(java.lang.Object,java.lang.Object)
11001100
meth public boolean isAvailable()
11011101

1102+
CLSS public abstract interface org.graalvm.nativeimage.dynamicaccess.AccessCondition
1103+
meth public static org.graalvm.nativeimage.dynamicaccess.AccessCondition unconditional()
1104+
meth public static org.graalvm.nativeimage.dynamicaccess.AccessCondition typeReached(java.lang.Class<?>)
1105+
11021106
CLSS public final org.graalvm.nativeimage.hosted.RuntimeClassInitialization
11031107
meth public !varargs static void initializeAtBuildTime(java.lang.Class<?>[])
11041108
meth public !varargs static void initializeAtBuildTime(java.lang.String[])
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package org.graalvm.nativeimage.dynamicaccess;
42+
43+
import org.graalvm.nativeimage.impl.TypeReachabilityCondition;
44+
45+
/**
46+
* A condition that must be satisfied to register elements for dynamic access (i.e., reflection,
47+
* serialization, JNI access, resource access, and foreign access at run time). Conditions should be
48+
* used whenever possible to constrain unnecessary growth of the binary size.
49+
* <p>
50+
* There are currently two types of conditions:
51+
* <ul>
52+
* <li>{@link #typeReached} - satisfied when the type is both reachable by static analysis at build
53+
* time, and reached at run time.</li>
54+
* <li>{@link #unconditional} - a condition that is always satisfied. This condition should be
55+
* avoided to prevent unnecessary increases in binary size.</li>
56+
* </ul>
57+
* <p>
58+
* Conditions can only be created via the {@link #unconditional} and {@link #typeReached} factory
59+
* methods. These methods are best used with static import methods. For example:
60+
*
61+
* <pre>{@code
62+
* reflection.register(unconditional(), ReflectivelyAccessed.class);
63+
* reflection.register(typeReached(ConditionalType.class), ConditionallyAccessed.class)
64+
* }</pre>
65+
*
66+
* @since 25.0.1
67+
*/
68+
public interface AccessCondition {
69+
70+
/**
71+
* Returns a condition that is always satisfied. Any element that is predicated with this
72+
* condition will always be included and accessible.
73+
*
74+
* @return instance of the condition
75+
*
76+
* @since 25.0.1
77+
*/
78+
static AccessCondition unconditional() {
79+
return TypeReachabilityCondition.JAVA_LANG_OBJECT_REACHED;
80+
}
81+
82+
/**
83+
* Creates the {@code typeReached} condition that is satisfied when the type is reached at run
84+
* time. A type is reached at run time, if the class-initialization is triggered for that type
85+
* (right before the first step of initialization described in
86+
* <a href="https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-5.html#jvms-5.5">Java Spec
87+
* - Initialization</a>), or any of the type's subtypes are reached. Elements predicated with
88+
* this condition will be included in the image only if the type is <em>reachable</em> at build
89+
* time, but will be accessible when the type is <em>reached</em> at run time.
90+
* <p>
91+
* <strong>Example:</strong>
92+
*
93+
* <pre>{@code
94+
* public class App {
95+
* public static void main(String[] args) {
96+
* // ConditionalType not reached => element access not allowed
97+
* Class<?> clazz = ConditionalType.class;
98+
* // ConditionalType not reached (ConditionalType.class doesn't start class initialization)
99+
* // => element access not allowed
100+
* ConditionalType.singleton();
101+
* // ConditionalType reached (already initialized) => element access allowed
102+
* }
103+
* }
104+
*
105+
* class SuperType {
106+
* static {
107+
* // ConditionalType reached (subtype reached) => element access allowed
108+
* }
109+
* }
110+
*
111+
* class ConditionalType extends SuperType {
112+
* static {
113+
* // ConditionalType reached (before static initializer) => element access allowed
114+
* }
115+
*
116+
* static ConditionalType singleton() {
117+
* // ConditionalType reached (already initialized) => element access allowed
118+
* }
119+
* }
120+
* }</pre>
121+
* <p>
122+
* A type is also considered as reached, if it is marked as {@code --initialize-at-build-time}
123+
* or if any of its subtypes on the classpath are marked as {@code --initialize-at-build-time}.
124+
* Array types (e.g., <code>int[]</code>) are never marked as reached and therefore cannot be
125+
* used as the <code>type</code> in a condition.
126+
*
127+
* @param type the type that has to be reached for this condition to be satisfied, must not be
128+
* {@code null}
129+
*
130+
* @return instance of the condition
131+
*
132+
* @since 25.0.1
133+
*/
134+
static AccessCondition typeReached(Class<?> type) {
135+
return TypeReachabilityCondition.create(type, true);
136+
}
137+
}

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeForeignAccess.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
import org.graalvm.nativeimage.ImageSingletons;
4747
import org.graalvm.nativeimage.Platform;
4848
import org.graalvm.nativeimage.Platforms;
49-
import org.graalvm.nativeimage.impl.ConfigurationCondition;
49+
import org.graalvm.nativeimage.dynamicaccess.AccessCondition;
5050
import org.graalvm.nativeimage.impl.RuntimeForeignAccessSupport;
5151

5252
@Platforms(Platform.HOSTED_ONLY.class)
@@ -69,7 +69,7 @@ public final class RuntimeForeignAccess {
6969
* @since 23.1
7070
*/
7171
public static void registerForDowncall(Object desc, Object... options) {
72-
ImageSingletons.lookup(RuntimeForeignAccessSupport.class).registerForDowncall(ConfigurationCondition.alwaysTrue(), desc, options);
72+
ImageSingletons.lookup(RuntimeForeignAccessSupport.class).registerForDowncall(AccessCondition.unconditional(), desc, options);
7373
}
7474

7575
/**
@@ -87,7 +87,7 @@ public static void registerForDowncall(Object desc, Object... options) {
8787
* @since 24.1
8888
*/
8989
public static void registerForUpcall(Object desc, Object... options) {
90-
ImageSingletons.lookup(RuntimeForeignAccessSupport.class).registerForUpcall(ConfigurationCondition.alwaysTrue(), desc, options);
90+
ImageSingletons.lookup(RuntimeForeignAccessSupport.class).registerForUpcall(AccessCondition.unconditional(), desc, options);
9191
}
9292

9393
/**
@@ -115,7 +115,7 @@ public static void registerForUpcall(Object desc, Object... options) {
115115
* @since 24.2
116116
*/
117117
public static void registerForDirectUpcall(MethodHandle target, Object desc, Object... options) {
118-
ImageSingletons.lookup(RuntimeForeignAccessSupport.class).registerForDirectUpcall(ConfigurationCondition.alwaysTrue(), target, desc, options);
118+
ImageSingletons.lookup(RuntimeForeignAccessSupport.class).registerForDirectUpcall(AccessCondition.unconditional(), target, desc, options);
119119
}
120120

121121
private RuntimeForeignAccess() {

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeJNIAccess.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -46,7 +46,7 @@
4646
import org.graalvm.nativeimage.ImageSingletons;
4747
import org.graalvm.nativeimage.Platform;
4848
import org.graalvm.nativeimage.Platforms;
49-
import org.graalvm.nativeimage.impl.ConfigurationCondition;
49+
import org.graalvm.nativeimage.dynamicaccess.AccessCondition;
5050
import org.graalvm.nativeimage.impl.RuntimeJNIAccessSupport;
5151

5252
/**
@@ -66,7 +66,7 @@ public final class RuntimeJNIAccess {
6666
* @since 22.3
6767
*/
6868
public static void register(Class<?>... classes) {
69-
ImageSingletons.lookup(RuntimeJNIAccessSupport.class).register(ConfigurationCondition.alwaysTrue(), classes);
69+
ImageSingletons.lookup(RuntimeJNIAccessSupport.class).register(AccessCondition.unconditional(), classes);
7070
}
7171

7272
/**
@@ -79,7 +79,7 @@ public static void register(Class<?>... classes) {
7979
* @since 22.3
8080
*/
8181
public static void register(Executable... methods) {
82-
ImageSingletons.lookup(RuntimeJNIAccessSupport.class).register(ConfigurationCondition.alwaysTrue(), false, methods);
82+
ImageSingletons.lookup(RuntimeJNIAccessSupport.class).register(AccessCondition.unconditional(), false, methods);
8383
}
8484

8585
/**
@@ -92,7 +92,7 @@ public static void register(Executable... methods) {
9292
* @since 22.3
9393
*/
9494
public static void register(Field... fields) {
95-
ImageSingletons.lookup(RuntimeJNIAccessSupport.class).register(ConfigurationCondition.alwaysTrue(), false, fields);
95+
ImageSingletons.lookup(RuntimeJNIAccessSupport.class).register(AccessCondition.unconditional(), false, fields);
9696
}
9797

9898
private RuntimeJNIAccess() {

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeProxyCreation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import org.graalvm.nativeimage.ImageSingletons;
4444
import org.graalvm.nativeimage.Platform;
4545
import org.graalvm.nativeimage.Platforms;
46-
import org.graalvm.nativeimage.impl.ConfigurationCondition;
46+
import org.graalvm.nativeimage.dynamicaccess.AccessCondition;
4747
import org.graalvm.nativeimage.impl.RuntimeProxyRegistrySupport;
4848

4949
/**
@@ -62,7 +62,7 @@ public final class RuntimeProxyCreation {
6262
* @since 22.3
6363
*/
6464
public static void register(Class<?>... interfaces) {
65-
ImageSingletons.lookup(RuntimeProxyRegistrySupport.class).registerProxy(ConfigurationCondition.alwaysTrue(), interfaces);
65+
ImageSingletons.lookup(RuntimeProxyRegistrySupport.class).registerProxy(AccessCondition.unconditional(), interfaces);
6666
}
6767

6868
private RuntimeProxyCreation() {

0 commit comments

Comments
 (0)