26 27 import static org.graalvm.compiler.nodeinfo.InputType.Anchor; 28 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; 29 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; 30 31 import java.util.Objects; 32 33 import org.graalvm.compiler.core.common.type.ObjectStamp; 34 import org.graalvm.compiler.core.common.type.Stamp; 35 import org.graalvm.compiler.core.common.type.StampFactory; 36 import org.graalvm.compiler.core.common.type.TypeReference; 37 import org.graalvm.compiler.graph.NodeClass; 38 import org.graalvm.compiler.graph.spi.CanonicalizerTool; 39 import org.graalvm.compiler.nodeinfo.NodeInfo; 40 import org.graalvm.compiler.nodes.LogicConstantNode; 41 import org.graalvm.compiler.nodes.LogicNegationNode; 42 import org.graalvm.compiler.nodes.LogicNode; 43 import org.graalvm.compiler.nodes.NodeView; 44 import org.graalvm.compiler.nodes.UnaryOpLogicNode; 45 import org.graalvm.compiler.nodes.ValueNode; 46 import org.graalvm.compiler.nodes.calc.IsNullNode; 47 import org.graalvm.compiler.nodes.extended.AnchoringNode; 48 import org.graalvm.compiler.nodes.spi.Lowerable; 49 import org.graalvm.compiler.nodes.spi.LoweringTool; 50 import org.graalvm.compiler.nodes.spi.Virtualizable; 51 import org.graalvm.compiler.nodes.spi.VirtualizerTool; 52 import org.graalvm.compiler.nodes.type.StampTool; 53 54 import jdk.vm.ci.meta.JavaTypeProfile; 55 import jdk.vm.ci.meta.TriState; 56 57 /** 58 * The {@code InstanceOfNode} represents an instanceof test. 59 */ 60 @NodeInfo(cycles = CYCLES_8, size = SIZE_8) 61 public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable { 62 public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class); 63 64 private final ObjectStamp checkedStamp; 65 66 private JavaTypeProfile profile; 67 @OptionalInput(Anchor) protected AnchoringNode anchor; 68 69 private InstanceOfNode(ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) { 70 this(TYPE, checkedStamp, object, profile, anchor); 71 } 72 73 protected InstanceOfNode(NodeClass<? extends InstanceOfNode> c, ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) { 74 super(c, object); 201 202 public boolean allowsNull() { 203 return !checkedStamp.nonNull(); 204 } 205 206 public void setProfile(JavaTypeProfile typeProfile, AnchoringNode anchor) { 207 this.profile = typeProfile; 208 updateUsagesInterface(this.anchor, anchor); 209 this.anchor = anchor; 210 assert (profile == null) || (anchor != null) : "profiles must be anchored"; 211 } 212 213 public AnchoringNode getAnchor() { 214 return anchor; 215 } 216 217 public ObjectStamp getCheckedStamp() { 218 return checkedStamp; 219 } 220 221 @Override 222 public TriState implies(boolean thisNegated, LogicNode other) { 223 if (other instanceof InstanceOfNode) { 224 InstanceOfNode instanceOfNode = (InstanceOfNode) other; 225 if (instanceOfNode.getValue() == getValue()) { 226 if (thisNegated) { 227 // !X => Y 228 if (this.getCheckedStamp().meet(instanceOfNode.getCheckedStamp()).equals(this.getCheckedStamp())) { 229 return TriState.get(false); 230 } 231 } else { 232 // X => Y 233 if (instanceOfNode.getCheckedStamp().meet(this.getCheckedStamp()).equals(instanceOfNode.getCheckedStamp())) { 234 return TriState.get(true); 235 } 236 } 237 } 238 } 239 return super.implies(thisNegated, other); 240 } | 26 27 import static org.graalvm.compiler.nodeinfo.InputType.Anchor; 28 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; 29 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; 30 31 import java.util.Objects; 32 33 import org.graalvm.compiler.core.common.type.ObjectStamp; 34 import org.graalvm.compiler.core.common.type.Stamp; 35 import org.graalvm.compiler.core.common.type.StampFactory; 36 import org.graalvm.compiler.core.common.type.TypeReference; 37 import org.graalvm.compiler.graph.NodeClass; 38 import org.graalvm.compiler.graph.spi.CanonicalizerTool; 39 import org.graalvm.compiler.nodeinfo.NodeInfo; 40 import org.graalvm.compiler.nodes.LogicConstantNode; 41 import org.graalvm.compiler.nodes.LogicNegationNode; 42 import org.graalvm.compiler.nodes.LogicNode; 43 import org.graalvm.compiler.nodes.NodeView; 44 import org.graalvm.compiler.nodes.UnaryOpLogicNode; 45 import org.graalvm.compiler.nodes.ValueNode; 46 import org.graalvm.compiler.nodes.calc.ConditionalNode; 47 import org.graalvm.compiler.nodes.calc.IsNullNode; 48 import org.graalvm.compiler.nodes.extended.AnchoringNode; 49 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; 50 import org.graalvm.compiler.nodes.spi.Lowerable; 51 import org.graalvm.compiler.nodes.spi.LoweringTool; 52 import org.graalvm.compiler.nodes.spi.Virtualizable; 53 import org.graalvm.compiler.nodes.spi.VirtualizerTool; 54 import org.graalvm.compiler.nodes.type.StampTool; 55 56 import jdk.vm.ci.meta.JavaKind; 57 import jdk.vm.ci.meta.JavaTypeProfile; 58 import jdk.vm.ci.meta.ResolvedJavaMethod; 59 import jdk.vm.ci.meta.ResolvedJavaType; 60 import jdk.vm.ci.meta.TriState; 61 62 /** 63 * The {@code InstanceOfNode} represents an instanceof test. 64 */ 65 @NodeInfo(cycles = CYCLES_8, size = SIZE_8) 66 public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable { 67 public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class); 68 69 private final ObjectStamp checkedStamp; 70 71 private JavaTypeProfile profile; 72 @OptionalInput(Anchor) protected AnchoringNode anchor; 73 74 private InstanceOfNode(ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) { 75 this(TYPE, checkedStamp, object, profile, anchor); 76 } 77 78 protected InstanceOfNode(NodeClass<? extends InstanceOfNode> c, ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) { 79 super(c, object); 206 207 public boolean allowsNull() { 208 return !checkedStamp.nonNull(); 209 } 210 211 public void setProfile(JavaTypeProfile typeProfile, AnchoringNode anchor) { 212 this.profile = typeProfile; 213 updateUsagesInterface(this.anchor, anchor); 214 this.anchor = anchor; 215 assert (profile == null) || (anchor != null) : "profiles must be anchored"; 216 } 217 218 public AnchoringNode getAnchor() { 219 return anchor; 220 } 221 222 public ObjectStamp getCheckedStamp() { 223 return checkedStamp; 224 } 225 226 @NodeIntrinsic 227 public static native boolean doInstanceof(@ConstantNodeParameter ResolvedJavaType type, Object object); 228 229 @SuppressWarnings("unused") 230 static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ResolvedJavaType type, ValueNode object) { 231 InstanceOfNode node = new InstanceOfNode(StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), type)), object, null, null); 232 node = b.add(node); 233 b.addPush(JavaKind.Int, ConditionalNode.create(node, NodeView.DEFAULT)); 234 return true; 235 } 236 237 @Override 238 public TriState implies(boolean thisNegated, LogicNode other) { 239 if (other instanceof InstanceOfNode) { 240 InstanceOfNode instanceOfNode = (InstanceOfNode) other; 241 if (instanceOfNode.getValue() == getValue()) { 242 if (thisNegated) { 243 // !X => Y 244 if (this.getCheckedStamp().meet(instanceOfNode.getCheckedStamp()).equals(this.getCheckedStamp())) { 245 return TriState.get(false); 246 } 247 } else { 248 // X => Y 249 if (instanceOfNode.getCheckedStamp().meet(this.getCheckedStamp()).equals(instanceOfNode.getCheckedStamp())) { 250 return TriState.get(true); 251 } 252 } 253 } 254 } 255 return super.implies(thisNegated, other); 256 } |