Skip to content

Commit 3ff585b

Browse files
committed
[GR-68990] [GR-69008] Fix graph equality when replaying libgraal compilation on jargraal and fix cache replacements
PullRequest: graal/21937
2 parents f4a4dcf + f1b321e commit 3ff585b

File tree

5 files changed

+60
-6
lines changed

5 files changed

+60
-6
lines changed

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/replaycomp/test/ReplayCompilationTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
import org.graalvm.collections.EconomicMap;
4040
import org.graalvm.collections.EconomicSet;
41+
import org.junit.AfterClass;
42+
import org.junit.BeforeClass;
4143
import org.junit.Test;
4244

4345
import com.oracle.truffle.api.Truffle;
@@ -46,6 +48,7 @@
4648
import jdk.graal.compiler.core.CompilationWrapper;
4749
import jdk.graal.compiler.core.GraalCompilerOptions;
4850
import jdk.graal.compiler.core.test.GraalCompilerTest;
51+
import jdk.graal.compiler.debug.DebugCloseable;
4952
import jdk.graal.compiler.debug.DebugOptions;
5053
import jdk.graal.compiler.debug.GlobalMetrics;
5154
import jdk.graal.compiler.debug.LogStream;
@@ -54,9 +57,11 @@
5457
import jdk.graal.compiler.hotspot.CompilerConfigurationFactory;
5558
import jdk.graal.compiler.hotspot.HotSpotGraalCompiler;
5659
import jdk.graal.compiler.hotspot.HotSpotGraalCompilerFactory;
60+
import jdk.graal.compiler.hotspot.HotSpotReplacementsImpl;
5761
import jdk.graal.compiler.hotspot.replaycomp.CompilerInterfaceDeclarations;
5862
import jdk.graal.compiler.hotspot.replaycomp.ReplayCompilationRunner;
5963
import jdk.graal.compiler.options.OptionValues;
64+
import jdk.graal.compiler.phases.util.Providers;
6065
import jdk.graal.compiler.runtime.RuntimeProvider;
6166
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
6267
import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult;
@@ -69,6 +74,25 @@
6974
* Tests for compilation recording and replay.
7075
*/
7176
public class ReplayCompilationTest extends GraalCompilerTest {
77+
/**
78+
* A separate encoded snippet scope is necessary in case the global encoded snippets have cache
79+
* replacements.
80+
*/
81+
private static DebugCloseable snippetScope;
82+
83+
@BeforeClass
84+
public static void setup() {
85+
Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders();
86+
HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements();
87+
snippetScope = replacements.suppressEncodedSnippets();
88+
replacements.encode(getInitialOptions());
89+
}
90+
91+
@AfterClass
92+
public static void teardown() {
93+
snippetScope.close();
94+
}
95+
7296
private static int[] lengthsSquared(List<String> strings) {
7397
return strings.stream().mapToInt(String::length).map(i -> i * i).toArray();
7498
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import jdk.graal.compiler.core.common.type.StampPair;
4848
import jdk.graal.compiler.core.common.type.SymbolicJVMCIReference;
4949
import jdk.graal.compiler.debug.DebugContext;
50+
import jdk.graal.compiler.debug.DebugOptions;
5051
import jdk.graal.compiler.debug.GraalError;
5152
import jdk.graal.compiler.nodeinfo.Verbosity;
5253
import jdk.graal.compiler.nodes.ConstantNode;
@@ -250,12 +251,14 @@ StructuredGraph getEncodedSnippet(ResolvedJavaMethod method, ResolvedJavaMethod
250251
declaringClass = replacements.getProviders().getMetaAccess().lookupJavaType(Object.class);
251252
}
252253
/*
253-
* If this is a recorded/replayed compilation, we must not mutate the snippet objects. This
254-
* ensures we record all relevant operations during recording and no proxies are stored in
255-
* the snippet objects during replay.
254+
* If there is a possibility of a recorded/replayed compilation, we must not mutate the
255+
* snippet objects. During recording, this ensures that we record all relevant operations
256+
* and the cached objects are resolved to proxies. During replay, this ensures that no
257+
* proxies are stored in the snippet objects.
256258
*/
257259
boolean allowCacheReplacements = replacements.getProviders().getReplayCompilationSupport() == null &&
258-
GraalCompilerOptions.CompilationFailureAction.getValue(options) != CompilationWrapper.ExceptionAction.Diagnose;
260+
GraalCompilerOptions.CompilationFailureAction.getValue(options) != CompilationWrapper.ExceptionAction.Diagnose &&
261+
!DebugOptions.RecordForReplay.hasBeenSet(options);
259262
SymbolicEncodedGraph encodedGraph = new SymbolicEncodedGraph(snippetEncoding, startOffset, snippetObjects, allowCacheReplacements,
260263
snippetNodeClasses, data.originalMethod, declaringClass);
261264
return decodeSnippetGraph(encodedGraph, method, original, replacements, args, allowAssumptions, options, true);

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/AssertionSnippets.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void lower(AssertionNode assertionNode, LoweringTool tool) {
9090
Arguments args = new Arguments(graph.start() instanceof StubStartNode ? stubAssertion : assertion, graph, tool.getLoweringStage());
9191
args.add("condition", assertionNode.condition());
9292
args.add("message",
93-
graph.unique(new ConstantNode(new CStringConstant("failed runtime assertion in snippet/stub: " + assertionNode.message() + " (" + graph.method() + ")"),
93+
graph.unique(new ConstantNode(new CStringConstant("failed runtime assertion in snippet/stub: " + assertionNode.message() + " (" + graph.method().format("%H.%n(%p)") + ")"),
9494
StampFactory.pointer())));
9595
args.add("l1", assertionNode.getL1());
9696
args.add("l2", assertionNode.getL2());

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/CompilerInterfaceDeclarations.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import static jdk.graal.compiler.bytecode.Bytecodes.INVOKESPECIAL;
3131
import static jdk.graal.compiler.bytecode.Bytecodes.INVOKESTATIC;
3232
import static jdk.graal.compiler.bytecode.Bytecodes.INVOKEVIRTUAL;
33+
import static jdk.graal.compiler.hotspot.HotSpotReplacementsImpl.isGraalClass;
3334
import static jdk.graal.compiler.java.StableMethodNameFormatter.isMethodHandle;
3435

3536
import java.lang.reflect.Proxy;
@@ -48,6 +49,7 @@
4849
import jdk.graal.compiler.core.common.CompilerProfiler;
4950
import jdk.graal.compiler.debug.DebugContext;
5051
import jdk.graal.compiler.debug.GraalError;
52+
import jdk.graal.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
5153
import jdk.graal.compiler.hotspot.replaycomp.proxy.CompilationProxy;
5254
import jdk.graal.compiler.hotspot.replaycomp.proxy.CompilationProxyBase;
5355
import jdk.graal.compiler.hotspot.replaycomp.proxy.CompilerProfilerProxy;
@@ -66,6 +68,7 @@
6668
import jdk.graal.compiler.hotspot.replaycomp.proxy.SignatureProxy;
6769
import jdk.graal.compiler.hotspot.replaycomp.proxy.SpeculationLogProxy;
6870
import jdk.graal.compiler.java.LambdaUtils;
71+
import jdk.graal.compiler.options.ExcludeFromJacocoGeneratedReport;
6972
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
7073
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
7174
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
@@ -703,6 +706,7 @@ public static CompilerInterfaceDeclarations build() {
703706
}
704707
return List.of();
705708
})
709+
.setFallbackInvocationHandler(HotSpotResolvedObjectTypeProxy.isInstanceMethod, CompilerInterfaceDeclarations::objectTypeIsInstanceFallback)
706710
.register(declarations);
707711
// Must come after HotSpotResolvedObjectType. Needed for HotSpotResolvedPrimitiveType.
708712
new RegistrationBuilder<>(HotSpotResolvedJavaType.class)
@@ -921,4 +925,27 @@ private static ResolvedJavaType javaLangObjectSupplier(Object proxy, Compilation
921925
MetaAccessProvider metaAccess = (MetaAccessProvider) singletonObjects.get(MetaAccessProvider.class);
922926
return metaAccess.lookupJavaType(Object.class);
923927
}
928+
929+
/**
930+
* Implements a fallback for {@link HotSpotResolvedObjectType#isInstance} calls performed by
931+
* {@link HotSpotGraalConstantFieldProvider} when replaying a libgraal compilation on jargraal.
932+
* <p>
933+
* The provider performs checks like {@code getHotSpotVMConfigType().isInstance(receiver)},
934+
* which use snippet types on libgraal and HotSpot types on jargraal. Replay on jargraal needs
935+
* to answer these queries when the receiver and argument are HotSpot proxies.
936+
*/
937+
@SuppressWarnings("unused")
938+
@ExcludeFromJacocoGeneratedReport("related to replay of libgraal compilations on jargraal")
939+
private static boolean objectTypeIsInstanceFallback(Object proxy, CompilationProxy.SymbolicMethod method, Object[] args, EconomicMap<Class<?>, Object> singletonObjects) {
940+
HotSpotResolvedObjectType receiverType = (HotSpotResolvedObjectType) proxy;
941+
if (!(args[0] instanceof HotSpotObjectConstant objectConstant)) {
942+
return false;
943+
}
944+
HotSpotResolvedObjectType constantType = objectConstant.getType();
945+
if (isGraalClass(receiverType) && !isGraalClass(constantType)) {
946+
// Assumes that only a Graal class can subtype a Graal class.
947+
return false;
948+
}
949+
return receiverType.isAssignableFrom(constantType);
950+
}
924951
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/proxy/HotSpotResolvedJavaTypeProxy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public final boolean isAssignableFrom(ResolvedJavaType other) {
241241
return (boolean) handle(isAssignableFromMethod, isAssignableFromInvokable, other);
242242
}
243243

244-
private static final SymbolicMethod isInstanceMethod = method("isInstance", JavaConstant.class);
244+
public static final SymbolicMethod isInstanceMethod = method("isInstance", JavaConstant.class);
245245
private static final InvokableMethod isInstanceInvokable = (receiver, args) -> ((HotSpotResolvedJavaType) receiver).isInstance((JavaConstant) args[0]);
246246

247247
@Override

0 commit comments

Comments
 (0)