1 /* 2 * Copyright (c) 2011, 2018, 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 */ 23 24 25 package org.graalvm.compiler.nodes; 26 27 import static org.graalvm.compiler.nodeinfo.InputType.Extension; 28 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; 29 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; 30 31 import org.graalvm.compiler.core.common.type.Stamp; 32 import org.graalvm.compiler.core.common.type.StampFactory; 33 import org.graalvm.compiler.core.common.type.StampPair; 34 import org.graalvm.compiler.core.common.type.TypeReference; 35 import org.graalvm.compiler.graph.NodeClass; 36 import org.graalvm.compiler.graph.NodeInputList; 37 import org.graalvm.compiler.nodeinfo.NodeInfo; 38 import org.graalvm.compiler.nodes.spi.LIRLowerable; 39 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; 40 41 import jdk.vm.ci.meta.Assumptions; 42 import jdk.vm.ci.meta.JavaKind; 43 import jdk.vm.ci.meta.JavaType; 44 import jdk.vm.ci.meta.ResolvedJavaMethod; 45 import jdk.vm.ci.meta.ResolvedJavaType; 46 47 @NodeInfo(allowedUsageTypes = Extension, cycles = CYCLES_0, size = SIZE_0) 48 public abstract class CallTargetNode extends ValueNode implements LIRLowerable { 49 public static final NodeClass<CallTargetNode> TYPE = NodeClass.create(CallTargetNode.class); 50 51 public enum InvokeKind { 52 Interface(false), 53 Special(true), 54 Static(true), 55 Virtual(false); 56 57 InvokeKind(boolean direct) { 58 this.direct = direct; 59 } 60 61 private final boolean direct; 62 63 public boolean hasReceiver() { 64 return this != Static; 65 } 66 67 public boolean isDirect() { 68 return direct; 69 } 70 71 public boolean isIndirect() { 72 return !direct; 73 } 74 75 public boolean isInterface() { 76 return this == InvokeKind.Interface; 77 } 78 } 79 80 @Input protected NodeInputList<ValueNode> arguments; 81 protected ResolvedJavaMethod targetMethod; 82 protected InvokeKind invokeKind; 83 protected final StampPair returnStamp; 84 85 protected CallTargetNode(NodeClass<? extends CallTargetNode> c, ValueNode[] arguments, ResolvedJavaMethod targetMethod, InvokeKind invokeKind, StampPair returnStamp) { 86 super(c, StampFactory.forVoid()); 87 this.targetMethod = targetMethod; 88 this.invokeKind = invokeKind; 89 this.arguments = new NodeInputList<>(this, arguments); 90 this.returnStamp = returnStamp; 91 } 92 93 public NodeInputList<ValueNode> arguments() { 94 return arguments; 95 } 96 97 public static Stamp createReturnStamp(Assumptions assumptions, JavaType returnType) { 98 JavaKind kind = returnType.getJavaKind(); 99 if (kind == JavaKind.Object && returnType instanceof ResolvedJavaType) { 100 return StampFactory.object(TypeReference.create(assumptions, (ResolvedJavaType) returnType)); 101 } else { 102 return StampFactory.forKind(kind); 103 } 104 } 105 106 public StampPair returnStamp() { 107 return this.returnStamp; 108 } 109 110 /** 111 * A human-readable representation of the target, used for debug printing only. 112 */ 113 public abstract String targetName(); 114 115 @Override 116 public void generate(NodeLIRBuilderTool gen) { 117 // nop 118 } 119 120 public void setTargetMethod(ResolvedJavaMethod method) { 121 targetMethod = method; 122 } 123 124 /** 125 * Gets the target method for this invocation instruction. 126 * 127 * @return the target method 128 */ 129 public ResolvedJavaMethod targetMethod() { 130 return targetMethod; 131 } 132 133 public InvokeKind invokeKind() { 134 return invokeKind; 135 } 136 137 public void setInvokeKind(InvokeKind kind) { 138 this.invokeKind = kind; 139 } 140 141 public Invoke invoke() { 142 return (Invoke) this.usages().first(); 143 } 144 }