1/*
2 * Copyright (c) 2014, 2016, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.nodes.java;
24
25import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_30;
26import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_30;
27
28import org.graalvm.compiler.core.common.type.Stamp;
29import org.graalvm.compiler.graph.Node;
30import org.graalvm.compiler.graph.NodeClass;
31import org.graalvm.compiler.graph.spi.Canonicalizable;
32import org.graalvm.compiler.graph.spi.CanonicalizerTool;
33import org.graalvm.compiler.nodeinfo.NodeInfo;
34import org.graalvm.compiler.nodes.BinaryOpLogicNode;
35import org.graalvm.compiler.nodes.LogicConstantNode;
36import org.graalvm.compiler.nodes.ValueNode;
37import org.graalvm.compiler.nodes.spi.Lowerable;
38import org.graalvm.compiler.nodes.spi.LoweringTool;
39
40import jdk.vm.ci.meta.ConstantReflectionProvider;
41import jdk.vm.ci.meta.ResolvedJavaType;
42import jdk.vm.ci.meta.TriState;
43
44/**
45 * The {@code ClassIsAssignableFromNode} represents a type check against {@link Class} instead of
46 * against instances. This is used, for instance, to intrinsify
47 * {@link Class#isAssignableFrom(Class)} .
48 */
49@NodeInfo(cycles = CYCLES_30, size = SIZE_30)
50public final class ClassIsAssignableFromNode extends BinaryOpLogicNode implements Canonicalizable.Binary<ValueNode>, Lowerable {
51
52    public static final NodeClass<ClassIsAssignableFromNode> TYPE = NodeClass.create(ClassIsAssignableFromNode.class);
53
54    public ClassIsAssignableFromNode(ValueNode thisClass, ValueNode otherClass) {
55        super(TYPE, thisClass, otherClass);
56    }
57
58    public Object getThisClass() {
59        return getX();
60    }
61
62    public Object getOtherClass() {
63        return getY();
64    }
65
66    @Override
67    public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
68        if (forX.isConstant() && forY.isConstant()) {
69            ConstantReflectionProvider constantReflection = tool.getConstantReflection();
70            ResolvedJavaType thisType = constantReflection.asJavaType(forX.asJavaConstant());
71            ResolvedJavaType otherType = constantReflection.asJavaType(forY.asJavaConstant());
72            if (thisType != null && otherType != null) {
73                return LogicConstantNode.forBoolean(thisType.isAssignableFrom(otherType));
74            }
75        }
76        return this;
77    }
78
79    @Override
80    public void lower(LoweringTool tool) {
81        tool.getLowerer().lower(this, tool);
82    }
83
84    @Override
85    public Stamp getSucceedingStampForX(boolean negated) {
86        return null;
87    }
88
89    @Override
90    public Stamp getSucceedingStampForY(boolean negated) {
91        return null;
92    }
93
94    @Override
95    public TriState tryFold(Stamp xStamp, Stamp yStamp) {
96        return TriState.UNKNOWN;
97    }
98
99}
100