src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java
Print this page
*** 20,76 ****
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot.replacements;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PRIMARY_SUPERS_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.SECONDARY_SUPER_CACHE_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubIntrinsic;
import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.TypeCheckMaxHints;
import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.TypeCheckMinProfileHitProbability;
import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.checkSecondarySubType;
import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.checkUnknownSubType;
import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.createHints;
- import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.displayHit;
- import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.displayMiss;
- import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.exactHit;
- import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.exactMiss;
- import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.hintsHit;
- import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.hintsMiss;
- import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.isNull;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_LIKELY_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
- import static jdk.vm.ci.meta.DeoptimizationAction.InvalidateReprofile;
- import static jdk.vm.ci.meta.DeoptimizationReason.OptimizedTypeCheckViolated;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
import org.graalvm.compiler.api.replacements.Snippet.VarargsParameter;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
- import org.graalvm.compiler.hotspot.nodes.SnippetAnchorNode;
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.Hints;
import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.TypeCheckHints;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.BranchProbabilityNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
import org.graalvm.compiler.nodes.java.ClassIsAssignableFromNode;
import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.replacements.InstanceOfSnippetsTemplates;
import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
import org.graalvm.compiler.replacements.Snippets;
import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
--- 20,74 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot.replacements;
+ import static jdk.vm.ci.meta.DeoptimizationAction.InvalidateReprofile;
+ import static jdk.vm.ci.meta.DeoptimizationReason.OptimizedTypeCheckViolated;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PRIMARY_SUPERS_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.SECONDARY_SUPER_CACHE_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubIntrinsic;
import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.TypeCheckMaxHints;
import static org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions.TypeCheckMinProfileHitProbability;
import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.checkSecondarySubType;
import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.checkUnknownSubType;
import static org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.createHints;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_LIKELY_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
+ import org.graalvm.compiler.api.replacements.Snippet.NonNullParameter;
import org.graalvm.compiler.api.replacements.Snippet.VarargsParameter;
+ import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
+ import org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.Counters;
import org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.Hints;
import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.PiNode;
+ import org.graalvm.compiler.nodes.SnippetAnchorNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.TypeCheckHints;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.BranchProbabilityNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
import org.graalvm.compiler.nodes.java.ClassIsAssignableFromNode;
import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
+ import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.replacements.InstanceOfSnippetsTemplates;
+ import org.graalvm.compiler.replacements.SnippetCounter;
import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
import org.graalvm.compiler.replacements.Snippets;
import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
*** 97,109 ****
* A test against a set of hints derived from a profile with 100% precise coverage of seen
* types. This snippet deoptimizes on hint miss paths.
*/
@Snippet
public static Object instanceofWithProfile(Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
! @ConstantParameter boolean nullSeen) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! isNull.inc();
if (!nullSeen) {
// See comment below for other deoptimization path; the
// same reasoning applies here.
DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated);
}
--- 95,107 ----
* A test against a set of hints derived from a profile with 100% precise coverage of seen
* types. This snippet deoptimizes on hint miss paths.
*/
@Snippet
public static Object instanceofWithProfile(Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
! @ConstantParameter boolean nullSeen, @ConstantParameter Counters counters) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! counters.isNull.inc();
if (!nullSeen) {
// See comment below for other deoptimization path; the
// same reasoning applies here.
DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated);
}
*** 115,128 ****
ExplodeLoopNode.explodeLoop();
for (int i = 0; i < hints.length; i++) {
KlassPointer hintHub = hints[i];
boolean positive = hintIsPositive[i];
if (probability(LIKELY_PROBABILITY, hintHub.equal(objectHub))) {
! hintsHit.inc();
return positive ? trueValue : falseValue;
}
! hintsMiss.inc();
}
// This maybe just be a rare event but it might also indicate a phase change
// in the application. Ideally we want to use DeoptimizationAction.None for
// the former but the cost is too high if indeed it is the latter. As such,
// we defensively opt for InvalidateReprofile.
--- 113,126 ----
ExplodeLoopNode.explodeLoop();
for (int i = 0; i < hints.length; i++) {
KlassPointer hintHub = hints[i];
boolean positive = hintIsPositive[i];
if (probability(LIKELY_PROBABILITY, hintHub.equal(objectHub))) {
! counters.hintsHit.inc();
return positive ? trueValue : falseValue;
}
! counters.hintsMiss.inc();
}
// This maybe just be a rare event but it might also indicate a phase change
// in the application. Ideally we want to use DeoptimizationAction.None for
// the former but the cost is too high if indeed it is the latter. As such,
// we defensively opt for InvalidateReprofile.
*** 132,262 ****
/**
* A test against a final type.
*/
@Snippet
! public static Object instanceofExact(Object object, KlassPointer exactHub, Object trueValue, Object falseValue) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! isNull.inc();
return falseValue;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
KlassPointer objectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
if (probability(LIKELY_PROBABILITY, objectHub.notEqual(exactHub))) {
! exactMiss.inc();
return falseValue;
}
! exactHit.inc();
return trueValue;
}
@Snippet
! public static Object instanceofExactPIC(Object object, KlassPointer exactHub, Object trueValue, Object falseValue) {
KlassPointer exactHubPIC = ResolveConstantSnippets.resolveKlassConstant(exactHub);
! return instanceofExact(object, exactHubPIC, trueValue, falseValue);
}
/**
* A test against a primary type.
*/
@Snippet
! public static Object instanceofPrimary(KlassPointer hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! isNull.inc();
return falseValue;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
KlassPointer objectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
if (probability(NOT_LIKELY_PROBABILITY, objectHub.readKlassPointer(superCheckOffset, PRIMARY_SUPERS_LOCATION).notEqual(hub))) {
! displayMiss.inc();
return falseValue;
}
! displayHit.inc();
return trueValue;
}
@Snippet
! public static Object instanceofPrimaryPIC(KlassPointer hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue) {
KlassPointer resolvedHub = ResolveConstantSnippets.resolveKlassConstant(hub);
! return instanceofPrimary(resolvedHub, object, superCheckOffset, trueValue, falseValue);
}
/**
* A test against a restricted secondary type type.
*/
@Snippet
! public static Object instanceofSecondary(KlassPointer hub, Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! isNull.inc();
return falseValue;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
KlassPointer objectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
// if we get an exact match: succeed immediately
ExplodeLoopNode.explodeLoop();
for (int i = 0; i < hints.length; i++) {
KlassPointer hintHub = hints[i];
boolean positive = hintIsPositive[i];
if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) {
! hintsHit.inc();
return positive ? trueValue : falseValue;
}
}
! hintsMiss.inc();
! if (!checkSecondarySubType(hub, objectHub)) {
return falseValue;
}
return trueValue;
}
@Snippet
public static Object instanceofSecondaryPIC(KlassPointer hub, Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue,
! Object falseValue) {
KlassPointer resolvedHub = ResolveConstantSnippets.resolveKlassConstant(hub);
! return instanceofSecondary(resolvedHub, object, hints, hintIsPositive, trueValue, falseValue);
}
/**
* Type test used when the type being tested against is not known at compile time.
*/
@Snippet
! public static Object instanceofDynamic(KlassPointer hub, Object object, Object trueValue, Object falseValue, @ConstantParameter boolean allowNull) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! isNull.inc();
if (allowNull) {
return trueValue;
} else {
return falseValue;
}
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
! KlassPointer objectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
// The hub of a primitive type can be null => always return false in this case.
! if (hub.isNull() || !checkUnknownSubType(hub, objectHub)) {
! return falseValue;
! }
return trueValue;
}
@Snippet
! public static Object isAssignableFrom(Class<?> thisClass, Class<?> otherClass, Object trueValue, Object falseValue) {
! if (BranchProbabilityNode.probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, otherClass == null)) {
DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
return false;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
! KlassPointer thisHub = ClassGetHubNode.readClass(thisClass, anchorNode);
! KlassPointer otherHub = ClassGetHubNode.readClass(otherClass, anchorNode);
! if (thisHub.isNull() || otherHub.isNull()) {
! // primitive types, only true if equal.
! return thisClass == otherClass ? trueValue : falseValue;
! }
! if (!TypeCheckSnippetUtils.checkUnknownSubType(thisHub, otherHub)) {
! return falseValue;
}
return trueValue;
}
public static class Templates extends InstanceOfSnippetsTemplates {
private final SnippetInfo instanceofWithProfile = snippet(InstanceOfSnippets.class, "instanceofWithProfile");
private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact");
--- 130,274 ----
/**
* A test against a final type.
*/
@Snippet
! public static Object instanceofExact(Object object, KlassPointer exactHub, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! counters.isNull.inc();
return falseValue;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
KlassPointer objectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
if (probability(LIKELY_PROBABILITY, objectHub.notEqual(exactHub))) {
! counters.exactMiss.inc();
return falseValue;
}
! counters.exactHit.inc();
return trueValue;
}
@Snippet
! public static Object instanceofExactPIC(Object object, KlassPointer exactHub, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
KlassPointer exactHubPIC = ResolveConstantSnippets.resolveKlassConstant(exactHub);
! return instanceofExact(object, exactHubPIC, trueValue, falseValue, counters);
}
/**
* A test against a primary type.
*/
@Snippet
! public static Object instanceofPrimary(KlassPointer hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! counters.isNull.inc();
return falseValue;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
KlassPointer objectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
if (probability(NOT_LIKELY_PROBABILITY, objectHub.readKlassPointer(superCheckOffset, PRIMARY_SUPERS_LOCATION).notEqual(hub))) {
! counters.displayMiss.inc();
return falseValue;
}
! counters.displayHit.inc();
return trueValue;
}
@Snippet
! public static Object instanceofPrimaryPIC(KlassPointer hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
KlassPointer resolvedHub = ResolveConstantSnippets.resolveKlassConstant(hub);
! return instanceofPrimary(resolvedHub, object, superCheckOffset, trueValue, falseValue, counters);
}
/**
* A test against a restricted secondary type type.
*/
@Snippet
! public static Object instanceofSecondary(KlassPointer hub, Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
! @ConstantParameter Counters counters) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! counters.isNull.inc();
return falseValue;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
KlassPointer objectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
// if we get an exact match: succeed immediately
ExplodeLoopNode.explodeLoop();
for (int i = 0; i < hints.length; i++) {
KlassPointer hintHub = hints[i];
boolean positive = hintIsPositive[i];
if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) {
! counters.hintsHit.inc();
return positive ? trueValue : falseValue;
}
}
! counters.hintsMiss.inc();
! if (!checkSecondarySubType(hub, objectHub, counters)) {
return falseValue;
}
return trueValue;
}
@Snippet
public static Object instanceofSecondaryPIC(KlassPointer hub, Object object, @VarargsParameter KlassPointer[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue,
! Object falseValue, @ConstantParameter Counters counters) {
KlassPointer resolvedHub = ResolveConstantSnippets.resolveKlassConstant(hub);
! return instanceofSecondary(resolvedHub, object, hints, hintIsPositive, trueValue, falseValue, counters);
}
/**
* Type test used when the type being tested against is not known at compile time.
*/
@Snippet
! public static Object instanceofDynamic(KlassPointer hub, Object object, Object trueValue, Object falseValue, @ConstantParameter boolean allowNull, @ConstantParameter Counters counters) {
if (probability(NOT_FREQUENT_PROBABILITY, object == null)) {
! counters.isNull.inc();
if (allowNull) {
return trueValue;
} else {
return falseValue;
}
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
! KlassPointer nonNullObjectHub = loadHubIntrinsic(PiNode.piCastNonNull(object, anchorNode));
// The hub of a primitive type can be null => always return false in this case.
! if (BranchProbabilityNode.probability(BranchProbabilityNode.FAST_PATH_PROBABILITY, !hub.isNull())) {
! if (checkUnknownSubType(hub, nonNullObjectHub, counters)) {
return trueValue;
}
+ }
+ return falseValue;
+ }
@Snippet
! public static Object isAssignableFrom(@NonNullParameter Class<?> thisClassNonNull, Class<?> otherClass, Object trueValue, Object falseValue, @ConstantParameter Counters counters) {
! if (otherClass == null) {
DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
return false;
}
GuardingNode anchorNode = SnippetAnchorNode.anchor();
! Class<?> otherClassNonNull = PiNode.piCastNonNullClass(otherClass, anchorNode);
!
! if (BranchProbabilityNode.probability(BranchProbabilityNode.NOT_LIKELY_PROBABILITY, thisClassNonNull == otherClassNonNull)) {
! return trueValue;
}
+
+ KlassPointer thisHub = ClassGetHubNode.readClass(thisClassNonNull);
+ KlassPointer otherHub = ClassGetHubNode.readClass(otherClassNonNull);
+ if (BranchProbabilityNode.probability(BranchProbabilityNode.FAST_PATH_PROBABILITY, !thisHub.isNull())) {
+ if (BranchProbabilityNode.probability(BranchProbabilityNode.FAST_PATH_PROBABILITY, !otherHub.isNull())) {
+ GuardingNode guardNonNull = SnippetAnchorNode.anchor();
+ KlassPointer nonNullOtherHub = ClassGetHubNode.piCastNonNull(otherHub, guardNonNull);
+ if (TypeCheckSnippetUtils.checkUnknownSubType(thisHub, nonNullOtherHub, counters)) {
return trueValue;
}
+ }
+ }
+
+ // If either hub is null, one of them is a primitive type and given that the class is not
+ // equal, return false.
+ return falseValue;
+ }
public static class Templates extends InstanceOfSnippetsTemplates {
private final SnippetInfo instanceofWithProfile = snippet(InstanceOfSnippets.class, "instanceofWithProfile");
private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact");
*** 266,293 ****
private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo instanceofSecondaryPIC = snippet(InstanceOfSnippets.class, "instanceofSecondaryPIC", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom", SECONDARY_SUPER_CACHE_LOCATION);
! public Templates(HotSpotProviders providers, TargetDescription target) {
! super(providers, providers.getSnippetReflection(), target);
}
@Override
protected Arguments makeArguments(InstanceOfUsageReplacer replacer, LoweringTool tool) {
if (replacer.instanceOf instanceof InstanceOfNode) {
InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf;
ValueNode object = instanceOf.getValue();
Assumptions assumptions = instanceOf.graph().getAssumptions();
JavaTypeProfile profile = instanceOf.profile();
! if (GeneratePIC.getValue()) {
// FIXME: We can't embed constants in hints. We can't really load them from GOT
// either. Hard problem.
profile = null;
}
! TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), profile, assumptions, TypeCheckMinProfileHitProbability.getValue(), TypeCheckMaxHints.getValue());
final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type().getType();
ConstantNode hub = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), type.klass(), providers.getMetaAccess(), instanceOf.graph());
Arguments args;
--- 278,310 ----
private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo instanceofSecondaryPIC = snippet(InstanceOfSnippets.class, "instanceofSecondaryPIC", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic", SECONDARY_SUPER_CACHE_LOCATION);
private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom", SECONDARY_SUPER_CACHE_LOCATION);
! private final Counters counters;
!
! public Templates(OptionValues options, SnippetCounter.Group.Factory factory, HotSpotProviders providers, TargetDescription target) {
! super(options, providers, providers.getSnippetReflection(), target);
! this.counters = new Counters(factory);
}
@Override
protected Arguments makeArguments(InstanceOfUsageReplacer replacer, LoweringTool tool) {
if (replacer.instanceOf instanceof InstanceOfNode) {
InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf;
ValueNode object = instanceOf.getValue();
Assumptions assumptions = instanceOf.graph().getAssumptions();
+ OptionValues localOptions = instanceOf.getOptions();
JavaTypeProfile profile = instanceOf.profile();
! if (GeneratePIC.getValue(localOptions)) {
// FIXME: We can't embed constants in hints. We can't really load them from GOT
// either. Hard problem.
profile = null;
}
! TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), profile, assumptions, TypeCheckMinProfileHitProbability.getValue(localOptions),
! TypeCheckMaxHints.getValue(localOptions));
final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type().getType();
ConstantNode hub = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), type.klass(), providers.getMetaAccess(), instanceOf.graph());
Arguments args;
*** 297,319 ****
args = new Arguments(instanceofWithProfile, graph.getGuardsStage(), tool.getLoweringStage());
args.add("object", object);
args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs);
args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(JavaKind.Boolean), hints.isPositive);
} else if (hintInfo.exact != null) {
! SnippetInfo snippet = GeneratePIC.getValue() ? instanceofExactPIC : instanceofExact;
args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("object", object);
args.add("exactHub", ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph));
} else if (type.isPrimaryType()) {
! SnippetInfo snippet = GeneratePIC.getValue() ? instanceofPrimaryPIC : instanceofPrimary;
args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("hub", hub);
args.add("object", object);
args.addConst("superCheckOffset", type.superCheckOffset());
} else {
Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
! SnippetInfo snippet = GeneratePIC.getValue() ? instanceofSecondaryPIC : instanceofSecondary;
args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("hub", hub);
args.add("object", object);
args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs);
args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(JavaKind.Boolean), hints.isPositive);
--- 314,336 ----
args = new Arguments(instanceofWithProfile, graph.getGuardsStage(), tool.getLoweringStage());
args.add("object", object);
args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs);
args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(JavaKind.Boolean), hints.isPositive);
} else if (hintInfo.exact != null) {
! SnippetInfo snippet = GeneratePIC.getValue(localOptions) ? instanceofExactPIC : instanceofExact;
args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("object", object);
args.add("exactHub", ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph));
} else if (type.isPrimaryType()) {
! SnippetInfo snippet = GeneratePIC.getValue(localOptions) ? instanceofPrimaryPIC : instanceofPrimary;
args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("hub", hub);
args.add("object", object);
args.addConst("superCheckOffset", type.superCheckOffset());
} else {
Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
! SnippetInfo snippet = GeneratePIC.getValue(localOptions) ? instanceofSecondaryPIC : instanceofSecondary;
args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("hub", hub);
args.add("object", object);
args.addVarargs("hints", KlassPointer.class, KlassPointerStamp.klassNonNull(), hints.hubs);
args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(JavaKind.Boolean), hints.isPositive);
*** 321,330 ****
--- 338,348 ----
args.add("trueValue", replacer.trueValue);
args.add("falseValue", replacer.falseValue);
if (hintInfo.hintHitProbability >= 1.0 && hintInfo.exact == null) {
args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE);
}
+ args.addConst("counters", counters);
return args;
} else if (replacer.instanceOf instanceof InstanceOfDynamicNode) {
InstanceOfDynamicNode instanceOf = (InstanceOfDynamicNode) replacer.instanceOf;
ValueNode object = instanceOf.getObject();
*** 332,349 ****
args.add("hub", instanceOf.getMirrorOrHub());
args.add("object", object);
args.add("trueValue", replacer.trueValue);
args.add("falseValue", replacer.falseValue);
args.addConst("allowNull", instanceOf.allowsNull());
return args;
} else if (replacer.instanceOf instanceof ClassIsAssignableFromNode) {
ClassIsAssignableFromNode isAssignable = (ClassIsAssignableFromNode) replacer.instanceOf;
Arguments args = new Arguments(isAssignableFrom, isAssignable.graph().getGuardsStage(), tool.getLoweringStage());
! args.add("thisClass", isAssignable.getThisClass());
args.add("otherClass", isAssignable.getOtherClass());
args.add("trueValue", replacer.trueValue);
args.add("falseValue", replacer.falseValue);
return args;
} else {
throw GraalError.shouldNotReachHere();
}
}
--- 350,370 ----
args.add("hub", instanceOf.getMirrorOrHub());
args.add("object", object);
args.add("trueValue", replacer.trueValue);
args.add("falseValue", replacer.falseValue);
args.addConst("allowNull", instanceOf.allowsNull());
+ args.addConst("counters", counters);
return args;
} else if (replacer.instanceOf instanceof ClassIsAssignableFromNode) {
ClassIsAssignableFromNode isAssignable = (ClassIsAssignableFromNode) replacer.instanceOf;
Arguments args = new Arguments(isAssignableFrom, isAssignable.graph().getGuardsStage(), tool.getLoweringStage());
! assert ((ObjectStamp) isAssignable.getThisClass().stamp()).nonNull();
! args.add("thisClassNonNull", isAssignable.getThisClass());
args.add("otherClass", isAssignable.getOtherClass());
args.add("trueValue", replacer.trueValue);
args.add("falseValue", replacer.falseValue);
+ args.addConst("counters", counters);
return args;
} else {
throw GraalError.shouldNotReachHere();
}
}
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File