Skip to content

Commit ab898a9

Browse files
committed
[GR-54850] Respect UseSecondarySupersCache and UseSecondarySupersTable
PullRequest: graal/19177
2 parents 444850e + 14ae2e9 commit ab898a9

File tree

4 files changed

+46
-35
lines changed

4 files changed

+46
-35
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ public final int logMinObjAlignment() {
226226
public final int markOffset = getFieldOffset("oopDesc::_mark", Integer.class, markWord);
227227
public final int hubOffset = getFieldOffset("oopDesc::_metadata._klass", Integer.class, "Klass*");
228228

229+
public final boolean useSecondarySupersCache = getFlag("UseSecondarySupersCache", Boolean.class, true, JDK >= 23);
230+
public final boolean useSecondarySupersTable = getFlag("UseSecondarySupersTable", Boolean.class, true, JDK >= 23);
231+
229232
public final int superCheckOffsetOffset = getFieldOffset("Klass::_super_check_offset", Integer.class, "juint");
230233
public final int secondarySuperCacheOffset = getFieldOffset("Klass::_secondary_super_cache", Integer.class, "Klass*");
231234
public final int secondarySupersOffset = getFieldOffset("Klass::_secondary_supers", Integer.class, "Array<Klass*>*");

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,16 @@ public static int g1SATBQueueBufferOffset(@InjectedParameter GraalHotSpotVMConfi
624624

625625
public static final LocationIdentity KLASS_SUPER_CHECK_OFFSET_LOCATION = NamedLocationIdentity.immutable("Klass::_super_check_offset");
626626

627+
@Fold
628+
public static boolean useSecondarySupersCache(@InjectedParameter GraalHotSpotVMConfig config) {
629+
return config.useSecondarySupersCache;
630+
}
631+
632+
@Fold
633+
public static boolean useSecondarySupersTable(@InjectedParameter GraalHotSpotVMConfig config) {
634+
return config.useSecondarySupersTable;
635+
}
636+
627637
@Fold
628638
public static int superCheckOffsetOffset(@InjectedParameter GraalHotSpotVMConfig config) {
629639
return config.superCheckOffsetOffset;
@@ -1037,6 +1047,8 @@ public static int javaLangThreadTIDOffset(@InjectedParameter GraalHotSpotVMConfi
10371047
return config.javaLangThreadTIDOffset;
10381048
}
10391049

1050+
public static final LocationIdentity PRIMARY_SUPERS_LOCATION = NamedLocationIdentity.immutable("PrimarySupers");
1051+
10401052
/**
10411053
* This location identity is intended for accesses to {@code Klass::_primary_supers}, which is
10421054
* immutable. However, in {@link TypeCheckSnippetUtils#checkUnknownSubType}, it is possible to
@@ -1046,7 +1058,7 @@ public static int javaLangThreadTIDOffset(@InjectedParameter GraalHotSpotVMConfi
10461058
* corresponding reads when the displacement is not
10471059
* {@link GraalHotSpotVMConfig#secondarySuperCacheOffset}.
10481060
*/
1049-
public static final LocationIdentity PRIMARY_SUPERS_LOCATION = new HotSpotOptimizingLocationIdentity("PrimarySupers", false) {
1061+
public static final LocationIdentity OPTIMIZING_PRIMARY_SUPERS_LOCATION = new HotSpotOptimizingLocationIdentity("PrimarySupersOrSecondarySuperCache", false) {
10501062
@Override
10511063
public ValueNode canonicalizeRead(ValueNode read, ValueNode object, ValueNode offset, NodeView view, CoreProviders tool) {
10521064
int secondarySuperCacheOffset = ((HotSpotLoweringProvider) tool.getLowerer()).getVMConfig().secondarySuperCacheOffset;

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

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

27+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.OPTIMIZING_PRIMARY_SUPERS_LOCATION;
2728
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.PRIMARY_SUPERS_LOCATION;
2829
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.SECONDARY_SUPER_CACHE_LOCATION;
2930
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubIntrinsic;
@@ -74,7 +75,6 @@
7475
import jdk.graal.compiler.replacements.SnippetTemplate.SnippetInfo;
7576
import jdk.graal.compiler.replacements.Snippets;
7677
import jdk.graal.compiler.replacements.nodes.ExplodeLoopNode;
77-
import jdk.graal.compiler.serviceprovider.JavaVersionUtil;
7878
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
7979
import jdk.vm.ci.meta.Assumptions;
8080
import jdk.vm.ci.meta.DeoptimizationAction;
@@ -85,11 +85,11 @@
8585
/**
8686
* Snippets used for implementing the type test of an instanceof instruction. Since instanceof is a
8787
* floating node, it is lowered separately for each of its usages.
88-
*
88+
* <p>
8989
* The type tests implemented are described in the paper
9090
* <a href="http://dl.acm.org/citation.cfm?id=583821"> Fast subtype checking in the HotSpot JVM</a>
9191
* by Cliff Click and John Rose, with the adaption on the secondary supers hashed lookup algorithm
92-
* described in JDK-8180450 (see comments in {@link TypeCheckSnippetUtils#checkSelfAndSupers}).
92+
* described in JDK-8180450 (see comments in {@link TypeCheckSnippetUtils#checkSecondarySubType}).
9393
*/
9494
public class InstanceOfSnippets implements Snippets {
9595

@@ -167,8 +167,8 @@ public static Object instanceofPrimary(KlassPointer hub, Object object, @Constan
167167
* A test against a restricted secondary type.
168168
*/
169169
@Snippet(allowMissingProbabilities = true)
170-
public static Object instanceofSecondary(KlassPointer hub, Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
171-
@ConstantParameter Counters counters) {
170+
public static Object instanceofSecondary(KlassPointer hub, Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive,
171+
@ConstantParameter boolean isHubAbstract, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
172172
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
173173
counters.isNull.inc();
174174
return falseValue;
@@ -186,7 +186,7 @@ public static Object instanceofSecondary(KlassPointer hub, Object object, @Varar
186186
}
187187
}
188188
counters.hintsMiss.inc();
189-
if (!checkSecondarySubType(hub, objectHub, counters)) {
189+
if (!checkSecondarySubType(hub, objectHub, isHubAbstract, counters)) {
190190
return falseValue;
191191
}
192192
return trueValue;
@@ -267,15 +267,9 @@ public Templates(OptionValues options, SnippetCounter.Group.Factory factory, Hot
267267
this.instanceofWithProfile = snippet(providers, InstanceOfSnippets.class, "instanceofWithProfile");
268268
this.instanceofExact = snippet(providers, InstanceOfSnippets.class, "instanceofExact");
269269
this.instanceofPrimary = snippet(providers, InstanceOfSnippets.class, "instanceofPrimary", PRIMARY_SUPERS_LOCATION);
270-
if (JavaVersionUtil.JAVA_SPEC == 21) {
271-
this.instanceofSecondary = snippet(providers, InstanceOfSnippets.class, "instanceofSecondary", SECONDARY_SUPER_CACHE_LOCATION);
272-
this.instanceofDynamic = snippet(providers, InstanceOfSnippets.class, "instanceofDynamic", PRIMARY_SUPERS_LOCATION, SECONDARY_SUPER_CACHE_LOCATION);
273-
this.isAssignableFrom = snippet(providers, InstanceOfSnippets.class, "isAssignableFrom", PRIMARY_SUPERS_LOCATION, SECONDARY_SUPER_CACHE_LOCATION);
274-
} else {
275-
this.instanceofSecondary = snippet(providers, InstanceOfSnippets.class, "instanceofSecondary");
276-
this.instanceofDynamic = snippet(providers, InstanceOfSnippets.class, "instanceofDynamic", PRIMARY_SUPERS_LOCATION);
277-
this.isAssignableFrom = snippet(providers, InstanceOfSnippets.class, "isAssignableFrom", PRIMARY_SUPERS_LOCATION);
278-
}
270+
this.instanceofSecondary = snippet(providers, InstanceOfSnippets.class, "instanceofSecondary", SECONDARY_SUPER_CACHE_LOCATION);
271+
this.instanceofDynamic = snippet(providers, InstanceOfSnippets.class, "instanceofDynamic", OPTIMIZING_PRIMARY_SUPERS_LOCATION, SECONDARY_SUPER_CACHE_LOCATION);
272+
this.isAssignableFrom = snippet(providers, InstanceOfSnippets.class, "isAssignableFrom", OPTIMIZING_PRIMARY_SUPERS_LOCATION, SECONDARY_SUPER_CACHE_LOCATION);
279273

280274
this.counters = new Counters(factory);
281275
}
@@ -319,6 +313,7 @@ protected Arguments makeArguments(InstanceOfUsageReplacer replacer, LoweringTool
319313
args.add("object", object);
320314
args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs);
321315
args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(JavaKind.Boolean), hints.isPositive);
316+
args.addConst("isHubAbstract", type.isAbstract() || type.isInterface());
322317
}
323318
args.add("trueValue", replacer.trueValue);
324319
args.add("falseValue", replacer.falseValue);

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

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,21 @@
2929
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_HASH_SLOT_LOCATION;
3030
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.KLASS_SUPER_CHECK_OFFSET_LOCATION;
3131
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.METASPACE_ARRAY_LENGTH_LOCATION;
32-
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.PRIMARY_SUPERS_LOCATION;
32+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.OPTIMIZING_PRIMARY_SUPERS_LOCATION;
3333
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.SECONDARY_SUPERS_LOCATION;
3434
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.SECONDARY_SUPER_CACHE_LOCATION;
3535
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassBitmapOffset;
3636
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.klassHashSlotOffset;
3737
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.metaspaceArrayLengthOffset;
3838
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.secondarySuperCacheOffset;
39+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.secondarySupersOffset;
3940
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.superCheckOffsetOffset;
41+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.useSecondarySupersCache;
42+
import static jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil.useSecondarySupersTable;
4043
import static jdk.graal.compiler.hotspot.stubs.LookUpSecondarySupersTableStub.SECONDARY_SUPERS_TABLE_MASK;
4144
import static jdk.graal.compiler.hotspot.stubs.LookUpSecondarySupersTableStub.loadSecondarySupersElement;
4245
import static jdk.graal.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY;
46+
import static jdk.graal.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
4347
import static jdk.graal.compiler.nodes.extended.BranchProbabilityNode.NOT_LIKELY_PROBABILITY;
4448
import static jdk.graal.compiler.nodes.extended.BranchProbabilityNode.probability;
4549

@@ -67,23 +71,13 @@
6771
*/
6872
public class TypeCheckSnippetUtils {
6973

70-
static boolean checkSecondarySubType(KlassPointer t, KlassPointer sNonNull, Counters counters) {
71-
// if (S.cache == T) return true
72-
if (JavaVersionUtil.JAVA_SPEC == 21 && sNonNull.readKlassPointer(secondarySuperCacheOffset(INJECTED_VMCONFIG), SECONDARY_SUPER_CACHE_LOCATION).equal(t)) {
73-
counters.cacheHit.inc();
74-
return true;
75-
}
76-
77-
return checkSelfAndSupers(t, sNonNull, counters);
78-
}
79-
8074
static boolean checkUnknownSubType(KlassPointer t, KlassPointer sNonNull, Counters counters) {
8175
// int off = T.offset
8276
int superCheckOffset = t.readInt(superCheckOffsetOffset(INJECTED_VMCONFIG), KLASS_SUPER_CHECK_OFFSET_LOCATION);
8377
boolean primary = superCheckOffset != secondarySuperCacheOffset(INJECTED_VMCONFIG);
8478

85-
if (primary) {
86-
if (sNonNull.readKlassPointer(superCheckOffset, PRIMARY_SUPERS_LOCATION).equal(t)) {
79+
if (probability(LIKELY_PROBABILITY, primary)) {
80+
if (probability(LIKELY_PROBABILITY, sNonNull.readKlassPointer(superCheckOffset, OPTIMIZING_PRIMARY_SUPERS_LOCATION).equal(t))) {
8781
// if (T = S[off]) return true
8882
counters.displayHit.inc();
8983
return true;
@@ -92,24 +86,30 @@ static boolean checkUnknownSubType(KlassPointer t, KlassPointer sNonNull, Counte
9286
return false;
9387
}
9488
} else {
95-
return checkSecondarySubType(t, sNonNull, counters);
89+
return checkSecondarySubType(t, sNonNull, false, counters);
9690
}
9791
}
9892

9993
// @formatter:off
10094
@SyncPort(from = "https://github.com/openjdk/jdk/blob/7131f053b0d26b62cbf0d8376ec117d6e8d79f9e/src/hotspot/cpu/x86/macroAssembler_x86.cpp#L4802-L4897",
10195
sha1 = "c0e2fdd973dc975757d58080ba94efe628d6a380")
10296
// @formatter:on
103-
static boolean checkSelfAndSupers(KlassPointer t, KlassPointer s, Counters counters) {
97+
static boolean checkSecondarySubType(KlassPointer t, KlassPointer s, boolean isTAlwaysAbstract, Counters counters) {
98+
// if (S.cache == T) return true
99+
if ((JavaVersionUtil.JAVA_SPEC == 21 || (JavaVersionUtil.JAVA_SPEC >= 23 && useSecondarySupersCache(INJECTED_VMCONFIG))) &&
100+
probability(FREQUENT_PROBABILITY, s.readKlassPointer(secondarySuperCacheOffset(INJECTED_VMCONFIG), SECONDARY_SUPER_CACHE_LOCATION).equal(t))) {
101+
counters.cacheHit.inc();
102+
return true;
103+
}
104+
104105
// if (T == S) return true
105-
if (s.equal(t)) {
106+
if (!isTAlwaysAbstract && probability(LIKELY_PROBABILITY, s.equal(t))) {
106107
counters.equalsSecondary.inc();
107108
return true;
108109
}
109110

110-
Word secondarySupers = s.readWord(HotSpotReplacementsUtil.secondarySupersOffset(INJECTED_VMCONFIG), SECONDARY_SUPERS_LOCATION);
111-
112-
if (JavaVersionUtil.JAVA_SPEC == 21) {
111+
if (JavaVersionUtil.JAVA_SPEC == 21 || (JavaVersionUtil.JAVA_SPEC >= 23 && !useSecondarySupersTable(INJECTED_VMCONFIG))) {
112+
Word secondarySupers = s.readWord(secondarySupersOffset(INJECTED_VMCONFIG), SECONDARY_SUPERS_LOCATION);
113113
int length = secondarySupers.readInt(metaspaceArrayLengthOffset(INJECTED_VMCONFIG), METASPACE_ARRAY_LENGTH_LOCATION);
114114
for (int i = 0; i < length; i++) {
115115
if (probability(NOT_LIKELY_PROBABILITY, t.equal(loadSecondarySupersElement(secondarySupers, i)))) {
@@ -165,6 +165,7 @@ static boolean checkSelfAndSupers(KlassPointer t, KlassPointer s, Counters count
165165
// We instead rely on the compiler for constant folding.
166166
// Use long to avoid unnecessary zero extension.
167167
long index = Long.bitCount(bitmapShifted) - 1L;
168+
Word secondarySupers = s.readWord(secondarySupersOffset(INJECTED_VMCONFIG), SECONDARY_SUPERS_LOCATION);
168169
KlassPointer hashed = loadSecondarySupersElement(secondarySupers, index);
169170

170171
if (probability(FREQUENT_PROBABILITY, t.equal(hashed))) {

0 commit comments

Comments
 (0)