-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GR-49526] Introduce Runtime Checks for typeReachable
and Change the Name to typeReached
#7480
Comments
From the community workshop: maybe we should consider calling it |
vjovanov
changed the title
Introduce Runtime Checks for
Introduce Runtime Checks for Sep 26, 2023
typeReachable
and Call it typeInitialized
typeReachable
and Change the Name
vjovanov
modified the milestones:
GraalVM for JDK 22 (March 19, 2024),
GraalVM for JDK 23 (September 17, 2024)
Dec 7, 2023
graalvmbot
pushed a commit
that referenced
this issue
Apr 17, 2024
The core implementation of #7480 This PR applies only for `Class.forName`. The other cases will be covered in the consecutive PRs. A type is reached if the type is initialized (successfuly, or unsuccesfully), or any of the type's subtypes are reached. Type is also reached if any of the subtypes is stored in the image heap. The JSON elements `typeReached` and `typeReachable` are currently distinguished as different elements and can not be merged. This is due to the possible restriction in semantics if we merge different reflection descriptors with a condition that is different only in a runtime check. The agent still outputs `typeReachable` as the implementation is not finished for all elements. Implementation notes: * The `ClassInitializationInfo` is contains the extra field `typeReached`. * The `ClassInitializationInfo` is not a singleton for build-time initialized classes that require tracking for being reached. This is required as the field `reached` can be mutated at runtime. Review entry points: 1) For the runtime computation of reached and build-time metadata construction: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/ClassInitializationInfo.java 2) For the usage of the mechanism in `Class.forName`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java 3) For parsing the JSON files: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java 4) For interactions with optimizations related to class initalization follow the `EnsureClassInitializedNode`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/EnsureClassInitializedNode.java.
graalvmbot
pushed a commit
that referenced
this issue
Apr 17, 2024
The core implementation of #7480 This PR applies only for `Class.forName`. The other cases will be covered in the consecutive PRs. A type is reached if the type is initialized (successfuly, or unsuccesfully), or any of the type's subtypes are reached. Type is also reached if any of the subtypes is stored in the image heap. The JSON elements `typeReached` and `typeReachable` are currently distinguished as different elements and can not be merged. This is due to the possible restriction in semantics if we merge different reflection descriptors with a condition that is different only in a runtime check. The agent still outputs `typeReachable` as the implementation is not finished for all elements. Implementation notes: * The `ClassInitializationInfo` is contains the extra field `typeReached`. * The `ClassInitializationInfo` is not a singleton for build-time initialized classes that require tracking for being reached. This is required as the field `reached` can be mutated at runtime. Review entry points: 1) For the runtime computation of reached and build-time metadata construction: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/ClassInitializationInfo.java 2) For the usage of the mechanism in `Class.forName`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java 3) For parsing the JSON files: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java 4) For interactions with optimizations related to class initalization follow the `EnsureClassInitializedNode`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/EnsureClassInitializedNode.java.
graalvmbot
pushed a commit
that referenced
this issue
Apr 22, 2024
The core implementation of #7480 This PR applies only for `Class.forName`. The other cases will be covered in the consecutive PRs. A type is reached if the type is initialized (successfuly, or unsuccesfully), or any of the type's subtypes are reached. Type is also reached if any of the subtypes is marked as `initialize-at-build-time`. The JSON elements `typeReached` and `typeReachable` are currently distinguished as different elements and can not be merged. This is due to the possible restriction in semantics if we merge different reflection descriptors with a condition that is different only in a runtime check. The agent still outputs `typeReachable` as the implementation is not finished for all elements. Implementation notes: * The `ClassInitializationInfo` is contains the extra field `typeReached`. * The `ClassInitializationInfo` is not a singleton for build-time initialized classes that require tracking for being reached. This is required as the field `reached` can be mutated at runtime. Review entry points: 1) For the runtime computation of reached and build-time metadata construction: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/ClassInitializationInfo.java 2) For the usage of the mechanism in `Class.forName`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java 3) For parsing the JSON files: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java 4) For interactions with optimizations related to class initalization follow the `EnsureClassInitializedNode`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/EnsureClassInitializedNode.java.
graalvmbot
pushed a commit
that referenced
this issue
Apr 23, 2024
The core implementation of #7480 This PR applies only for `Class.forName`. The other cases will be covered in the consecutive PRs. A type is reached if the type is initialized (successfuly, or unsuccesfully), or any of the type's subtypes are reached. Type is also reached if any of the subtypes is marked as `initialize-at-build-time`. The JSON elements `typeReached` and `typeReachable` are currently distinguished as different elements and can not be merged. This is due to the possible restriction in semantics if we merge different reflection descriptors with a condition that is different only in a runtime check. The agent still outputs `typeReachable` as the implementation is not finished for all elements. Implementation notes: * The `ClassInitializationInfo` is contains the extra field `typeReached`. * The `ClassInitializationInfo` is not a singleton for build-time initialized classes that require tracking for being reached. This is required as the field `reached` can be mutated at runtime. Review entry points: 1) For the runtime computation of reached and build-time metadata construction: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/ClassInitializationInfo.java 2) For the usage of the mechanism in `Class.forName`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java 3) For parsing the JSON files: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java 4) For interactions with optimizations related to class initalization follow the `EnsureClassInitializedNode`: substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/EnsureClassInitializedNode.java.
vjovanov
changed the title
Introduce Runtime Checks for
Introduce Runtime Checks for Apr 29, 2024
typeReachable
and Change the NametypeReachable
and Change the Name to typeReached
spavlusieva
changed the title
Introduce Runtime Checks for
[GR-49526] Introduce Runtime Checks for Apr 29, 2024
typeReachable
and Change the Name to typeReached
typeReachable
and Change the Name to typeReached
This has been fixed in GraalVM for JDK 23. Documentation can be found here. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TL;DR
Native Image uses static analysis to determine if types are registered for reflective access. This is hard to explain in terms of standard programming practices (e.g., lambda calculus and the type theory) and can lead to unpredictable errors. For example:
In JSON, reachability-based registration is defined with the
typeReachable
conditions, and in the Feature API with reachability handlers for types, methods, and fields.To overcome the issues with reachability we need to introduce runtime checks to verify that types have been "reached" at run time and deprecate the behavior of
typeReachable
. In JSON metadata we would express this condition withtypeReached
:Type initialized is equivalent to
typeReachable
with an extra runtime check at every reflective access to see if the class (e.g.,app.MyApp
) was initialized. If the type is not accessible the reflective access will throw aMissingReflectionRegistrationError
with a special message that says what type initialization was missing to make this access possible.The
org.graalvm.nativeimage.hosted.RuntimeReflection
,org.graalvm.nativeimage.hosted.RuntimeSerialization
, andorg.graalvm.nativeimage.hosted.RuntimeResourceAccess
from the feature API need to get an additional parameter that describes the condition.Goals
Non-Goals
Interactions with the Rest of the System
The biggest change is that all types that appear in
typeReached
conditions must have additional conditional checks. These checks will be invisible to the user, but they might introduce a small performance overhead. From the experience with class initialization, this overhead can be greatly reduced with optimization passes.Native Image Agent Support
In the agent with the conditional mode, we will simply output the
typeReached
conditions. Since these conditions come from the stack, that means that the type was certainly initialized.Backward Compatibility
The value of "name" in reflect-config.json will continue to have the implicit meaning that the class can be fetched with Class.forName.
The new element will be output by the agent and described in all documentation as the default. The reachability metadata will be migrated to the new format immediately. The previous versions of GraalVM must be modified to accept
typeInitialized
but treat it as if it istypeReachable
.typeReachable
should be supported until the majority of the ecosystem adopts the new semanticsThe text was updated successfully, but these errors were encountered: