Skip to content

Commit 0cbbdab

Browse files
committed
[GR-57160] Refactorings around TypeSnippets and StrengthenGraphs.
PullRequest: graal/19435
2 parents 6120d4e + 682d0ed commit 0cbbdab

File tree

11 files changed

+133
-83
lines changed

11 files changed

+133
-83
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/GraalOptions.java

+8
Original file line numberDiff line numberDiff line change
@@ -336,4 +336,12 @@ public final class GraalOptions {
336336
@Option(help = "Optimize integer division operation by using various mathematical foundations to "
337337
+ " express it in faster, equivalent, arithmetic.", type = OptionType.Debug)
338338
public static final OptionKey<Boolean> OptimizeDiv = new OptionKey<>(true);
339+
340+
@Option(help = "If the probability that a type check will hit one of the profiled types (up to " +
341+
"TypeCheckMaxHints) is below this value, the type check will be compiled without profiling info.", type = OptionType.Debug)
342+
public static final OptionKey<Double> TypeCheckMinProfileHitProbability = new OptionKey<>(0.5);
343+
344+
@Option(help = "The maximum number of profiled types that will be used when compiling a profiled type check. " +
345+
"Note that TypeCheckMinProfileHitProbability also influences whether profiling info is used in compiled type checks.", type = OptionType.Debug)
346+
public static final OptionKey<Integer> TypeCheckMaxHints = new OptionKey<>(2);
339347
}

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

+1-10
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,14 @@
2626

2727
import jdk.graal.compiler.options.EnumOptionKey;
2828
import jdk.graal.compiler.options.Option;
29-
import jdk.graal.compiler.options.OptionType;
3029
import jdk.graal.compiler.options.OptionKey;
30+
import jdk.graal.compiler.options.OptionType;
3131

