comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java @ 15102:175111728365

improve canBeStaticallyBound
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 14 Apr 2014 15:08:30 -0700
parents 8db6e76cb658
children 2c0cfbf454b5
comparison
equal deleted inserted replaced
15101:9f7eac122d61 15102:175111728365
53 this.targetMethod = targetMethod; 53 this.targetMethod = targetMethod;
54 } 54 }
55 55
56 /** 56 /**
57 * Gets the target method for this invocation instruction. 57 * Gets the target method for this invocation instruction.
58 * 58 *
59 * @return the target method 59 * @return the target method
60 */ 60 */
61 public ResolvedJavaMethod targetMethod() { 61 public ResolvedJavaMethod targetMethod() {
62 return targetMethod; 62 return targetMethod;
63 } 63 }
74 targetMethod = method; 74 targetMethod = method;
75 } 75 }
76 76
77 /** 77 /**
78 * Gets the instruction that produces the receiver object for this invocation, if any. 78 * Gets the instruction that produces the receiver object for this invocation, if any.
79 * 79 *
80 * @return the instruction that produces the receiver object for this invocation if any, 80 * @return the instruction that produces the receiver object for this invocation if any,
81 * {@code null} if this invocation does not take a receiver object 81 * {@code null} if this invocation does not take a receiver object
82 */ 82 */
83 public ValueNode receiver() { 83 public ValueNode receiver() {
84 return isStatic() ? null : arguments().get(0); 84 return isStatic() ? null : arguments().get(0);
85 } 85 }
86 86
87 /** 87 /**
88 * Checks whether this is an invocation of a static method. 88 * Checks whether this is an invocation of a static method.
89 * 89 *
90 * @return {@code true} if the invocation is a static invocation 90 * @return {@code true} if the invocation is a static invocation
91 */ 91 */
92 public boolean isStatic() { 92 public boolean isStatic() {
93 return invokeKind() == InvokeKind.Static; 93 return invokeKind() == InvokeKind.Static;
94 } 94 }
136 if (targetMethod.canBeStaticallyBound()) { 136 if (targetMethod.canBeStaticallyBound()) {
137 invokeKind = InvokeKind.Special; 137 invokeKind = InvokeKind.Special;
138 return this; 138 return this;
139 } 139 }
140 140
141 // check if the exact type of the receiver can be determined 141 assert targetMethod.getDeclaringClass().asExactType() == null : "should have been handled by canBeStaticallyBound";
142
143 // check if the type of the receiver can narrow the result
142 ValueNode receiver = receiver(); 144 ValueNode receiver = receiver();
143 ResolvedJavaType exact = targetMethod.getDeclaringClass().asExactType(); 145 ResolvedJavaType type = ObjectStamp.typeOrNull(receiver);
144 if (exact == null && ObjectStamp.isExactType(receiver)) { 146 if (type != null) {
145 exact = ObjectStamp.typeOrNull(receiver);
146 }
147 if (exact != null) {
148 // either the holder class is exact, or the receiver object has an exact type 147 // either the holder class is exact, or the receiver object has an exact type
149 ResolvedJavaMethod exactMethod = exact.resolveMethod(targetMethod); 148 ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod);
150 if (exactMethod != null) { 149 if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || ObjectStamp.isExactType(receiver))) {
151 invokeKind = InvokeKind.Special; 150 invokeKind = InvokeKind.Special;
152 targetMethod = exactMethod; 151 targetMethod = resolvedMethod;
153 return this; 152 return this;
154 } 153 }
155 } 154 }
156 } 155 }
157 return this; 156 return this;