001/*
002 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.nodes.java;
024
025import jdk.internal.jvmci.meta.*;
026
027import com.oracle.graal.graph.*;
028import com.oracle.graal.graph.spi.*;
029import com.oracle.graal.nodeinfo.*;
030import com.oracle.graal.nodes.*;
031import com.oracle.graal.nodes.spi.*;
032
033/**
034 * The {@code ClassIsAssignableFromNode} represents a type check against {@link Class} instead of
035 * against instances. This is used, for instance, to intrinsify
036 * {@link Class#isAssignableFrom(Class)} .
037 */
038@NodeInfo
039public final class ClassIsAssignableFromNode extends LogicNode implements Canonicalizable.Binary<ValueNode>, Lowerable {
040
041    public static final NodeClass<ClassIsAssignableFromNode> TYPE = NodeClass.create(ClassIsAssignableFromNode.class);
042    @Input ValueNode thisClass;
043    @Input ValueNode otherClass;
044
045    public ClassIsAssignableFromNode(ValueNode thisClass, ValueNode otherClass) {
046        super(TYPE);
047        this.thisClass = thisClass;
048        this.otherClass = otherClass;
049    }
050
051    public Object getThisClass() {
052        return thisClass;
053    }
054
055    public Object getOtherClass() {
056        return otherClass;
057    }
058
059    @Override
060    public ValueNode getX() {
061        return thisClass;
062    }
063
064    @Override
065    public ValueNode getY() {
066        return otherClass;
067    }
068
069    @Override
070    public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
071        if (forX.isConstant() && forY.isConstant()) {
072            ConstantReflectionProvider constantReflection = tool.getConstantReflection();
073            ResolvedJavaType thisType = constantReflection.asJavaType(forX.asJavaConstant());
074            ResolvedJavaType otherType = constantReflection.asJavaType(forY.asJavaConstant());
075            if (thisType != null && otherType != null) {
076                return LogicConstantNode.forBoolean(thisType.isAssignableFrom(otherType));
077            }
078        }
079        return this;
080    }
081
082    @Override
083    public void lower(LoweringTool tool) {
084        tool.getLowerer().lower(this, tool);
085    }
086
087}