Skip to content

Commit cc8e914

Browse files
committed
[GR-63458] VM crashes when using -Djdk.graal.PrintCompilation=true for runtime compilation.
PullRequest: graal/20387
2 parents f696872 + ba44fb5 commit cc8e914

File tree

8 files changed

+170
-12
lines changed

8 files changed

+170
-12
lines changed

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyDebugUsage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ protected int verifyDumpLevelParameter(MethodCallTargetNode debugCallTarget, Res
203203
protected void verifyDumpObjectParameter(MethodCallTargetNode debugCallTarget, ValueNode arg, ResolvedJavaMethod verifiedCallee, Integer dumpLevel)
204204
throws VerifyPhase.VerificationError {
205205
ResolvedJavaType argType = ((ObjectStamp) arg.stamp(NodeView.DEFAULT)).type();
206-
if (metaAccess.lookupJavaType(Graph.class).isAssignableFrom(argType)) {
206+
// GR-64309: Calls returning interface type are built with an unrestricted stamp. ArgType is
207+
// null for SubstrateInstalledCode.
208+
if (argType != null && metaAccess.lookupJavaType(Graph.class).isAssignableFrom(argType)) {
207209
verifyStructuredGraphDumping(debugCallTarget, verifiedCallee, dumpLevel);
208210
}
209211
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalVMEventListener.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package jdk.graal.compiler.hotspot;
2626

27-
import jdk.graal.compiler.code.CompilationResult;
2827
import jdk.graal.compiler.debug.DebugContext;
2928
import jdk.graal.compiler.debug.DebugOptions;
3029
import jdk.vm.ci.code.CompiledCode;
@@ -56,8 +55,6 @@ public void notifyShutdown() {
5655
public void notifyInstall(HotSpotCodeCacheProvider codeCache, InstalledCode installedCode, CompiledCode compiledCode) {
5756
DebugContext debug = DebugContext.forCurrentThread();
5857
if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) {
59-
CompilationResult compResult = debug.contextLookup(CompilationResult.class);
60-
assert compResult != null : "can't dump installed code properly without CompilationResult";
6158
debug.dump(DebugContext.BASIC_LEVEL, installedCode, "After code installation");
6259
}
6360
if (debug.isLogEnabled()) {

substratevm/mx.substratevm/mx_substratevm.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,29 @@ def truffle_unittest_task(extra_build_args=None):
395395
# GR-44492
396396
native_unittest(['jdk.graal.compiler.truffle.test.ContextLookupCompilationTest'] + truffle_args(extra_build_args + svm_experimental_options(['-H:-SupportCompileInIsolates'])))
397397

398+
logfile = tempfile.NamedTemporaryFile(mode='w', delete=False)
399+
logfile.close()
400+
success = False
401+
try:
402+
native_unittest(['com.oracle.truffle.sl.test.SLFactorialTest'] + truffle_args(extra_build_args) +[
403+
'-Dpolyglot.engine.CompileImmediately=true',
404+
'-Dpolyglot.engine.BackgroundCompilation=false',
405+
f'-Dpolyglot.log.file={logfile.name}',
406+
'-Djdk.graal.PrintCompilation=true'
407+
])
408+
compilation_pattern = re.compile(r"^SubstrateCompilation-.*root_eval.*allocated start=0x([0-9a-f]*)$")
409+
with open(logfile.name) as f:
410+
for line in f:
411+
match = compilation_pattern.match(line)
412+
if match and int(match.group(1), 16) != 0:
413+
success = True
414+
break
415+
if not success:
416+
mx.abort(f"Failed to find expected PrintCompilation output in log file: {logfile.name}.")
417+
finally:
418+
if success:
419+
os.unlink(logfile.name)
420+
398421

399422
def truffle_context_pre_init_unittest_task(extra_build_args):
400423
native_unittest(['com.oracle.truffle.api.test.polyglot.ContextPreInitializationNativeImageTest'] + truffle_args(extra_build_args))

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolateAwareCodeCacheProvider.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.oracle.svm.graal.meta.SubstrateCodeCacheProvider;
3535
import com.oracle.svm.graal.meta.SubstrateMethod;
3636

37+
import jdk.graal.compiler.debug.DebugContext;
3738
import jdk.vm.ci.code.CompiledCode;
3839
import jdk.vm.ci.code.InstalledCode;
3940
import jdk.vm.ci.code.RegisterConfig;
@@ -68,8 +69,11 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile
6869
ImageHeapRef<SubstrateMethod> methodRef = ImageHeapObjects.ref((SubstrateMethod) method);
6970
installedCode = IsolatedRuntimeCodeInstaller.installInClientIsolate(methodRef, result, installedCodeFactoryHandle);
7071
}
71-
7272
installBridge.setSubstrateInstalledCodeHandle(installedCode);
73+
DebugContext debug = DebugContext.forCurrentThread();
74+
if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) {
75+
debug.dump(DebugContext.BASIC_LEVEL, installBridge, "After code installation");
76+
}
7377
return installBridge;
7478
}
7579
}

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedCodeInstallBridge.java

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,21 @@
2424
*/
2525
package com.oracle.svm.graal.isolated;
2626

27+
import com.oracle.svm.core.Uninterruptible;
28+
import com.oracle.svm.core.code.CodeInfo;
29+
import com.oracle.svm.core.code.CodeInfoAccess;
30+
import com.oracle.svm.core.code.CodeInfoTable;
31+
import com.oracle.svm.core.code.UntetheredCodeInfo;
2732
import com.oracle.svm.core.deopt.SubstrateInstalledCode;
2833
import com.oracle.svm.core.util.VMError;
2934
import com.oracle.truffle.compiler.OptimizedAssumptionDependency;
3035
import com.oracle.truffle.compiler.TruffleCompilable;
3136

37+
import jdk.graal.compiler.word.Word;
3238
import jdk.vm.ci.code.InstalledCode;
39+
import org.graalvm.nativeimage.c.function.CEntryPoint;
40+
import org.graalvm.nativeimage.c.function.CodePointer;
41+
import org.graalvm.nativeimage.c.type.CTypeConversion;
3342

3443
/**
3544
* A helper to pass information for installing code in the compilation client through a Truffle
@@ -66,24 +75,52 @@ public String getName() {
6675
throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON);
6776
}
6877

78+
/**
79+
* This method is used by the compiler debugging feature
80+
* {@code jdk.graal.PrintCompilation=true}.
81+
*/
6982
@Override
7083
public long getStart() {
71-
throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON);
84+
ClientHandle<? extends SubstrateInstalledCode> handle = installedCodeHandle;
85+
if (handle.notEqual(IsolatedHandles.nullHandle())) {
86+
return getStart0(IsolatedCompileContext.get().getClient(), handle);
87+
} else {
88+
return 0L;
89+
}
7290
}
7391

