Skip to content

Commit 837030b

Browse files
author
Christian Wimmer
committed
Provide FieldValueTransformer API
1 parent f008967 commit 837030b

File tree

52 files changed

+627
-753
lines changed

Some content is hidden

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

52 files changed

+627
-753
lines changed

sdk/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
This changelog summarizes major changes between GraalVM SDK versions. The main focus is on APIs exported by GraalVM SDK.
44

5+
## Version 22.3.0
6+
* (GR-39852) Native Image API: Added FieldValueTransformer API
7+
58
## Version 22.2.0
69
* (GR-38925) Added `Value.hasMetaParents() and Value.getMetaParents()` that allow lookup of the hierarchy of parents for meta objects (e.g. super class or implemented interface of Java classes).
710
* (GR-38351) Added [FileSystem#allowLanguageHomeAccess](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/io/FileSystem.html#allowLanguageHomeAccess-org.graalvm.polyglot.io.FileSystem-) returning a `FileSystem` that forwards access to files in the language home to the default file system.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,7 @@ meth public abstract void registerAsUsed(java.lang.Class<?>)
922922
meth public abstract void registerClassInitializerReachabilityHandler(java.util.function.Consumer<org.graalvm.nativeimage.hosted.Feature$DuringAnalysisAccess>,java.lang.Class<?>)
923923
meth public abstract void registerMethodOverrideReachabilityHandler(java.util.function.BiConsumer<org.graalvm.nativeimage.hosted.Feature$DuringAnalysisAccess,java.lang.reflect.Executable>,java.lang.reflect.Executable)
924924
meth public abstract void registerSubtypeReachabilityHandler(java.util.function.BiConsumer<org.graalvm.nativeimage.hosted.Feature$DuringAnalysisAccess,java.lang.Class<?>>,java.lang.Class<?>)
925+
meth public abstract void registerFieldValueTransformer(java.lang.reflect.Field,org.graalvm.nativeimage.hosted.FieldValueTransformer)
925926

926927
CLSS public abstract interface static org.graalvm.nativeimage.hosted.Feature$BeforeCompilationAccess
927928
outer org.graalvm.nativeimage.hosted.Feature
@@ -1024,3 +1025,5 @@ meth public abstract boolean equals(java.lang.Object)
10241025
anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="")
10251026
meth public abstract long rawValue()
10261027

1028+
CLSS public abstract interface org.graalvm.nativeimage.hosted.FieldValueTransformer
1029+
meth public abstract java.lang.Object transform(java.lang.Object,java.lang.Object)

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,14 @@ interface BeforeAnalysisAccess extends FeatureAccess {
296296
* @since 21.0
297297
*/
298298
void registerClassInitializerReachabilityHandler(Consumer<DuringAnalysisAccess> callback, Class<?> clazz);
299+
300+
/**
301+
* Registers a field value transformer for the provided field. See the JavaDoc of
302+
* {@link FieldValueTransformer} for details.
303+
*
304+
* @since 22.3
305+
*/
306+
void registerFieldValueTransformer(Field field, FieldValueTransformer transformer);
299307
}
300308

