comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java @ 16564:688f84e397a3

Move the target method from MethodCallTargetNode and LoweredCallTargetNode to their superclass CallTargetNode
author Gilles Duboscq <duboscq@ssw.jku.at>
date Mon, 14 Jul 2014 14:00:55 +0200
parents 1e63cb55f61d
children 2b63e51e7789
comparison
equal deleted inserted replaced
16563:1e63cb55f61d 16564:688f84e397a3
30 import com.oracle.graal.nodes.type.*; 30 import com.oracle.graal.nodes.type.*;
31 31
32 public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Canonicalizable { 32 public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Canonicalizable {
33 33
34 private final JavaType returnType; 34 private final JavaType returnType;
35 private ResolvedJavaMethod targetMethod;
36 private InvokeKind invokeKind; 35 private InvokeKind invokeKind;
37 36
38 /** 37 /**
39 * @param arguments 38 * @param arguments
40 */ 39 */
41 public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) { 40 public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) {
42 super(arguments); 41 super(arguments, targetMethod);
43 this.invokeKind = invokeKind; 42 this.invokeKind = invokeKind;
44 this.returnType = returnType; 43 this.returnType = returnType;
45 this.targetMethod = targetMethod;
46 }
47
48 /**
49 * Gets the target method for this invocation instruction.
50 *
51 * @return the target method
52 */
53 public ResolvedJavaMethod targetMethod() {
54 return targetMethod;
55 } 44 }
56 45
57 public InvokeKind invokeKind() { 46 public InvokeKind invokeKind() {
58 return invokeKind; 47 return invokeKind;
59 } 48 }
60 49
61 public void setInvokeKind(InvokeKind kind) { 50 public void setInvokeKind(InvokeKind kind) {
62 this.invokeKind = kind; 51 this.invokeKind = kind;
63 }
64
65 public void setTargetMethod(ResolvedJavaMethod method) {
66 targetMethod = method;
67 } 52 }
68 53
69 /** 54 /**
70 * Gets the instruction that produces the receiver object for this invocation, if any. 55 * Gets the instruction that produces the receiver object for this invocation, if any.
71 * 56 *
98 assert usages().count() <= 1 : "call target may only be used by a single invoke"; 83 assert usages().count() <= 1 : "call target may only be used by a single invoke";
99 for (Node n : usages()) { 84 for (Node n : usages()) {
100 assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n); 85 assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n);
101 } 86 }
102 if (invokeKind == InvokeKind.Special || invokeKind == InvokeKind.Static) { 87 if (invokeKind == InvokeKind.Special || invokeKind == InvokeKind.Static) {
103 assertFalse(targetMethod.isAbstract(), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod); 88 assertFalse(targetMethod().isAbstract(), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod());
104 } 89 }
105 if (invokeKind == InvokeKind.Static) { 90 if (invokeKind == InvokeKind.Static) {
106 assertTrue(targetMethod.isStatic(), "static calls are only allowed for static methods (%s)", targetMethod); 91 assertTrue(targetMethod().isStatic(), "static calls are only allowed for static methods (%s)", targetMethod());
107 } else { 92 } else {
108 assertFalse(targetMethod.isStatic(), "static calls are only allowed for non-static methods (%s)", targetMethod); 93 assertFalse(targetMethod().isStatic(), "static calls are only allowed for non-static methods (%s)", targetMethod());
109 } 94 }
110 return super.verify(); 95 return super.verify();
111 } 96 }
112 97
113 @Override 98 @Override
123 public Node canonical(CanonicalizerTool tool) { 108 public Node canonical(CanonicalizerTool tool) {
124 if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { 109 if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
125 // attempt to devirtualize the call 110 // attempt to devirtualize the call
126 111
127 // check for trivial cases (e.g. final methods, nonvirtual methods) 112 // check for trivial cases (e.g. final methods, nonvirtual methods)
128 if (targetMethod.canBeStaticallyBound()) { 113 if (targetMethod().canBeStaticallyBound()) {
129 invokeKind = InvokeKind.Special; 114 invokeKind = InvokeKind.Special;
130 return this; 115 return this;
131 } 116 }
132 117
133 // check if the type of the receiver can narrow the result 118 // check if the type of the receiver can narrow the result
136 if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) { 121 if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) {
137 /* 122 /*
138 * either the holder class is exact, or the receiver object has an exact type, or 123 * either the holder class is exact, or the receiver object has an exact type, or
139 * it's an array type 124 * it's an array type
140 */ 125 */
141 ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod, invoke().getContextType()); 126 ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod(), invoke().getContextType());
142 if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) { 127 if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) {
143 invokeKind = InvokeKind.Special; 128 invokeKind = InvokeKind.Special;
144 targetMethod = resolvedMethod; 129 setTargetMethod(resolvedMethod);
145 return this; 130 return this;
146 } 131 }
147 if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) { 132 if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) {
148 ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype(); 133 ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype();
149 if (uniqueConcreteType != null) { 134 if (uniqueConcreteType != null) {
150 ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveMethod(targetMethod, invoke().getContextType()); 135 ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveMethod(targetMethod(), invoke().getContextType());
151 if (methodFromUniqueType != null) { 136 if (methodFromUniqueType != null) {
152 tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType); 137 tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType);
153 invokeKind = InvokeKind.Special; 138 invokeKind = InvokeKind.Special;
154 targetMethod = methodFromUniqueType; 139 setTargetMethod(methodFromUniqueType);
155 return this; 140 return this;
156 } 141 }
157 } 142 }
158 143
159 ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod); 144 ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod());
160 if (uniqueConcreteMethod != null) { 145 if (uniqueConcreteMethod != null) {
161 tool.assumptions().recordConcreteMethod(targetMethod, type, uniqueConcreteMethod); 146 tool.assumptions().recordConcreteMethod(targetMethod(), type, uniqueConcreteMethod);
162 invokeKind = InvokeKind.Special; 147 invokeKind = InvokeKind.Special;
163 targetMethod = uniqueConcreteMethod; 148 setTargetMethod(uniqueConcreteMethod);
164 return this; 149 return this;
165 } 150 }
166 } 151 }
167 } 152 }
168 } 153 }
169 return this; 154 return this;
170 } 155 }
171 156
172 @Override 157 @Override
173 public Stamp returnStamp() { 158 public Stamp returnStamp() {
174 Kind returnKind = targetMethod.getSignature().getReturnKind(); 159 Kind returnKind = targetMethod().getSignature().getReturnKind();
175 if (returnKind == Kind.Object && returnType instanceof ResolvedJavaType) { 160 if (returnKind == Kind.Object && returnType instanceof ResolvedJavaType) {
176 return StampFactory.declared((ResolvedJavaType) returnType); 161 return StampFactory.declared((ResolvedJavaType) returnType);
177 } else { 162 } else {
178 return StampFactory.forKind(returnKind); 163 return StampFactory.forKind(returnKind);
179 } 164 }
191 return targetMethod().format("%h.%n"); 176 return targetMethod().format("%h.%n");
192 } 177 }
193 178
194 public static MethodCallTargetNode find(StructuredGraph graph, ResolvedJavaMethod method) { 179 public static MethodCallTargetNode find(StructuredGraph graph, ResolvedJavaMethod method) {
195 for (MethodCallTargetNode target : graph.getNodes(MethodCallTargetNode.class)) { 180 for (MethodCallTargetNode target : graph.getNodes(MethodCallTargetNode.class)) {
196 if (target.targetMethod.equals(method)) { 181 if (target.targetMethod().equals(method)) {
197 return target; 182 return target;
198 } 183 }
199 } 184 }
200 return null; 185 return null;
201 } 186 }