Mercurial > hg > graal-compiler
comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java @ 16565:2b63e51e7789
Move invokeKind into CallTragetNode from its subclasses
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Mon, 14 Jul 2014 14:17:33 +0200 |
parents | 688f84e397a3 |
children | 5d468add216f |
comparison
equal
deleted
inserted
replaced
16564:688f84e397a3 | 16565:2b63e51e7789 |
---|---|
28 import com.oracle.graal.graph.spi.*; | 28 import com.oracle.graal.graph.spi.*; |
29 import com.oracle.graal.nodes.*; | 29 import com.oracle.graal.nodes.*; |
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 | |
34 private final JavaType returnType; | 33 private final JavaType returnType; |
35 private InvokeKind invokeKind; | |
36 | 34 |
37 /** | 35 /** |
38 * @param arguments | 36 * @param arguments |
39 */ | 37 */ |
40 public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) { | 38 public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) { |
41 super(arguments, targetMethod); | 39 super(arguments, targetMethod, invokeKind); |
42 this.invokeKind = invokeKind; | |
43 this.returnType = returnType; | 40 this.returnType = returnType; |
44 } | |
45 | |
46 public InvokeKind invokeKind() { | |
47 return invokeKind; | |
48 } | |
49 | |
50 public void setInvokeKind(InvokeKind kind) { | |
51 this.invokeKind = kind; | |
52 } | 41 } |
53 | 42 |
54 /** | 43 /** |
55 * Gets the instruction that produces the receiver object for this invocation, if any. | 44 * Gets the instruction that produces the receiver object for this invocation, if any. |
56 * | 45 * |
82 public boolean verify() { | 71 public boolean verify() { |
83 assert usages().count() <= 1 : "call target may only be used by a single invoke"; | 72 assert usages().count() <= 1 : "call target may only be used by a single invoke"; |
84 for (Node n : usages()) { | 73 for (Node n : usages()) { |
85 assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n); | 74 assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n); |
86 } | 75 } |
87 if (invokeKind == InvokeKind.Special || invokeKind == InvokeKind.Static) { | 76 if (invokeKind() == InvokeKind.Special || invokeKind() == InvokeKind.Static) { |
88 assertFalse(targetMethod().isAbstract(), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod()); | 77 assertFalse(targetMethod().isAbstract(), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod()); |
89 } | 78 } |
90 if (invokeKind == InvokeKind.Static) { | 79 if (invokeKind() == InvokeKind.Static) { |
91 assertTrue(targetMethod().isStatic(), "static calls are only allowed for static methods (%s)", targetMethod()); | 80 assertTrue(targetMethod().isStatic(), "static calls are only allowed for static methods (%s)", targetMethod()); |
92 } else { | 81 } else { |
93 assertFalse(targetMethod().isStatic(), "static calls are only allowed for non-static methods (%s)", targetMethod()); | 82 assertFalse(targetMethod().isStatic(), "static calls are only allowed for non-static methods (%s)", targetMethod()); |
94 } | 83 } |
95 return super.verify(); | 84 return super.verify(); |
104 } | 93 } |
105 } | 94 } |
106 | 95 |
107 @Override | 96 @Override |
108 public Node canonical(CanonicalizerTool tool) { | 97 public Node canonical(CanonicalizerTool tool) { |
109 if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { | 98 if (invokeKind() == InvokeKind.Interface || invokeKind() == InvokeKind.Virtual) { |
110 // attempt to devirtualize the call | 99 // attempt to devirtualize the call |
111 | 100 |
112 // check for trivial cases (e.g. final methods, nonvirtual methods) | 101 // check for trivial cases (e.g. final methods, nonvirtual methods) |
113 if (targetMethod().canBeStaticallyBound()) { | 102 if (targetMethod().canBeStaticallyBound()) { |
114 invokeKind = InvokeKind.Special; | 103 setInvokeKind(InvokeKind.Special); |
115 return this; | 104 return this; |
116 } | 105 } |
117 | 106 |
118 // check if the type of the receiver can narrow the result | 107 // check if the type of the receiver can narrow the result |
119 ValueNode receiver = receiver(); | 108 ValueNode receiver = receiver(); |
123 * either the holder class is exact, or the receiver object has an exact type, or | 112 * either the holder class is exact, or the receiver object has an exact type, or |
124 * it's an array type | 113 * it's an array type |
125 */ | 114 */ |
126 ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod(), invoke().getContextType()); | 115 ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod(), invoke().getContextType()); |
127 if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) { | 116 if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) { |
128 invokeKind = InvokeKind.Special; | 117 setInvokeKind(InvokeKind.Special); |
129 setTargetMethod(resolvedMethod); | 118 setTargetMethod(resolvedMethod); |
130 return this; | 119 return this; |
131 } | 120 } |
132 if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) { | 121 if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) { |
133 ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype(); | 122 ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype(); |
134 if (uniqueConcreteType != null) { | 123 if (uniqueConcreteType != null) { |
135 ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveMethod(targetMethod(), invoke().getContextType()); | 124 ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveMethod(targetMethod(), invoke().getContextType()); |
136 if (methodFromUniqueType != null) { | 125 if (methodFromUniqueType != null) { |
137 tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType); | 126 tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType); |
138 invokeKind = InvokeKind.Special; | 127 setInvokeKind(InvokeKind.Special); |
139 setTargetMethod(methodFromUniqueType); | 128 setTargetMethod(methodFromUniqueType); |
140 return this; | 129 return this; |
141 } | 130 } |
142 } | 131 } |
143 | 132 |
144 ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod()); | 133 ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod()); |
145 if (uniqueConcreteMethod != null) { | 134 if (uniqueConcreteMethod != null) { |
146 tool.assumptions().recordConcreteMethod(targetMethod(), type, uniqueConcreteMethod); | 135 tool.assumptions().recordConcreteMethod(targetMethod(), type, uniqueConcreteMethod); |
147 invokeKind = InvokeKind.Special; | 136 setInvokeKind(InvokeKind.Special); |
148 setTargetMethod(uniqueConcreteMethod); | 137 setTargetMethod(uniqueConcreteMethod); |
149 return this; | 138 return this; |
150 } | 139 } |
151 } | 140 } |
152 } | 141 } |