Mercurial > hg > graal-compiler
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 } |