< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java

Print this page




  32 import org.graalvm.compiler.core.common.type.TypeReference;
  33 import org.graalvm.compiler.graph.NodeClass;
  34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
  35 import org.graalvm.compiler.nodeinfo.NodeInfo;
  36 import org.graalvm.compiler.nodes.LogicConstantNode;
  37 import org.graalvm.compiler.nodes.LogicNegationNode;
  38 import org.graalvm.compiler.nodes.LogicNode;
  39 import org.graalvm.compiler.nodes.UnaryOpLogicNode;
  40 import org.graalvm.compiler.nodes.ValueNode;
  41 import org.graalvm.compiler.nodes.calc.IsNullNode;
  42 import org.graalvm.compiler.nodes.extended.AnchoringNode;
  43 import org.graalvm.compiler.nodes.spi.Lowerable;
  44 import org.graalvm.compiler.nodes.spi.LoweringTool;
  45 import org.graalvm.compiler.nodes.spi.Virtualizable;
  46 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
  47 import org.graalvm.compiler.nodes.type.StampTool;
  48 
  49 import jdk.vm.ci.meta.JavaTypeProfile;
  50 import jdk.vm.ci.meta.TriState;
  51 


  52 /**
  53  * The {@code InstanceOfNode} represents an instanceof test.
  54  */
  55 @NodeInfo(cycles = CYCLES_8, size = SIZE_8)
  56 public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable {
  57     public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class);
  58 
  59     protected final ObjectStamp checkedStamp;
  60 
  61     private JavaTypeProfile profile;
  62     @OptionalInput(Anchor) protected AnchoringNode anchor;
  63 
  64     private InstanceOfNode(ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
  65         this(TYPE, checkedStamp, object, profile, anchor);
  66     }
  67 
  68     protected InstanceOfNode(NodeClass<? extends InstanceOfNode> c, ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
  69         super(c, object);
  70         this.checkedStamp = checkedStamp;
  71         this.profile = profile;
  72         this.anchor = anchor;
  73         assert (profile == null) || (anchor != null) : "profiles must be anchored";
  74         assert checkedStamp != null;
  75     }
  76 
  77     public static LogicNode createAllowNull(TypeReference type, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
  78         if (StampTool.isPointerNonNull(object)) {
  79             return create(type, object, profile, anchor);


 109         if (synonym != null) {
 110             return synonym;
 111         } else {
 112             return this;
 113         }
 114     }
 115 
 116     public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object) {
 117         ObjectStamp inputStamp = (ObjectStamp) object.stamp();
 118         ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
 119 
 120         if (joinedStamp.isEmpty()) {
 121             // The check can never succeed, the intersection of the two stamps is empty.
 122             return LogicConstantNode.contradiction();
 123         } else {
 124             ObjectStamp meetStamp = (ObjectStamp) checkedStamp.meet(inputStamp);
 125             if (checkedStamp.equals(meetStamp)) {
 126                 // The check will always succeed, the union of the two stamps is equal to the
 127                 // checked stamp.
 128                 return LogicConstantNode.tautology();
 129             } else if (checkedStamp.type().equals(meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {


 130                 assert checkedStamp.nonNull() != inputStamp.nonNull();
 131                 // The only difference makes the null-ness of the value => simplify the check.
 132                 if (checkedStamp.nonNull()) {
 133                     return LogicNegationNode.create(IsNullNode.create(object));
 134                 } else {
 135                     return IsNullNode.create(object);
 136                 }
 137             }

 138         }
 139 
 140         return null;
 141     }
 142 
 143     /**
 144      * Gets the type being tested.
 145      */
 146     public TypeReference type() {
 147         return StampTool.typeReferenceOrNull(checkedStamp);
 148     }
 149 
 150     public JavaTypeProfile profile() {
 151         return profile;
 152     }
 153 
 154     @Override
 155     public void virtualize(VirtualizerTool tool) {
 156         ValueNode alias = tool.getAlias(getValue());
 157         TriState fold = tryFold(alias.stamp());
 158         if (fold != TriState.UNKNOWN) {
 159             tool.replaceWithValue(LogicConstantNode.forBoolean(fold.isTrue(), graph()));


 186                     return TriState.TRUE;
 187                 }
 188             }
 189         }
 190         return TriState.UNKNOWN;
 191     }
 192 
 193     public boolean allowsNull() {
 194         return !checkedStamp.nonNull();
 195     }
 196 
 197     public void setProfile(JavaTypeProfile typeProfile, AnchoringNode anchor) {
 198         this.profile = typeProfile;
 199         updateUsagesInterface(this.anchor, anchor);
 200         this.anchor = anchor;
 201         assert (profile == null) || (anchor != null) : "profiles must be anchored";
 202     }
 203 
 204     public AnchoringNode getAnchor() {
 205         return anchor;









 206     }
 207 }


  32 import org.graalvm.compiler.core.common.type.TypeReference;
  33 import org.graalvm.compiler.graph.NodeClass;
  34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
  35 import org.graalvm.compiler.nodeinfo.NodeInfo;
  36 import org.graalvm.compiler.nodes.LogicConstantNode;
  37 import org.graalvm.compiler.nodes.LogicNegationNode;
  38 import org.graalvm.compiler.nodes.LogicNode;
  39 import org.graalvm.compiler.nodes.UnaryOpLogicNode;
  40 import org.graalvm.compiler.nodes.ValueNode;
  41 import org.graalvm.compiler.nodes.calc.IsNullNode;
  42 import org.graalvm.compiler.nodes.extended.AnchoringNode;
  43 import org.graalvm.compiler.nodes.spi.Lowerable;
  44 import org.graalvm.compiler.nodes.spi.LoweringTool;
  45 import org.graalvm.compiler.nodes.spi.Virtualizable;
  46 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
  47 import org.graalvm.compiler.nodes.type.StampTool;
  48 
  49 import jdk.vm.ci.meta.JavaTypeProfile;
  50 import jdk.vm.ci.meta.TriState;
  51 
  52 import java.util.Objects;
  53 
  54 /**
  55  * The {@code InstanceOfNode} represents an instanceof test.
  56  */
  57 @NodeInfo(cycles = CYCLES_8, size = SIZE_8)
  58 public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable {
  59     public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class);
  60 
  61     private ObjectStamp checkedStamp;
  62 
  63     private JavaTypeProfile profile;
  64     @OptionalInput(Anchor) protected AnchoringNode anchor;
  65 
  66     private InstanceOfNode(ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
  67         this(TYPE, checkedStamp, object, profile, anchor);
  68     }
  69 
  70     protected InstanceOfNode(NodeClass<? extends InstanceOfNode> c, ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
  71         super(c, object);
  72         this.checkedStamp = checkedStamp;
  73         this.profile = profile;
  74         this.anchor = anchor;
  75         assert (profile == null) || (anchor != null) : "profiles must be anchored";
  76         assert checkedStamp != null;
  77     }
  78 
  79     public static LogicNode createAllowNull(TypeReference type, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
  80         if (StampTool.isPointerNonNull(object)) {
  81             return create(type, object, profile, anchor);


 111         if (synonym != null) {
 112             return synonym;
 113         } else {
 114             return this;
 115         }
 116     }
 117 
 118     public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object) {
 119         ObjectStamp inputStamp = (ObjectStamp) object.stamp();
 120         ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
 121 
 122         if (joinedStamp.isEmpty()) {
 123             // The check can never succeed, the intersection of the two stamps is empty.
 124             return LogicConstantNode.contradiction();
 125         } else {
 126             ObjectStamp meetStamp = (ObjectStamp) checkedStamp.meet(inputStamp);
 127             if (checkedStamp.equals(meetStamp)) {
 128                 // The check will always succeed, the union of the two stamps is equal to the
 129                 // checked stamp.
 130                 return LogicConstantNode.tautology();
 131             } else if (checkedStamp.alwaysNull()) {
 132                 return IsNullNode.create(object);
 133             } else if (Objects.equals(checkedStamp.type(), meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
 134                 assert checkedStamp.nonNull() != inputStamp.nonNull();
 135                 // The only difference makes the null-ness of the value => simplify the check.
 136                 if (checkedStamp.nonNull()) {
 137                     return LogicNegationNode.create(IsNullNode.create(object));
 138                 } else {
 139                     return IsNullNode.create(object);
 140                 }
 141             }
 142             assert checkedStamp.type() != null;
 143         }

 144         return null;
 145     }
 146 
 147     /**
 148      * Gets the type being tested.
 149      */
 150     public TypeReference type() {
 151         return StampTool.typeReferenceOrNull(checkedStamp);
 152     }
 153 
 154     public JavaTypeProfile profile() {
 155         return profile;
 156     }
 157 
 158     @Override
 159     public void virtualize(VirtualizerTool tool) {
 160         ValueNode alias = tool.getAlias(getValue());
 161         TriState fold = tryFold(alias.stamp());
 162         if (fold != TriState.UNKNOWN) {
 163             tool.replaceWithValue(LogicConstantNode.forBoolean(fold.isTrue(), graph()));


 190                     return TriState.TRUE;
 191                 }
 192             }
 193         }
 194         return TriState.UNKNOWN;
 195     }
 196 
 197     public boolean allowsNull() {
 198         return !checkedStamp.nonNull();
 199     }
 200 
 201     public void setProfile(JavaTypeProfile typeProfile, AnchoringNode anchor) {
 202         this.profile = typeProfile;
 203         updateUsagesInterface(this.anchor, anchor);
 204         this.anchor = anchor;
 205         assert (profile == null) || (anchor != null) : "profiles must be anchored";
 206     }
 207 
 208     public AnchoringNode getAnchor() {
 209         return anchor;
 210     }
 211 
 212     public ObjectStamp getCheckedStamp() {
 213         return checkedStamp;
 214     }
 215 
 216     public void strengthenCheckedStamp(ObjectStamp newCheckedStamp) {
 217         assert this.checkedStamp.join(newCheckedStamp).equals(newCheckedStamp) : "stamp can only improve";
 218         this.checkedStamp = newCheckedStamp;
 219     }
 220 }
< prev index next >