diff --git a/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py b/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py index e3ddee80bb3e..c7293de5605e 100644 --- a/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py +++ b/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py @@ -368,7 +368,6 @@ def extra_image_build_argument(self, benchmark, args): '-H:+AddAllCharsets', '-H:+ReportExceptionStackTraces', ] + mx_sdk_vm_impl.svm_experimental_options([ - '-H:-ParseOnce', '-H:+AllowFoldMethods', '-H:-UseServiceLoaderFeature', '-H:+AllowDeprecatedBuilderClassesOnImageClasspath', # needs to be removed once GR-41746 is fixed diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java index 23928e949593..bafa82038f62 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java @@ -168,7 +168,7 @@ protected void scanField(AnalysisField field, JavaConstant receiver, ScanReason System.lineSeparator() + backtrace); } - if (fieldValue.getJavaKind() == JavaKind.Object && bb.getHostVM().isRelocatedPointer(bb.getMetaAccess(), fieldValue)) { + if (fieldValue.getJavaKind() == JavaKind.Object && bb.getHostVM().isRelocatedPointer(fieldValue)) { scanningObserver.forRelocatedPointerFieldValue(receiver, field, fieldValue, reason); } else if (fieldValue.isNull()) { scanningObserver.forNullFieldValue(receiver, field, reason); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java index 5fb82aaff105..4ed6438b42bc 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java @@ -36,21 +36,11 @@ import java.util.function.BiConsumer; import java.util.function.Function; -import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor; -import jdk.graal.compiler.core.common.spi.ForeignCallsProvider; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.java.GraphBuilderPhase.Instance; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; -import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext; -import jdk.graal.compiler.options.OptionValues; -import jdk.graal.compiler.phases.OptimisticOptimizations; import org.graalvm.nativeimage.hosted.Feature.DuringAnalysisAccess; import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.PointsToAnalysis; import com.oracle.graal.pointsto.flow.InvokeTypeFlow; -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.AnalysisType; @@ -62,6 +52,15 @@ import com.oracle.graal.pointsto.util.AnalysisError; import com.oracle.svm.common.meta.MultiMethod; +import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor; +import jdk.graal.compiler.core.common.spi.ForeignCallsProvider; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.java.GraphBuilderPhase.Instance; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; +import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext; +import jdk.graal.compiler.options.OptionValues; +import jdk.graal.compiler.phases.OptimisticOptimizations; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -94,7 +93,7 @@ public OptionValues options() { * @param metaAccess the meta-access provider * @param constant the constant to check */ - public boolean isRelocatedPointer(UniverseMetaAccess metaAccess, JavaConstant constant) { + public boolean isRelocatedPointer(JavaConstant constant) { return false; } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java index bd27e1af7c5e..c5a303c1b34a 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/heap/ImageHeapScanner.java @@ -407,7 +407,7 @@ private void notifyAnalysis(AnalysisField field, ImageHeapInstance receiver, Jav private boolean doNotifyAnalysis(AnalysisField field, JavaConstant receiver, JavaConstant fieldValue, ScanReason reason) { boolean analysisModified = false; - if (fieldValue.getJavaKind() == JavaKind.Object && hostVM.isRelocatedPointer(metaAccess, fieldValue)) { + if (fieldValue.getJavaKind() == JavaKind.Object && hostVM.isRelocatedPointer(fieldValue)) { /* Ensure the relocatable pointer type is analysed. */ ((AnalysisType) ((TypedConstant) fieldValue).getType(metaAccess)).registerAsReachable(reason); analysisModified = scanningObserver.forRelocatedPointerFieldValue(receiver, field, fieldValue, reason); @@ -450,7 +450,7 @@ private void notifyAnalysis(ImageHeapArray array, AnalysisType arrayType, int el } private boolean isNonNullObjectConstant(JavaConstant constant) { - return constant.getJavaKind() == JavaKind.Object && constant.isNonNull() && !universe.hostVM().isRelocatedPointer(metaAccess, constant); + return constant.getJavaKind() == JavaKind.Object && constant.isNonNull() && !universe.hostVM().isRelocatedPointer(constant); } private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaConstant elementValue, int elementIndex, ScanReason reason) { @@ -458,7 +458,7 @@ private boolean notifyAnalysis(JavaConstant array, AnalysisType arrayType, JavaC if (elementValue.isNull()) { analysisModified = scanningObserver.forNullArrayElement(array, arrayType, elementIndex, reason); } else { - if (universe.hostVM().isRelocatedPointer(metaAccess, elementValue)) { + if (universe.hostVM().isRelocatedPointer(elementValue)) { return false; } AnalysisType elementType = metaAccess.lookupJavaType(elementValue); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/GraphProvider.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/GraphProvider.java index 2452b980511b..f4c3ef594311 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/GraphProvider.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/GraphProvider.java @@ -24,17 +24,15 @@ */ package com.oracle.graal.pointsto.infrastructure; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.nodes.StructuredGraph; - import com.oracle.graal.pointsto.meta.HostedProviders; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.nodes.StructuredGraph; import jdk.vm.ci.meta.ResolvedJavaMethod; public interface GraphProvider { enum Purpose { ANALYSIS, - AOT_COMPILATION, PREPARE_RUNTIME_COMPILATION, } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/ParsingReason.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/ParsingReason.java index 985a1f122b72..0d01c3d11de8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/ParsingReason.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/ParsingReason.java @@ -37,6 +37,6 @@ public boolean isForHosted() { } public boolean duringAnalysis() { - return this == PointsToAnalysis || (SubstrateOptions.parseOnce() && this == JITCompilation); + return this == PointsToAnalysis || this == JITCompilation; } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 6b508f845416..1ea68732a1dc 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -75,7 +75,7 @@ public class SubstrateOptions { @Option(help = "Deprecated, option no longer has any effect.", deprecated = true, deprecationMessage = "It no longer has any effect, and no replacement is available")// - public static final HostedOptionKey ParseOnce = new HostedOptionKey<>(true); + static final HostedOptionKey ParseOnce = new HostedOptionKey<>(true); @Option(help = "Deprecated, option no longer has any effect.", deprecated = true, deprecationMessage = "It no longer has any effect, and no replacement is available")// static final HostedOptionKey ParseOnceJIT = new HostedOptionKey<>(true); @Option(help = "Preserve the local variable information for every Java source line to allow line-by-line stepping in the debugger. Allow the lookup of Java-level method information, e.g., in stack traces.")// @@ -86,14 +86,6 @@ public class SubstrateOptions { @Option(help = "Image Build ID is a 128-bit UUID string generated randomly, once per bundle or digest of input args when bundles are not used.")// public static final HostedOptionKey ImageBuildID = new HostedOptionKey<>(""); - public static boolean parseOnce() { - /* - * GR-48579: Old code only reachable when this method would return false will be deleted - * later. - */ - return true; - } - @Option(help = "Module containing the class that contains the main entry point. Optional if --shared is used.", type = OptionType.User)// public static final HostedOptionKey Module = new HostedOptionKey<>(""); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/nodes/TestDeoptimizeNode.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/nodes/TestDeoptimizeNode.java index 44cfd709af09..41563cde02ba 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/nodes/TestDeoptimizeNode.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/nodes/TestDeoptimizeNode.java @@ -24,6 +24,8 @@ */ package com.oracle.svm.core.graal.nodes; +import com.oracle.svm.common.meta.MultiMethod; + import jdk.graal.compiler.core.common.type.StampFactory; import jdk.graal.compiler.graph.Node; import jdk.graal.compiler.graph.NodeClass; @@ -34,14 +36,8 @@ import jdk.graal.compiler.nodes.FixedWithNextNode; import jdk.graal.compiler.nodes.spi.Canonicalizable; import jdk.graal.compiler.nodes.spi.CanonicalizerTool; - -import com.oracle.svm.common.meta.MultiMethod; -import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.core.meta.SharedMethod; - import jdk.vm.ci.meta.DeoptimizationAction; import jdk.vm.ci.meta.DeoptimizationReason; -import jdk.vm.ci.meta.ResolvedJavaMethod; /** * For deoptimzation testing. The node performs a deoptimization in a normally compiled method, but @@ -57,28 +53,12 @@ public TestDeoptimizeNode() { @Override public Node canonical(CanonicalizerTool tool) { - ResolvedJavaMethod method = graph().method(); - - if (SubstrateOptions.parseOnce()) { - if (MultiMethod.isDeoptTarget(method)) { - /* no-op for deoptimization target methods. */ - return null; - } else { - /* deoptimization for all other methods. */ - return new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter); - } + if (MultiMethod.isDeoptTarget(graph().method())) { + /* no-op for deoptimization target methods. */ + return null; } else { - if (method instanceof SharedMethod) { - if (MultiMethod.isDeoptTarget(method)) { - /* no-op for deoptimization target methods. */ - return null; - } else { - /* deoptimization for all other methods. */ - return new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter); - } - } + /* deoptimization for all other methods. */ + return new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter); } - - return this; } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/replacements/SubstrateGraphKit.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/replacements/SubstrateGraphKit.java index 93581b390642..825273d5343c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/replacements/SubstrateGraphKit.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/replacements/SubstrateGraphKit.java @@ -29,7 +29,6 @@ import org.graalvm.word.WordBase; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.graal.code.SubstrateCallingConventionKind; import com.oracle.svm.core.graal.meta.SubstrateLoweringProvider; import com.oracle.svm.core.graal.nodes.DeoptEntryNode; @@ -100,14 +99,10 @@ public class SubstrateGraphKit extends GraphKit { private final FrameStateBuilder frameState; private int nextBCI; - private static boolean trackNodeSourcePosition(boolean forceTrackNodeSourcePosition) { - return forceTrackNodeSourcePosition || SubstrateOptions.parseOnce(); - } - @SuppressWarnings("this-escape") public SubstrateGraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers providers, WordTypes wordTypes, - GraphBuilderConfiguration.Plugins graphBuilderPlugins, CompilationIdentifier compilationId, boolean forceTrackNodeSourcePosition, boolean recordInlinedMethods) { - super(debug, stubMethod, providers, wordTypes, graphBuilderPlugins, compilationId, null, trackNodeSourcePosition(forceTrackNodeSourcePosition), recordInlinedMethods); + GraphBuilderConfiguration.Plugins graphBuilderPlugins, CompilationIdentifier compilationId, boolean recordInlinedMethods) { + super(debug, stubMethod, providers, wordTypes, graphBuilderPlugins, compilationId, null, true, recordInlinedMethods); assert wordTypes != null : "Support for Word types is mandatory"; frameState = new FrameStateBuilder(this, stubMethod, graph); frameState.disableKindVerification(); @@ -117,8 +112,8 @@ public SubstrateGraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Prov } public SubstrateGraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers providers, WordTypes wordTypes, - GraphBuilderConfiguration.Plugins graphBuilderPlugins, CompilationIdentifier compilationId, boolean forceTrackNodeSourcePosition) { - this(debug, stubMethod, providers, wordTypes, graphBuilderPlugins, compilationId, forceTrackNodeSourcePosition, false); + GraphBuilderConfiguration.Plugins graphBuilderPlugins, CompilationIdentifier compilationId) { + this(debug, stubMethod, providers, wordTypes, graphBuilderPlugins, compilationId, false); } @Override diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java index 56ce06ee608b..9bac1a343d42 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java @@ -410,7 +410,7 @@ private void installRuntimeConfig(BeforeAnalysisAccessImpl config) { FeatureHandler featureHandler = config.getFeatureHandler(); final boolean supportsStubBasedPlugins = !SubstrateOptions.useLLVMBackend(); - NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, runtimeConfig, hostedProviders, config.getMetaAccess(), config.getUniverse(), null, null, config.getNativeLibraries(), + NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, runtimeConfig, hostedProviders, config.getMetaAccess(), config.getUniverse(), null, config.getNativeLibraries(), config.getImageClassLoader(), ParsingReason.JITCompilation, ((Inflation) config.getBigBang()).getAnnotationSubstitutionProcessor(), new SubstrateClassInitializationPlugin(config.getHostVM()), ConfigurationValues.getTarget(), supportsStubBasedPlugins); @@ -512,15 +512,11 @@ public void initializeRuntimeCompilationConfiguration(HostedProviders newHostedP initialized = true; hostedProviders = newHostedProviders; - graphBuilderConfig = newGraphBuilderConfig; + graphBuilderConfig = newGraphBuilderConfig.withNodeSourcePosition(true); assert !runtimeCompilationCandidatePredicateUpdated : "Updated compilation predicate multiple times"; runtimeCompilationCandidatePredicate = newRuntimeCompilationCandidatePredicate; runtimeCompilationCandidatePredicateUpdated = true; deoptimizeOnExceptionPredicate = newDeoptimizeOnExceptionPredicate; - - if (SubstrateOptions.IncludeNodeSourcePositions.getValue() || SubstrateOptions.parseOnce()) { - graphBuilderConfig = graphBuilderConfig.withNodeSourcePosition(true); - } } public SubstrateMethod requireFrameInformationForMethod(ResolvedJavaMethod method, BeforeAnalysisAccessImpl config, boolean registerAsRoot) { diff --git a/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignGraphKit.java b/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignGraphKit.java index 413b09979d56..74895b998037 100644 --- a/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignGraphKit.java +++ b/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignGraphKit.java @@ -28,19 +28,19 @@ import java.util.List; import org.graalvm.collections.Pair; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.nodes.ValueNode; import com.oracle.graal.pointsto.infrastructure.GraphProvider; import com.oracle.graal.pointsto.meta.HostedProviders; import com.oracle.svm.hosted.phases.HostedGraphKit; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.nodes.ValueNode; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; class ForeignGraphKit extends HostedGraphKit { ForeignGraphKit(DebugContext debug, HostedProviders providers, ResolvedJavaMethod method, GraphProvider.Purpose purpose) { - super(debug, providers, method, purpose); + super(debug, providers, method); } Pair, ValueNode> unpackArgumentsAndExtractNEP(ValueNode argumentsArray, MethodType methodType) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index 371f33b84c04..1a2ef21fa657 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -600,7 +600,7 @@ protected void doRun(Map entryPoints, JavaMainSupport j classInitializationSupport, GraalAccess.getOriginalProviders().getLoopsDataProvider(), platformConfig).build(); registerGraphBuilderPlugins(featureHandler, runtimeConfiguration, (HostedProviders) runtimeConfiguration.getProviders(), bb.getMetaAccess(), aUniverse, - hMetaAccess, hUniverse, + hUniverse, nativeLibraries, loader, ParsingReason.AOTCompilation, bb.getAnnotationSubstitutionProcessor(), new SubstrateClassInitializationPlugin((SVMHost) aUniverse.hostVM()), ConfigurationValues.getTarget(), this.isStubBasedPluginsSupported()); @@ -1134,7 +1134,7 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature */ bb.getMetaAccess().lookupJavaType(com.oracle.svm.core.graal.stackvalue.StackValueNode.StackSlotIdentity.class).registerAsReachable("root class"); - NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, null, null, nativeLibraries, loader, ParsingReason.PointsToAnalysis, + NativeImageGenerator.registerGraphBuilderPlugins(featureHandler, null, aProviders, aMetaAccess, aUniverse, null, nativeLibraries, loader, ParsingReason.PointsToAnalysis, bb.getAnnotationSubstitutionProcessor(), classInitializationPlugin, ConfigurationValues.getTarget(), supportsStubBasedPlugins); registerReplacements(debug, featureHandler, null, aProviders, true, initForeignCalls); @@ -1339,7 +1339,7 @@ public void notifyNoPlugin(ResolvedJavaMethod targetMethod, OptionValues options } public static void registerGraphBuilderPlugins(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, HostedProviders providers, AnalysisMetaAccess aMetaAccess, - AnalysisUniverse aUniverse, HostedMetaAccess hMetaAccess, HostedUniverse hUniverse, NativeLibraries nativeLibs, ImageClassLoader loader, ParsingReason reason, + AnalysisUniverse aUniverse, HostedUniverse hUniverse, NativeLibraries nativeLibs, ImageClassLoader loader, ParsingReason reason, AnnotationSubstitutionProcessor annotationSubstitutionProcessor, ClassInitializationPlugin classInitializationPlugin, TargetDescription target, boolean supportsStubBasedPlugins) { GraphBuilderConfiguration.Plugins plugins = new GraphBuilderConfiguration.Plugins(new SubstitutionInvocationPlugins(annotationSubstitutionProcessor)); @@ -1418,22 +1418,8 @@ public T getInjectedArgument(Class type) { ImageSingletons.lookup(TargetGraphBuilderPlugins.class).register(plugins, replacements, architecture, /* registerForeignCallMath */ false, options); - /* - * When the context is hosted, i.e., ahead-of-time compilation, and after the analysis we - * need the hosted meta access. - */ - MetaAccessProvider pluginsMetaAccess; - if (reason == ParsingReason.PointsToAnalysis || reason == ParsingReason.JITCompilation) { - pluginsMetaAccess = aMetaAccess; - } else { - VMError.guarantee(reason == ParsingReason.AOTCompilation); - pluginsMetaAccess = hMetaAccess; - } - - assert pluginsMetaAccess != null; SubstrateGraphBuilderPlugins.registerInvocationPlugins(annotationSubstitutionProcessor, loader, - pluginsMetaAccess, hostedSnippetReflection, plugins.getInvocationPlugins(), replacements, diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java index 2980c468cd20..019e4d0d9c19 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java @@ -51,27 +51,6 @@ import java.util.function.BooleanSupplier; import java.util.function.Function; -import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor; -import jdk.graal.compiler.core.common.spi.ForeignCallsProvider; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.debug.MethodFilter; -import jdk.graal.compiler.graph.Node; -import jdk.graal.compiler.java.GraphBuilderPhase.Instance; -import jdk.graal.compiler.nodes.StaticDeoptimizingNode; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.extended.UnsafeAccessNode; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; -import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext; -import jdk.graal.compiler.nodes.java.AccessFieldNode; -import jdk.graal.compiler.nodes.java.AccessMonitorNode; -import jdk.graal.compiler.options.Option; -import jdk.graal.compiler.options.OptionValues; -import jdk.graal.compiler.phases.OptimisticOptimizations; -import jdk.graal.compiler.phases.common.BoxNodeIdentityPhase; -import jdk.graal.compiler.phases.common.CanonicalizerPhase; -import jdk.graal.compiler.virtual.phases.ea.PartialEscapePhase; import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; @@ -83,7 +62,6 @@ import com.oracle.graal.pointsto.api.PointstoOptions; import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException; import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMethod; @@ -143,6 +121,27 @@ import com.oracle.svm.util.LogUtils; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor; +import jdk.graal.compiler.core.common.spi.ForeignCallsProvider; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.debug.MethodFilter; +import jdk.graal.compiler.graph.Node; +import jdk.graal.compiler.java.GraphBuilderPhase.Instance; +import jdk.graal.compiler.nodes.StaticDeoptimizingNode; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.extended.UnsafeAccessNode; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; +import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext; +import jdk.graal.compiler.nodes.java.AccessFieldNode; +import jdk.graal.compiler.nodes.java.AccessMonitorNode; +import jdk.graal.compiler.options.Option; +import jdk.graal.compiler.options.OptionValues; +import jdk.graal.compiler.phases.OptimisticOptimizations; +import jdk.graal.compiler.phases.common.BoxNodeIdentityPhase; +import jdk.graal.compiler.phases.common.CanonicalizerPhase; +import jdk.graal.compiler.virtual.phases.ea.PartialEscapePhase; import jdk.vm.ci.meta.DeoptimizationReason; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.ResolvedJavaField; @@ -276,7 +275,7 @@ public void recordActivity() { } @Override - public boolean isRelocatedPointer(UniverseMetaAccess metaAccess, JavaConstant constant) { + public boolean isRelocatedPointer(JavaConstant constant) { return constant instanceof RelocatableConstant; } @@ -327,8 +326,6 @@ public boolean isInitialized(AnalysisType type) { return initializedAtBuildTime; } - private final boolean parseOnce = SubstrateOptions.parseOnce(); - @Override public GraphBuilderConfiguration updateGraphBuilderConfiguration(GraphBuilderConfiguration config, AnalysisMethod method) { GraphBuilderConfiguration updatedConfig = config.withRetainLocalVariables(retainLocalVariables()).withUnresolvedIsError(linkAtBuildTimeSupport.linkAtBuildTime(method.getDeclaringClass())) @@ -341,22 +338,12 @@ public GraphBuilderConfiguration updateGraphBuilderConfiguration(GraphBuilderCon } private boolean retainLocalVariables() { - if (parseOnce) { - /* - * Disabling liveness analysis preserves the values of local variables beyond the - * bytecode-liveness. This greatly helps debugging. Note that when local variable - * numbers are reused by javac, local variables can still be assigned to illegal values. - */ - return SubstrateOptions.optimizationLevel() == OptimizationLevel.O0; - - } else { - /* - * We want to always disable the liveness analysis, since we want the points-to analysis - * to be as conservative as possible. The analysis results can then be used with the - * liveness analysis enabled or disabled. - */ - return true; - } + /* + * Disabling liveness analysis preserves the values of local variables beyond the + * bytecode-liveness. This greatly helps debugging. Note that when local variable numbers + * are reused by javac, local variables can still be assigned to illegal values. + */ + return SubstrateOptions.optimizationLevel() == OptimizationLevel.O0; } @Override @@ -565,31 +552,27 @@ public void methodAfterParsingHook(BigBang bb, AnalysisMethod method, Structured graph.getGraphState().configureExplicitExceptionsNoDeoptIfNecessary(); } - if (parseOnce) { - if (!SubstrateCompilationDirectives.isRuntimeCompiledMethod(method)) { - /* - * Runtime compiled methods should not have assertions. If they do, then they - * should be caught via the blocklist instead of being converted to bytecode - * exceptions. - */ - new ImplicitAssertionsPhase().apply(graph, getProviders(method.getMultiMethodKey())); - } - UninterruptibleAnnotationChecker.checkAfterParsing(method, graph); - - optimizeAfterParsing(bb, method, graph); + if (!SubstrateCompilationDirectives.isRuntimeCompiledMethod(method)) { /* - * Do a complete Canonicalizer run once before graph encoding, to clean up any - * leftover uncanonicalized nodes. + * Runtime compiled methods should not have assertions. If they do, then they should + * be caught via the blocklist instead of being converted to bytecode exceptions. */ - CanonicalizerPhase.create().apply(graph, getProviders(method.getMultiMethodKey())); - /* - * To avoid keeping the whole Graal graphs alive in production use cases, we extract - * the necessary bits of information and store them in secondary storage maps. - */ - if (InliningUtilities.isTrivialMethod(graph)) { - analysisTrivialMethods.put(method, true); - } + new ImplicitAssertionsPhase().apply(graph, getProviders(method.getMultiMethodKey())); + } + UninterruptibleAnnotationChecker.checkAfterParsing(method, graph); + optimizeAfterParsing(bb, method, graph); + /* + * Do a complete Canonicalizer run once before graph encoding, to clean up any leftover + * uncanonicalized nodes. + */ + CanonicalizerPhase.create().apply(graph, getProviders(method.getMultiMethodKey())); + /* + * To avoid keeping the whole Graal graphs alive in production use cases, we extract the + * necessary bits of information and store them in secondary storage maps. + */ + if (InliningUtilities.isTrivialMethod(graph)) { + analysisTrivialMethods.put(method, true); } super.methodAfterParsingHook(bb, method, graph); @@ -648,15 +631,6 @@ public void methodBeforeTypeFlowCreationHook(BigBang bb, AnalysisMethod method, */ analysisGraphs.put(method, graph); } - /* - * To avoid keeping the whole Graal graphs alive in production use cases, we extract the - * necessary bits of information and store them in secondary storage maps. - */ - if (!parseOnce) { - if (InliningUtilities.isTrivialMethod(graph)) { - analysisTrivialMethods.put(method, true); - } - } for (Node n : graph.getNodes()) { if (n instanceof StackValueNode) { containsStackValueNode.put(method, true); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/cenum/CEnumCallWrapperMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/cenum/CEnumCallWrapperMethod.java index b6991e90ae08..a7946c3648a2 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/cenum/CEnumCallWrapperMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/cenum/CEnumCallWrapperMethod.java @@ -26,12 +26,6 @@ import java.lang.reflect.Modifier; -import jdk.graal.compiler.core.common.type.Stamp; -import jdk.graal.compiler.core.common.type.StampFactory; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.nodes.NodeView; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; import org.graalvm.nativeimage.c.constant.CEnumLookup; import org.graalvm.nativeimage.c.constant.CEnumValue; @@ -44,6 +38,12 @@ import com.oracle.svm.hosted.phases.CInterfaceInvocationPlugin; import com.oracle.svm.hosted.phases.HostedGraphKit; +import jdk.graal.compiler.core.common.type.Stamp; +import jdk.graal.compiler.core.common.type.StampFactory; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.nodes.NodeView; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -74,7 +74,7 @@ public boolean isSynthetic() { @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); StructuredGraph graph = kit.getGraph(); ResolvedJavaType returnType = (ResolvedJavaType) method.getSignature().getReturnType(null); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/SimulateClassInitializerSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/SimulateClassInitializerSupport.java index 029d0b2b8fef..5d5ca8d5b022 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/SimulateClassInitializerSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/SimulateClassInitializerSupport.java @@ -29,6 +29,27 @@ import java.util.stream.Collectors; import org.graalvm.collections.EconomicSet; +import org.graalvm.nativeimage.ImageSingletons; + +import com.oracle.graal.pointsto.BigBang; +import com.oracle.graal.pointsto.flow.AnalysisParsedGraph; +import com.oracle.graal.pointsto.meta.AnalysisField; +import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; +import com.oracle.graal.pointsto.meta.AnalysisMethod; +import com.oracle.graal.pointsto.meta.AnalysisType; +import com.oracle.graal.pointsto.meta.HostedProviders; +import com.oracle.graal.pointsto.phases.InlineBeforeAnalysis; +import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder; +import com.oracle.svm.core.classinitialization.EnsureClassInitializedNode; +import com.oracle.svm.core.util.VMError; +import com.oracle.svm.hosted.SVMHost; +import com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider; +import com.oracle.svm.hosted.fieldfolding.MarkStaticFinalFieldInitializedNode; +import com.oracle.svm.hosted.meta.HostedConstantReflectionProvider; +import com.oracle.svm.hosted.meta.HostedType; +import com.oracle.svm.hosted.phases.InlineBeforeAnalysisGraphDecoderImpl; +import com.oracle.svm.util.ClassUtil; + import jdk.graal.compiler.core.common.spi.ConstantFieldProvider; import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.graph.Node; @@ -52,28 +73,6 @@ import jdk.graal.compiler.phases.common.CanonicalizerPhase; import jdk.graal.compiler.printer.GraalDebugHandlersFactory; import jdk.graal.compiler.replacements.PEGraphDecoder; -import org.graalvm.nativeimage.ImageSingletons; - -import com.oracle.graal.pointsto.BigBang; -import com.oracle.graal.pointsto.flow.AnalysisParsedGraph; -import com.oracle.graal.pointsto.meta.AnalysisField; -import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; -import com.oracle.graal.pointsto.meta.AnalysisMethod; -import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.graal.pointsto.phases.InlineBeforeAnalysis; -import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder; -import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.core.classinitialization.EnsureClassInitializedNode; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.SVMHost; -import com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider; -import com.oracle.svm.hosted.fieldfolding.MarkStaticFinalFieldInitializedNode; -import com.oracle.svm.hosted.meta.HostedConstantReflectionProvider; -import com.oracle.svm.hosted.meta.HostedType; -import com.oracle.svm.hosted.phases.InlineBeforeAnalysisGraphDecoderImpl; -import com.oracle.svm.util.ClassUtil; - import jdk.vm.ci.meta.JavaConstant; /** @@ -170,12 +169,7 @@ public class SimulateClassInitializerSupport { /** The main data structure that stores all published results of the simulation. */ protected final ConcurrentMap analyzedClasses = new ConcurrentHashMap<>(); - /** - * Simulation of class initializer (like {@link InlineBeforeAnalysis}) requires ParseOnce, - * because otherwise graphs parsed for static analysis omits exception edges. - */ - protected final boolean enabled = ClassInitializationOptions.SimulateClassInitializer.getValue() && SubstrateOptions.parseOnce(); - + protected final boolean enabled = ClassInitializationOptions.SimulateClassInitializer.getValue(); /* Cached value of options to avoid frequent lookup of option values. */ protected final boolean collectAllReasons = ClassInitializationOptions.SimulateClassInitializerCollectAllReasons.getValue(); protected final int maxInlineDepth = ClassInitializationOptions.SimulateClassInitializerMaxInlineDepth.getValue(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CCallStubMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CCallStubMethod.java index af95c9973032..1ae0c7087cdd 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CCallStubMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CCallStubMethod.java @@ -26,10 +26,6 @@ import java.util.List; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.java.FrameStateBuilder; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; import org.graalvm.nativeimage.c.constant.CEnum; import org.graalvm.nativeimage.c.constant.CEnumLookup; @@ -44,6 +40,10 @@ import com.oracle.svm.hosted.phases.CInterfaceEnumTool; import com.oracle.svm.hosted.phases.HostedGraphKit; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.java.FrameStateBuilder; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaAccessProvider; @@ -67,7 +67,7 @@ public abstract class CCallStubMethod extends CustomSubstitutionMethod { public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { NativeLibraries nativeLibraries = CEntryPointCallStubSupport.singleton().getNativeLibraries(); boolean deoptimizationTarget = MultiMethod.isDeoptTarget(method); - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); FrameStateBuilder state = kit.getFrameState(); List arguments = kit.loadArguments(getParameterTypesForLoad(method)); ValueNode callAddress = createTargetAddressNode(kit, providers, arguments); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointCallStubMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointCallStubMethod.java index e1e51480dac9..ef4a6ae5eee6 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointCallStubMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CEntryPointCallStubMethod.java @@ -36,12 +36,11 @@ import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateContext; import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext; -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; -import com.oracle.graal.pointsto.infrastructure.WrappedJavaMethod; import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.meta.HostedProviders; +import com.oracle.graal.pointsto.util.GraalAccess; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.c.function.CEntryPointBuiltins; @@ -68,6 +67,7 @@ import jdk.graal.compiler.core.common.type.StampFactory; import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.graph.NodeSourcePosition; +import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; import jdk.graal.compiler.nodes.ConstantNode; import jdk.graal.compiler.nodes.DeadEndNode; import jdk.graal.compiler.nodes.FrameState; @@ -75,7 +75,6 @@ import jdk.graal.compiler.nodes.ParameterNode; import jdk.graal.compiler.nodes.StructuredGraph; import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; import jdk.graal.compiler.nodes.calc.FloatConvertNode; import jdk.graal.compiler.nodes.calc.IntegerEqualsNode; import jdk.graal.compiler.nodes.calc.SignExtendNode; @@ -92,11 +91,11 @@ import jdk.vm.ci.meta.Signature; public final class CEntryPointCallStubMethod extends EntryPointCallStubMethod { - static CEntryPointCallStubMethod create(AnalysisMethod targetMethod, CEntryPointData entryPointData, AnalysisMetaAccess metaAccess) { - MetaAccessProvider unwrappedMetaAccess = metaAccess.getWrapped(); - ResolvedJavaType declaringClass = unwrappedMetaAccess.lookupJavaType(IsolateEnterStub.class); - ConstantPool constantPool = IsolateEnterStub.getConstantPool(unwrappedMetaAccess); - return new CEntryPointCallStubMethod(entryPointData, targetMethod, declaringClass, constantPool, metaAccess.getUniverse().getWordKind(), unwrappedMetaAccess); + static CEntryPointCallStubMethod create(AnalysisMethod targetMethod, CEntryPointData entryPointData, AnalysisMetaAccess aMetaAccess) { + MetaAccessProvider originalMetaAccess = GraalAccess.getOriginalProviders().getMetaAccess(); + ResolvedJavaType declaringClass = originalMetaAccess.lookupJavaType(IsolateEnterStub.class); + ConstantPool constantPool = IsolateEnterStub.getConstantPool(originalMetaAccess); + return new CEntryPointCallStubMethod(entryPointData, targetMethod, declaringClass, constantPool, aMetaAccess.getUniverse().getWordKind(), originalMetaAccess); } private static final JavaKind cEnumParameterKind = JavaKind.Int; @@ -122,8 +121,7 @@ private CEntryPointCallStubMethod(CEntryPointData entryPointData, AnalysisMethod * @see CEnum * @see CEntryPointCallStubMethod#adaptParameterTypes(HostedProviders, NativeLibraries, * HostedGraphKit, JavaType[], JavaType[]) - * @see CEntryPointCallStubMethod#adaptReturnValue(ResolvedJavaMethod, HostedProviders, Purpose, - * HostedGraphKit, ValueNode) + * @see CEntryPointCallStubMethod#adaptReturnValue(HostedProviders, HostedGraphKit, ValueNode) */ private static SimpleSignature createSignature(AnalysisMethod targetMethod, JavaKind wordKind, MetaAccessProvider metaAccess) { JavaType[] paramTypes = Arrays.stream(targetMethod.toParameterTypes()) @@ -142,36 +140,19 @@ public Parameter[] getParameters() { return targetMethod.getParameters(); } - private static ResolvedJavaMethod lookupMethodInUniverse(UniverseMetaAccess metaAccess, ResolvedJavaMethod method) { - ResolvedJavaMethod universeMethod = method; - MetaAccessProvider wrappedMetaAccess = metaAccess.getWrapped(); - if (wrappedMetaAccess instanceof UniverseMetaAccess) { - universeMethod = lookupMethodInUniverse((UniverseMetaAccess) wrappedMetaAccess, universeMethod); - } - return metaAccess.getUniverse().lookup(universeMethod); - } - AnalysisMethod lookupTargetMethod(AnalysisMetaAccess metaAccess) { - return (AnalysisMethod) lookupMethodInUniverse(metaAccess, targetMethod); - } - - private ResolvedJavaMethod unwrapMethodAndLookupInUniverse(UniverseMetaAccess metaAccess) { - ResolvedJavaMethod unwrappedTargetMethod = targetMethod; - while (unwrappedTargetMethod instanceof WrappedJavaMethod) { - unwrappedTargetMethod = ((WrappedJavaMethod) unwrappedTargetMethod).getWrapped(); - } - return lookupMethodInUniverse(metaAccess, unwrappedTargetMethod); + return metaAccess.getUniverse().lookup(targetMethod); } @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { if (entryPointData.getBuiltin() != CEntryPointData.DEFAULT_BUILTIN) { - return buildBuiltinGraph(debug, method, providers, purpose); + return buildBuiltinGraph(debug, method, providers); } - UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess(); + AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) providers.getMetaAccess(); NativeLibraries nativeLibraries = CEntryPointCallStubSupport.singleton().getNativeLibraries(); - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); JavaType[] parameterTypes = targetSignature.toParameterTypes(null); JavaType[] parameterLoadTypes = Arrays.copyOf(parameterTypes, parameterTypes.length); @@ -224,31 +205,31 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, adaptArgumentValues(providers, kit, parameterTypes, parameterEnumInfos, args); - ResolvedJavaMethod universeTargetMethod = unwrapMethodAndLookupInUniverse(metaAccess); - kit.emitEnsureInitializedCall(universeTargetMethod.getDeclaringClass()); + AnalysisMethod aTargetMethod = aMetaAccess.getUniverse().lookup(targetMethod); + kit.emitEnsureInitializedCall(aTargetMethod.getDeclaringClass()); int invokeBci = kit.bci(); // Also support non-static test methods (they are not allowed to use the receiver) - InvokeKind invokeKind = universeTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special; + InvokeKind invokeKind = aTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special; ValueNode[] invokeArgs = args; if (invokeKind != InvokeKind.Static) { invokeArgs = new ValueNode[args.length + 1]; invokeArgs[0] = kit.createObject(null); System.arraycopy(args, 0, invokeArgs, 1, args.length); } - InvokeWithExceptionNode invoke = kit.startInvokeWithException(universeTargetMethod, invokeKind, kit.getFrameState(), invokeBci, invokeArgs); + InvokeWithExceptionNode invoke = kit.startInvokeWithException(aTargetMethod, invokeKind, kit.getFrameState(), invokeBci, invokeArgs); patchNodeSourcePosition(invoke); kit.exceptionPart(); ExceptionObjectNode exception = kit.exceptionObject(); - generateExceptionHandler(method, providers, purpose, kit, exception, invoke.getStackKind()); + generateExceptionHandler(providers, kit, exception, invoke.getStackKind()); kit.endInvokeWithException(); - generateEpilogueAndReturn(method, providers, purpose, kit, invoke); + generateEpilogueAndReturn(providers, kit, invoke); return kit.finalizeGraph(); } - private void generateEpilogueAndReturn(ResolvedJavaMethod method, HostedProviders providers, Purpose purpose, HostedGraphKit kit, ValueNode value) { - ValueNode returnValue = adaptReturnValue(method, providers, purpose, kit, value); + private void generateEpilogueAndReturn(HostedProviders providers, HostedGraphKit kit, ValueNode value) { + ValueNode returnValue = adaptReturnValue(providers, kit, value); generateEpilogue(providers, kit); kit.createReturn(returnValue, returnValue.getStackKind()); } @@ -260,24 +241,24 @@ private static void patchNodeSourcePosition(InvokeWithExceptionNode invoke) { } } - private StructuredGraph buildBuiltinGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - ResolvedJavaMethod universeTargetMethod = unwrapMethodAndLookupInUniverse((UniverseMetaAccess) providers.getMetaAccess()); + private StructuredGraph buildBuiltinGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers) { + AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) providers.getMetaAccess(); + AnalysisMethod aTargetMethod = aMetaAccess.getUniverse().lookup(targetMethod); UserError.guarantee(entryPointData.getPrologue() == CEntryPointData.DEFAULT_PROLOGUE, - "@%s method declared as built-in must not have a custom prologue: %s", CEntryPoint.class.getSimpleName(), universeTargetMethod); + "@%s method declared as built-in must not have a custom prologue: %s", CEntryPoint.class.getSimpleName(), aTargetMethod); UserError.guarantee(entryPointData.getEpilogue() == CEntryPointData.DEFAULT_EPILOGUE, - "@%s method declared as built-in must not have a custom epilogue: %s", CEntryPoint.class.getSimpleName(), universeTargetMethod); + "@%s method declared as built-in must not have a custom epilogue: %s", CEntryPoint.class.getSimpleName(), aTargetMethod); UserError.guarantee(entryPointData.getExceptionHandler() == CEntryPointData.DEFAULT_EXCEPTION_HANDLER, - "@%s method declared as built-in must not have a custom exception handler: %s", CEntryPoint.class.getSimpleName(), universeTargetMethod); + "@%s method declared as built-in must not have a custom exception handler: %s", CEntryPoint.class.getSimpleName(), aTargetMethod); - UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess(); - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); - ExecutionContextParameters executionContext = findExecutionContextParameters(providers, universeTargetMethod.toParameterTypes(), universeTargetMethod.getParameterAnnotations()); + ExecutionContextParameters executionContext = findExecutionContextParameters(providers, aTargetMethod.toParameterTypes(), aTargetMethod.getParameterAnnotations()); final CEntryPoint.Builtin builtin = entryPointData.getBuiltin(); ResolvedJavaMethod builtinCallee = null; - for (ResolvedJavaMethod candidate : metaAccess.lookupJavaType(CEntryPointBuiltins.class).getDeclaredMethods(false)) { + for (ResolvedJavaMethod candidate : aMetaAccess.lookupJavaType(CEntryPointBuiltins.class).getDeclaredMethods(false)) { CEntryPointBuiltinImplementation annotation = candidate.getAnnotation(CEntryPointBuiltinImplementation.class); if (annotation != null && annotation.builtin().equals(builtin)) { VMError.guarantee(builtinCallee == null, "More than one candidate for @%s built-in %s", CEntryPoint.class.getSimpleName(), builtin); @@ -328,10 +309,10 @@ private StructuredGraph buildBuiltinGraph(DebugContext debug, ResolvedJavaMethod kit.exceptionPart(); ExceptionObjectNode exception = kit.exceptionObject(); - generateExceptionHandler(method, providers, purpose, kit, exception, invoke.getStackKind()); + generateExceptionHandler(providers, kit, exception, invoke.getStackKind()); kit.endInvokeWithException(); - kit.createReturn(invoke, universeTargetMethod.getSignature().getReturnKind()); + kit.createReturn(invoke, aTargetMethod.getSignature().getReturnKind()); return kit.finalizeGraph(); } @@ -529,7 +510,7 @@ private ValueNode[] matchPrologueParameters(HostedProviders providers, JavaType[ return prologueValues; } - private void generateExceptionHandler(ResolvedJavaMethod method, HostedProviders providers, Purpose purpose, HostedGraphKit kit, ExceptionObjectNode exception, JavaKind returnKind) { + private void generateExceptionHandler(HostedProviders providers, HostedGraphKit kit, ExceptionObjectNode exception, JavaKind returnKind) { if (entryPointData.getExceptionHandler() == CEntryPoint.FatalExceptionHandler.class) { CEntryPointLeaveNode leave = new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, exception); kit.append(leave); @@ -564,7 +545,7 @@ private void generateExceptionHandler(ResolvedJavaMethod method, HostedProviders } /* The exception is handled, we can continue with the normal epilogue. */ - generateEpilogueAndReturn(method, providers, purpose, kit, returnValue); + generateEpilogueAndReturn(providers, kit, returnValue); kit.exceptionPart(); // fail-safe for exceptions in exception handler kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, kit.exceptionObject())); @@ -573,7 +554,7 @@ private void generateExceptionHandler(ResolvedJavaMethod method, HostedProviders } } - private ValueNode adaptReturnValue(ResolvedJavaMethod method, HostedProviders providers, Purpose purpose, HostedGraphKit kit, ValueNode value) { + private ValueNode adaptReturnValue(HostedProviders providers, HostedGraphKit kit, ValueNode value) { ValueNode returnValue = value; if (returnValue.getStackKind().isPrimitive()) { return returnValue; @@ -594,8 +575,7 @@ private ValueNode adaptReturnValue(ResolvedJavaMethod method, HostedProviders pr kit.append(new LoweredDeadEndNode()); kit.endInvokeWithException(); - } else if (purpose != Purpose.ANALYSIS) { - // for analysis test cases: abort only during compilation + } else { throw UserError.abort("Entry point method return types are restricted to primitive types, word types and enumerations (@%s): %s", CEnum.class.getSimpleName(), targetMethod); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java index f37a653b7585..4f3119a4ee64 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java @@ -43,9 +43,7 @@ import com.oracle.graal.pointsto.api.PointstoOptions; import com.oracle.graal.pointsto.flow.AnalysisParsedGraph; -import com.oracle.graal.pointsto.infrastructure.GraphProvider.Purpose; import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.graal.pointsto.phases.SubstrateIntrinsicGraphBuilder; import com.oracle.graal.pointsto.util.CompletionExecutor; import com.oracle.graal.pointsto.util.CompletionExecutor.DebugContextRunnable; import com.oracle.svm.common.meta.MultiMethod; @@ -74,18 +72,14 @@ import com.oracle.svm.hosted.diagnostic.HostedHeapDumpFeature; import com.oracle.svm.hosted.meta.HostedMethod; import com.oracle.svm.hosted.meta.HostedUniverse; -import com.oracle.svm.hosted.phases.HostedGraphBuilderPhase; import com.oracle.svm.hosted.phases.ImageBuildStatisticsCounterPhase; import com.oracle.svm.hosted.phases.ImplicitAssertionsPhase; -import com.oracle.svm.hosted.substitute.DeletedMethod; import com.oracle.svm.util.ImageBuildStatistics; import jdk.graal.compiler.api.replacements.Fold; import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; import jdk.graal.compiler.asm.Assembler; -import jdk.graal.compiler.bytecode.Bytecode; import jdk.graal.compiler.bytecode.BytecodeProvider; -import jdk.graal.compiler.bytecode.ResolvedJavaMethodBytecode; import jdk.graal.compiler.code.CompilationResult; import jdk.graal.compiler.code.DataSection; import jdk.graal.compiler.core.GraalCompiler; @@ -125,7 +119,6 @@ import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode; import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; import jdk.graal.compiler.nodes.graphbuilderconf.InlineInvokePlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin; import jdk.graal.compiler.nodes.java.MethodCallTargetNode; import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.phases.OptimisticOptimizations; @@ -614,21 +607,11 @@ protected void parseAll() throws InterruptedException { private void parseAheadOfTimeCompiledMethods() { for (HostedMethod method : universe.getMethods()) { - if (parseOnce) { - if (SubstrateCompilationDirectives.singleton().isRegisteredForDeoptTesting(method)) { - method.compilationInfo.canDeoptForTesting = true; - assert SubstrateCompilationDirectives.singleton().isRegisteredDeoptTarget(method.getMultiMethod(DEOPT_TARGET_METHOD)); - } - } else { - /* - * Deoptimization target code for deoptimization testing: all methods that are not - * blacklisted are possible deoptimization targets. The methods are also flagged so - * that all possible deoptimization entry points are emitted. - */ - if (method.getWrapped().isImplementationInvoked() && DeoptimizationUtils.canDeoptForTesting(universe, method, deoptimizeAll)) { - method.compilationInfo.canDeoptForTesting = true; - } + if (SubstrateCompilationDirectives.singleton().isRegisteredForDeoptTesting(method)) { + method.compilationInfo.canDeoptForTesting = true; + assert SubstrateCompilationDirectives.singleton().isRegisteredDeoptTarget(method.getMultiMethod(DEOPT_TARGET_METHOD)); } + for (MultiMethod multiMethod : method.getAllMultiMethods()) { HostedMethod hMethod = (HostedMethod) multiMethod; if (hMethod.isDeoptTarget() || SubstrateCompilationDirectives.isRuntimeCompiledMethod(hMethod)) { @@ -672,27 +655,18 @@ public boolean isRegisteredDeoptTarget(HostedMethod method) { } private void parseDeoptimizationTargetMethods() { - if (parseOnce) { - /* - * Deoptimization target code for all methods that were manually marked as - * deoptimization targets. - */ - universe.getMethods().stream().map(method -> method.getMultiMethod(DEOPT_TARGET_METHOD)).filter(deoptMethod -> { - if (deoptMethod != null) { - return isRegisteredDeoptTarget(deoptMethod); - } - return false; - }).forEach(deoptMethod -> { - ensureParsed(deoptMethod, null, new EntryPointReason()); - }); - } else { - /* - * Deoptimization target code for all methods that were manually marked as - * deoptimization targets. - */ - universe.getMethods().stream().filter(method -> isRegisteredDeoptTarget(method) || method.compilationInfo.canDeoptForTesting).forEach( - method -> ensureParsed(method.getOrCreateMultiMethod(DEOPT_TARGET_METHOD), null, new EntryPointReason())); - } + /* + * Deoptimization target code for all methods that were manually marked as deoptimization + * targets. + */ + universe.getMethods().stream().map(method -> method.getMultiMethod(DEOPT_TARGET_METHOD)).filter(deoptMethod -> { + if (deoptMethod != null) { + return isRegisteredDeoptTarget(deoptMethod); + } + return false; + }).forEach(deoptMethod -> { + ensureParsed(deoptMethod, null, new EntryPointReason()); + }); } private static boolean checkTrivial(HostedMethod method, StructuredGraph graph) { @@ -940,18 +914,11 @@ public void scheduleDeoptTargets() { for (HostedMethod method : universe.getMethods()) { HostedMethod deoptTarget = method.getMultiMethod(DEOPT_TARGET_METHOD); if (deoptTarget != null) { - boolean isDeoptTarget; - if (parseOnce) { - /* - * Not all methods will be deopt targets since the optimization of runtime - * compiled methods may eliminate FrameStates. - */ - isDeoptTarget = isRegisteredDeoptTarget(deoptTarget); - } else { - isDeoptTarget = isRegisteredDeoptTarget(method) || method.compilationInfo.canDeoptForTesting; - assert isDeoptTarget : "unexpected Deopt Target " + deoptTarget; - } - if (isDeoptTarget) { + /* + * Not all methods will be deopt targets since the optimization of runtime compiled + * methods may eliminate FrameStates. + */ + if (isRegisteredDeoptTarget(deoptTarget)) { ensureCompiled(deoptTarget, new EntryPointReason()); } } @@ -984,8 +951,6 @@ protected final void doParse(DebugContext debug, ParseTask task) { } } - private final boolean parseOnce = SubstrateOptions.parseOnce(); - @SuppressWarnings("try") private void defaultParseFunction(DebugContext debug, HostedMethod method, CompileReason reason, RuntimeConfiguration config, ParseHooks hooks) { if (method.getAnnotation(NodeIntrinsic.class) != null) { @@ -995,50 +960,17 @@ private void defaultParseFunction(DebugContext debug, HostedMethod method, Compi } HostedProviders providers = (HostedProviders) config.lookupBackend(method).getProviders(); - boolean needParsing = false; - StructuredGraph graph; - if (parseOnce) { - graph = graphTransplanter.transplantGraph(debug, method, reason); - } else { - graph = method.buildGraph(debug, method, providers, Purpose.AOT_COMPILATION); - if (graph == null) { - InvocationPlugin plugin = providers.getGraphBuilderPlugins().getInvocationPlugins().lookupInvocation(method, debug.getOptions()); - if (plugin != null && !plugin.inlineOnly()) { - Bytecode code = new ResolvedJavaMethodBytecode(method); - graph = new SubstrateIntrinsicGraphBuilder(getCustomizedOptions(method, debug), debug, providers, - code).buildGraph(plugin); - } - } - if (graph == null && method.isNative() && - NativeImageOptions.ReportUnsupportedElementsAtRuntime.getValue()) { - graph = DeletedMethod.buildGraph(debug, method, providers, DeletedMethod.NATIVE_MESSAGE, Purpose.AOT_COMPILATION); - } - if (graph == null) { - needParsing = true; - graph = new StructuredGraph.Builder(getCustomizedOptions(method, debug), debug) - .method(method) - .recordInlinedMethods(false) - .build(); - } - } + StructuredGraph graph = graphTransplanter.transplantGraph(debug, method, reason); try (DebugContext.Scope s = debug.scope("Parsing", graph, method, this)) { try { - if (needParsing) { - GraphBuilderConfiguration gbConf = createHostedGraphBuilderConfiguration(providers, method); - new HostedGraphBuilderPhase(providers, gbConf, getOptimisticOpts(), null, providers.getWordTypes()).apply(graph); - } else { - graph.getGraphState().configureExplicitExceptionsNoDeoptIfNecessary(); - } + graph.getGraphState().configureExplicitExceptionsNoDeoptIfNecessary(); PhaseSuite afterParseSuite = hooks.getAfterParseSuite(); afterParseSuite.apply(graph, new HighTierContext(providers, afterParseSuite, getOptimisticOpts())); method.compilationInfo.numNodesAfterParsing = graph.getNodeCount(); - if (!parseOnce) { - UninterruptibleAnnotationChecker.checkAfterParsing(method, graph); - } for (Invoke invoke : graph.getInvokes()) { if (!canBeUsedForInlining(invoke)) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethod.java index 871b6b94165a..2b6a0695a31c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethod.java @@ -24,15 +24,9 @@ */ package com.oracle.svm.hosted.code; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.UnwindNode; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.java.AbstractNewObjectNode; import org.graalvm.nativeimage.ImageSingletons; -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; +import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.HostedProviders; import com.oracle.svm.core.NeverInlineTrivial; @@ -42,8 +36,13 @@ import com.oracle.svm.hosted.phases.HostedGraphKit; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.UnwindNode; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.java.AbstractNewObjectNode; import jdk.vm.ci.meta.ConstantPool; -import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.Signature; @@ -85,17 +84,17 @@ public AnnotationValue[] getInjectedAnnotations() { public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { FactoryMethodSupport support = ImageSingletons.lookup(FactoryMethodSupport.class); - UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess(); - ResolvedJavaMethod universeTargetConstructor = lookupMethodInUniverse(metaAccess, targetConstructor); - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) providers.getMetaAccess(); + AnalysisMethod aTargetConstructor = aMetaAccess.getUniverse().lookup(targetConstructor); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); - AbstractNewObjectNode newInstance = support.createNewInstance(kit, universeTargetConstructor.getDeclaringClass(), true); + AbstractNewObjectNode newInstance = support.createNewInstance(kit, aTargetConstructor.getDeclaringClass(), true); ValueNode[] originalArgs = kit.loadArguments(method.toParameterTypes()).toArray(ValueNode.EMPTY_ARRAY); ValueNode[] invokeArgs = new ValueNode[originalArgs.length + 1]; invokeArgs[0] = newInstance; System.arraycopy(originalArgs, 0, invokeArgs, 1, originalArgs.length); - kit.createInvokeWithExceptionAndUnwind(universeTargetConstructor, InvokeKind.Special, kit.getFrameState(), kit.bci(), invokeArgs); + kit.createInvokeWithExceptionAndUnwind(aTargetConstructor, InvokeKind.Special, kit.getFrameState(), kit.bci(), invokeArgs); if (throwAllocatedObject) { kit.append(new UnwindNode(newInstance)); @@ -105,15 +104,6 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, return kit.finalizeGraph(); } - private ResolvedJavaMethod lookupMethodInUniverse(UniverseMetaAccess metaAccess, ResolvedJavaMethod method) { - ResolvedJavaMethod universeMethod = method; - MetaAccessProvider wrappedMetaAccess = metaAccess.getWrapped(); - if (wrappedMetaAccess instanceof UniverseMetaAccess) { - universeMethod = lookupMethodInUniverse((UniverseMetaAccess) wrappedMetaAccess, universeMethod); - } - return metaAccess.getUniverse().lookup(universeMethod); - } - public ResolvedJavaMethod getTargetConstructor() { return targetConstructor; } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethodSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethodSupport.java index 2a10c80aa937..64084526336e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethodSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/FactoryMethodSupport.java @@ -27,25 +27,20 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import jdk.graal.compiler.nodes.java.AbstractNewObjectNode; -import jdk.graal.compiler.nodes.java.NewInstanceNode; import org.graalvm.nativeimage.ImageSingletons; -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.graal.pointsto.meta.AnalysisUniverse; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.code.FactoryMethodHolder; import com.oracle.svm.core.code.FactoryThrowMethodHolder; import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton; import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.meta.HostedMetaAccess; -import com.oracle.svm.hosted.meta.HostedMethod; -import com.oracle.svm.hosted.meta.HostedUniverse; import com.oracle.svm.hosted.phases.HostedGraphKit; +import jdk.graal.compiler.nodes.java.AbstractNewObjectNode; +import jdk.graal.compiler.nodes.java.NewInstanceNode; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -61,19 +56,7 @@ public static FactoryMethodSupport singleton() { private final Map factoryMethods = new ConcurrentHashMap<>(); private final Map factoryThrowMethods = new ConcurrentHashMap<>(); - public ResolvedJavaMethod lookup(UniverseMetaAccess metaAccess, ResolvedJavaMethod constructor, boolean throwAllocatedObject) { - HostedUniverse hUniverse; - AnalysisMetaAccess aMetaAccess; - if (metaAccess instanceof HostedMetaAccess) { - hUniverse = (HostedUniverse) metaAccess.getUniverse(); - aMetaAccess = (AnalysisMetaAccess) metaAccess.getWrapped(); - } else { - hUniverse = null; - aMetaAccess = (AnalysisMetaAccess) metaAccess; - } - AnalysisUniverse aUniverse = aMetaAccess.getUniverse(); - - AnalysisMethod aConstructor = constructor instanceof HostedMethod ? ((HostedMethod) constructor).getWrapped() : (AnalysisMethod) constructor; + public AnalysisMethod lookup(AnalysisMetaAccess aMetaAccess, AnalysisMethod aConstructor, boolean throwAllocatedObject) { VMError.guarantee(aConstructor.getDeclaringClass().isInstanceClass() && !aConstructor.getDeclaringClass().isAbstract(), "Must be a non-abstract instance class"); Map methods = throwAllocatedObject ? factoryThrowMethods : factoryMethods; FactoryMethod factoryMethod = methods.computeIfAbsent(aConstructor, key -> { @@ -98,12 +81,7 @@ public ResolvedJavaMethod lookup(UniverseMetaAccess metaAccess, ResolvedJavaMeth return new FactoryMethod(name, unwrappedConstructor, unwrappedDeclaringClass, unwrappedSignature, unwrappedConstantPool, throwAllocatedObject); }); - AnalysisMethod aFactoryMethod = aUniverse.lookup(factoryMethod); - if (hUniverse != null) { - return hUniverse.lookup(aFactoryMethod); - } else { - return aFactoryMethod; - } + return aMetaAccess.getUniverse().lookup(factoryMethod); } protected AbstractNewObjectNode createNewInstance(HostedGraphKit kit, ResolvedJavaType type, boolean fillContents) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/IncompatibleClassChangeFallbackMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/IncompatibleClassChangeFallbackMethod.java index 3928b216ccba..05433c56074a 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/IncompatibleClassChangeFallbackMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/IncompatibleClassChangeFallbackMethod.java @@ -24,18 +24,17 @@ */ package com.oracle.svm.hosted.code; +import com.oracle.graal.pointsto.meta.HostedProviders; +import com.oracle.svm.hosted.analysis.NativeImagePointsToAnalysis; +import com.oracle.svm.hosted.phases.HostedGraphKit; +import com.oracle.svm.util.ReflectionUtil; + import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; import jdk.graal.compiler.nodes.StructuredGraph; import jdk.graal.compiler.nodes.UnwindNode; import jdk.graal.compiler.nodes.java.AbstractNewObjectNode; import jdk.graal.compiler.nodes.java.NewInstanceNode; - -import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.svm.hosted.analysis.NativeImagePointsToAnalysis; -import com.oracle.svm.hosted.phases.HostedGraphKit; -import com.oracle.svm.util.ReflectionUtil; - import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -69,7 +68,7 @@ public ResolvedJavaMethod getOriginal() { @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); ResolvedJavaMethod constructor = providers.getMetaAccess().lookupJavaMethod(ReflectionUtil.lookupConstructor(resolutionError)); AbstractNewObjectNode newInstance = kit.append(new NewInstanceNode(constructor.getDeclaringClass(), true)); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/SubstrateCompilationDirectives.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/SubstrateCompilationDirectives.java index 4a418f4c9752..212bff292022 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/SubstrateCompilationDirectives.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/SubstrateCompilationDirectives.java @@ -28,19 +28,18 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import jdk.graal.compiler.debug.Assertions; -import jdk.graal.compiler.nodes.FrameState; -import jdk.graal.compiler.nodes.ValueNode; import org.graalvm.nativeimage.ImageSingletons; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.svm.common.meta.MultiMethod; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.code.FrameInfoEncoder; import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.meta.HostedMethod; +import jdk.graal.compiler.debug.Assertions; +import jdk.graal.compiler.nodes.FrameState; +import jdk.graal.compiler.nodes.ValueNode; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -187,7 +186,6 @@ public void registerFrameInformationRequired(AnalysisMethod frameMethod, Analysi } public boolean isFrameInformationRequired(ResolvedJavaMethod method) { - assert deoptInfoQueryable(); return frameInformationRequired.contains(toAnalysisMethod(method)); } @@ -217,12 +215,10 @@ public void registerForDeoptTesting(ResolvedJavaMethod method) { } public boolean isRegisteredForDeoptTesting(ResolvedJavaMethod method) { - assert deoptInfoQueryable(); return deoptForTestingMethods.contains(toAnalysisMethod(method)); } public boolean isRegisteredDeoptTarget(ResolvedJavaMethod method) { - assert deoptInfoQueryable(); return deoptEntries.containsKey(toAnalysisMethod(method)); } @@ -232,8 +228,6 @@ public void registerDeoptTarget(ResolvedJavaMethod method) { } public boolean isDeoptEntry(MultiMethod method, int bci, FrameState.StackState stackState) { - assert deoptInfoQueryable(); - if (method instanceof HostedMethod && ((HostedMethod) method).getMultiMethod(MultiMethod.ORIGINAL_METHOD).compilationInfo.canDeoptForTesting()) { return true; } @@ -242,7 +236,6 @@ public boolean isDeoptEntry(MultiMethod method, int bci, FrameState.StackState s } public boolean isRegisteredDeoptEntry(MultiMethod method, int bci, FrameState.StackState stackState) { - assert deoptInfoQueryable(); Map bciMap = deoptEntries.get(toAnalysisMethod((ResolvedJavaMethod) method)); assert bciMap != null : "can only query for deopt entries for methods registered as deopt targets"; @@ -256,12 +249,10 @@ public void registerAsDeoptInlininingExclude(ResolvedJavaMethod method) { } public boolean isDeoptInliningExclude(ResolvedJavaMethod method) { - assert deoptInfoQueryable(); return deoptInliningExcludes.contains(toAnalysisMethod(method)); } public Map> getDeoptEntries() { - assert deoptInfoQueryable(); return deoptEntries; } @@ -275,32 +266,17 @@ private static AnalysisMethod toAnalysisMethod(ResolvedJavaMethod method) { } } - private boolean deoptInfoQueryable() { - if (!SubstrateOptions.parseOnce()) { - /* - * Without parseonce, once querying starts, then the deopt information should no longer - * be modified. - * - * However, with parseonce, we require deoptimization information to be incrementally - * read throughout execution, so it must be always queryable. - */ - deoptInfoSealed = true; - } - return true; - } - private boolean deoptInfoModifiable() { return !deoptInfoSealed; } /** - * Parse once records the deoptimization information twice: once during analysis and then again - * during compilation. The information recorded during compilation will be strictly a subset of - * the information recorded during analysis. + * We record the deoptimization information twice: once during analysis and then again during + * compilation. The information recorded during compilation will be strictly a subset of the + * information recorded during analysis. */ public void resetDeoptEntries() { assert !deoptInfoSealed; - assert SubstrateOptions.parseOnce(); // all methods which are registered for deopt testing cannot be cleared Map> newDeoptEntries = new ConcurrentHashMap<>(); for (var deoptForTestingMethod : deoptForTestingMethods) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodFactorySubstitutionMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodFactorySubstitutionMethod.java index df694c4f96fe..5f8376567a7b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodFactorySubstitutionMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/heap/PodFactorySubstitutionMethod.java @@ -29,22 +29,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import jdk.graal.compiler.core.common.type.StampFactory; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.graph.NodeSourcePosition; -import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; -import jdk.graal.compiler.nodes.ConstantNode; -import jdk.graal.compiler.nodes.FixedNode; -import jdk.graal.compiler.nodes.FixedWithNextNode; -import jdk.graal.compiler.nodes.FrameState; -import jdk.graal.compiler.nodes.InvokeWithExceptionNode; -import jdk.graal.compiler.nodes.PiNode; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.UnreachableBeginNode; -import jdk.graal.compiler.nodes.UnwindNode; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.java.ExceptionObjectNode; import org.graalvm.nativeimage.AnnotationAccess; import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor; @@ -64,6 +48,22 @@ import com.oracle.svm.hosted.nodes.DeoptProxyNode; import com.oracle.svm.hosted.phases.HostedGraphKit; +import jdk.graal.compiler.core.common.type.StampFactory; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.graph.NodeSourcePosition; +import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; +import jdk.graal.compiler.nodes.ConstantNode; +import jdk.graal.compiler.nodes.FixedNode; +import jdk.graal.compiler.nodes.FixedWithNextNode; +import jdk.graal.compiler.nodes.FrameState; +import jdk.graal.compiler.nodes.InvokeWithExceptionNode; +import jdk.graal.compiler.nodes.PiNode; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.UnreachableBeginNode; +import jdk.graal.compiler.nodes.UnwindNode; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.java.ExceptionObjectNode; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -120,7 +120,7 @@ public int getModifiers() { @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); DeoptInfoProvider deoptInfo = null; if (MultiMethod.isDeoptTarget(method)) { deoptInfo = new DeoptInfoProvider((MultiMethod) method); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java index fee9606ad777..285dd7e7462f 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java @@ -373,7 +373,7 @@ private void addMethod(Executable method, DuringAnalysisAccessImpl access) { ResolvedJavaMethod newObjectMethod = null; if (targetMethod.isConstructor() && !targetMethod.getDeclaringClass().isAbstract()) { - var aFactoryMethod = (AnalysisMethod) FactoryMethodSupport.singleton().lookup(access.getMetaAccess(), aTargetMethod, false); + var aFactoryMethod = FactoryMethodSupport.singleton().lookup(access.getMetaAccess(), aTargetMethod, false); access.registerAsRoot(aFactoryMethod, true, "JNI constructor, registered in " + JNIAccessFeature.class); newObjectMethod = aFactoryMethod.getWrapped(); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNICallTrampolineMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNICallTrampolineMethod.java index 665254269950..6570f6022478 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNICallTrampolineMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNICallTrampolineMethod.java @@ -28,8 +28,6 @@ import java.util.ArrayList; import java.util.List; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.nodes.StructuredGraph; import org.graalvm.nativeimage.ImageSingletons; import com.oracle.graal.pointsto.meta.AnalysisUniverse; @@ -52,6 +50,8 @@ import com.oracle.svm.hosted.phases.HostedGraphKit; import com.oracle.svm.hosted.thread.VMThreadMTFeature; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.nodes.StructuredGraph; import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.code.RegisterValue; import jdk.vm.ci.meta.JavaType; @@ -91,7 +91,7 @@ public int getModifiers() { @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - HostedGraphKit kit = new JNIGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new JNIGraphKit(debug, providers, method); kit.append(new LoweredDeadEndNode()); return kit.finalizeGraph(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFieldAccessorMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFieldAccessorMethod.java index 946e813e4746..c85051b33080 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFieldAccessorMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFieldAccessorMethod.java @@ -28,12 +28,6 @@ import java.util.EnumSet; import java.util.List; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.java.FrameStateBuilder; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.extended.RawLoadNode; -import jdk.graal.compiler.nodes.extended.RawStoreNode; import org.graalvm.nativeimage.c.function.CEntryPoint.FatalExceptionHandler; import org.graalvm.nativeimage.c.function.CEntryPoint.Publish; import org.graalvm.word.LocationIdentity; @@ -53,6 +47,12 @@ import com.oracle.svm.hosted.code.EntryPointCallStubMethod; import com.oracle.svm.hosted.code.SimpleSignature; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.java.FrameStateBuilder; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.extended.RawLoadNode; +import jdk.graal.compiler.nodes.extended.RawStoreNode; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; @@ -173,7 +173,7 @@ private static SimpleSignature createSignature(JavaKind fieldKind, boolean isSet @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - JNIGraphKit kit = new JNIGraphKit(debug, providers, method, purpose); + JNIGraphKit kit = new JNIGraphKit(debug, providers, method); StructuredGraph graph = kit.getGraph(); FrameStateBuilder state = new FrameStateBuilder(null, method, graph); state.initializeForMethodStart(null, true, providers.getGraphBuilderPlugins()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIGraphKit.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIGraphKit.java index 24dd690d412d..3e354d89dd12 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIGraphKit.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIGraphKit.java @@ -24,6 +24,13 @@ */ package com.oracle.svm.hosted.jni; +import com.oracle.graal.pointsto.meta.HostedProviders; +import com.oracle.svm.core.jni.JNIGeneratedMethodSupport; +import com.oracle.svm.core.jni.access.JNIAccessibleMethod; +import com.oracle.svm.core.jni.access.JNIReflectionDictionary; +import com.oracle.svm.core.jni.headers.JNIMethodId; +import com.oracle.svm.hosted.phases.HostedGraphKit; + import jdk.graal.compiler.core.common.type.ObjectStamp; import jdk.graal.compiler.core.common.type.Stamp; import jdk.graal.compiler.core.common.type.StampFactory; @@ -46,15 +53,6 @@ import jdk.graal.compiler.nodes.extended.GuardingNode; import jdk.graal.compiler.nodes.java.ExceptionObjectNode; import jdk.graal.compiler.nodes.java.InstanceOfNode; - -import com.oracle.graal.pointsto.infrastructure.GraphProvider; -import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.svm.core.jni.JNIGeneratedMethodSupport; -import com.oracle.svm.core.jni.access.JNIAccessibleMethod; -import com.oracle.svm.core.jni.access.JNIReflectionDictionary; -import com.oracle.svm.core.jni.headers.JNIMethodId; -import com.oracle.svm.hosted.phases.HostedGraphKit; - import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -64,8 +62,8 @@ */ public class JNIGraphKit extends HostedGraphKit { - JNIGraphKit(DebugContext debug, HostedProviders providers, ResolvedJavaMethod method, GraphProvider.Purpose purpose) { - super(debug, providers, method, purpose); + JNIGraphKit(DebugContext debug, HostedProviders providers, ResolvedJavaMethod method) { + super(debug, providers, method); } public ValueNode checkObjectType(ValueNode uncheckedValue, ResolvedJavaType type, boolean checkNonNull) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallVariantWrapperMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallVariantWrapperMethod.java index c7a057e5b8fc..1cf25dd9970e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallVariantWrapperMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallVariantWrapperMethod.java @@ -27,6 +27,24 @@ import java.util.ArrayList; import java.util.List; +import org.graalvm.nativeimage.Platform; +import org.graalvm.word.LocationIdentity; + +import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; +import com.oracle.graal.pointsto.meta.HostedProviders; +import com.oracle.svm.core.graal.code.SubstrateCallingConventionKind; +import com.oracle.svm.core.graal.nodes.CEntryPointEnterNode; +import com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode; +import com.oracle.svm.core.graal.nodes.CInterfaceReadNode; +import com.oracle.svm.core.graal.nodes.ReadCallerStackPointerNode; +import com.oracle.svm.core.graal.nodes.VaListInitializationNode; +import com.oracle.svm.core.graal.nodes.VaListNextArgNode; +import com.oracle.svm.core.jni.CallVariant; +import com.oracle.svm.core.jni.JNIJavaCallVariantWrapperHolder; +import com.oracle.svm.core.util.VMError; +import com.oracle.svm.hosted.code.EntryPointCallStubMethod; +import com.oracle.svm.hosted.code.SimpleSignature; + import jdk.graal.compiler.core.common.calc.FloatConvert; import jdk.graal.compiler.core.common.memory.BarrierType; import jdk.graal.compiler.core.common.memory.MemoryOrderMode; @@ -49,27 +67,6 @@ import jdk.graal.compiler.nodes.calc.ReinterpretNode; import jdk.graal.compiler.nodes.memory.address.OffsetAddressNode; import jdk.graal.compiler.word.WordTypes; -import org.graalvm.nativeimage.Platform; -import org.graalvm.word.LocationIdentity; - -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; -import com.oracle.graal.pointsto.infrastructure.WrappedSignature; -import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; -import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.svm.core.graal.code.SubstrateCallingConventionKind; -import com.oracle.svm.core.graal.nodes.CEntryPointEnterNode; -import com.oracle.svm.core.graal.nodes.CEntryPointLeaveNode; -import com.oracle.svm.core.graal.nodes.CInterfaceReadNode; -import com.oracle.svm.core.graal.nodes.ReadCallerStackPointerNode; -import com.oracle.svm.core.graal.nodes.VaListInitializationNode; -import com.oracle.svm.core.graal.nodes.VaListNextArgNode; -import com.oracle.svm.core.jni.CallVariant; -import com.oracle.svm.core.jni.JNIJavaCallVariantWrapperHolder; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.code.EntryPointCallStubMethod; -import com.oracle.svm.hosted.code.SimpleSignature; -import com.oracle.svm.hosted.meta.HostedMetaAccess; - import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; @@ -141,15 +138,10 @@ private static Signature createSignature(Signature callWrapperSignature, CallVar @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess(); - JNIGraphKit kit = new JNIGraphKit(debug, providers, method, purpose); + AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) providers.getMetaAccess(); + JNIGraphKit kit = new JNIGraphKit(debug, providers, method); - AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) ((metaAccess instanceof AnalysisMetaAccess) ? metaAccess : metaAccess.getWrapped()); Signature invokeSignature = aMetaAccess.getUniverse().lookup(callWrapperSignature, getDeclaringClass()); - if (metaAccess instanceof HostedMetaAccess) { - // signature might not exist in the hosted universe because it does not match any method - invokeSignature = new WrappedSignature(metaAccess.getUniverse(), invokeSignature, getDeclaringClass()); - } JavaKind wordKind = providers.getWordTypes().getWordKind(); int slotIndex = 0; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java index 3d8c805e994f..59b7d3104064 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIJavaCallWrapperMethod.java @@ -27,6 +27,17 @@ import java.lang.reflect.Constructor; import java.util.List; +import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; +import com.oracle.graal.pointsto.meta.HostedProviders; +import com.oracle.svm.core.graal.code.SubstrateCallingConventionKind; +import com.oracle.svm.core.graal.nodes.LoweredDeadEndNode; +import com.oracle.svm.core.jni.JNIJavaCallWrapperHolder; +import com.oracle.svm.core.jni.access.JNIAccessibleMethod; +import com.oracle.svm.hosted.code.FactoryMethodSupport; +import com.oracle.svm.hosted.code.NonBytecodeMethod; +import com.oracle.svm.hosted.code.SimpleSignature; +import com.oracle.svm.util.ReflectionUtil; + import jdk.graal.compiler.core.common.type.Stamp; import jdk.graal.compiler.core.common.type.StampFactory; import jdk.graal.compiler.core.common.type.StampPair; @@ -48,21 +59,6 @@ import jdk.graal.compiler.nodes.java.ExceptionObjectNode; import jdk.graal.compiler.nodes.type.StampTool; import jdk.graal.compiler.word.WordTypes; - -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; -import com.oracle.graal.pointsto.infrastructure.WrappedSignature; -import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; -import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.svm.core.graal.code.SubstrateCallingConventionKind; -import com.oracle.svm.core.graal.nodes.LoweredDeadEndNode; -import com.oracle.svm.core.jni.JNIJavaCallWrapperHolder; -import com.oracle.svm.core.jni.access.JNIAccessibleMethod; -import com.oracle.svm.hosted.code.FactoryMethodSupport; -import com.oracle.svm.hosted.code.NonBytecodeMethod; -import com.oracle.svm.hosted.code.SimpleSignature; -import com.oracle.svm.hosted.meta.HostedMetaAccess; -import com.oracle.svm.util.ReflectionUtil; - import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaAccessProvider; @@ -161,15 +157,10 @@ public SimpleSignature getSignature() { @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess(); - JNIGraphKit kit = new JNIGraphKit(debug, providers, method, purpose); + AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) providers.getMetaAccess(); + JNIGraphKit kit = new JNIGraphKit(debug, providers, method); - AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) ((metaAccess instanceof AnalysisMetaAccess) ? metaAccess : metaAccess.getWrapped()); Signature invokeSignature = aMetaAccess.getUniverse().lookup(targetSignature, getDeclaringClass()); - if (metaAccess instanceof HostedMetaAccess) { - // signature might not exist in the hosted universe because it does not match any method - invokeSignature = new WrappedSignature(metaAccess.getUniverse(), invokeSignature, getDeclaringClass()); - } JavaKind wordKind = providers.getWordTypes().getWordKind(); int slotIndex = 0; @@ -261,8 +252,8 @@ private static ValueNode createNewObjectCall(JNIGraphKit kit, Signature invokeSi ConstantNode abstractTypeSentinel = kit.createWord(JNIAccessibleMethod.NEW_OBJECT_INVALID_FOR_ABSTRACT_TYPE); kit.startIf(IntegerEqualsNode.create(newObjectAddress, abstractTypeSentinel, NodeView.DEFAULT), BranchProbabilityNode.SLOW_PATH_PROFILE); kit.thenPart(); - ResolvedJavaMethod exceptionCtor = kit.getMetaAccess().lookupJavaMethod(INSTANTIATION_EXCEPTION_CONSTRUCTOR); - ResolvedJavaMethod throwMethod = FactoryMethodSupport.singleton().lookup((UniverseMetaAccess) kit.getMetaAccess(), exceptionCtor, true); + var exceptionCtor = kit.getMetaAccess().lookupJavaMethod(INSTANTIATION_EXCEPTION_CONSTRUCTOR); + var throwMethod = FactoryMethodSupport.singleton().lookup(kit.getMetaAccess(), exceptionCtor, true); kit.createInvokeWithExceptionAndUnwind(throwMethod, CallTargetNode.InvokeKind.Static, kit.getFrameState(), kit.bci()); kit.append(new LoweredDeadEndNode()); kit.endIf(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNINativeCallWrapperMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNINativeCallWrapperMethod.java index 5fd0ce5341fb..40e26eb3ba01 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNINativeCallWrapperMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNINativeCallWrapperMethod.java @@ -30,15 +30,6 @@ import java.util.List; import java.util.function.Function; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.nodes.ConstantNode; -import jdk.graal.compiler.nodes.InvokeWithExceptionNode; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.java.MonitorEnterNode; -import jdk.graal.compiler.nodes.java.MonitorExitNode; -import jdk.graal.compiler.nodes.java.MonitorIdNode; - import com.oracle.graal.pointsto.infrastructure.WrappedJavaMethod; import com.oracle.graal.pointsto.meta.HostedProviders; import com.oracle.svm.core.c.CGlobalDataFactory; @@ -54,6 +45,14 @@ import com.oracle.svm.hosted.heap.SVMImageHeapScanner; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.nodes.ConstantNode; +import jdk.graal.compiler.nodes.InvokeWithExceptionNode; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.java.MonitorEnterNode; +import jdk.graal.compiler.nodes.java.MonitorExitNode; +import jdk.graal.compiler.nodes.java.MonitorIdNode; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.LineNumberTable; @@ -108,7 +107,7 @@ public StackTraceElement asStackTraceElement(int bci) { @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - JNIGraphKit kit = new JNIGraphKit(debug, providers, method, purpose); + JNIGraphKit kit = new JNIGraphKit(debug, providers, method); StructuredGraph graph = kit.getGraph(); InvokeWithExceptionNode handleFrame = kit.nativeCallPrologue(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIPrimitiveArrayOperationMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIPrimitiveArrayOperationMethod.java index 76eee57ae931..b83fbd4773aa 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIPrimitiveArrayOperationMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIPrimitiveArrayOperationMethod.java @@ -28,12 +28,6 @@ import java.util.EnumSet; import java.util.List; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.java.FrameStateBuilder; -import jdk.graal.compiler.nodes.FixedWithNextNode; -import jdk.graal.compiler.nodes.MergeNode; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; import org.graalvm.nativeimage.c.function.CEntryPoint.FatalExceptionHandler; import org.graalvm.nativeimage.c.function.CEntryPoint.Publish; import org.graalvm.nativeimage.c.type.CCharPointer; @@ -53,6 +47,12 @@ import com.oracle.svm.hosted.code.EntryPointCallStubMethod; import com.oracle.svm.hosted.code.SimpleSignature; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.java.FrameStateBuilder; +import jdk.graal.compiler.nodes.FixedWithNextNode; +import jdk.graal.compiler.nodes.MergeNode; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; @@ -175,7 +175,7 @@ private static SimpleSignature createSignature(Operation operation, MetaAccessPr @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - JNIGraphKit kit = new JNIGraphKit(debug, providers, method, purpose); + JNIGraphKit kit = new JNIGraphKit(debug, providers, method); StructuredGraph graph = kit.getGraph(); FrameStateBuilder state = new FrameStateBuilder(null, method, graph); state.initializeForMethodStart(null, true, providers.getGraphBuilderPlugins()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedType.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedType.java index 0ea3d9b28aa9..a5e072466837 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedType.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedType.java @@ -238,11 +238,6 @@ public final AssumptionResult hasFinalizableSubclass() { @Override public final boolean isInitialized() { - if (!wrapped.isReachable()) { - /* Workaround until ParseOnce can always be enabled. */ - return wrapped.isInitialized(); - } - /* * Note that we do not delegate to wrapped.isInitialized here: when a class initializer is * simulated at image build time, then AnalysisType.isInitialized() returns false but diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/AnalysisGraphBuilderPhase.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/AnalysisGraphBuilderPhase.java index 127df6fb7f62..bbd3c04c1a4c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/AnalysisGraphBuilderPhase.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/AnalysisGraphBuilderPhase.java @@ -24,6 +24,12 @@ */ package com.oracle.svm.hosted.phases; +import com.oracle.graal.pointsto.infrastructure.AnalysisConstantPool; +import com.oracle.graal.pointsto.meta.AnalysisMethod; +import com.oracle.svm.hosted.SVMHost; +import com.oracle.svm.hosted.code.SubstrateCompilationDirectives; +import com.oracle.svm.util.ModuleSupport; + import jdk.graal.compiler.core.common.BootstrapMethodIntrospection; import jdk.graal.compiler.java.BciBlockMapping; import jdk.graal.compiler.java.BytecodeParser; @@ -33,21 +39,12 @@ import jdk.graal.compiler.nodes.StructuredGraph; import jdk.graal.compiler.nodes.ValueNode; import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; -import jdk.graal.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo; import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext; import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin; import jdk.graal.compiler.nodes.graphbuilderconf.NodePlugin; import jdk.graal.compiler.nodes.spi.CoreProviders; import jdk.graal.compiler.phases.OptimisticOptimizations; import jdk.graal.compiler.word.WordTypes; - -import com.oracle.graal.pointsto.infrastructure.AnalysisConstantPool; -import com.oracle.graal.pointsto.meta.AnalysisMethod; -import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.hosted.SVMHost; -import com.oracle.svm.hosted.code.SubstrateCompilationDirectives; -import com.oracle.svm.util.ModuleSupport; - import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -105,21 +102,6 @@ protected boolean applyInvocationPlugin(InvokeKind invokeKind, ValueNode[] args, return super.applyInvocationPlugin(invokeKind, args, targetMethod, resultType, plugin); } - private final boolean parseOnce = SubstrateOptions.parseOnce(); - - @Override - protected BytecodeParser.ExceptionEdgeAction getActionForInvokeExceptionEdge(InlineInfo lastInlineInfo) { - if (!parseOnce && !insideTryBlock()) { - /* - * The static analysis does not track the flow of exceptions across method - * boundaries. Therefore, it is not necessary to have exception edges that go - * directly to an UnwindNode because there is no exception handler in between. - */ - return ExceptionEdgeAction.OMIT; - } - return super.getActionForInvokeExceptionEdge(lastInlineInfo); - } - private boolean tryNodePluginForDynamicInvocation(BootstrapMethodIntrospection bootstrap) { for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) { var result = plugin.convertInvokeDynamic(this, bootstrap); @@ -133,11 +115,9 @@ private boolean tryNodePluginForDynamicInvocation(BootstrapMethodIntrospection b @Override protected void genInvokeDynamic(int cpi, int opcode) { - if (parseOnce) { - BootstrapMethodIntrospection bootstrap = ((AnalysisConstantPool) constantPool).lookupBootstrapMethodIntrospection(cpi, opcode); - if (bootstrap != null && tryNodePluginForDynamicInvocation(bootstrap)) { - return; - } + BootstrapMethodIntrospection bootstrap = ((AnalysisConstantPool) constantPool).lookupBootstrapMethodIntrospection(cpi, opcode); + if (bootstrap != null && tryNodePluginForDynamicInvocation(bootstrap)) { + return; } super.genInvokeDynamic(cpi, opcode); } @@ -151,18 +131,16 @@ protected void genStoreField(ValueNode receiver, ResolvedJavaField field, ValueN @Override protected FrameStateBuilder createFrameStateForExceptionHandling(int bci) { var dispatchState = super.createFrameStateForExceptionHandling(bci); - if (SubstrateOptions.parseOnce()) { - /* - * It is beneficial to eagerly clear all non-live locals on the exception object - * before entering the dispatch target. This helps us prune unneeded values from the - * graph, which can positively impact our analysis. Since deoptimization is not - * possible, then there is no risk in clearing the unneeded locals. - */ - AnalysisMethod aMethod = (AnalysisMethod) method; - if (aMethod.isOriginalMethod() && !SubstrateCompilationDirectives.singleton().isRegisteredForDeoptTesting(aMethod)) { - BciBlockMapping.BciBlock dispatchBlock = getDispatchBlock(bci); - clearNonLiveLocals(dispatchState, dispatchBlock, true); - } + /* + * It is beneficial to eagerly clear all non-live locals on the exception object before + * entering the dispatch target. This helps us prune unneeded values from the graph, + * which can positively impact our analysis. Since deoptimization is not possible, then + * there is no risk in clearing the unneeded locals. + */ + AnalysisMethod aMethod = (AnalysisMethod) method; + if (aMethod.isOriginalMethod() && !SubstrateCompilationDirectives.singleton().isRegisteredForDeoptTesting(aMethod)) { + BciBlockMapping.BciBlock dispatchBlock = getDispatchBlock(bci); + clearNonLiveLocals(dispatchState, dispatchBlock, true); } return dispatchState; } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/EnumSwitchPlugin.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/EnumSwitchPlugin.java index 5107aa6d5199..1a0df5e4a9ff 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/EnumSwitchPlugin.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/EnumSwitchPlugin.java @@ -28,15 +28,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.nodes.ConstantNode; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; -import jdk.graal.compiler.nodes.graphbuilderconf.NodePlugin; -import jdk.graal.compiler.phases.util.Providers; import org.graalvm.nativeimage.ImageSingletons; import com.oracle.graal.pointsto.BigBang; @@ -45,11 +36,19 @@ import com.oracle.svm.core.classinitialization.EnsureClassInitializedNode; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; +import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; -import com.oracle.svm.hosted.snippets.IntrinsificationPluginRegistry; -import com.oracle.svm.hosted.snippets.ReflectionPlugins; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.nodes.ConstantNode; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; +import jdk.graal.compiler.nodes.graphbuilderconf.NodePlugin; +import jdk.graal.compiler.phases.util.Providers; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -74,51 +73,46 @@ final class EnumSwitchPlugin implements NodePlugin { } @Override - public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) { + public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod m, ValueNode[] args) { + VMError.guarantee(reason.duringAnalysis(), "plugin can only be used during parsing for analysis"); + AnalysisMethod method = (AnalysisMethod) m; + if (!method.getName().startsWith(METHOD_NAME_PREFIX) || !method.isStatic() || method.getSignature().getParameterCount(false) != 0) { return false; } - - if (reason.duringAnalysis()) { - if (!method.getDeclaringClass().isInitialized()) { - /* - * Declaring class is initialized at run time. Even if the enum itself is - * initialized at image build time, we cannot invoke the switch-table method because - * it is declared in the class that contains the switch. - */ - return false; - } - + if (!method.getDeclaringClass().isInitialized()) { /* - * There is no easy link from the method to the enum that it is actually used for. But - * we need to ensure that invoking the method does not trigger any class initialization. - * Parsing the method is the easiest way to find out what the method is going to do. If - * any class initialization happens inside method, we must not invoke it. Note that we - * do not check for transitive callees, because we trust that the Eclipse compiler only - * emits calls that end up in the same class or in the JDK. + * Declaring class is initialized at run time. Even if the enum itself is initialized at + * image build time, we cannot invoke the switch-table method because it is declared in + * the class that contains the switch. */ - AnalysisMethod aMethod = (AnalysisMethod) method; - EnumSwitchFeature feature = ImageSingletons.lookup(EnumSwitchFeature.class); - aMethod.ensureGraphParsed(feature.bb); - Boolean methodSafeForExecution = feature.methodsSafeForExecution.get(aMethod); - assert methodSafeForExecution != null : "after-parsing hook not executed for method " + aMethod.format("%H.%n(%p)"); - if (!methodSafeForExecution.booleanValue()) { - return false; - - } - try { - Method switchTableMethod = ReflectionUtil.lookupMethod(aMethod.getDeclaringClass().getJavaClass(), method.getName()); - Object switchTable = switchTableMethod.invoke(null); - if (switchTable instanceof int[]) { - ImageSingletons.lookup(ReflectionPlugins.ReflectionPluginRegistry.class).add(b.getMethod(), b.bci(), switchTable); - } - } catch (ReflectiveOperationException ex) { - throw GraalError.shouldNotReachHere(ex); // ExcludeFromJacocoGeneratedReport - } + return false; + } + /* + * There is no easy link from the method to the enum that it is actually used for. But we + * need to ensure that invoking the method does not trigger any class initialization. + * Parsing the method is the easiest way to find out what the method is going to do. If any + * class initialization happens inside method, we must not invoke it. Note that we do not + * check for transitive callees, because we trust that the Eclipse compiler only emits calls + * that end up in the same class or in the JDK. + */ + EnumSwitchFeature feature = ImageSingletons.lookup(EnumSwitchFeature.class); + method.ensureGraphParsed(feature.bb); + Boolean methodSafeForExecution = feature.methodsSafeForExecution.get(method); + assert methodSafeForExecution != null : "after-parsing hook not executed for method " + method.format("%H.%n(%p)"); + if (!methodSafeForExecution.booleanValue()) { + return false; } - Object switchTable = ImageSingletons.lookup(ReflectionPlugins.ReflectionPluginRegistry.class).get(b.getMethod(), b.bci()); - if (switchTable != null) { + Object switchTable; + try { + Method switchTableMethod = ReflectionUtil.lookupMethod(method.getDeclaringClass().getJavaClass(), method.getName()); + switchTable = switchTableMethod.invoke(null); + } catch (ReflectiveOperationException ex) { + throw GraalError.shouldNotReachHere(ex); // ExcludeFromJacocoGeneratedReport + } + + if (switchTable instanceof int[]) { b.addPush(JavaKind.Object, ConstantNode.forConstant(snippetReflection.forObject(switchTable), 1, true, b.getMetaAccess())); return true; } @@ -126,9 +120,6 @@ public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Va } } -final class EnumSwitchPluginRegistry extends IntrinsificationPluginRegistry { -} - @AutomaticallyRegisteredFeature final class EnumSwitchFeature implements InternalFeature { @@ -138,7 +129,6 @@ final class EnumSwitchFeature implements InternalFeature { @Override public void duringSetup(DuringSetupAccess a) { - ImageSingletons.add(EnumSwitchPluginRegistry.class, new EnumSwitchPluginRegistry()); DuringSetupAccessImpl access = (DuringSetupAccessImpl) a; bb = access.getBigBang(); access.getHostVM().addMethodAfterParsingListener(this::onMethodParsed); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/HostedGraphBuilderPhase.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/HostedGraphBuilderPhase.java deleted file mode 100644 index 7e6597ee0712..000000000000 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/HostedGraphBuilderPhase.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2013, 2022, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 com.oracle.svm.hosted.phases; - -import com.oracle.svm.core.nodes.SubstrateMethodCallTargetNode; -import com.oracle.svm.hosted.meta.HostedMethod; -import com.oracle.svm.hosted.phases.SubstrateGraphBuilderPhase.SubstrateBytecodeParser; - -import jdk.graal.compiler.core.common.type.StampPair; -import jdk.graal.compiler.java.BytecodeParser; -import jdk.graal.compiler.java.FrameStateBuilder; -import jdk.graal.compiler.java.GraphBuilderPhase; -import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; -import jdk.graal.compiler.nodes.FixedWithNextNode; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; -import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext; -import jdk.graal.compiler.nodes.java.MethodCallTargetNode; -import jdk.graal.compiler.nodes.spi.CoreProviders; -import jdk.graal.compiler.phases.OptimisticOptimizations; -import jdk.graal.compiler.word.WordTypes; -import jdk.vm.ci.meta.JavaTypeProfile; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -public class HostedGraphBuilderPhase extends SubstrateGraphBuilderPhase { - - public HostedGraphBuilderPhase(CoreProviders providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext, - WordTypes wordTypes) { - super(providers, graphBuilderConfig, optimisticOpts, initialIntrinsicContext, wordTypes); - } - - @Override - protected BytecodeParser createBytecodeParser(StructuredGraph graph, BytecodeParser parent, ResolvedJavaMethod method, int entryBCI, IntrinsicContext intrinsicContext) { - return new HostedBytecodeParser(this, graph, parent, method, entryBCI, intrinsicContext); - } -} - -class HostedBytecodeParser extends SubstrateBytecodeParser { - - HostedBytecodeParser(GraphBuilderPhase.Instance graphBuilderInstance, StructuredGraph graph, BytecodeParser parent, ResolvedJavaMethod method, int entryBCI, IntrinsicContext intrinsicContext) { - super(graphBuilderInstance, graph, parent, method, entryBCI, intrinsicContext, true); - } - - @Override - public HostedMethod getMethod() { - return (HostedMethod) super.getMethod(); - } - - @Override - protected boolean stampFromValueForForcedPhis() { - return true; - } - - @Override - public boolean allowDeoptInPlugins() { - return false; - } - - @Override - protected void build(FixedWithNextNode startInstruction, FrameStateBuilder startFrameState) { - super.build(startInstruction, startFrameState); - - /* We never have floating guards in AOT compiled code. */ - getGraph().getGraphState().configureExplicitExceptionsNoDeopt(); - - assert !getMethod().isEntryPoint() : "Cannot directly use as entry point, create a call stub "; - } - - @Override - public MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, StampPair returnStamp, JavaTypeProfile profile) { - return new SubstrateMethodCallTargetNode(invokeKind, targetMethod, args, returnStamp); - } - -} diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/HostedGraphKit.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/HostedGraphKit.java index 2df926b43b03..64563ac088de 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/HostedGraphKit.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/HostedGraphKit.java @@ -28,7 +28,7 @@ import java.util.Arrays; import java.util.List; -import com.oracle.graal.pointsto.infrastructure.GraphProvider; +import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.HostedProviders; import com.oracle.svm.core.c.BoxedRelocatedPointer; import com.oracle.svm.core.classinitialization.EnsureClassInitializedNode; @@ -57,17 +57,21 @@ import jdk.graal.compiler.nodes.java.LoadFieldNode; import jdk.graal.compiler.nodes.type.StampTool; import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; public class HostedGraphKit extends SubstrateGraphKit { - public HostedGraphKit(DebugContext debug, HostedProviders providers, ResolvedJavaMethod method, GraphProvider.Purpose purpose) { - super(debug, method, providers, providers.getWordTypes(), providers.getGraphBuilderPlugins(), new SubstrateCompilationIdentifier(), purpose == GraphProvider.Purpose.ANALYSIS, + public HostedGraphKit(DebugContext debug, HostedProviders providers, ResolvedJavaMethod method) { + super(debug, method, providers, providers.getWordTypes(), providers.getGraphBuilderPlugins(), new SubstrateCompilationIdentifier(), SubstrateCompilationDirectives.isRuntimeCompiledMethod(method)); } + @Override + public AnalysisMetaAccess getMetaAccess() { + return (AnalysisMetaAccess) super.getMetaAccess(); + } + public void emitEnsureInitializedCall(ResolvedJavaType type) { if (EnsureClassInitializedNode.needsRuntimeInitialization(graph.method().getDeclaringClass(), type)) { ValueNode hub = createConstant(getConstantReflection().asJavaClass(type), JavaKind.Object); @@ -85,8 +89,8 @@ public T appendWithUnwind(T withExceptionNode) { public LoadFieldNode createLoadFieldNode(ConstantNode receiver, Class clazz, String fieldName) { try { - ResolvedJavaField field = getMetaAccess().lookupJavaField(clazz.getDeclaredField(fieldName)); - return LoadFieldNode.createOverrideStamp(StampPair.createSingle(wordStamp((ResolvedJavaType) field.getType())), receiver, field); + var field = getMetaAccess().lookupJavaField(clazz.getDeclaredField(fieldName)); + return LoadFieldNode.createOverrideStamp(StampPair.createSingle(wordStamp(field.getType())), receiver, field); } catch (NoSuchFieldException e) { throw VMError.shouldNotReachHere(e); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/IntrinsifyMethodHandlesInvocationPlugin.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/IntrinsifyMethodHandlesInvocationPlugin.java index 2242bff7b9ac..242acbc508eb 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/IntrinsifyMethodHandlesInvocationPlugin.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/IntrinsifyMethodHandlesInvocationPlugin.java @@ -40,6 +40,27 @@ import org.graalvm.collections.Pair; import org.graalvm.collections.UnmodifiableEconomicMap; + +import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; +import com.oracle.graal.pointsto.meta.AnalysisMethod; +import com.oracle.graal.pointsto.meta.AnalysisType; +import com.oracle.graal.pointsto.meta.AnalysisUniverse; +import com.oracle.graal.pointsto.meta.HostedProviders; +import com.oracle.graal.pointsto.phases.NoClassInitializationPlugin; +import com.oracle.graal.pointsto.util.GraalAccess; +import com.oracle.svm.core.FrameAccess; +import com.oracle.svm.core.ParsingReason; +import com.oracle.svm.core.graal.phases.TrustedInterfaceTypePlugin; +import com.oracle.svm.core.graal.word.SubstrateWordTypes; +import com.oracle.svm.core.jdk.VarHandleFeature; +import com.oracle.svm.core.util.VMError; +import com.oracle.svm.hosted.SVMHost; +import com.oracle.svm.hosted.meta.HostedMethod; +import com.oracle.svm.hosted.meta.HostedSnippetReflectionProvider; +import com.oracle.svm.hosted.meta.HostedType; +import com.oracle.svm.hosted.meta.HostedUniverse; +import com.oracle.svm.util.ReflectionUtil; + import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; import jdk.graal.compiler.core.common.spi.MetaAccessExtensionProvider; import jdk.graal.compiler.core.common.type.ObjectStamp; @@ -107,29 +128,6 @@ import jdk.graal.compiler.replacements.InlineDuringParsingPlugin; import jdk.graal.compiler.replacements.MethodHandlePlugin; import jdk.graal.compiler.word.WordOperationPlugin; -import org.graalvm.nativeimage.ImageSingletons; - -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; -import com.oracle.graal.pointsto.meta.AnalysisMethod; -import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.graal.pointsto.meta.AnalysisUniverse; -import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.graal.pointsto.phases.NoClassInitializationPlugin; -import com.oracle.graal.pointsto.util.GraalAccess; -import com.oracle.svm.core.FrameAccess; -import com.oracle.svm.core.ParsingReason; -import com.oracle.svm.core.graal.phases.TrustedInterfaceTypePlugin; -import com.oracle.svm.core.graal.word.SubstrateWordTypes; -import com.oracle.svm.core.jdk.VarHandleFeature; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.SVMHost; -import com.oracle.svm.hosted.meta.HostedMethod; -import com.oracle.svm.hosted.meta.HostedSnippetReflectionProvider; -import com.oracle.svm.hosted.meta.HostedType; -import com.oracle.svm.hosted.meta.HostedUniverse; -import com.oracle.svm.hosted.snippets.IntrinsificationPluginRegistry; -import com.oracle.svm.util.ReflectionUtil; - import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.DeoptimizationReason; @@ -143,9 +141,7 @@ /** * Legacy code which will be replaced by the more general method handle intrinsification and - * inlining in {@link com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder} once - * {@link com.oracle.svm.core.SubstrateOptions#parseOnce()} is always on, including when JIT - * compilation is enabled. + * inlining in {@link com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder}. * * Support for method handles that can be reduced to a plain invocation. This is enough to support * the method handles used for Java 8 Lambda expressions. Support for arbitrary method handles is @@ -194,9 +190,6 @@ public class IntrinsifyMethodHandlesInvocationPlugin implements NodePlugin { } } - public static class IntrinsificationRegistry extends IntrinsificationPluginRegistry { - } - private final ParsingReason reason; private final Providers parsingProviders; private final HostedProviders universeProviders; @@ -206,8 +199,6 @@ public static class IntrinsificationRegistry extends IntrinsificationPluginRegis private final ClassInitializationPlugin classInitializationPlugin; - private final IntrinsificationRegistry intrinsificationRegistry; - private final ResolvedJavaType methodHandleType; private final ResolvedJavaType varHandleType; @@ -224,13 +215,6 @@ public IntrinsifyMethodHandlesInvocationPlugin(ParsingReason reason, HostedSnipp this.classInitializationPlugin = new SubstrateClassInitializationPlugin((SVMHost) aUniverse.hostVM()); - if (reason == ParsingReason.PointsToAnalysis) { - intrinsificationRegistry = new IntrinsificationRegistry(); - ImageSingletons.add(IntrinsificationRegistry.class, intrinsificationRegistry); - } else { - intrinsificationRegistry = ImageSingletons.lookup(IntrinsificationRegistry.class); - } - methodHandleType = universeProviders.getMetaAccess().lookupJavaType(MethodHandle.class); varHandleType = universeProviders.getMetaAccess().lookupJavaType(VarHandle.class); } @@ -594,14 +578,6 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec @SuppressWarnings("try") private boolean processInvokeWithMethodHandle(GraphBuilderContext b, Replacements replacements, ResolvedJavaMethod methodHandleMethod, ValueNode[] methodHandleArguments) { - /* - * When parsing for compilation, we must not intrinsify method handles that were not - * intrinsified during analysis. Otherwise new code that was not seen as reachable by the - * static analysis would be compiled. - */ - if (!reason.duringAnalysis() && intrinsificationRegistry.get(b.getMethod(), b.bci()) != Boolean.TRUE) { - return false; - } Plugins graphBuilderPlugins = new Plugins(parsingProviders.getReplacements().getGraphBuilderPlugins()); registerInvocationPlugins(graphBuilderPlugins.getInvocationPlugins(), replacements); @@ -649,14 +625,6 @@ private boolean processInvokeWithMethodHandle(GraphBuilderContext b, Replacement Transplanter transplanter = new Transplanter(b, transplanted); try { transplanter.graph(graph); - - if (reason.duringAnalysis()) { - /* - * Successfully intrinsified during analysis, remember that we can intrinsify - * when parsing for compilation. - */ - intrinsificationRegistry.add(b.getMethod(), b.bci(), Boolean.TRUE); - } return true; } catch (AbortTransplantException ex) { /* diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/SharedGraphBuilderPhase.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/SharedGraphBuilderPhase.java index 66fdd7f21d9d..37d38b7ff361 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/SharedGraphBuilderPhase.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/SharedGraphBuilderPhase.java @@ -35,9 +35,8 @@ import com.oracle.graal.pointsto.constraints.UnresolvedElementException; import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException; import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; +import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.svm.common.meta.MultiMethod; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.deopt.DeoptimizationSupport; import com.oracle.svm.core.graal.nodes.DeoptEntryBeginNode; @@ -53,16 +52,13 @@ import com.oracle.svm.hosted.LinkAtBuildTimeSupport; import com.oracle.svm.hosted.code.FactoryMethodSupport; import com.oracle.svm.hosted.code.SubstrateCompilationDirectives; -import com.oracle.svm.hosted.meta.HostedMethod; import com.oracle.svm.hosted.nodes.DeoptProxyNode; import com.oracle.svm.util.ReflectionUtil; import jdk.graal.compiler.api.replacements.Fold; import jdk.graal.compiler.core.common.calc.Condition; import jdk.graal.compiler.core.common.type.StampPair; -import jdk.graal.compiler.debug.DebugCloseable; import jdk.graal.compiler.graph.Node.NodeIntrinsic; -import jdk.graal.compiler.graph.NodeSourcePosition; import jdk.graal.compiler.java.BciBlockMapping; import jdk.graal.compiler.java.BytecodeParser; import jdk.graal.compiler.java.FrameStateBuilder; @@ -375,7 +371,7 @@ protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKi public static void replaceWithThrowingAtRuntime(SharedBytecodeParser b, T throwable) { Throwable cause = throwable.getCause(); if (cause != null) { - var metaAccess = (UniverseMetaAccess) b.getMetaAccess(); + var metaAccess = (AnalysisMetaAccess) b.getMetaAccess(); /* Invoke method that creates a cause-instance with cause-message */ var causeCtor = ReflectionUtil.lookupConstructor(cause.getClass(), String.class); ResolvedJavaMethod causeCtorMethod = FactoryMethodSupport.singleton().lookup(metaAccess, metaAccess.lookupJavaMethod(causeCtor), false); @@ -415,7 +411,7 @@ public static void replaceWithThrowingAtRuntime(SharedBytecodeParser b, Class invocationTargetExceptionPaths = new ArrayList<>(); public ReflectionGraphKit(DebugContext debug, HostedProviders providers, ResolvedJavaMethod method, GraphProvider.Purpose purpose) { - super(debug, providers, method, purpose); + super(debug, providers, method); } @Override @@ -155,7 +153,7 @@ public void emitIllegalArgumentException(ValueNode obj, ValueNode args) { public void emitInvocationTargetException() { AbstractMergeNode merge = continueWithMerge(invocationTargetExceptionPaths); ValueNode exception = createPhi(invocationTargetExceptionPaths, merge); - ResolvedJavaMethod throwInvocationTargetException = FactoryMethodSupport.singleton().lookup((UniverseMetaAccess) getMetaAccess(), + ResolvedJavaMethod throwInvocationTargetException = FactoryMethodSupport.singleton().lookup(getMetaAccess(), getMetaAccess().lookupJavaMethod(invocationTargetExceptionConstructor), true); InvokeWithExceptionNode invoke = createJavaCallWithExceptionAndUnwind(CallTargetNode.InvokeKind.Static, throwInvocationTargetException, exception); invoke.setInlineControl(Invoke.InlineControl.Never); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/IntrinsificationPluginRegistry.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/IntrinsificationPluginRegistry.java deleted file mode 100644 index 58adc4e4cb5a..000000000000 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/IntrinsificationPluginRegistry.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2019, 2019, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 com.oracle.svm.hosted.snippets; - -import java.util.concurrent.ConcurrentHashMap; - -import com.oracle.graal.pointsto.meta.AnalysisMethod; -import com.oracle.svm.common.meta.MultiMethod; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.meta.HostedMethod; - -import jdk.vm.ci.meta.ResolvedJavaMethod; - -public class IntrinsificationPluginRegistry { - - static final class CallSiteDescriptor { - private final AnalysisMethod method; - private final int bci; - - private CallSiteDescriptor(ResolvedJavaMethod method, int bci) { - this.method = toAnalysisMethod(method); - this.bci = bci; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof CallSiteDescriptor) { - CallSiteDescriptor other = (CallSiteDescriptor) obj; - return other.bci == this.bci && other.method.equals(this.method); - } - return false; - } - - @Override - public int hashCode() { - return method.hashCode() ^ bci; - } - - @Override - public String toString() { - return method.format("%h.%n(%p)") + "@" + bci; - } - - private static AnalysisMethod toAnalysisMethod(ResolvedJavaMethod method) { - if (method instanceof HostedMethod) { - return ((HostedMethod) method).wrapped; - } else { - VMError.guarantee(method instanceof AnalysisMethod); - return (AnalysisMethod) method; - } - } - } - - private static final Object NULL_MARKER = new Object(); - - /** - * Contains all the elements intrinsified during analysis. Only these elements will be - * intrinsified during compilation. We cannot intrinsify an element during compilation if it was - * not intrinsified during analysis since it can lead to compiling code that was not seen during - * analysis. - */ - private final ConcurrentHashMap analysisElements = new ConcurrentHashMap<>(); - - public void add(ResolvedJavaMethod method, int bci, Object element) { - Object nonNullElement = element != null ? element : NULL_MARKER; - Object previous = analysisElements.put(new CallSiteDescriptor(method, bci), nonNullElement); - - /* - * New elements can only be added when the intrinsification is executed during the analysis. - * If an intrinsified element was already registered that's an error. - * - * The only exception to this is deoptimization target methods; as these methods can be - * reparsed during analysis, the same element may be registered multiple times. - */ - VMError.guarantee(previous == null || MultiMethod.isDeoptTarget(method), "Detected previously intrinsified element"); - } - - @SuppressWarnings("unchecked") - public T get(ResolvedJavaMethod method, int bci) { - Object nonNullElement = analysisElements.get(new CallSiteDescriptor(method, bci)); - return nonNullElement != NULL_MARKER ? (T) nonNullElement : null; - } -} diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/ReflectionPlugins.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/ReflectionPlugins.java index 74b2971940af..e048e06e2e86 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/ReflectionPlugins.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/ReflectionPlugins.java @@ -48,18 +48,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.nodes.ConstantNode; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.graphbuilderconf.ClassInitializationPlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; -import jdk.graal.compiler.options.Option; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.RuntimeReflection; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; @@ -68,7 +56,6 @@ import com.oracle.graal.pointsto.meta.AnalysisUniverse; import com.oracle.svm.core.MissingRegistrationUtils; import com.oracle.svm.core.ParsingReason; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.TypeResult; import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.hub.PredefinedClassesSupport; @@ -85,6 +72,18 @@ import com.oracle.svm.util.ModuleSupport; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.nodes.ConstantNode; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.graphbuilderconf.ClassInitializationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; +import jdk.graal.compiler.options.Option; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; @@ -105,9 +104,6 @@ * JDK so that any code that would rely on object identity is error-prone on any JVM. */ public final class ReflectionPlugins { - public static class ReflectionPluginRegistry extends IntrinsificationPluginRegistry { - } - static class Options { @Option(help = "Enable trace logging for reflection plugins.")// static final HostedOptionKey ReflectionPluginTracing = new HostedOptionKey<>(false); @@ -142,16 +138,6 @@ private ReflectionPlugins(ImageClassLoader imageClassLoader, SnippetReflectionPr public static void registerInvocationPlugins(ImageClassLoader imageClassLoader, SnippetReflectionProvider snippetReflection, AnnotationSubstitutionProcessor annotationSubstitutions, ClassInitializationPlugin classInitializationPlugin, InvocationPlugins plugins, AnalysisUniverse aUniverse, ParsingReason reason, FallbackFeature fallbackFeature) { - /* - * Initialize the registry if we are during analysis. If hosted is false, i.e., we are - * analyzing the static initializers, then we always intrinsify, so don't need a registry. - */ - if (reason == ParsingReason.PointsToAnalysis) { - if (!ImageSingletons.contains(ReflectionPluginRegistry.class)) { - ImageSingletons.add(ReflectionPluginRegistry.class, new ReflectionPluginRegistry()); - } - } - ReflectionPlugins rp = new ReflectionPlugins(imageClassLoader, snippetReflection, annotationSubstitutions, classInitializationPlugin, aUniverse, reason, fallbackFeature); rp.registerMethodHandlesPlugins(plugins); rp.registerClassPlugins(plugins); @@ -646,8 +632,6 @@ private Object unboxObjectConstant(GraphBuilderContext b, JavaConstant argConsta return null; } - private final boolean parseOnce = SubstrateOptions.parseOnce(); - /** * This method checks if the element should be intrinsified and returns the cached intrinsic * element if found. Caching intrinsic elements during analysis and reusing the same element @@ -664,32 +648,15 @@ private T getIntrinsic(GraphBuilderContext context, T element) { /* We are analyzing the static initializers and should always intrinsify. */ return element; } - /* We don't intrinsify if bci is not unique. */ - if (context.bciCanBeDuplicated()) { + if (isDeleted(element, context.getMetaAccess())) { + /* + * Should not intrinsify. Will fail during the reflective lookup at runtime. @Delete-ed + * elements are ignored by the reflection plugins regardless of the value of + * ReportUnsupportedElementsAtRuntime. + */ return null; } - if (parseOnce || reason.duringAnalysis()) { - if (isDeleted(element, context.getMetaAccess())) { - /* - * Should not intrinsify. Will fail during the reflective lookup at - * runtime. @Delete-ed elements are ignored by the reflection plugins regardless of - * the value of ReportUnsupportedElementsAtRuntime. - */ - return null; - } - - Object replaced = aUniverse.replaceObject(element); - - if (parseOnce) { - /* No separate parsing for compilation, so no need to cache the result. */ - return (T) replaced; - } - - /* During parsing for analysis we intrinsify and cache the result for compilation. */ - ImageSingletons.lookup(ReflectionPluginRegistry.class).add(context.getMethod(), context.bci(), replaced); - } - /* During parsing for compilation we only intrinsify if intrinsified during analysis. */ - return ImageSingletons.lookup(ReflectionPluginRegistry.class).get(context.getMethod(), context.bci()); + return (T) aUniverse.replaceObject(element); } private static boolean isDeleted(T element, MetaAccessProvider metaAccess) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java index 23ab1ac7fb42..23c886345d27 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java @@ -39,64 +39,6 @@ import java.util.function.Function; import java.util.stream.Stream; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.core.common.CompressEncoding; -import jdk.graal.compiler.core.common.type.AbstractObjectStamp; -import jdk.graal.compiler.core.common.type.IntegerStamp; -import jdk.graal.compiler.core.common.type.StampFactory; -import jdk.graal.compiler.graph.Edges; -import jdk.graal.compiler.graph.Node; -import jdk.graal.compiler.graph.NodeList; -import jdk.graal.compiler.graph.NodeSourcePosition; -import jdk.graal.compiler.java.BytecodeParser; -import jdk.graal.compiler.java.LambdaUtils; -import jdk.graal.compiler.nodes.AbstractBeginNode; -import jdk.graal.compiler.nodes.BeginNode; -import jdk.graal.compiler.nodes.ConstantNode; -import jdk.graal.compiler.nodes.DynamicPiNode; -import jdk.graal.compiler.nodes.FixedNode; -import jdk.graal.compiler.nodes.FixedWithNextNode; -import jdk.graal.compiler.nodes.FullInfopointNode; -import jdk.graal.compiler.nodes.LogicNode; -import jdk.graal.compiler.nodes.NodeView; -import jdk.graal.compiler.nodes.PiNode; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.calc.NarrowNode; -import jdk.graal.compiler.nodes.calc.ZeroExtendNode; -import jdk.graal.compiler.nodes.extended.BytecodeExceptionNode; -import jdk.graal.compiler.nodes.extended.LoadHubNode; -import jdk.graal.compiler.nodes.extended.StateSplitProxyNode; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; -import jdk.graal.compiler.nodes.java.DynamicNewInstanceNode; -import jdk.graal.compiler.nodes.java.InstanceOfDynamicNode; -import jdk.graal.compiler.nodes.java.NewArrayNode; -import jdk.graal.compiler.nodes.java.StoreIndexedNode; -import jdk.graal.compiler.nodes.spi.ArrayLengthProvider; -import jdk.graal.compiler.nodes.spi.CoreProviders; -import jdk.graal.compiler.nodes.spi.Replacements; -import jdk.graal.compiler.nodes.type.NarrowOopStamp; -import jdk.graal.compiler.nodes.type.StampTool; -import jdk.graal.compiler.nodes.util.GraphUtil; -import jdk.graal.compiler.nodes.virtual.AllocatedObjectNode; -import jdk.graal.compiler.nodes.virtual.CommitAllocationNode; -import jdk.graal.compiler.nodes.virtual.VirtualArrayNode; -import jdk.graal.compiler.nodes.virtual.VirtualObjectNode; -import jdk.graal.compiler.options.Option; -import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins; -import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins.AllocateUninitializedArrayPlugin; -import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins.CounterModeCryptPlugin; -import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins.ReachabilityFencePlugin; -import jdk.graal.compiler.replacements.nodes.AESNode; -import jdk.graal.compiler.replacements.nodes.CipherBlockChainingAESNode; -import jdk.graal.compiler.replacements.nodes.CounterModeAESNode; -import jdk.graal.compiler.replacements.nodes.MacroNode.MacroParams; -import jdk.graal.compiler.word.WordCastNode; import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.ImageSingletons; @@ -149,7 +91,6 @@ import com.oracle.svm.core.identityhashcode.SubstrateIdentityHashCodeNode; import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry; import com.oracle.svm.core.meta.SharedField; -import com.oracle.svm.core.meta.SharedMethod; import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.snippets.KnownIntrinsics; import com.oracle.svm.core.util.UserError; @@ -157,12 +98,68 @@ import com.oracle.svm.hosted.FallbackFeature; import com.oracle.svm.hosted.ImageClassLoader; import com.oracle.svm.hosted.ReachabilityRegistrationNode; -import com.oracle.svm.hosted.meta.HostedField; -import com.oracle.svm.hosted.meta.HostedMetaAccess; import com.oracle.svm.hosted.nodes.DeoptProxyNode; import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor; import com.oracle.svm.util.ClassUtil; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.core.common.CompressEncoding; +import jdk.graal.compiler.core.common.type.AbstractObjectStamp; +import jdk.graal.compiler.core.common.type.IntegerStamp; +import jdk.graal.compiler.core.common.type.StampFactory; +import jdk.graal.compiler.graph.Edges; +import jdk.graal.compiler.graph.Node; +import jdk.graal.compiler.graph.NodeList; +import jdk.graal.compiler.graph.NodeSourcePosition; +import jdk.graal.compiler.java.BytecodeParser; +import jdk.graal.compiler.java.LambdaUtils; +import jdk.graal.compiler.nodes.AbstractBeginNode; +import jdk.graal.compiler.nodes.BeginNode; +import jdk.graal.compiler.nodes.ConstantNode; +import jdk.graal.compiler.nodes.DynamicPiNode; +import jdk.graal.compiler.nodes.FixedNode; +import jdk.graal.compiler.nodes.FixedWithNextNode; +import jdk.graal.compiler.nodes.FullInfopointNode; +import jdk.graal.compiler.nodes.LogicNode; +import jdk.graal.compiler.nodes.NodeView; +import jdk.graal.compiler.nodes.PiNode; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.calc.NarrowNode; +import jdk.graal.compiler.nodes.calc.ZeroExtendNode; +import jdk.graal.compiler.nodes.extended.BytecodeExceptionNode; +import jdk.graal.compiler.nodes.extended.LoadHubNode; +import jdk.graal.compiler.nodes.extended.StateSplitProxyNode; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; +import jdk.graal.compiler.nodes.java.DynamicNewInstanceNode; +import jdk.graal.compiler.nodes.java.InstanceOfDynamicNode; +import jdk.graal.compiler.nodes.java.NewArrayNode; +import jdk.graal.compiler.nodes.java.StoreIndexedNode; +import jdk.graal.compiler.nodes.spi.ArrayLengthProvider; +import jdk.graal.compiler.nodes.spi.CoreProviders; +import jdk.graal.compiler.nodes.spi.Replacements; +import jdk.graal.compiler.nodes.type.NarrowOopStamp; +import jdk.graal.compiler.nodes.type.StampTool; +import jdk.graal.compiler.nodes.util.GraphUtil; +import jdk.graal.compiler.nodes.virtual.AllocatedObjectNode; +import jdk.graal.compiler.nodes.virtual.CommitAllocationNode; +import jdk.graal.compiler.nodes.virtual.VirtualArrayNode; +import jdk.graal.compiler.nodes.virtual.VirtualObjectNode; +import jdk.graal.compiler.options.Option; +import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins; +import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins.AllocateUninitializedArrayPlugin; +import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins.CounterModeCryptPlugin; +import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins.ReachabilityFencePlugin; +import jdk.graal.compiler.replacements.nodes.AESNode; +import jdk.graal.compiler.replacements.nodes.CipherBlockChainingAESNode; +import jdk.graal.compiler.replacements.nodes.CounterModeAESNode; +import jdk.graal.compiler.replacements.nodes.MacroNode.MacroParams; +import jdk.graal.compiler.word.WordCastNode; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.meta.DeoptimizationAction; import jdk.vm.ci.meta.JavaConstant; @@ -184,7 +181,6 @@ public static class Options { public static void registerInvocationPlugins(AnnotationSubstitutionProcessor annotationSubstitutions, ImageClassLoader loader, - MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, InvocationPlugins plugins, Replacements replacements, @@ -193,19 +189,19 @@ public static void registerInvocationPlugins(AnnotationSubstitutionProcessor ann boolean supportsStubBasedPlugins) { // register the substratevm plugins - registerSystemPlugins(metaAccess, snippetReflection, plugins); + registerSystemPlugins(snippetReflection, plugins); registerReflectionPlugins(plugins, replacements); - registerImageInfoPlugins(metaAccess, plugins); + registerImageInfoPlugins(plugins); registerProxyPlugins(snippetReflection, annotationSubstitutions, plugins, parsingReason); registerSerializationPlugins(loader, snippetReflection, plugins, parsingReason); - registerAtomicUpdaterPlugins(metaAccess, snippetReflection, plugins, parsingReason); + registerAtomicUpdaterPlugins(snippetReflection, plugins); registerObjectPlugins(plugins); - registerUnsafePlugins(metaAccess, plugins, snippetReflection, parsingReason); + registerUnsafePlugins(plugins, snippetReflection, parsingReason); registerKnownIntrinsicsPlugins(plugins); registerStackValuePlugins(snippetReflection, plugins); registerArrayPlugins(plugins, snippetReflection, parsingReason); registerClassPlugins(plugins, snippetReflection); - registerEdgesPlugins(metaAccess, plugins); + registerEdgesPlugins(plugins); registerVMConfigurationPlugins(snippetReflection, plugins); registerPlatformPlugins(snippetReflection, plugins); registerSizeOfPlugins(snippetReflection, plugins); @@ -358,14 +354,14 @@ private static void parsePatternAndRegister(String pattern) { } } - private static void registerSystemPlugins(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, InvocationPlugins plugins) { + private static void registerSystemPlugins(SnippetReflectionProvider snippetReflection, InvocationPlugins plugins) { Registration r = new Registration(plugins, System.class); if (SubstrateOptions.FoldSecurityManagerGetter.getValue()) { r.register(new RequiredInvocationPlugin("getSecurityManager") { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { /* System.getSecurityManager() always returns null. */ - b.addPush(JavaKind.Object, ConstantNode.forConstant(snippetReflection.forObject(null), metaAccess, b.getGraph())); + b.addPush(JavaKind.Object, ConstantNode.forConstant(snippetReflection.forObject(null), b.getMetaAccess(), b.getGraph())); return true; } }); @@ -393,13 +389,13 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec }); } - private static void registerImageInfoPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerImageInfoPlugins(InvocationPlugins plugins) { Registration proxyRegistration = new Registration(plugins, ImageInfo.class); proxyRegistration.register(new RequiredInvocationPlugin("inImageCode") { /** See {@link ImageInfo#inImageCode()}. */ @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - b.push(JavaKind.Boolean, ConstantNode.forConstant(JavaConstant.TRUE, metaAccess, b.getGraph())); + b.push(JavaKind.Boolean, ConstantNode.forConstant(JavaConstant.TRUE, b.getMetaAccess(), b.getGraph())); return true; } }); @@ -407,7 +403,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec /** See {@link ImageInfo#inImageBuildtimeCode()}. */ @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - b.push(JavaKind.Boolean, ConstantNode.forConstant(JavaConstant.FALSE, metaAccess, b.getGraph())); + b.push(JavaKind.Boolean, ConstantNode.forConstant(JavaConstant.FALSE, b.getMetaAccess(), b.getGraph())); return true; } }); @@ -415,18 +411,16 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec /** See {@link ImageInfo#inImageRuntimeCode()}. */ @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - b.push(JavaKind.Boolean, ConstantNode.forConstant(JavaConstant.TRUE, metaAccess, b.getGraph())); + b.push(JavaKind.Boolean, ConstantNode.forConstant(JavaConstant.TRUE, b.getMetaAccess(), b.getGraph())); return true; } }); } private static void registerProxyPlugins(SnippetReflectionProvider snippetReflection, AnnotationSubstitutionProcessor annotationSubstitutions, InvocationPlugins plugins, ParsingReason reason) { - if (SubstrateOptions.parseOnce() || reason.duringAnalysis()) { - Registration proxyRegistration = new Registration(plugins, Proxy.class); - registerProxyPlugin(proxyRegistration, snippetReflection, annotationSubstitutions, reason, "getProxyClass", ClassLoader.class, Class[].class); - registerProxyPlugin(proxyRegistration, snippetReflection, annotationSubstitutions, reason, "newProxyInstance", ClassLoader.class, Class[].class, InvocationHandler.class); - } + Registration proxyRegistration = new Registration(plugins, Proxy.class); + registerProxyPlugin(proxyRegistration, snippetReflection, annotationSubstitutions, reason, "getProxyClass", ClassLoader.class, Class[].class); + registerProxyPlugin(proxyRegistration, snippetReflection, annotationSubstitutions, reason, "newProxyInstance", ClassLoader.class, Class[].class, InvocationHandler.class); } private static void registerProxyPlugin(Registration proxyRegistration, SnippetReflectionProvider snippetReflection, AnnotationSubstitutionProcessor annotationSubstitutions, ParsingReason reason, @@ -672,12 +666,12 @@ private static FixedNode unwrapNode(FixedNode node) { } } - private static void registerAtomicUpdaterPlugins(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, InvocationPlugins plugins, ParsingReason reason) { + private static void registerAtomicUpdaterPlugins(SnippetReflectionProvider snippetReflection, InvocationPlugins plugins) { Registration referenceUpdaterRegistration = new Registration(plugins, AtomicReferenceFieldUpdater.class); referenceUpdaterRegistration.register(new RequiredInvocationPlugin("newUpdater", Class.class, Class.class, String.class) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode tclassNode, ValueNode vclassNode, ValueNode fieldNameNode) { - interceptUpdaterInvoke(b, metaAccess, snippetReflection, reason, tclassNode, fieldNameNode); + interceptUpdaterInvoke(b, snippetReflection, tclassNode, fieldNameNode); /* Always return false; the call is not replaced. */ return false; } @@ -687,7 +681,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec integerUpdaterRegistration.register(new RequiredInvocationPlugin("newUpdater", Class.class, String.class) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode tclassNode, ValueNode fieldNameNode) { - interceptUpdaterInvoke(b, metaAccess, snippetReflection, reason, tclassNode, fieldNameNode); + interceptUpdaterInvoke(b, snippetReflection, tclassNode, fieldNameNode); /* Always return false; the call is not replaced. */ return false; } @@ -697,7 +691,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec longUpdaterRegistration.register(new RequiredInvocationPlugin("newUpdater", Class.class, String.class) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode tclassNode, ValueNode fieldNameNode) { - interceptUpdaterInvoke(b, metaAccess, snippetReflection, reason, tclassNode, fieldNameNode); + interceptUpdaterInvoke(b, snippetReflection, tclassNode, fieldNameNode); /* Always return false; the call is not replaced. */ return false; } @@ -708,35 +702,32 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec * Intercept the invoke to newUpdater. If the holder class and field name are constant register * them for reflection/unsafe access. */ - private static void interceptUpdaterInvoke(GraphBuilderContext b, MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, ParsingReason reason, ValueNode tclassNode, - ValueNode fieldNameNode) { - if (SubstrateOptions.parseOnce() || reason.duringAnalysis()) { - if (tclassNode.isConstant() && fieldNameNode.isConstant()) { - Class tclass = snippetReflection.asObject(Class.class, tclassNode.asJavaConstant()); - String fieldName = snippetReflection.asObject(String.class, fieldNameNode.asJavaConstant()); - try { - Field field = tclass.getDeclaredField(fieldName); - // register the holder class and the field for reflection - RuntimeReflection.register(tclass); - RuntimeReflection.register(field); - - // register the field for unsafe access - registerAsUnsafeAccessed(b, metaAccess, field); - } catch (NoSuchFieldException e) { - /* - * Ignore the exception. : If the field does not exist, there will be an error - * at run time. That is then the same behavior as on HotSpot. The allocation of - * the AtomicReferenceFieldUpdater could be in a never-executed path, in which - * case, if we threw the exception during image building, we would wrongly - * prohibit image generation. - */ - } + private static void interceptUpdaterInvoke(GraphBuilderContext b, SnippetReflectionProvider snippetReflection, ValueNode tclassNode, ValueNode fieldNameNode) { + if (tclassNode.isConstant() && fieldNameNode.isConstant()) { + Class tclass = snippetReflection.asObject(Class.class, tclassNode.asJavaConstant()); + String fieldName = snippetReflection.asObject(String.class, fieldNameNode.asJavaConstant()); + try { + Field field = tclass.getDeclaredField(fieldName); + // register the holder class and the field for reflection + RuntimeReflection.register(tclass); + RuntimeReflection.register(field); + + // register the field for unsafe access + registerAsUnsafeAccessed(b, field); + } catch (NoSuchFieldException e) { + /* + * Ignore the exception. If the field does not exist, there will be an error at run + * time. That is then the same behavior as on HotSpot. The allocation of the + * AtomicReferenceFieldUpdater could be in a never-executed path, in which case, if + * we threw the exception during image building, we would wrongly prohibit image + * generation. + */ } } } - private static void registerAsUnsafeAccessed(GraphBuilderContext b, MetaAccessProvider metaAccess, Field field) { - AnalysisField targetField = (AnalysisField) metaAccess.lookupJavaField(field); + private static void registerAsUnsafeAccessed(GraphBuilderContext b, Field field) { + AnalysisField targetField = (AnalysisField) b.getMetaAccess().lookupJavaField(field); Object reason = nonNullReason(b.getGraph().currentNodeSourcePosition()); targetField.registerAsAccessed(reason); targetField.registerAsUnsafeAccessed(reason); @@ -763,10 +754,10 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec }); } - private static void registerUnsafePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins, SnippetReflectionProvider snippetReflection, ParsingReason reason) { - registerUnsafePlugins(metaAccess, new Registration(plugins, "sun.misc.Unsafe"), snippetReflection, reason, true); + private static void registerUnsafePlugins(InvocationPlugins plugins, SnippetReflectionProvider snippetReflection, ParsingReason reason) { + registerUnsafePlugins(new Registration(plugins, "sun.misc.Unsafe"), snippetReflection, reason, true); Registration r = new Registration(plugins, "jdk.internal.misc.Unsafe"); - registerUnsafePlugins(metaAccess, r, snippetReflection, reason, false); + registerUnsafePlugins(r, snippetReflection, reason, false); r.register(new RequiredInvocationPlugin("objectFieldOffset", Receiver.class, Class.class, String.class) { @Override @@ -780,7 +771,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec String fieldName = snippetReflection.asObject(String.class, nameNode.asJavaConstant()); try { Field targetField = clazz.getDeclaredField(fieldName); - return processFieldOffset(b, targetField, reason, metaAccess, false); + return processFieldOffset(b, targetField, reason, false); } catch (NoSuchFieldException | LinkageError e) { return false; } @@ -796,7 +787,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec r.register(new AllocateUninitializedArrayPlugin("allocateUninitializedArray", true)); } - private static void registerUnsafePlugins(MetaAccessProvider metaAccess, Registration r, SnippetReflectionProvider snippetReflection, ParsingReason reason, boolean isSunMiscUnsafe) { + private static void registerUnsafePlugins(Registration r, SnippetReflectionProvider snippetReflection, ParsingReason reason, boolean isSunMiscUnsafe) { r.register(new RequiredInvocationPlugin("staticFieldOffset", Receiver.class, Field.class) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode fieldNode) { @@ -805,7 +796,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec receiver.get(); Field targetField = snippetReflection.asObject(Field.class, fieldNode.asJavaConstant()); - return processFieldOffset(b, targetField, reason, metaAccess, isSunMiscUnsafe); + return processFieldOffset(b, targetField, reason, isSunMiscUnsafe); } return false; } @@ -832,7 +823,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec receiver.get(); Field targetField = snippetReflection.asObject(Field.class, fieldNode.asJavaConstant()); - return processFieldOffset(b, targetField, reason, metaAccess, isSunMiscUnsafe); + return processFieldOffset(b, targetField, reason, isSunMiscUnsafe); } return false; } @@ -877,27 +868,13 @@ public JavaConstant apply(CoreProviders providers) { } } - private static boolean processFieldOffset(GraphBuilderContext b, Field targetField, ParsingReason reason, MetaAccessProvider metaAccess, boolean isSunMiscUnsafe) { + private static boolean processFieldOffset(GraphBuilderContext b, Field targetField, ParsingReason reason, boolean isSunMiscUnsafe) { if (!isValidField(targetField, isSunMiscUnsafe) || reason == ParsingReason.JITCompilation) { return false; } - if (SubstrateOptions.parseOnce() || reason == ParsingReason.PointsToAnalysis) { - /* Register the field for unsafe access. */ - registerAsUnsafeAccessed(b, metaAccess, targetField); - - } else { - HostedMetaAccess hostedMetaAccess = (HostedMetaAccess) metaAccess; - HostedField hostedField = hostedMetaAccess.lookupJavaField(targetField); - if (!hostedField.wrapped.isUnsafeAccessed()) { - /* - * The target field was not constant folded during static analysis, so the above - * unsafe access registration did not run. A UnsupportedFeatureError will be thrown - * at run time for this call. - */ - return false; - } - } + /* Register the field for unsafe access. */ + registerAsUnsafeAccessed(b, targetField); b.addPush(JavaKind.Long, LazyConstantNode.create(StampFactory.forKind(JavaKind.Long), new FieldOffsetConstantProvider(targetField), b)); return true; @@ -932,23 +909,21 @@ private static void registerArrayPlugins(InvocationPlugins plugins, SnippetRefle r.register(new RequiredInvocationPlugin("newInstance", Class.class, int[].class) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazzNode, ValueNode dimensionsNode) { - if (SubstrateOptions.parseOnce() || reason.duringAnalysis()) { - /* - * There is no Graal node for dynamic multi array allocation, and it is also not - * necessary for performance reasons. But when the arguments are constant, we - * can register the array types as instantiated so that the allocation succeeds - * at run time without manual registration. - */ - ValueNode dimensionCountNode = GraphUtil.arrayLength(dimensionsNode, ArrayLengthProvider.FindLengthMode.SEARCH_ONLY, b.getConstantReflection()); - if (clazzNode.isConstant() && !clazzNode.isNullConstant() && dimensionCountNode != null && dimensionCountNode.isConstant()) { - Class clazz = snippetReflection.asObject(Class.class, clazzNode.asJavaConstant()); - int dimensionCount = dimensionCountNode.asJavaConstant().asInt(); - - AnalysisType type = (AnalysisType) b.getMetaAccess().lookupJavaType(clazz); - for (int i = 0; i < dimensionCount; i++) { - type = type.getArrayClass(); - type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(clazzNode)); - } + /* + * There is no Graal node for dynamic multi array allocation, and it is also not + * necessary for performance reasons. But when the arguments are constant, we can + * register the array types as instantiated so that the allocation succeeds at run + * time without manual registration. + */ + ValueNode dimensionCountNode = GraphUtil.arrayLength(dimensionsNode, ArrayLengthProvider.FindLengthMode.SEARCH_ONLY, b.getConstantReflection()); + if (clazzNode.isConstant() && !clazzNode.isNullConstant() && dimensionCountNode != null && dimensionCountNode.isConstant()) { + Class clazz = snippetReflection.asObject(Class.class, clazzNode.asJavaConstant()); + int dimensionCount = dimensionCountNode.asJavaConstant().asInt(); + + AnalysisType type = (AnalysisType) b.getMetaAccess().lookupJavaType(clazz); + for (int i = 0; i < dimensionCount; i++) { + type = type.getArrayClass(); + type.registerAsAllocated(AbstractAnalysisEngine.sourcePosition(clazzNode)); } } return false; @@ -1028,19 +1003,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec r.register(new RequiredInvocationPlugin("isDeoptimizationTarget") { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - - ResolvedJavaMethod method = b.getGraph().method(); - if (SubstrateOptions.parseOnce()) { - b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(MultiMethod.isDeoptTarget(method))); - } else { - if (method instanceof SharedMethod) { - b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(MultiMethod.isDeoptTarget(method))); - } else { - // In analysis the value is always true. - b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true)); - } - } - + b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(MultiMethod.isDeoptTarget(b.getGraph().method()))); return true; } }); @@ -1177,13 +1140,13 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec }); } - private static void registerEdgesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerEdgesPlugins(InvocationPlugins plugins) { Registration r = new Registration(plugins, Edges.class).setAllowOverwrite(true); for (Class c : new Class[]{Node.class, NodeList.class}) { r.register(new RequiredInvocationPlugin("get" + ClassUtil.getUnqualifiedName(c) + "Unsafe", Node.class, long.class) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode node, ValueNode offset) { - b.addPush(JavaKind.Object, new UnsafePartitionLoadNode(node, offset, JavaKind.Object, LocationIdentity.any(), GraalEdgeUnsafePartition.get(), metaAccess.lookupJavaType(c))); + b.addPush(JavaKind.Object, new UnsafePartitionLoadNode(node, offset, JavaKind.Object, LocationIdentity.any(), GraalEdgeUnsafePartition.get(), b.getMetaAccess().lookupJavaType(c))); return true; } }); @@ -1191,7 +1154,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec r.register(new RequiredInvocationPlugin("put" + ClassUtil.getUnqualifiedName(c) + "Unsafe", Node.class, long.class, c) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode node, ValueNode offset, ValueNode value) { - b.add(new UnsafePartitionStoreNode(node, offset, value, JavaKind.Object, LocationIdentity.any(), GraalEdgeUnsafePartition.get(), metaAccess.lookupJavaType(c))); + b.add(new UnsafePartitionStoreNode(node, offset, value, JavaKind.Object, LocationIdentity.any(), GraalEdgeUnsafePartition.get(), b.getMetaAccess().lookupJavaType(c))); return true; } }); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java index b577937e70ba..8970ee6efc23 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java @@ -123,15 +123,6 @@ public AnnotationSubstitutionProcessor(ImageClassLoader imageClassLoader, MetaAc public void registerFieldValueTransformer(Field reflectionField, FieldValueTransformer transformer) { ResolvedJavaField field = metaAccess.lookupJavaField(reflectionField); - if (!SubstrateOptions.parseOnce() && !classInitializationSupport.maybeInitializeAtBuildTime(reflectionField.getDeclaringClass())) { - String parseOnce = SubstrateOptions.ParseOnce.getName(); - String reason = "It was detected that " + parseOnce + " is disabled. " + - "Registering a field value transformer for a field whose declaring class is marked for run time initialization is not supported in this configuration. " + - "(This can happen for example when trying to include a Truffle Language implementation in a Spring Boot application. " + - "Since the Truffle framework doesn't currently support " + parseOnce + " it automatically disables this feature. " + - "For more information see https://github.com/oracle/graal/issues/4473.)"; - throw UserError.abort("Cannot register a field value transformer for field %s: %s", field, reason); - } boolean isFinal = field.isFinal(); ComputedValueField computedValueField = new ComputedValueField(field, field, Kind.Custom, reflectionField.getType(), transformer, null, null, isFinal, false); ResolvedJavaField existingSubstitution = fieldSubstitutions.put(field, computedValueField); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/DeletedMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/DeletedMethod.java index 947e7b4a30d8..3f079b169e83 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/DeletedMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/DeletedMethod.java @@ -27,14 +27,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.java.FrameStateBuilder; -import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; -import jdk.graal.compiler.nodes.ConstantNode; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.UnwindNode; -import jdk.graal.compiler.nodes.ValueNode; - import com.oracle.graal.pointsto.meta.HostedProviders; import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.option.SubstrateOptionsParser; @@ -45,6 +37,13 @@ import com.oracle.svm.hosted.phases.HostedGraphKit; import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.java.FrameStateBuilder; +import jdk.graal.compiler.nodes.CallTargetNode.InvokeKind; +import jdk.graal.compiler.nodes.ConstantNode; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.UnwindNode; +import jdk.graal.compiler.nodes.ValueNode; import jdk.vm.ci.meta.ResolvedJavaMethod; public class DeletedMethod extends CustomSubstitutionMethod { @@ -84,7 +83,7 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, } public static StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, String message, Purpose purpose) { - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); StructuredGraph graph = kit.getGraph(); FrameStateBuilder state = new FrameStateBuilder(null, method, graph); state.initializeForMethodStart(null, true, providers.getGraphBuilderPlugins()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java index 1f943dfb8114..0a433748e3eb 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java @@ -33,16 +33,7 @@ import java.lang.reflect.Type; import java.util.List; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.nodes.CallTargetNode; -import jdk.graal.compiler.nodes.InvokeWithExceptionNode; -import jdk.graal.compiler.nodes.StateSplit; -import jdk.graal.compiler.nodes.StructuredGraph; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.java.NewArrayNode; - import com.oracle.graal.pointsto.infrastructure.GraphProvider; -import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.HostedProviders; import com.oracle.svm.core.invoke.MethodHandleUtils; @@ -51,6 +42,13 @@ import com.oracle.svm.hosted.annotation.AnnotationWrapper; import com.oracle.svm.hosted.phases.HostedGraphKit; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.nodes.CallTargetNode; +import jdk.graal.compiler.nodes.InvokeWithExceptionNode; +import jdk.graal.compiler.nodes.StateSplit; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.java.NewArrayNode; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.ExceptionHandler; @@ -85,8 +83,8 @@ public class PolymorphicSignatureWrapperMethod implements ResolvedJavaMethod, Gr @Override public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) { - UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess(); - HostedGraphKit kit = new HostedGraphKit(debug, providers, method, purpose); + AnalysisMetaAccess metaAccess = (AnalysisMetaAccess) providers.getMetaAccess(); + HostedGraphKit kit = new HostedGraphKit(debug, providers, method); List args = kit.loadArguments(method.toParameterTypes()); ValueNode receiver = null; @@ -105,13 +103,7 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, storeIndexedNode.setStateAfter(kit.getFrameState().create(kit.bci(), storeIndexedNode)); } - ResolvedJavaMethod invokeTarget; - if (metaAccess instanceof AnalysisMetaAccess) { - invokeTarget = metaAccess.getUniverse().lookup(substitutionBaseMethod.getOriginal()); - } else { - invokeTarget = metaAccess.getUniverse().lookup(((AnalysisMetaAccess) metaAccess.getWrapped()).getUniverse().lookup(substitutionBaseMethod.getOriginal())); - } - + ResolvedJavaMethod invokeTarget = metaAccess.getUniverse().lookup(substitutionBaseMethod.getOriginal()); InvokeWithExceptionNode invoke; if (substitutionBaseMethod.isStatic()) { invoke = kit.createInvokeWithExceptionAndUnwind(invokeTarget, CallTargetNode.InvokeKind.Static, kit.getFrameState(), kit.bci(), parameterArray); diff --git a/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaFeature.java b/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaFeature.java index 0ca9f145fe32..450d4c4de5ce 100644 --- a/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaFeature.java +++ b/substratevm/src/com.oracle.svm.polyglot/src/com/oracle/svm/polyglot/scala/ScalaFeature.java @@ -29,19 +29,19 @@ import java.util.Arrays; import java.util.function.BooleanSupplier; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; -import jdk.graal.compiler.phases.util.Providers; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; import org.graalvm.nativeimage.hosted.RuntimeReflection; import com.oracle.svm.core.ParsingReason; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.util.UserError; import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; import com.oracle.svm.util.ModuleSupport; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; +import jdk.graal.compiler.phases.util.Providers; + public class ScalaFeature implements InternalFeature { public static final String UNSUPPORTED_SCALA_VERSION = "This is not a supported Scala version. native-image supports Scala 2.11.x and onwards."; @@ -73,9 +73,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { @Override public void registerGraphBuilderPlugins(Providers providers, Plugins plugins, ParsingReason reason) { ModuleSupport.accessPackagesToClass(ModuleSupport.Access.EXPORT, ScalaFeature.class, false, "jdk.internal.vm.ci", "jdk.vm.ci.meta"); - if (SubstrateOptions.parseOnce() || reason.duringAnalysis()) { - plugins.appendNodePlugin(new ScalaAnalysisPlugin()); - } + plugins.appendNodePlugin(new ScalaAnalysisPlugin()); } private static boolean isValDef(Field[] fields, Method m) { diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/HostedTruffleConstantFieldProvider.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/HostedTruffleConstantFieldProvider.java index c3ccc7e6c32f..7ec3bb237101 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/HostedTruffleConstantFieldProvider.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/HostedTruffleConstantFieldProvider.java @@ -24,16 +24,14 @@ */ package com.oracle.svm.truffle; -import jdk.graal.compiler.core.common.spi.ConstantFieldProvider; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; -import com.oracle.graal.pointsto.meta.AnalysisField; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; +import jdk.graal.compiler.core.common.spi.ConstantFieldProvider; import jdk.vm.ci.meta.ResolvedJavaField; @Platforms(Platform.HOSTED_ONLY.class) @@ -65,18 +63,6 @@ public HostedTruffleConstantFieldProvider(ConstantFieldProvider wrappedConstantF public T readConstantField(ResolvedJavaField field, ConstantFieldTool tool) { boolean hasTruffleFoldedAnnotation = field.isAnnotationPresent(CompilationFinal.class) || field.isAnnotationPresent(Child.class) || field.isAnnotationPresent(Children.class); if (hasTruffleFoldedAnnotation) { - if ((!SubstrateOptions.parseOnce()) && field instanceof AnalysisField) { - /* - * Without ParseOnce, this field might only be read within runtime graphs (it might - * be folded during static analysis and also in AOT compilation). - * - * Therefore, we explicitly mark the field as read. - * - * When using ParseOnce, this precaution is unnecessary, as runtime graphs are - * properly integrated into analysis. - */ - ((AnalysisField) field).registerAsRead("it is annotated with a Truffle folded annotation (@CompilationFinal, @Children, or @Child)"); - } return null; } diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java index 324217b1eb77..e305d2233e41 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java @@ -28,9 +28,6 @@ import static com.oracle.svm.graal.hosted.RuntimeCompilationFeature.AllowInliningPredicate.InlineDecision.INLINE; import static com.oracle.svm.graal.hosted.RuntimeCompilationFeature.AllowInliningPredicate.InlineDecision.INLINING_DISALLOWED; import static com.oracle.svm.graal.hosted.RuntimeCompilationFeature.AllowInliningPredicate.InlineDecision.NO_DECISION; -import static jdk.graal.compiler.java.BytecodeParserOptions.InlineDuringParsingMaxDepth; -import static jdk.graal.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; -import static jdk.graal.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createStandardInlineInfo; import java.lang.reflect.Executable; import java.lang.reflect.Field; @@ -104,27 +101,6 @@ import java.util.function.UnaryOperator; import org.graalvm.collections.Pair; -import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; -import jdk.graal.compiler.core.phases.HighTier; -import jdk.graal.compiler.graph.Node; -import jdk.graal.compiler.nodes.FrameState; -import jdk.graal.compiler.nodes.ValueNode; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; -import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; -import jdk.graal.compiler.nodes.graphbuilderconf.InlineInvokePlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin; -import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; -import jdk.graal.compiler.nodes.spi.Replacements; -import jdk.graal.compiler.options.Option; -import jdk.graal.compiler.options.OptionValues; -import jdk.graal.compiler.phases.common.CanonicalizerPhase; -import jdk.graal.compiler.phases.tiers.Suites; -import jdk.graal.compiler.phases.util.Providers; -import jdk.graal.compiler.truffle.KnownTruffleTypes; -import jdk.graal.compiler.truffle.PartialEvaluator; -import jdk.graal.compiler.truffle.host.HostInliningPhase; -import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; -import jdk.graal.compiler.truffle.nodes.asserts.NeverPartOfCompilationNode; import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; @@ -132,7 +108,6 @@ import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.HostedProviders; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; @@ -157,7 +132,6 @@ import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; -import com.oracle.svm.hosted.SVMHost; import com.oracle.svm.hosted.meta.HostedType; import com.oracle.svm.truffle.api.SubstrateThreadLocalHandshake; import com.oracle.svm.truffle.api.SubstrateThreadLocalHandshakeSnippets; @@ -176,6 +150,26 @@ import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.runtime.TruffleCallBoundary; +import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; +import jdk.graal.compiler.core.phases.HighTier; +import jdk.graal.compiler.graph.Node; +import jdk.graal.compiler.nodes.FrameState; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; +import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins; +import jdk.graal.compiler.nodes.spi.Replacements; +import jdk.graal.compiler.options.Option; +import jdk.graal.compiler.options.OptionValues; +import jdk.graal.compiler.phases.common.CanonicalizerPhase; +import jdk.graal.compiler.phases.tiers.Suites; +import jdk.graal.compiler.phases.util.Providers; +import jdk.graal.compiler.truffle.KnownTruffleTypes; +import jdk.graal.compiler.truffle.PartialEvaluator; +import jdk.graal.compiler.truffle.host.HostInliningPhase; +import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; +import jdk.graal.compiler.truffle.nodes.asserts.NeverPartOfCompilationNode; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -213,8 +207,8 @@ public static class Options { @Option(help = "Fail if a method known as not suitable for partial evaluation is reachable for runtime compilation")// public static final HostedOptionKey TruffleCheckBlockListMethods = new HostedOptionKey<>(true); - @Option(help = "Inline trivial methods in Truffle graphs during native image generation")// - public static final HostedOptionKey TruffleInlineDuringParsing = new HostedOptionKey<>(true); + @Option(help = "No longer has any effect", deprecated = true)// + static final HostedOptionKey TruffleInlineDuringParsing = new HostedOptionKey<>(true); } @@ -371,9 +365,6 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { TruffleAllowInliningPredicate allowInliningPredicate = new TruffleAllowInliningPredicate(runtimeCompilationFeature.getHostedProviders().getReplacements(), graphBuilderConfig.getPlugins().getInvocationPlugins(), partialEvaluator, this::allowRuntimeCompilation); - if (Options.TruffleInlineDuringParsing.getValue() && !SubstrateOptions.parseOnce()) { - graphBuilderConfig.getPlugins().appendInlineInvokePlugin(new TruffleParsingInlineInvokePlugin(config.getHostVM(), allowInliningPredicate)); - } runtimeCompilationFeature.registerAllowInliningPredicate(allowInliningPredicate::allowInlining); registerNeverPartOfCompilation(graphBuilderConfig.getPlugins().getInvocationPlugins()); @@ -504,39 +495,6 @@ public RuntimeCompilationFeature.AllowInliningPredicate.InlineDecision allowInli } } - static class TruffleParsingInlineInvokePlugin implements InlineInvokePlugin { - - private final SVMHost hostVM; - TruffleAllowInliningPredicate inlineCriteria; - - TruffleParsingInlineInvokePlugin(SVMHost hostVM, TruffleAllowInliningPredicate inlineCriteria) { - this.hostVM = hostVM; - this.inlineCriteria = inlineCriteria; - } - - @Override - public InlineInfo shouldInlineInvoke(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments) { - assert !SubstrateOptions.parseOnce() : "inlining during parsing is not enabled with parse once"; - - var result = inlineCriteria.allowInlining(builder, original); - switch (result) { - case NO_DECISION -> { - return null; - } - case INLINING_DISALLOWED -> { - return DO_NOT_INLINE_WITH_EXCEPTION; - } - } - assert result == INLINE; - if (hostVM.isAnalysisTrivialMethod((AnalysisMethod) original) && - builder.getDepth() < InlineDuringParsingMaxDepth.getValue(HostedOptionValues.singleton())) { - return createStandardInlineInfo(original); - } - - return null; - } - } - private static void registerKnownTruffleFields(BeforeAnalysisAccessImpl config, KnownTruffleTypes knownTruffleFields) { for (Class klass = knownTruffleFields.getClass(); klass != Object.class; klass = klass.getSuperclass()) { for (Field field : klass.getDeclaredFields()) {