301309
/**
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2022, 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.hosted;
42+
43+
import org.graalvm.nativeimage.Platform;
44+
import org.graalvm.nativeimage.Platforms;
45+
import org.graalvm.nativeimage.hosted.Feature.BeforeAnalysisAccess;
46+
47+
/**
48+
* A transformer for a field value that can be registered using
49+
* {@link BeforeAnalysisAccess#registerFieldValueTransformer}.
50+
* <p>
51+
* At image build time, the field value transformer provides the value of the field for the image
52+
* heap. Without a transformer, the value of the field in the image heap is the same as the hosted
53+
* value in the image generator. A field value transformer allows to intercept the value. A field
54+
* value transformer can, for example, reset a field to the default null/0 value, replace a filled
55+
* collection with a new empty collection, or provide any kind of new value for a field.
56+
* <p>
57+
* Only one field value transformer can be registered for each field.
58+
* <p>
59+
* A field value transformer can be registered for fields of classes that are initialized at image
60+
* run time. That allows constant folding of final fields even though the declaring class is not
61+
* initialized at image build time.
62+
* <p>
63+
* A field value transformer must be registered before the field is seen as reachable by the static
64+
* analysis. It is generally safe to register a transformer in {@link Feature#beforeAnalysis} before
65+
* the static analysis is started, in a {@link BeforeAnalysisAccess#registerReachabilityHandler type
66+
* reachability handler} for the declaring class of the field, or a
67+
* {@link BeforeAnalysisAccess#registerSubtypeReachabilityHandler subtype reachability handler} for
68+
* a super-type of the declaring class of the field.
69+
*
70+
* @since 22.3
71+
*/
72+
@Platforms(Platform.HOSTED_ONLY.class)
73+
public interface FieldValueTransformer {
74+
75+
/**
76+
* Transforms the field value for the provided receiver. The receiver is null for static fields.
77+
* The original value of the field, i.e., the hosted value of the field in the image generator,
78+
* is also provided as an argument.
79+
* <p>
80+
* The type of the returned object must be assignable to the declared type of the field. If the
81+
* field has a primitive type, the return value must be a boxed value, and must not be null.
82+
*
83+
* @since 22.3
84+
*/
85+
Object transform(Object receiver, Object originalValue);
86+
}

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsUtils.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@
3636
import org.graalvm.nativeimage.c.type.CCharPointer;
3737
import org.graalvm.nativeimage.c.type.CIntPointer;
3838
import org.graalvm.nativeimage.c.type.CLongPointer;
39+
import org.graalvm.nativeimage.hosted.FieldValueTransformer;
3940
import org.graalvm.word.PointerBase;
4041
import org.graalvm.word.UnsignedWord;
4142
import org.graalvm.word.WordFactory;
4243

4344
import com.oracle.svm.core.SubstrateUtil;
4445
import com.oracle.svm.core.annotate.Alias;
4546
import com.oracle.svm.core.annotate.RecomputeFieldValue;
46-
import com.oracle.svm.core.annotate.RecomputeFieldValue.CustomFieldValueComputer;
4747
import com.oracle.svm.core.annotate.TargetClass;
4848
import com.oracle.svm.core.annotate.Uninterruptible;
4949
import com.oracle.svm.core.c.function.CEntryPointActions;
@@ -52,9 +52,6 @@
5252
import com.oracle.svm.core.windows.headers.WinBase;
5353
import com.oracle.svm.core.windows.headers.WinBase.HMODULE;
5454

55-
import jdk.vm.ci.meta.MetaAccessProvider;
56-
import jdk.vm.ci.meta.ResolvedJavaField;
57-
5855
public class WindowsUtils {
5956

6057
@TargetClass(className = "java.lang.ProcessImpl")
@@ -70,14 +67,9 @@ public static int getpid(java.lang.Process process) {
7067
@TargetClass(java.io.FileDescriptor.class)
7168
private static final class Target_java_io_FileDescriptor {
7269
/** Invalidates the standard FileDescriptors, which are allowed in the image heap. */
73-
static class InvalidHandleValueComputer implements CustomFieldValueComputer {
74-
@Override
75-
public RecomputeFieldValue.ValueAvailability valueAvailability() {
76-
return RecomputeFieldValue.ValueAvailability.BeforeAnalysis;
77-
}
78-
70+
static class InvalidHandleValueComputer implements FieldValueTransformer {
7971
@Override
80-
public Object compute(MetaAccessProvider metaAccess, ResolvedJavaField original, ResolvedJavaField annotated, Object receiver) {
72+
public Object transform(Object receiver, Object originalValue) {
8173
return -1L;
8274
}
8375
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/annotate/Alias.java

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

27-
import org.graalvm.nativeimage.Platform;
28-
import org.graalvm.nativeimage.Platforms;
29-
3027
import java.lang.annotation.ElementType;
3128
import java.lang.annotation.Retention;
3229
import java.lang.annotation.RetentionPolicy;
3330
import java.lang.annotation.Target;
3431

32+
import org.graalvm.nativeimage.Platform;
33+
import org.graalvm.nativeimage.Platforms;
34+
3535
/**
3636
* Mechanism for referring to fields and methods otherwise inaccessible due to Java language access
3737
* control rules. This enables VM code to directly access a private field or invoke a private method
@@ -40,10 +40,12 @@
4040
* <p>
4141
* The idiom for using {@link Alias} is somewhat related to the {@link Substitute} annotation, but
4242
* reversed; both are often used in combination. In both cases a separate class is used to declare
43-
* the aliased or substituted methods. In the substitution case occurrences of {@code this} actually
44-
* refer to the instance of the class being substituted. In the aliased case we pretend that the
45-
* class declaring the aliased method is an instance of the aliasee in order to access its fields or
46-
* invoke its methods.
43+
* the aliased and/or substituted methods. In the substitution case occurrences of {@code this}
44+
* actually refer to the instance of the class being substituted. In the aliased case we pretend
45+
* that the class declaring the aliased method or field is an instance of the aliasee in order to
46+
* access its fields or invoke its methods. An alias is always called (method alias) or accessed
47+
* (field alias), whereas a substitution method is only implemented (usually not called directly).
48+
* In the body of a substitution method, aliases are often called or accessed.
4749
* <p>
4850
* The element can also be annotated with {@link TargetElement} to specify additional properties.
4951
* See {@link TargetClass} for an overview of the annotation system.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/annotate/AutomaticFeature.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@
2424
*/
2525
package com.oracle.svm.core.annotate;
2626

27-
import org.graalvm.nativeimage.Platform;
28-
import org.graalvm.nativeimage.Platforms;
29-
3027
import java.lang.annotation.ElementType;
3128
import java.lang.annotation.Retention;
3229
import java.lang.annotation.RetentionPolicy;
3330
import java.lang.annotation.Target;
3431

32+
import org.graalvm.nativeimage.Platform;
33+
import org.graalvm.nativeimage.Platforms;
34+
3535
/**
36+
* Supported API is available to replace this non-API annotation: Instead of using this annotation,
37+
* use {@code "--features <fqn.of.FeatureClass>"} in the {@code Args} of a
38+
* {@code native-image.properties} file to ensure a user-provided feature gets processed.
39+
*
3640
* Feature classes can use this annotation are unconditionally added when they are reachable on the
3741
* class path.
3842
*/

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/annotate/Inject.java

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

27-
import org.graalvm.nativeimage.Platform;
28-
import org.graalvm.nativeimage.Platforms;
29-
3027
import java.lang.annotation.ElementType;
3128
import java.lang.annotation.Retention;
3229
import java.lang.annotation.RetentionPolicy;
3330
import java.lang.annotation.Target;
3431

32+
import org.graalvm.nativeimage.Platform;
33+
import org.graalvm.nativeimage.Platforms;
34+
3535
/**
3636
* Injects the annotated field into the {@link TargetClass}.
3737
*
38-
* The field must not be declared static. If instances of the target class are in the native image
39-
* heap, the field also needs to be annotated with {@link RecomputeFieldValue} to provide a value
40-
* for the native image objects.
38+
* The field must not be declared static. If instances of the target class are in the image heap,
39+
* the field also needs to be annotated with {@link RecomputeFieldValue} to provide a value for the
40+
* injected field.
4141
*/
4242
@Retention(RetentionPolicy.RUNTIME)
4343
@Target({ElementType.FIELD})

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/annotate/KeepOriginal.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,25 @@
2424
*/
2525
package com.oracle.svm.core.annotate;
2626

27-
import org.graalvm.nativeimage.Platform;
28-
import org.graalvm.nativeimage.Platforms;
29-
3027
import java.lang.annotation.ElementType;
3128
import java.lang.annotation.Retention;
3229
import java.lang.annotation.RetentionPolicy;
3330
import java.lang.annotation.Target;
3431

32+
import org.graalvm.nativeimage.Platform;
33+
import org.graalvm.nativeimage.Platforms;
34+
3535
/**
36-
* In a {@link Substitute substituted} type, keep the original definition of this method. The
37-
* default behavior is that all non-substituted methods are implicitly treated as {@link Delete
38-
* deleted}. Unless this annotation is applied to the {@link Substitute substituted} type itself,
39-
* then the original definition of all methods and fields in the target type are kept by default.
36+
* If a class annotated with {@link TargetClass} is also annotated with {@link Substitute}, all
37+
* non-substituted methods in that class are by default treated as {@link Delete deleted}. This
38+
* annotation changes the behavior: A method annotated with {@link KeepOriginal} keeps the original
39+
* definition of the method.
40+
* <p>
41+
* If this annotation is used to the {@link Substitute * substituted} type itself, then the original
42+
* definition of all methods and fields in the target type are kept by default.
4043
* <p>
4144
* The element can also be annotated with {@link TargetElement} to specify additional properties.
4245
* See {@link TargetClass} for an overview of the annotation system.
43-
* </p>
4446
*/
4547
@Retention(RetentionPolicy.RUNTIME)
4648
@Target({ElementType.METHOD, ElementType.TYPE})

0 commit comments

Comments
 (0)