92+
/**
93+
* This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to
94+
* dump a code at the point of code installation.
95+
*/
7496
@Override
7597
public boolean isValid() {
76-
throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON);
98+
ClientHandle<? extends SubstrateInstalledCode> handle = installedCodeHandle;
99+
if (handle.notEqual(IsolatedHandles.nullHandle())) {
100+
return isValid0(IsolatedCompileContext.get().getClient(), handle);
101+
} else {
102+
return false;
103+
}
77104
}
78105

79106
@Override
80107
public boolean isAlive() {
81108
throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON);
82109
}
83110

111+
/**
112+
* This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to
113+
* dump a code at the point of code installation.
114+
*/
84115
@Override
85116
public byte[] getCode() {
86-
throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON);
117+
ClientHandle<? extends SubstrateInstalledCode> handle = installedCodeHandle;
118+
if (handle.notEqual(IsolatedHandles.nullHandle())) {
119+
CompilerHandle<byte[]> codeHandle = getCode0(IsolatedCompileContext.get().getClient(), handle);
120+
return codeHandle == IsolatedHandles.nullHandle() ? null : IsolatedCompileContext.get().unhand(codeHandle);
121+
} else {
122+
return null;
123+
}
87124
}
88125

89126
@Override
@@ -101,4 +138,46 @@ public TruffleCompilable getCompilable() {
101138
throw VMError.shouldNotReachHere(DO_NOT_CALL_REASON);
102139
}
103140

