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 org.graalvm.compiler.graph.Node; 28 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; 29 import org.graalvm.compiler.nodes.java.MethodCallTargetNode; 30 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint; 31 import org.graalvm.compiler.nodes.spi.Lowerable; 32 import org.graalvm.compiler.nodes.type.StampTool; 33 34 import jdk.vm.ci.meta.ResolvedJavaMethod; 35 import jdk.vm.ci.meta.ResolvedJavaType; 36 37 public interface Invoke extends StateSplit, Lowerable, MemoryCheckpoint.Single, DeoptimizingNode.DeoptDuring, FixedNodeInterface, Invokable { 38 39 FixedNode next(); 40 41 void setNext(FixedNode x); 42 43 CallTargetNode callTarget(); 44 45 @Override 46 int bci(); 47 48 Node predecessor(); 49 50 ValueNode classInit(); 51 52 void setClassInit(ValueNode node); 53 54 boolean useForInlining(); 55 56 void setUseForInlining(boolean value); 57 58 /** 59 * True if this invocation is almost certainly polymorphic, false when in doubt. 60 */ 61 boolean isPolymorphic(); 62 63 void setPolymorphic(boolean value); 64 65 @Override 66 default ResolvedJavaMethod getTargetMethod() { 67 return callTarget() != null ? callTarget().targetMethod() : null; 68 } 69 70 /** 71 * Returns the {@linkplain ResolvedJavaMethod method} from which this invoke is executed. This 72 * is the caller method and in the case of inlining may be different from the method of the 73 * graph this node is in. 74 * 75 * @return the method from which this invoke is executed. 76 */ 77 default ResolvedJavaMethod getContextMethod() { 78 FrameState state = stateAfter(); 79 if (state == null) { 80 state = stateDuring(); 81 } 82 return state.getMethod(); 83 } 84 85 /** 86 * Returns the {@linkplain ResolvedJavaType type} from which this invoke is executed. This is 87 * the declaring type of the caller method. 88 * 89 * @return the type from which this invoke is executed. 90 */ 91 default ResolvedJavaType getContextType() { 92 ResolvedJavaMethod contextMethod = getContextMethod(); 93 if (contextMethod == null) { 94 return null; 95 } 96 return contextMethod.getDeclaringClass(); 97 } 98 99 @Override 100 default void computeStateDuring(FrameState stateAfter) { 101 FrameState newStateDuring = stateAfter.duplicateModifiedDuringCall(bci(), asNode().getStackKind()); 102 setStateDuring(newStateDuring); 103 } 104 105 default ValueNode getReceiver() { 106 assert getInvokeKind().hasReceiver(); 107 return callTarget().arguments().get(0); 108 } 109 110 default ResolvedJavaType getReceiverType() { 111 ResolvedJavaType receiverType = StampTool.typeOrNull(getReceiver()); 112 if (receiverType == null) { 113 receiverType = ((MethodCallTargetNode) callTarget()).targetMethod().getDeclaringClass(); 114 } 115 return receiverType; 116 } 117 118 default InvokeKind getInvokeKind() { 119 return callTarget().invokeKind(); 120 } 121 122 void replaceBci(int newBci); 123 }