3232
/**
3333
* Options related to HotSpot snippets in this package.
3434
*/
3535
public class HotspotSnippetsOptions {
36-
3736
// @formatter:off
38-
@Option(help = "If the probability that a type check will hit one the profiled types (up to " +
39-
"TypeCheckMaxHints) is below this value, the type check will be compiled without profiling info", type = OptionType.Debug)
40-
public static final OptionKey<Double> TypeCheckMinProfileHitProbability = new OptionKey<>(0.5);
41-
42-
@Option(help = "The maximum number of profiled types that will be used when compiling a profiled type check. " +
43-
"Note that TypeCheckMinProfileHitProbability also influences whether profiling info is used in compiled type checks.", type = OptionType.Debug)
44-
public static final OptionKey<Integer> TypeCheckMaxHints = new OptionKey<>(2);
45-
4637
@Option(help = "Use a VM runtime call to load and clear the exception object from the thread at the start of a compiled exception handler.", type = OptionType.Debug)
4738
public static final OptionKey<Boolean> LoadExceptionObjectInVM = new OptionKey<>(false);
4839

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424
*/
2525
package jdk.graal.compiler.hotspot.replacements;
2626

27+
import static jdk.graal.compiler.core.common.GraalOptions.TypeCheckMaxHints;
28+
import static jdk.graal.compiler.core.common.GraalOptions.TypeCheckMinProfileHitProbability;
2729
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.OPTIMIZING_PRIMARY_SUPERS_LOCATION;
2830
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.PRIMARY_SUPERS_LOCATION;
2931
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.SECONDARY_SUPER_CACHE_LOCATION;
3032
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubIntrinsic;
3133
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubOrNullIntrinsic;
32-
import static jdk.graal.compiler.hotspot.replacements.HotspotSnippetsOptions.TypeCheckMaxHints;
33-
import static jdk.graal.compiler.hotspot.replacements.HotspotSnippetsOptions.TypeCheckMinProfileHitProbability;
3434
import static jdk.graal.compiler.hotspot.replacements.TypeCheckSnippetUtils.checkSecondarySubType;
3535
import static jdk.graal.compiler.hotspot.replacements.TypeCheckSnippetUtils.checkUnknownSubType;
3636
import static jdk.graal.compiler.hotspot.replacements.TypeCheckSnippetUtils.createHints;

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/java/InstanceOfNode.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import java.util.Objects;
3232

33+
import jdk.graal.compiler.core.common.NativeImageSupport;
3334
import jdk.graal.compiler.core.common.type.ObjectStamp;
3435
import jdk.graal.compiler.core.common.type.Stamp;
3536
import jdk.graal.compiler.core.common.type.StampFactory;
@@ -83,7 +84,7 @@ protected InstanceOfNode(NodeClass<? extends InstanceOfNode> c, ObjectStamp chec
8384
this.checkedStamp = checkedStamp;
8485
this.profile = profile;
8586
this.anchor = anchor;
86-
assert (profile == null) || (anchor != null) : "profiles must be anchored";
87+
assert NativeImageSupport.inBuildtimeCode() || (profile == null) || (anchor != null) : "profiles must be anchored";
8788
assert checkedStamp != null;
8889
assert type() != null;
8990
}
@@ -213,7 +214,7 @@ public void setProfile(JavaTypeProfile typeProfile, AnchoringNode anchor) {
213214
this.profile = typeProfile;
214215
updateUsagesInterface(this.anchor, anchor);
215216
this.anchor = anchor;
216-
assert (profile == null) || (anchor != null) : "profiles must be anchored";
217+
assert NativeImageSupport.inBuildtimeCode() || (profile == null) || (anchor != null) : "profiles must be anchored";
217218
}
218219

219220
public AnchoringNode getAnchor() {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ public boolean equals(Object obj) {
190190
private final StrengthenGraphsCounters afterCounters;
191191

192192
/** Used to avoid aggressive optimizations for open type world analysis. */
193-
private final boolean isClosedTypeWorld;
193+
protected final boolean isClosedTypeWorld;
194194

195195
public StrengthenGraphs(BigBang bb, Universe converter) {
196196
this.bb = bb;
@@ -515,6 +515,8 @@ public void simplify(Node n, SimplifierTool tool) {
515515
AnalysisError.guarantee(node != replacement, "The new stamp needs to be different from the old stamp");
516516
node.replaceAndDelete(replacement);
517517
tool.addToWorkList(replacement);
518+
} else {
519+
maybeAssignInstanceOfProfiles(node);
518520
}
519521

520522
} else if (n instanceof ClassIsAssignableFromNode node) {
@@ -1176,6 +1178,11 @@ private Stamp strengthenStamp(Stamp s) {
11761178
}
11771179
}
11781180

1181+
@SuppressWarnings("unused")
1182+
protected void maybeAssignInstanceOfProfiles(InstanceOfNode iof) {
1183+
// placeholder
1184+
}
1185+
11791186
private static String getQualifiedName(StructuredGraph graph) {
11801187
return ((AnalysisMethod) graph.method()).getQualifiedName();
11811188
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/OpenTypeWorldSnippets.java

+25-23
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
/**
6363
* GR-51603 Once this snippet logic reaches a steady-state merge with {@link TypeSnippets}.
6464
*/
65-
public final class OpenTypeWorldSnippets extends SubstrateTemplates implements Snippets {
65+
public class OpenTypeWorldSnippets extends SubstrateTemplates implements Snippets {
6666

6767
@Snippet
6868
protected static SubstrateIntrinsics.Any typeEqualitySnippet(
@@ -156,7 +156,7 @@ protected static SubstrateIntrinsics.Any classIsAssignableFromSnippet(
156156
}
157157

158158
@DuplicatedInNativeCode
159-
private static SubstrateIntrinsics.Any classTypeCheck(
159+
protected static SubstrateIntrinsics.Any classTypeCheck(
160160
int typeID,
161161
int typeIDDepth,
162162
DynamicHub checkedHub,
@@ -179,7 +179,7 @@ private static SubstrateIntrinsics.Any classTypeCheck(
179179
}
180180

181181
@DuplicatedInNativeCode
182-
private static SubstrateIntrinsics.Any interfaceTypeCheck(
182+
protected static SubstrateIntrinsics.Any interfaceTypeCheck(
183183
int typeID,
184184
DynamicHub checkedHub,
185185
SubstrateIntrinsics.Any trueValue,
@@ -200,27 +200,25 @@ private static SubstrateIntrinsics.Any interfaceTypeCheck(
200200
return falseValue;
201201
}
202202

203-
@SuppressWarnings("unused")
204-
public static void registerLowerings(OptionValues options, Providers providers, Map<Class<? extends Node>, NodeLoweringProvider<?>> lowerings) {
205-
new OpenTypeWorldSnippets(options, providers, lowerings);
203+
public void registerLowerings(Map<Class<? extends Node>, NodeLoweringProvider<?>> lowerings, Providers providers) {
204+
lowerings.put(InstanceOfNode.class, new InstanceOfLowering(options, providers));
205+
lowerings.put(InstanceOfDynamicNode.class, new InstanceOfDynamicLowering(options, providers));
206+
lowerings.put(ClassIsAssignableFromNode.class, new ClassIsAssignableFromLowering(options, providers));
206207
}
207208

208209
final SnippetTemplate.SnippetInfo instanceOf;
209210
final SnippetTemplate.SnippetInfo instanceOfDynamic;
210211
final SnippetTemplate.SnippetInfo typeEquality;
211212
final SnippetTemplate.SnippetInfo assignableTypeCheck;
212213

213-
private OpenTypeWorldSnippets(OptionValues options, Providers providers, Map<Class<? extends Node>, NodeLoweringProvider<?>> lowerings) {
214+
@SuppressWarnings("this-escape")
215+
protected OpenTypeWorldSnippets(OptionValues options, Providers providers) {
214216
super(options, providers);
215217

216218
this.instanceOf = snippet(providers, OpenTypeWorldSnippets.class, "instanceOfSnippet");
217219
this.instanceOfDynamic = snippet(providers, OpenTypeWorldSnippets.class, "instanceOfDynamicSnippet");
218220
this.typeEquality = snippet(providers, OpenTypeWorldSnippets.class, "typeEqualitySnippet");
219221
this.assignableTypeCheck = snippet(providers, OpenTypeWorldSnippets.class, "classIsAssignableFromSnippet");
220-
221-
lowerings.put(InstanceOfNode.class, new InstanceOfLowering(options, providers));
222-
lowerings.put(InstanceOfDynamicNode.class, new InstanceOfDynamicLowering(options, providers));
223-
lowerings.put(ClassIsAssignableFromNode.class, new ClassIsAssignableFromLowering(options, providers));
224222
}
225223

226224
protected class InstanceOfLowering extends InstanceOfSnippetsTemplates implements NodeLoweringProvider<FloatingNode> {
@@ -244,26 +242,30 @@ protected SnippetTemplate.Arguments makeArguments(InstanceOfUsageReplacer replac
244242
SharedType type = (SharedType) typeReference.getType();
245243
DynamicHub hub = type.getHub();
246244

245+
SnippetTemplate.Arguments args;
247246
if (typeReference.isExact()) {
248-
SnippetTemplate.Arguments args = new SnippetTemplate.Arguments(typeEquality, node.graph().getGuardsStage(), tool.getLoweringStage());
247+
args = new SnippetTemplate.Arguments(typeEquality, node.graph().getGuardsStage(), tool.getLoweringStage());
249248
args.add("object", node.getValue());
250249
args.add("trueValue", replacer.trueValue);
251250
args.add("falseValue", replacer.falseValue);
252251
args.add("allowsNull", node.allowsNull());
253252
args.add("exactType", hub);
254-
return args;
255-
256253
} else {
257-
assert type.getSingleImplementor() == null : "Canonicalization of InstanceOfNode produces exact type for single implementor";
258-
SnippetTemplate.Arguments args = new SnippetTemplate.Arguments(instanceOf, node.graph().getGuardsStage(), tool.getLoweringStage());
259-
args.add("object", node.getValue());
260-
args.add("trueValue", replacer.trueValue);
261-
args.add("falseValue", replacer.falseValue);
262-
args.add("allowsNull", node.allowsNull());
263-
args.add("typeID", hub.getTypeID());
264-
args.add("typeIDDepth", hub.getTypeIDDepth());
265-
return args;
254+
args = makeArgumentsForInexactType(replacer, tool, node, type, hub);
266255
}
256+
return args;
257+
}
258+
259+
protected SnippetTemplate.Arguments makeArgumentsForInexactType(InstanceOfUsageReplacer replacer, LoweringTool tool, InstanceOfNode node, SharedType type, DynamicHub hub) {
260+
assert type.getSingleImplementor() == null : "Canonicalization of InstanceOfNode produces exact type for single implementor";
261+
SnippetTemplate.Arguments args = new SnippetTemplate.Arguments(instanceOf, node.graph().getGuardsStage(), tool.getLoweringStage());
262+
args.add("object", node.getValue());
263+
args.add("trueValue", replacer.trueValue);
264+
args.add("falseValue", replacer.falseValue);
265+
args.add("allowsNull", node.allowsNull());
266+
args.add("typeID", hub.getTypeID());
267+
args.add("typeIDDepth", hub.getTypeIDDepth());
268+
return args;
267269
}
268270
}
269271

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/SubstrateIntrinsics.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,22 @@
2424
*/
2525
package com.oracle.svm.core.graal.snippets;
2626

27+
import org.graalvm.word.Pointer;
28+
29+
import com.oracle.svm.core.hub.DynamicHub;
30+
2731
import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor;
2832
import jdk.graal.compiler.graph.Node.ConstantNodeParameter;
2933
import jdk.graal.compiler.graph.Node.NodeIntrinsic;
3034
import jdk.graal.compiler.nodes.BreakpointNode;
3135
import jdk.graal.compiler.nodes.extended.ForeignCallNode;
3236
import jdk.graal.compiler.nodes.extended.LoadHubNode;
3337
import jdk.graal.compiler.nodes.extended.LoadHubOrNullNode;
34-
import org.graalvm.word.Pointer;
35-
36-
import com.oracle.svm.core.hub.DynamicHub;
37-
3838
import jdk.vm.ci.meta.SpeculationLog.SpeculationReason;
3939

4040
public class SubstrateIntrinsics {
4141

42-
protected interface Any {
42+
public interface Any {
4343
}
4444

4545
@NodeIntrinsic(LoadHubNode.class)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2025, 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 com.oracle.svm.core.graal.snippets;
26+
27+
import java.util.Map;
28+
29+
import com.oracle.svm.core.SubstrateOptions;
30+
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
31+
import com.oracle.svm.core.feature.InternalFeature;
32+
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
33+
34+
import jdk.graal.compiler.graph.Node;
35+
import jdk.graal.compiler.options.OptionValues;
36+
import jdk.graal.compiler.phases.util.Providers;
37+
38+
@AutomaticallyRegisteredFeature
39+
public class TypeCheckFeature implements InternalFeature {
40+
41+
@Override
42+
public void registerLowerings(RuntimeConfiguration runtimeConfig, OptionValues options, Providers providers, Map<Class<? extends Node>, NodeLoweringProvider<?>> lowerings, boolean hosted) {
43+
if (SubstrateOptions.useClosedTypeWorldHubLayout()) {
44+
new TypeSnippets(options, providers).registerLowerings(lowerings, providers);
45+
} else {
46+
new OpenTypeWorldSnippets(options, providers).registerLowerings(lowerings, providers);
47+
OpenTypeWorldDispatchTableSnippets.registerLowerings(options, providers, lowerings);
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)