141+
@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished)
142+
private static long getStart0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle<? extends SubstrateInstalledCode> installedCodeHandle) {
143+
return IsolatedCompileClient.get().unhand(installedCodeHandle).getAddress();
144+
}
145+
146+
@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished)
147+
private static boolean isValid0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle<? extends SubstrateInstalledCode> installedCodeHandle) {
148+
return IsolatedCompileClient.get().unhand(installedCodeHandle).isValid();
149+
}
150+
151+
@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished)
152+
private static CompilerHandle<byte[]> getCode0(@SuppressWarnings("unused") ClientIsolateThread client, ClientHandle<? extends SubstrateInstalledCode> installedCodeHandle) {
153+
SubstrateInstalledCode installedCode = IsolatedCompileClient.get().unhand(installedCodeHandle);
154+
return getCodeUninterruptible(Word.pointer(installedCode.getEntryPoint()));
155+
}
156+
157+
@Uninterruptible(reason = "Accesses code info.")
158+
private static CompilerHandle<byte[]> getCodeUninterruptible(CodePointer entryPointAddress) {
159+
UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(entryPointAddress);
160+
if (untetheredCodeInfo.isNull()) {
161+
return IsolatedHandles.nullHandle();
162+
}
163+
Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo);
164+
try {
165+
CodeInfo codeInfo = CodeInfoAccess.convert(untetheredCodeInfo, tether);
166+
return copyCode0(codeInfo);
167+
} finally {
168+
CodeInfoAccess.releaseTether(untetheredCodeInfo, tether);
169+
}
170+
}
171+
172+
@Uninterruptible(reason = "Wrap the now safe call to code info.", calleeMustBe = false)
173+
private static CompilerHandle<byte[]> copyCode0(CodeInfo codeInfo) {
174+
return copyCodeInCompilerIsolate0(IsolatedCompileClient.get().getCompiler(), CodeInfoAccess.getCodeStart(codeInfo), (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue());
175+
}
176+
177+
@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished)
178+
private static CompilerHandle<byte[]> copyCodeInCompilerIsolate0(@SuppressWarnings("unused") @CEntryPoint.IsolateThreadContext CompilerIsolateThread context, CodePointer codeStart, int codeSize) {
179+
byte[] code = new byte[codeSize];
180+
CTypeConversion.asByteBuffer(codeStart, codeSize).get(code);
181+
return IsolatedCompileContext.get().hand(code);
182+
}
104183
}

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateCodeCacheProvider.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.oracle.svm.core.graal.meta.SharedRuntimeMethod;
3434
import com.oracle.svm.core.util.VMError;
3535

36+
import jdk.graal.compiler.debug.DebugContext;
3637
import jdk.vm.ci.code.CompiledCode;
3738
import jdk.vm.ci.code.InstalledCode;
3839
import jdk.vm.ci.code.RegisterConfig;
@@ -60,6 +61,10 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile
6061
CompilationResult compResult = ((SubstrateCompiledCode) compiledCode).getCompilationResult();
6162
substrateInstalledCode.setCompilationId(compResult.getCompilationId());
6263
RuntimeCodeInstaller.install((SharedRuntimeMethod) method, compResult, substrateInstalledCode);
64+
DebugContext debug = DebugContext.forCurrentThread();
65+
if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) {
66+
debug.dump(DebugContext.BASIC_LEVEL, substrateInstalledCode, "After code installation");
67+
}
6368
return predefinedInstalledCode;
6469
}
6570
}

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateInstalledCodeImpl.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
import static com.oracle.svm.core.util.VMError.shouldNotReachHere;
2828

29+
import com.oracle.svm.core.code.CodeInfoAccess;
30+
import com.oracle.svm.core.code.UntetheredCodeInfo;
2931
import jdk.graal.compiler.core.common.CompilationIdentifier;
3032

3133
import com.oracle.svm.core.Uninterruptible;
@@ -37,8 +39,11 @@
3739
import com.oracle.svm.core.thread.VMOperation;
3840
import com.oracle.svm.core.util.VMError;
3941

