From e5c12fcfa41d4cf685f9831f57e3c21e009ec92c Mon Sep 17 00:00:00 2001 From: Codrut Stancu Date: Fri, 30 Aug 2024 16:55:35 +0200 Subject: [PATCH 1/6] Exclude identityHashOffset field from open world policy. --- .../src/com/oracle/svm/hosted/SVMHost.java | 3 +++ 1 file changed, 3 insertions(+) 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 8963a71d0144..9e617c1e1d0d 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 @@ -887,6 +887,9 @@ private void initializeExcludedFields() { excludedFields.add(ReflectionUtil.lookupField(DynamicHub.class, "monitorOffset")); excludedFields.add(ReflectionUtil.lookupField(DynamicHub.class, "hubType")); + /* Needs to be immutable for correct lowering of SubstrateIdentityHashCodeNode. */ + excludedFields.add(ReflectionUtil.lookupField(DynamicHub.class, "identityHashOffset")); + /* * Including this field makes ThreadLocalAllocation.getTlabDescriptorSize reachable through * ThreadLocalAllocation.regularTLAB which is accessed with From c1826e8a26c52cd9a8fa80326e9f6719a599a3bb Mon Sep 17 00:00:00 2001 From: Codrut Stancu Date: Fri, 30 Aug 2024 16:58:38 +0200 Subject: [PATCH 2/6] Exclude methods compiled in prior layer who are missing a graph from the trivial inliner. --- .../src/com/oracle/svm/hosted/code/CompileQueue.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 52adf8b68dae..61a1b85d2334 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 @@ -757,7 +757,17 @@ class InliningGraphDecoder extends PEGraphDecoder { @Override protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, BytecodeProvider intrinsicBytecodeProvider) { - return ((HostedMethod) method).compilationInfo.getCompilationGraph().getEncodedGraph(); + HostedMethod hostedMethod = (HostedMethod) method; + CompilationGraph compilationGraph = hostedMethod.compilationInfo.getCompilationGraph(); + if (compilationGraph == null) { + /* + * We have compiled this method in a prior layer, but don't have the graph available + * here. + */ + assert hostedMethod.isCompiledInPriorLayer() : method; + return null; + } + return compilationGraph.getEncodedGraph(); } @Override From 26767925cb9ee2567ee525ea8099e4b4034d67dc Mon Sep 17 00:00:00 2001 From: Codrut Stancu Date: Fri, 30 Aug 2024 16:59:22 +0200 Subject: [PATCH 3/6] Make OpenTypeWorldFeature less verbose. --- .../src/com/oracle/svm/hosted/OpenTypeWorldFeature.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java index 654d23130c67..d295d59178f0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java @@ -48,7 +48,6 @@ import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.meta.BaseLayerType; import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.hub.DynamicHub; @@ -318,7 +317,7 @@ public Set loadDispatchTableMethods(AnalysisType type) { } private static boolean logErrorMessages() { - return SubstrateUtil.assertionsEnabled() || Options.LogOpenTypeWorldDiscrepancies.getValue(); + return Options.LogOpenTypeWorldDiscrepancies.getValue(); } private static boolean generateErrorMessage() { From 3ce3684583a13b555bdf3b4326659a8fd7f6e4a5 Mon Sep 17 00:00:00 2001 From: Tom Shull Date: Mon, 2 Sep 2024 18:54:41 +0200 Subject: [PATCH 4/6] Ensure we have a valid endPointer while initializing image layers --- .../svm/core/posix/linux/LinuxImageHeapProvider.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxImageHeapProvider.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxImageHeapProvider.java index f8daf0193386..04295def9d88 100644 --- a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxImageHeapProvider.java +++ b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxImageHeapProvider.java @@ -163,6 +163,14 @@ protected int initializeLayeredImage(Pointer firstHeapStart, Pointer selfReserve int layerCount = 0; Pointer currentSection = ImageLayerSection.getInitialLayerSection().get(); Pointer currentHeapStart = firstHeapStart; + WordPointer curEndPointer = endPointer; + if (endPointer.isNull()) { + /* + * When endPointer is null, we still need to track it locally to compute the next heap + * starting location. + */ + curEndPointer = StackValue.get(WordPointer.class); + } while (currentSection.isNonNull()) { var cachedFDPointer = ImageLayerSection.getCachedImageFDs().get().addressOf(layerCount); var cachedOffsetsPointer = ImageLayerSection.getCachedImageHeapOffsets().get().addressOf(layerCount); @@ -174,7 +182,7 @@ protected int initializeLayeredImage(Pointer firstHeapStart, Pointer selfReserve Word heapWritableBegin = currentSection.readWord(ImageLayerSection.getEntryOffset(HEAP_WRITEABLE_BEGIN)); Word heapWritableEnd = currentSection.readWord(ImageLayerSection.getEntryOffset(HEAP_WRITEABLE_END)); - result = initializeImageHeap(currentHeapStart, remainingSize, endPointer, + result = initializeImageHeap(currentHeapStart, remainingSize, curEndPointer, cachedFDPointer, cachedOffsetsPointer, MAGIC.get(), heapBegin, heapEnd, heapRelocBegin, heapAnyRelocPointer, heapRelocEnd, @@ -183,7 +191,7 @@ protected int initializeLayeredImage(Pointer firstHeapStart, Pointer selfReserve freeImageHeap(selfReservedHeapBase); return result; } - Pointer newHeapStart = endPointer.read(); // aligned + Pointer newHeapStart = curEndPointer.read(); // aligned remainingSize = remainingSize.subtract(newHeapStart.subtract(currentHeapStart)); currentHeapStart = newHeapStart; From 4285c1c300d4031c9d4e5b20f36199abada146c3 Mon Sep 17 00:00:00 2001 From: Tom Shull Date: Mon, 2 Sep 2024 18:58:58 +0200 Subject: [PATCH 5/6] Create SubstrateMethodCallTarget within compiled graphs --- .../phases/InlineBeforeAnalysisGraphDecoder.java | 6 +++++- .../svm/core/nodes/SubstrateMethodCallTargetNode.java | 6 +++++- .../phases/InlineBeforeAnalysisGraphDecoderImpl.java | 9 +++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/phases/InlineBeforeAnalysisGraphDecoder.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/phases/InlineBeforeAnalysisGraphDecoder.java index e1fb9ca1b7b7..36307756c0c0 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/phases/InlineBeforeAnalysisGraphDecoder.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/phases/InlineBeforeAnalysisGraphDecoder.java @@ -269,6 +269,10 @@ protected LoopScope processNextNode(MethodScope ms, LoopScope loopScope) { return super.processNextNode(methodScope, loopScope); } + protected MethodCallTargetNode createCallTargetNode(ResolvedMethodHandleCallTargetNode t) { + return new MethodCallTargetNode(t.invokeKind(), t.targetMethod(), t.arguments().toArray(ValueNode.EMPTY_ARRAY), t.returnStamp(), t.getTypeProfile()); + } + @Override protected LoopScope handleMethodHandle(MethodScope s, LoopScope loopScope, InvokableData invokableData) { MethodHandleWithExceptionNode node = invokableData.invoke; @@ -287,7 +291,7 @@ protected LoopScope handleMethodHandle(MethodScope s, LoopScope loopScope, Invok if (invoke.callTarget() instanceof ResolvedMethodHandleCallTargetNode t) { // This special CallTargetNode lowers itself back to the original target (e.g. linkTo*) // if the invocation hasn't been inlined, which we don't want for Native Image. - callTarget = new MethodCallTargetNode(t.invokeKind(), t.targetMethod(), t.arguments().toArray(ValueNode.EMPTY_ARRAY), t.returnStamp(), t.getTypeProfile()); + callTarget = createCallTargetNode(t); } else { callTarget = (CallTargetNode) invoke.callTarget().copyWithInputs(false); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/nodes/SubstrateMethodCallTargetNode.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/nodes/SubstrateMethodCallTargetNode.java index b3f2db848548..cda372db451f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/nodes/SubstrateMethodCallTargetNode.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/nodes/SubstrateMethodCallTargetNode.java @@ -46,7 +46,11 @@ public final class SubstrateMethodCallTargetNode extends MethodCallTargetNode { private JavaTypeProfile staticTypeProfile; public SubstrateMethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, StampPair returnStamp) { - super(TYPE, invokeKind, targetMethod, arguments, returnStamp, null); + this(invokeKind, targetMethod, arguments, returnStamp, null); + } + + public SubstrateMethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, StampPair returnStamp, JavaTypeProfile typeProfile) { + super(TYPE, invokeKind, targetMethod, arguments, returnStamp, typeProfile); } public void setProfiles(JavaTypeProfile typeProfile, JavaMethodProfile methodProfile) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/InlineBeforeAnalysisGraphDecoderImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/InlineBeforeAnalysisGraphDecoderImpl.java index be4a6399b242..659f00c8f078 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/InlineBeforeAnalysisGraphDecoderImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/InlineBeforeAnalysisGraphDecoderImpl.java @@ -31,6 +31,7 @@ import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder; import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisPolicy; import com.oracle.svm.core.classinitialization.EnsureClassInitializedNode; +import com.oracle.svm.core.nodes.SubstrateMethodCallTargetNode; import com.oracle.svm.hosted.ameta.FieldValueInterceptionSupport; import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; import com.oracle.svm.hosted.classinitialization.SimulateClassInitializerSupport; @@ -39,7 +40,10 @@ import jdk.graal.compiler.graph.Node; import jdk.graal.compiler.nodes.ConstantNode; import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; import jdk.graal.compiler.nodes.java.LoadFieldNode; +import jdk.graal.compiler.nodes.java.MethodCallTargetNode; +import jdk.graal.compiler.replacements.nodes.ResolvedMethodHandleCallTargetNode; public class InlineBeforeAnalysisGraphDecoderImpl extends InlineBeforeAnalysisGraphDecoder { @@ -110,4 +114,9 @@ private Node handleIsStaticFinalFieldInitializedNode(IsStaticFinalFieldInitializ } return node; } + + @Override + protected MethodCallTargetNode createCallTargetNode(ResolvedMethodHandleCallTargetNode t) { + return new SubstrateMethodCallTargetNode(t.invokeKind(), t.targetMethod(), t.arguments().toArray(ValueNode.EMPTY_ARRAY), t.returnStamp(), t.getTypeProfile()); + } } From 8bdf7b9e94cb800ed9a83932c971e6ee10d6ef68 Mon Sep 17 00:00:00 2001 From: Tom Shull Date: Mon, 2 Sep 2024 19:19:26 +0200 Subject: [PATCH 6/6] Ensure trivial inlining is not triggered for methods where the graph is unavailable --- .../oracle/svm/hosted/code/CompileQueue.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) 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 61a1b85d2334..a1322a197ae6 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 @@ -757,17 +757,7 @@ class InliningGraphDecoder extends PEGraphDecoder { @Override protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, BytecodeProvider intrinsicBytecodeProvider) { - HostedMethod hostedMethod = (HostedMethod) method; - CompilationGraph compilationGraph = hostedMethod.compilationInfo.getCompilationGraph(); - if (compilationGraph == null) { - /* - * We have compiled this method in a prior layer, but don't have the graph available - * here. - */ - assert hostedMethod.isCompiledInPriorLayer() : method; - return null; - } - return compilationGraph.getEncodedGraph(); + return ((HostedMethod) method).compilationInfo.getCompilationGraph().getEncodedGraph(); } @Override @@ -855,6 +845,16 @@ private void doInlineTrivial(DebugContext debug, HostedMethod method) { } private boolean makeInlineDecision(HostedMethod method, HostedMethod callee) { + // GR-57832 this will be removed + if (callee.compilationInfo.getCompilationGraph() == null) { + /* + * We have compiled this method in a prior layer, but don't have the graph available + * here. + */ + assert callee.isCompiledInPriorLayer() : method; + return false; + } + if (universe.hostVM().neverInlineTrivial(method.getWrapped(), callee.getWrapped())) { return false; }