Skip to content

Commit 9d48cc1

Browse files
authored
Merge pull request #206 from bulasevich/GR-66289
[Backport] [Oracle GraalVM] [GR-66289] Backport to 23.1: TruffleLogger.getLevelNum() causes deopt loops.
2 parents 8372a49 + 780d6d4 commit 9d48cc1

File tree

5 files changed

+99
-12
lines changed

5 files changed

+99
-12
lines changed

compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ private StructuredGraph test(String methodName, EconomicMap<ResolvedJavaMethod,
231231
graphBuilderConfig = editGraphBuilderConfiguration(graphBuilderConfig);
232232
registerPlugins(graphBuilderConfig.getPlugins().getInvocationPlugins());
233233
targetGraph = new StructuredGraph.Builder(debug.getOptions(), debug, AllowAssumptions.YES).method(testMethod).build();
234-
CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE,
234+
CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE,
235235
null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null, null, null, graphCache, () -> null, false, false, true);
236236

237237
decoder.decode(testMethod);

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public class CachingPEGraphDecoder extends PEGraphDecoder {
6868

6969
private static final TimerKey BuildGraphTimer = DebugContext.timer("PartialEvaluation-GraphBuilding");
7070

71-
protected final Providers providers;
71+
protected final Providers graphCacheProviders;
7272
protected final GraphBuilderConfiguration graphBuilderConfig;
7373
protected final OptimisticOptimizations optimisticOpts;
7474
private final EconomicMap<ResolvedJavaMethod, EncodedGraph> persistentGraphCache;
@@ -84,21 +84,22 @@ public class CachingPEGraphDecoder extends PEGraphDecoder {
8484
* @param forceLink if {@code true} and the graph contains an invoke of a method from a class
8585
* that has not yet been linked, linking is performed.
8686
*/
87-
public CachingPEGraphDecoder(Architecture architecture, StructuredGraph graph, Providers providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
87+
public CachingPEGraphDecoder(Architecture architecture, StructuredGraph graph, Providers graphCacheProviders, Providers decodingProviders, GraphBuilderConfiguration graphBuilderConfig,
88+
OptimisticOptimizations optimisticOpts,
8889
LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins,
8990
ParameterPlugin parameterPlugin,
9091
NodePlugin[] nodePlugins, ResolvedJavaMethod peRootForInlining, SourceLanguagePositionProvider sourceLanguagePositionProvider,
9192
BasePhase<? super CoreProviders> postParsingPhase, EconomicMap<ResolvedJavaMethod, EncodedGraph> persistentGraphCache, Supplier<AutoCloseable> createPersistentCachedGraphScope,
9293
boolean allowAssumptionsDuringParsing,
9394
boolean needsExplicitException,
9495
boolean forceLink) {
95-
super(architecture, graph, providers, loopExplosionPlugin,
96+
super(architecture, graph, decodingProviders, loopExplosionPlugin,
9697
invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins, peRootForInlining, sourceLanguagePositionProvider,
9798
new ConcurrentHashMap<>(), new ConcurrentHashMap<>(), needsExplicitException, forceLink);
9899

99100
assert !graphBuilderConfig.trackNodeSourcePosition() || graph.trackNodeSourcePosition();
100101

101-
this.providers = providers;
102+
this.graphCacheProviders = graphCacheProviders;
102103
this.graphBuilderConfig = graphBuilderConfig;
103104
this.optimisticOpts = optimisticOpts;
104105
this.postParsingPhase = postParsingPhase;
@@ -128,9 +129,9 @@ private EncodedGraph createGraph(ResolvedJavaMethod method, BytecodeProvider int
128129
* initial graph.
129130
*/
130131
try (DebugContext.Scope scope = debug.scope("createGraph", graphToEncode)) {
131-
new ConvertDeoptimizeToGuardPhase(canonicalizer).apply(graphToEncode, providers);
132+
new ConvertDeoptimizeToGuardPhase(canonicalizer).apply(graphToEncode, graphCacheProviders);
132133
if (GraalOptions.EarlyGVN.getValue(graphToEncode.getOptions())) {
133-
new DominatorBasedGlobalValueNumberingPhase(canonicalizer).apply(graphToEncode, providers);
134+
new DominatorBasedGlobalValueNumberingPhase(canonicalizer).apply(graphToEncode, graphCacheProviders);
134135
}
135136
} catch (Throwable t) {
136137
throw debug.handle(t);
@@ -164,9 +165,9 @@ private StructuredGraph buildGraph(ResolvedJavaMethod method, BytecodeProvider i
164165
IntrinsicContext initialIntrinsicContext = null;
165166
GraphBuilderPhase.Instance graphBuilderPhaseInstance = createGraphBuilderPhaseInstance(initialIntrinsicContext);
166167
graphBuilderPhaseInstance.apply(graphToEncode);
167-
canonicalizer.apply(graphToEncode, providers);
168+
canonicalizer.apply(graphToEncode, graphCacheProviders);
168169
if (postParsingPhase != null) {
169-
postParsingPhase.apply(graphToEncode, providers);
170+
postParsingPhase.apply(graphToEncode, graphCacheProviders);
170171
}
171172
} catch (Throwable ex) {
172173
throw debug.handle(ex);

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/truffle/compiler/PartialEvaluator.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public abstract class PartialEvaluator {
122122
protected boolean persistentEncodedGraphCache;
123123

124124
protected final TruffleConstantFieldProvider constantFieldProvider;
125+
private final TruffleCachingConstantFieldProvider graphCacheConstantFieldProvider;
125126

126127
@SuppressWarnings("this-escape")
127128
public PartialEvaluator(TruffleCompilerConfiguration config, GraphBuilderConfiguration configForRoot) {
@@ -132,6 +133,7 @@ public PartialEvaluator(TruffleCompilerConfiguration config, GraphBuilderConfigu
132133
this.lastTierDecodingPlugins = createDecodingInvocationPlugins(config.lastTier().partialEvaluator(), configForRoot.getPlugins(), config.lastTier().providers());
133134
this.nodePlugins = createNodePlugins(configForRoot.getPlugins());
134135
this.constantFieldProvider = new TruffleConstantFieldProvider(this, getProviders().getConstantFieldProvider());
136+
this.graphCacheConstantFieldProvider = new TruffleCachingConstantFieldProvider(this, getProviders().getConstantFieldProvider());
135137
}
136138

137139
protected void initialize(OptionValues options) {
@@ -406,11 +408,11 @@ protected PEGraphDecoder createGraphDecoder(TruffleTierContext context, Invocati
406408
DeoptimizeOnExceptionPhase postParsingPhase = new DeoptimizeOnExceptionPhase(
407409
method -> getMethodInfo(method).inlineForPartialEvaluation() == InlineKind.DO_NOT_INLINE_WITH_SPECULATIVE_EXCEPTION);
408410

409-
Providers baseProviders = config.lastTier().providers();
410-
Providers compilationUnitProviders = config.lastTier().providers().copyWith(constantFieldProvider);
411+
Providers graphCacheProviders = config.lastTier().providers().copyWith(graphCacheConstantFieldProvider);
412+
Providers decoderProviders = config.lastTier().providers().copyWith(constantFieldProvider);
411413

412414
assert !allowAssumptionsDuringParsing || !persistentEncodedGraphCache;
413-
return new CachingPEGraphDecoder(config.architecture(), context.graph, compilationUnitProviders, newConfig, TruffleCompilerImpl.Optimizations,
415+
return new CachingPEGraphDecoder(config.architecture(), context.graph, graphCacheProviders, decoderProviders, newConfig, TruffleCompilerImpl.Optimizations,
414416
loopExplosionPlugin, decodingPlugins, inlineInvokePlugins, parameterPlugin, nodePluginList, types.OptimizedCallTarget_callInlined,
415417
sourceLanguagePositionProvider, postParsingPhase, graphCache, createCachedGraphScope, allowAssumptionsDuringParsing, false, true);
416418
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.compiler.truffle.compiler;
26+
27+
import com.oracle.truffle.compiler.ConstantFieldInfo;
28+
29+
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
30+
import org.graalvm.compiler.replacements.CachingPEGraphDecoder;
31+
import jdk.vm.ci.meta.ResolvedJavaField;
32+
33+
/**
34+
* Constant field provider used for parsing into the graph cache on HotSpot in
35+
* {@link CachingPEGraphDecoder}.
36+
*/
37+
final class TruffleCachingConstantFieldProvider implements ConstantFieldProvider {
38+
39+
private final PartialEvaluator partialEvaluator;
40+
private final ConstantFieldProvider delegate;
41+
42+
TruffleCachingConstantFieldProvider(PartialEvaluator partialEvaluator, ConstantFieldProvider delegate) {
43+
this.partialEvaluator = partialEvaluator;
44+
this.delegate = delegate;
45+
}
46+
47+
@Override
48+
public <T> T readConstantField(ResolvedJavaField field, ConstantFieldTool<T> tool) {
49+
boolean isStaticField = field.isStatic();
50+
if (!isStaticField && tool.getReceiver().isNull()) {
51+
return null;
52+
}
53+
ConstantFieldInfo info = partialEvaluator.getConstantFieldInfo(field);
54+
if (info != null) {
55+
/*
56+
* Non-null info means the field is annotated by one of the
57+
* annotations @CompilationFinal, @Child or @Children. We are not folding such fields
58+
* for the code cache on HotSpot. Not even static final fields. We delay this to the
59+
* partial evaluation phase to ensure we are not losing the annotation information and
60+
* are not reading values that are not yet stable when creating the graph for the cache.
61+
* For example, a static final array annotated by '@CompilationFinal(dimensions = 1)':
62+
* We cannot fold the array with 'stableDimension=1', because for the cache, the first
63+
* dimension is not stable. We cannot fold it with 'stableDimension=0' either, because
64+
* we would lose the information about the first dimension being stable for the partial
65+
* evaluation phase.
66+
**/
67+
return null;
68+
} else {
69+
// otherwise do regular constant folding.
70+
return delegate.readConstantField(field, tool);
71+
}
72+
}
73+
74+
@Override
75+
public boolean maybeFinal(ResolvedJavaField field) {
76+
return delegate.maybeFinal(field);
77+
}
78+
79+
}

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/truffle/compiler/TruffleConstantFieldProvider.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
import jdk.vm.ci.meta.JavaKind;
3333
import jdk.vm.ci.meta.ResolvedJavaField;
3434

35+
/**
36+
* Constant field provider used for Truffle partial evaluation.
37+
*
38+
* @see TruffleCachingConstantFieldProvider
39+
*/
3540
final class TruffleConstantFieldProvider implements ConstantFieldProvider {
3641

3742
private final PartialEvaluator partialEvaluator;

0 commit comments

Comments
 (0)