42+
import jdk.graal.compiler.word.Word;
4043
import jdk.vm.ci.code.InstalledCode;
4144
import jdk.vm.ci.meta.ResolvedJavaMethod;
45+
import org.graalvm.nativeimage.c.function.CodePointer;
46+
import org.graalvm.nativeimage.c.type.CTypeConversion;
4247

4348
/**
4449
* Represents the installed code of a runtime compiled method. Note that Truffle uses its own
@@ -119,14 +124,48 @@ public SubstrateSpeculationLog getSpeculationLog() {
119124
public void setCompilationId(CompilationIdentifier id) {
120125
}
121126

127+
/**
128+
* This method is used by the compiler debugging feature
129+
* {@code jdk.graal.PrintCompilation=true}.
130+
*/
122131
@Override
123132
public long getStart() {
124-
throw shouldNotReachHere("No implementation in Substrate VM");
133+
return getAddress();
125134
}
126135

136+
/**
137+
* This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to
138+
* dump a code at the point of code installation.
139+
*/
127140
@Override
128141
public byte[] getCode() {
129-
throw shouldNotReachHere("No implementation in Substrate VM");
142+
return getCode(Word.pointer(entryPoint));
143+
}
144+
145+
@Uninterruptible(reason = "Accesses code info.")
146+
public static byte[] getCode(CodePointer entryPointAddress) {
147+
UntetheredCodeInfo untetheredCodeInfo = CodeInfoTable.lookupCodeInfo(entryPointAddress);
148+
if (untetheredCodeInfo.isNull()) {
149+
return null;
150+
}
151+
Object tether = CodeInfoAccess.acquireTether(untetheredCodeInfo);
152+
try {
153+
CodeInfo codeInfo = CodeInfoAccess.convert(untetheredCodeInfo, tether);
154+
return copyCode0(codeInfo);
155+
} finally {
156+
CodeInfoAccess.releaseTether(untetheredCodeInfo, tether);
157+
}
158+
}
159+
160+
@Uninterruptible(reason = "Wrap the now safe call to code info.", calleeMustBe = false)
161+
private static byte[] copyCode0(CodeInfo codeInfo) {
162+
return copyCode(CodeInfoAccess.getCodeStart(codeInfo), (int) CodeInfoAccess.getCodeSize(codeInfo).rawValue());
163+
}
164+
165+
private static byte[] copyCode(CodePointer codeStart, int codeSize) {
166+
byte[] code = new byte[codeSize];
167+
CTypeConversion.asByteBuffer(codeStart, codeSize).get(code);
168+
return code;
130169
}
131170

132171
@Override

substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/api/SubstrateOptimizedCallTargetInstalledCode.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import java.lang.ref.WeakReference;
2828

29+
import com.oracle.svm.graal.meta.SubstrateInstalledCodeImpl;
2930
import jdk.graal.compiler.word.Word;
3031

3132
import com.oracle.svm.core.Uninterruptible;
@@ -250,14 +251,22 @@ boolean isValidLastTier() {
250251

251252
private static final String NOT_CALLED_IN_SUBSTRATE_VM = "No implementation in Substrate VM";
252253

254+
/**
255+
* This method is used by the compiler debugging feature
256+
* {@code jdk.graal.PrintCompilation=true}.
257+
*/
253258
@Override
254259
public long getStart() {
255-
throw VMError.shouldNotReachHere(NOT_CALLED_IN_SUBSTRATE_VM);
260+
return getAddress();
256261
}
257262

263+
/**
264+
* This method is used by the compiler debugging feature {@code jdk.graal.Dump=CodeInstall} to
265+
* dump a code at the point of code installation.
266+
*/
258267
@Override
259268
public byte[] getCode() {
260-
throw VMError.shouldNotReachHere(NOT_CALLED_IN_SUBSTRATE_VM);
269+
return SubstrateInstalledCodeImpl.getCode(Word.pointer(entryPoint));
261270
}
262271

263272
@Override

0 commit comments

Comments
 (0)