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 }