From acb54b269ec139972050b5d93a8beb6d0260ed37 Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Fri, 28 Mar 2025 13:36:48 +0100 Subject: [PATCH 1/6] VM crashes when using -Djdk.graal.PrintCompilation=true for runtime compilation. --- .../graal/isolated/IsolatedCodeInstallBridge.java | 12 +++++++++++- .../svm/graal/meta/SubstrateInstalledCodeImpl.java | 2 +- .../SubstrateOptimizedCallTargetInstalledCode.java | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java index 5bea3b0063b1..285ae64407d8 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java @@ -30,6 +30,7 @@ import com.oracle.truffle.compiler.TruffleCompilable; import jdk.vm.ci.code.InstalledCode; +import org.graalvm.nativeimage.c.function.CEntryPoint; /** * A helper to pass information for installing code in the compilation client through a Truffle @@ -68,7 +69,12 @@ public String getName() { @Override public long getStart() { - throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON); + ClientHandle handle = installedCodeHandle; + if (handle.notEqual(IsolatedHandles.nullHandle())) { + return getStart0(IsolatedCompileContext.get().getClient(), handle); + } else { + return 0L; + } } @Override @@ -101,4 +107,8 @@ public TruffleCompilable getCompilable() { throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON); } + @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) + private static long getStart0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle installedCodeHandle) { + return IsolatedCompileClient.get().unhand(installedCodeHandle).getAddress(); + } } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java index 1531fb92a064..b677620ce9e0 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java @@ -121,7 +121,7 @@ public void setCompilationId(CompilationIdentifier id) { @Override public long getStart() { - throw shouldNotReachHere("No implementation in Substrate VM"); + return getAddress(); } @Override diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java index f07b3b92341a..e94afd351531 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java @@ -252,7 +252,7 @@ boolean isValidLastTier() { @Override public long getStart() { - throw VMError.shouldNotReachHere(NOT_CALLED_IN_SUBSTRATE_VM); + return getAddress(); } @Override From 56793cc5ddbcdde96ae57b2d26fb9b53e779a940 Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Mon, 31 Mar 2025 10:25:24 +0200 Subject: [PATCH 2/6] Implemented InstalledCode#getCode for SubstrateVM. --- .../isolated/IsolatedCodeInstallBridge.java | 50 ++++++++++++++++++- .../meta/SubstrateInstalledCodeImpl.java | 30 ++++++++++- ...trateOptimizedCallTargetInstalledCode.java | 27 +++++++++- 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java index 285ae64407d8..aaecc6a82b23 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java @@ -24,13 +24,22 @@ */ package com.oracle.svm.graal.isolated; +import com.oracle.svm.core.Uninterruptible; +import com.oracle.svm.core.code.CodeInfo; +import com.oracle.svm.core.code.CodeInfoAccess; +import com.oracle.svm.core.code.CodeInfoTable; +import com.oracle.svm.core.code.UntetheredCodeInfo; import com.oracle.svm.core.deopt.SubstrateInstalledCode; import com.oracle.svm.core.util.VMError; import com.oracle.truffle.compiler.OptimizedAssumptionDependency; import com.oracle.truffle.compiler.TruffleCompilable; +import jdk.graal.compiler.word.Word; import jdk.vm.ci.code.InstalledCode; import org.graalvm.nativeimage.c.function.CEntryPoint; +import org.graalvm.nativeimage.c.function.CodePointer; +import org.graalvm.nativeimage.c.type.CTypeConversion; +import org.graalvm.word.WordFactory; /** * A helper to pass information for installing code in the compilation client through a Truffle @@ -89,7 +98,13 @@ public boolean isAlive() { @Override public byte[] getCode() { - throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON); + ClientHandle handle = installedCodeHandle; + if (handle.notEqual(IsolatedHandles.nullHandle())) { + CompilerHandle codeHandle = getCode0(IsolatedCompileContext.get().getClient(), handle); + return codeHandle == IsolatedHandles.nullHandle() ? null : IsolatedCompileContext.get().unhand(codeHandle); + } else { + return null; + } } @Override @@ -111,4 +126,37 @@ public TruffleCompilable getCompilable() { private static long getStart0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle installedCodeHandle) { return IsolatedCompileClient.get().unhand(installedCodeHandle).getAddress(); } + + @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) + private static CompilerHandle getCode0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle installedCodeHandle) { + SubstrateInstalledCode installedCode = IsolatedCompileClient.get().unhand(installedCodeHandle); + CodeInfo codeInfo = lookupCodeInfo(installedCode); + if (codeInfo.isNull()) { + return IsolatedHandles.nullHandle(); + } + CodePointer codeStart = CodeInfoAccess.getCodeStart(codeInfo); + int codeSize = (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue(); + return copyCode0(IsolatedCompileClient.get().getCompiler(), codeStart, codeSize); + } + + @Uninterruptible(reason = "Looks up code info.") + private static CodeInfo lookupCodeInfo(SubstrateInstalledCode installedCode) { + UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(Word.pointer(installedCode.getEntryPoint())); + if (untetheredCodeInfo.isNull()) { + return WordFactory.nullPointer(); + } + Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo); + try { + return CodeInfoAccess.convert(untetheredCodeInfo, tether); + } finally { + CodeInfoAccess.releaseTether(untetheredCodeInfo, tether); + } + } + + @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) + private static CompilerHandle copyCode0(@SuppressWarnings("unused") @CEntryPoint.IsolateThreadContext CompilerIsolateThread context, CodePointer codeStart, int codeSize) { + byte[] code = new byte[codeSize]; + CTypeConversion.asByteBuffer(codeStart, codeSize).get(code); + return IsolatedCompileContext.get().hand(code); + } } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java index b677620ce9e0..45a38b25b693 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java @@ -26,6 +26,8 @@ import static com.oracle.svm.core.util.VMError.shouldNotReachHere; +import com.oracle.svm.core.code.CodeInfoAccess; +import com.oracle.svm.core.code.UntetheredCodeInfo; import jdk.graal.compiler.core.common.CompilationIdentifier; import com.oracle.svm.core.Uninterruptible; @@ -37,8 +39,12 @@ import com.oracle.svm.core.thread.VMOperation; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.word.Word; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.ResolvedJavaMethod; +import org.graalvm.nativeimage.c.function.CodePointer; +import org.graalvm.nativeimage.c.type.CTypeConversion; +import org.graalvm.word.WordFactory; /** * Represents the installed code of a runtime compiled method. Note that Truffle uses its own @@ -126,7 +132,29 @@ public long getStart() { @Override public byte[] getCode() { - throw shouldNotReachHere("No implementation in Substrate VM"); + CodeInfo codeInfo = lookupCodeInfo(); + if (codeInfo.isNull()) { + return null; + } + CodePointer codeStart = CodeInfoAccess.getCodeStart(codeInfo); + int codeSize = (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue(); + byte[] code = new byte[codeSize]; + CTypeConversion.asByteBuffer(codeStart, codeSize).get(code); + return code; + } + + @Uninterruptible(reason = "Looks up code info.") + private CodeInfo lookupCodeInfo() { + UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(Word.pointer(entryPoint)); + if (untetheredCodeInfo.isNull()) { + return WordFactory.nullPointer(); + } + Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo); + try { + return CodeInfoAccess.convert(untetheredCodeInfo, tether); + } finally { + CodeInfoAccess.releaseTether(untetheredCodeInfo, tether); + } } @Override diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java index e94afd351531..1af2a47075d4 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java @@ -46,6 +46,9 @@ import jdk.graal.compiler.truffle.TruffleCompilerImpl; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.ResolvedJavaMethod; +import org.graalvm.nativeimage.c.function.CodePointer; +import org.graalvm.nativeimage.c.type.CTypeConversion; +import org.graalvm.word.WordFactory; /** * Represents the compiled code of a {@link SubstrateOptimizedCallTarget}. @@ -257,7 +260,29 @@ public long getStart() { @Override public byte[] getCode() { - throw VMError.shouldNotReachHere(NOT_CALLED_IN_SUBSTRATE_VM); + CodeInfo codeInfo = lookupCodeInfo(); + if (codeInfo.isNull()) { + return null; + } + CodePointer codeStart = CodeInfoAccess.getCodeStart(codeInfo); + int codeSize = (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue(); + byte[] code = new byte[codeSize]; + CTypeConversion.asByteBuffer(codeStart, codeSize).get(code); + return code; + } + + @Uninterruptible(reason = "Looks up code info.") + private CodeInfo lookupCodeInfo() { + UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(Word.pointer(entryPoint)); + if (untetheredCodeInfo.isNull()) { + return WordFactory.nullPointer(); + } + Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo); + try { + return CodeInfoAccess.convert(untetheredCodeInfo, tether); + } finally { + CodeInfoAccess.releaseTether(untetheredCodeInfo, tether); + } } @Override From 8934d539cd3b9ef0b7989fbf46dac5db34775a4b Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Wed, 9 Apr 2025 13:58:38 +0200 Subject: [PATCH 3/6] Added test for jdk.graal.PrintCompilation. --- substratevm/mx.substratevm/mx_substratevm.py | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index 636fe20fabfc..c677db57d28b 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -395,6 +395,27 @@ def truffle_unittest_task(extra_build_args=None): # GR-44492 native_unittest(['jdk.graal.compiler.truffle.test.ContextLookupCompilationTest'] + truffle_args(extra_build_args + svm_experimental_options(['-H:-SupportCompileInIsolates']))) + logfile = tempfile.NamedTemporaryFile(mode='w', delete=False) + logfile.close() + success = False + try: + native_unittest(['com.oracle.truffle.sl.test.SLFactorialTest'] + truffle_args(extra_build_args) +[ + '-Dpolyglot.engine.CompileImmediately=true', + '-Dpolyglot.engine.BackgroundCompilation=false', + f'-Dpolyglot.log.file={logfile.name}', + '-Djdk.graal.PrintCompilation=true' + ]) + compilation_pattern = re.compile(r"^SubstrateCompilation-.*root_eval.*allocated start=0x([0-9a-f]*)$") + with open(logfile.name) as f: + for line in f: + match = compilation_pattern.match(line) + if match and int(match.group(1), 16) != 0: + success = True + break + finally: + if success: + os.unlink(logfile.name) + def truffle_context_pre_init_unittest_task(extra_build_args): native_unittest(['com.oracle.truffle.api.test.polyglot.ContextPreInitializationNativeImageTest'] + truffle_args(extra_build_args)) From e7c684ffb6ac53af77a8b64d1a7ab421afcdb99c Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Wed, 9 Apr 2025 21:30:24 +0200 Subject: [PATCH 4/6] Support jdk.graal.Dump=CodeInstall in native-image runtime compilation. --- .../isolated/IsolateAwareCodeCacheProvider.java | 7 ++++++- .../graal/isolated/IsolatedCodeInstallBridge.java | 12 +++++++++++- .../svm/graal/meta/SubstrateCodeCacheProvider.java | 6 ++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java index 4e7d3bace565..51135336db5e 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java @@ -34,6 +34,7 @@ import com.oracle.svm.graal.meta.SubstrateCodeCacheProvider; import com.oracle.svm.graal.meta.SubstrateMethod; +import jdk.graal.compiler.debug.DebugContext; import jdk.vm.ci.code.CompiledCode; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.RegisterConfig; @@ -68,8 +69,12 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile ImageHeapRef methodRef = ImageHeapObjects.ref((SubstrateMethod) method); installedCode = IsolatedRuntimeCodeInstaller.installInClientIsolate(methodRef, result, installedCodeFactoryHandle); } - installBridge.setSubstrateInstalledCodeHandle(installedCode); + DebugContext debug = DebugContext.forCurrentThread(); + if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) { + assert debug.contextLookup(CompilationResult.class) != null : "can't dump installed code properly without CompilationResult"; + debug.dump(DebugContext.BASIC_LEVEL, installBridge, "After code installation"); + } return installBridge; } } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java index aaecc6a82b23..0fda66fdd357 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java @@ -88,7 +88,12 @@ public long getStart() { @Override public boolean isValid() { - throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON); + ClientHandle handle = installedCodeHandle; + if (handle.notEqual(IsolatedHandles.nullHandle())) { + return isValid0(IsolatedCompileContext.get().getClient(), handle); + } else { + return false; + } } @Override @@ -127,6 +132,11 @@ private static long getStart0(@SuppressWarnings("unused") ClientIsolateThread cl return IsolatedCompileClient.get().unhand(installedCodeHandle).getAddress(); } + @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) + private static boolean isValid0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle installedCodeHandle) { + return IsolatedCompileClient.get().unhand(installedCodeHandle).isValid(); + } + @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) private static CompilerHandle getCode0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle installedCodeHandle) { SubstrateInstalledCode installedCode = IsolatedCompileClient.get().unhand(installedCodeHandle); diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java index 3dd818d25f27..0e39b52c8674 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java @@ -33,6 +33,7 @@ import com.oracle.svm.core.graal.meta.SharedRuntimeMethod; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.debug.DebugContext; import jdk.vm.ci.code.CompiledCode; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.RegisterConfig; @@ -60,6 +61,11 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile CompilationResult compResult = ((SubstrateCompiledCode) compiledCode).getCompilationResult(); substrateInstalledCode.setCompilationId(compResult.getCompilationId()); RuntimeCodeInstaller.install((SharedRuntimeMethod) method, compResult, substrateInstalledCode); + DebugContext debug = DebugContext.forCurrentThread(); + if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) { + assert debug.contextLookup(CompilationResult.class) != null : "can't dump installed code properly without CompilationResult"; + debug.dump(DebugContext.BASIC_LEVEL, substrateInstalledCode, "After code installation"); + } return predefinedInstalledCode; } } From a21c01d801a7829d478d0292c9bc573d80d97a39 Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Thu, 10 Apr 2025 10:54:30 +0200 Subject: [PATCH 5/6] Resolved review comments. --- .../hotspot/HotSpotGraalVMEventListener.java | 3 -- substratevm/mx.substratevm/mx_substratevm.py | 2 + .../IsolateAwareCodeCacheProvider.java | 1 - .../isolated/IsolatedCodeInstallBridge.java | 39 +++++++++++------- .../meta/SubstrateCodeCacheProvider.java | 1 - .../meta/SubstrateInstalledCodeImpl.java | 41 ++++++++++++------- ...trateOptimizedCallTargetInstalledCode.java | 36 +++++----------- 7 files changed, 63 insertions(+), 60 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalVMEventListener.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalVMEventListener.java index e5b1ee7f03fc..75aa5268f0e1 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalVMEventListener.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalVMEventListener.java @@ -24,7 +24,6 @@ */ package jdk.graal.compiler.hotspot; -import jdk.graal.compiler.code.CompilationResult; import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.debug.DebugOptions; import jdk.vm.ci.code.CompiledCode; @@ -56,8 +55,6 @@ public void notifyShutdown() { public void notifyInstall(HotSpotCodeCacheProvider codeCache, InstalledCode installedCode, CompiledCode compiledCode) { DebugContext debug = DebugContext.forCurrentThread(); if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) { - CompilationResult compResult = debug.contextLookup(CompilationResult.class); - assert compResult != null : "can't dump installed code properly without CompilationResult"; debug.dump(DebugContext.BASIC_LEVEL, installedCode, "After code installation"); } if (debug.isLogEnabled()) { diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index c677db57d28b..1d86b58566b8 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -412,6 +412,8 @@ def truffle_unittest_task(extra_build_args=None): if match and int(match.group(1), 16) != 0: success = True break + if not success: + mx.abort(f"Failed to find expected PrintCompilation output in log file: {logfile.name}.") finally: if success: os.unlink(logfile.name) diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java index 51135336db5e..2c3322530f6d 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java @@ -72,7 +72,6 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile installBridge.setSubstrateInstalledCodeHandle(installedCode); DebugContext debug = DebugContext.forCurrentThread(); if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) { - assert debug.contextLookup(CompilationResult.class) != null : "can't dump installed code properly without CompilationResult"; debug.dump(DebugContext.BASIC_LEVEL, installBridge, "After code installation"); } return installBridge; diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java index 0fda66fdd357..80bb5e09e886 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java @@ -39,7 +39,6 @@ import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.c.function.CodePointer; import org.graalvm.nativeimage.c.type.CTypeConversion; -import org.graalvm.word.WordFactory; /** * A helper to pass information for installing code in the compilation client through a Truffle @@ -76,6 +75,10 @@ public String getName() { throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON); } + /** + * This method is used by the compiler debugging feature + * {@code jdk.graal.PrintCompilation=true}. + */ @Override public long getStart() { ClientHandle handle = installedCodeHandle; @@ -86,6 +89,10 @@ public long getStart() { } } + /** + * This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to + * dump a code at the point of code installation. + */ @Override public boolean isValid() { ClientHandle handle = installedCodeHandle; @@ -101,6 +108,10 @@ public boolean isAlive() { throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON); } + /** + * This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to + * dump a code at the point of code installation. + */ @Override public byte[] getCode() { ClientHandle handle = installedCodeHandle; @@ -140,31 +151,31 @@ private static boolean isValid0(@SuppressWarnings("unused") ClientIsolateThread @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) private static CompilerHandle getCode0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle installedCodeHandle) { SubstrateInstalledCode installedCode = IsolatedCompileClient.get().unhand(installedCodeHandle); - CodeInfo codeInfo = lookupCodeInfo(installedCode); - if (codeInfo.isNull()) { - return IsolatedHandles.nullHandle(); - } - CodePointer codeStart = CodeInfoAccess.getCodeStart(codeInfo); - int codeSize = (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue(); - return copyCode0(IsolatedCompileClient.get().getCompiler(), codeStart, codeSize); + return getCodeUninterruptible(Word.pointer(installedCode.getEntryPoint())); } - @Uninterruptible(reason = "Looks up code info.") - private static CodeInfo lookupCodeInfo(SubstrateInstalledCode installedCode) { - UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(Word.pointer(installedCode.getEntryPoint())); + @Uninterruptible(reason = "Accesses code info.") + private static CompilerHandle getCodeUninterruptible(CodePointer entryPointAddress) { + UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(entryPointAddress); if (untetheredCodeInfo.isNull()) { - return WordFactory.nullPointer(); + return IsolatedHandles.nullHandle(); } Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo); try { - return CodeInfoAccess.convert(untetheredCodeInfo, tether); + CodeInfo codeInfo = CodeInfoAccess.convert(untetheredCodeInfo, tether); + return copyCode0(codeInfo); } finally { CodeInfoAccess.releaseTether(untetheredCodeInfo, tether); } } + @Uninterruptible(reason = "Wrap the now safe call to code info.", calleeMustBe = false) + private static CompilerHandle copyCode0(CodeInfo codeInfo) { + return copyCodeInCompilerIsolate0(IsolatedCompileClient.get().getCompiler(), CodeInfoAccess.getCodeStart(codeInfo), (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue()); + } + @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) - private static CompilerHandle copyCode0(@SuppressWarnings("unused") @CEntryPoint.IsolateThreadContext CompilerIsolateThread context, CodePointer codeStart, int codeSize) { + private static CompilerHandle copyCodeInCompilerIsolate0(@SuppressWarnings("unused") @CEntryPoint.IsolateThreadContext CompilerIsolateThread context, CodePointer codeStart, int codeSize) { byte[] code = new byte[codeSize]; CTypeConversion.asByteBuffer(codeStart, codeSize).get(code); return IsolatedCompileContext.get().hand(code); diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java index 0e39b52c8674..a29e8da48cd0 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java @@ -63,7 +63,6 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile RuntimeCodeInstaller.install((SharedRuntimeMethod) method, compResult, substrateInstalledCode); DebugContext debug = DebugContext.forCurrentThread(); if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) { - assert debug.contextLookup(CompilationResult.class) != null : "can't dump installed code properly without CompilationResult"; debug.dump(DebugContext.BASIC_LEVEL, substrateInstalledCode, "After code installation"); } return predefinedInstalledCode; diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java index 45a38b25b693..116e8e9ae8f5 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java @@ -44,7 +44,6 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import org.graalvm.nativeimage.c.function.CodePointer; import org.graalvm.nativeimage.c.type.CTypeConversion; -import org.graalvm.word.WordFactory; /** * Represents the installed code of a runtime compiled method. Note that Truffle uses its own @@ -125,38 +124,50 @@ public SubstrateSpeculationLog getSpeculationLog() { public void setCompilationId(CompilationIdentifier id) { } + /** + * This method is used by the compiler debugging feature + * {@code jdk.graal.PrintCompilation=true}. + */ @Override public long getStart() { return getAddress(); } + /** + * This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to + * dump a code at the point of code installation. + */ @Override public byte[] getCode() { - CodeInfo codeInfo = lookupCodeInfo(); - if (codeInfo.isNull()) { - return null; - } - CodePointer codeStart = CodeInfoAccess.getCodeStart(codeInfo); - int codeSize = (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue(); - byte[] code = new byte[codeSize]; - CTypeConversion.asByteBuffer(codeStart, codeSize).get(code); - return code; + return getCode(Word.pointer(entryPoint)); } - @Uninterruptible(reason = "Looks up code info.") - private CodeInfo lookupCodeInfo() { - UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(Word.pointer(entryPoint)); + @Uninterruptible(reason = "Accesses code info.") + public static byte[] getCode(CodePointer entryPointAddress) { + UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(entryPointAddress); if (untetheredCodeInfo.isNull()) { - return WordFactory.nullPointer(); + return null; } Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo); try { - return CodeInfoAccess.convert(untetheredCodeInfo, tether); + CodeInfo codeInfo = CodeInfoAccess.convert(untetheredCodeInfo, tether); + return copyCode0(codeInfo); } finally { CodeInfoAccess.releaseTether(untetheredCodeInfo, tether); } } + @Uninterruptible(reason = "Wrap the now safe call to code info.", calleeMustBe = false) + private static byte[] copyCode0(CodeInfo codeInfo) { + return copyCode(CodeInfoAccess.getCodeStart(codeInfo), (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue()); + } + + private static byte[] copyCode(CodePointer codeStart, int codeSize) { + byte[] code = new byte[codeSize]; + CTypeConversion.asByteBuffer(codeStart, codeSize).get(code); + return code; + } + @Override public Object executeVarargs(Object... args) { throw shouldNotReachHere("No implementation in Substrate VM"); diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java index 1af2a47075d4..917cf84885bd 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java @@ -26,6 +26,7 @@ import java.lang.ref.WeakReference; +import com.oracle.svm.graal.meta.SubstrateInstalledCodeImpl; import jdk.graal.compiler.word.Word; import com.oracle.svm.core.Uninterruptible; @@ -46,9 +47,6 @@ import jdk.graal.compiler.truffle.TruffleCompilerImpl; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.ResolvedJavaMethod; -import org.graalvm.nativeimage.c.function.CodePointer; -import org.graalvm.nativeimage.c.type.CTypeConversion; -import org.graalvm.word.WordFactory; /** * Represents the compiled code of a {@link SubstrateOptimizedCallTarget}. @@ -253,36 +251,22 @@ boolean isValidLastTier() { private static final String NOT_CALLED_IN_SUBSTRATE_VM = "No implementation in Substrate VM"; + /** + * This method is used by the compiler debugging feature + * {@code jdk.graal.PrintCompilation=true}. + */ @Override public long getStart() { return getAddress(); } + /** + * This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to + * dump a code at the point of code installation. + */ @Override public byte[] getCode() { - CodeInfo codeInfo = lookupCodeInfo(); - if (codeInfo.isNull()) { - return null; - } - CodePointer codeStart = CodeInfoAccess.getCodeStart(codeInfo); - int codeSize = (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue(); - byte[] code = new byte[codeSize]; - CTypeConversion.asByteBuffer(codeStart, codeSize).get(code); - return code; - } - - @Uninterruptible(reason = "Looks up code info.") - private CodeInfo lookupCodeInfo() { - UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(Word.pointer(entryPoint)); - if (untetheredCodeInfo.isNull()) { - return WordFactory.nullPointer(); - } - Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo); - try { - return CodeInfoAccess.convert(untetheredCodeInfo, tether); - } finally { - CodeInfoAccess.releaseTether(untetheredCodeInfo, tether); - } + return SubstrateInstalledCodeImpl.getCode(Word.pointer(entryPoint)); } @Override From ba44fb5d7cbfdb3b182392ebfe6d8adec0fd706d Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Wed, 16 Apr 2025 15:19:27 +0200 Subject: [PATCH 6/6] Fixed VerifyDebugUsage test. --- .../src/jdk/graal/compiler/core/test/VerifyDebugUsage.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyDebugUsage.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyDebugUsage.java index 340d1da1f6e4..64b7b52a4747 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyDebugUsage.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyDebugUsage.java @@ -203,7 +203,9 @@ protected int verifyDumpLevelParameter(MethodCallTargetNode debugCallTarget, Res protected void verifyDumpObjectParameter(MethodCallTargetNode debugCallTarget, ValueNode arg, ResolvedJavaMethod verifiedCallee, Integer dumpLevel) throws VerifyPhase.VerificationError { ResolvedJavaType argType = ((ObjectStamp) arg.stamp(NodeView.DEFAULT)).type(); - if (metaAccess.lookupJavaType(Graph.class).isAssignableFrom(argType)) { + // GR-64309: Calls returning interface type are built with an unrestricted stamp. ArgType is + // null for SubstrateInstalledCode. + if (argType != null && metaAccess.lookupJavaType(Graph.class).isAssignableFrom(argType)) { verifyStructuredGraphDumping(debugCallTarget, verifiedCallee, dumpLevel); } }