Mercurial > hg > graal-compiler
comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java @ 18314:3cc813ce3cea
MethodCallTargetNode: document the single implementor optimization.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Mon, 10 Nov 2014 11:31:41 +0100 |
parents | 6b8bceeecb30 |
children | c7cd54360119 |
comparison
equal
deleted
inserted
replaced
18313:6b8bceeecb30 | 18314:3cc813ce3cea |
---|---|
147 setTargetMethod(uniqueConcreteMethod); | 147 setTargetMethod(uniqueConcreteMethod); |
148 return; | 148 return; |
149 } | 149 } |
150 } | 150 } |
151 } | 151 } |
152 // try to turn a interface call into a virtual call | |
152 ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass(); | 153 ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass(); |
153 /* | 154 /* |
154 * We need to check the invoke kind to avoid recursive simplification for default | 155 * We need to check the invoke kind to avoid recursive simplification for virtual |
155 * methods calls. | 156 * interface methods calls. |
156 */ | 157 */ |
157 if (declaredReceiverType.isInterface() && !invokeKind().equals(InvokeKind.Virtual)) { | 158 if (declaredReceiverType.isInterface() && !invokeKind().equals(InvokeKind.Virtual)) { |
158 ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor(); | 159 ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor(); |
159 if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) { | 160 if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) { |
160 ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true); | 161 ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true); |
161 if (singleImplementorMethod != null) { | 162 if (singleImplementorMethod != null) { |
163 assert graph().getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal() : "Graph already fixed!"; | |
164 /** | |
165 * We have an invoke on an interface with a single implementor. We can | |
166 * replace this with an invoke virtual. | |
167 * | |
168 * To do so we need to ensure two properties: 1) the receiver must implement | |
169 * the interface (declaredReceiverType). The verifier does not prove this so | |
170 * we need a dynamic check. 2) we need to ensure that there is still only | |
171 * one implementor of this interface, i.e. that we are calling the right | |
172 * method. We could do this with an assumption but as we need an instanceof | |
173 * check anyway we can verify both properties by checking of the receiver is | |
174 * an instance of the single implementor. | |
175 */ | |
162 LogicNode condition = graph().unique(InstanceOfNode.create(singleImplementor, receiver, getProfile())); | 176 LogicNode condition = graph().unique(InstanceOfNode.create(singleImplementor, receiver, getProfile())); |
163 assert graph().getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal() : "Graph already fixed!"; | |
164 GuardNode guard = graph().unique( | 177 GuardNode guard = graph().unique( |
165 GuardNode.create(condition, BeginNode.prevBegin(invoke().asNode()), DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, | 178 GuardNode.create(condition, BeginNode.prevBegin(invoke().asNode()), DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, |
166 false, JavaConstant.NULL_OBJECT)); | 179 false, JavaConstant.NULL_OBJECT)); |
167 PiNode piNode = graph().unique(PiNode.create(receiver, StampFactory.declared(singleImplementor), guard)); | 180 PiNode piNode = graph().unique(PiNode.create(receiver, StampFactory.declared(singleImplementor), guard)); |
168 arguments().set(0, piNode); | 181 arguments().set(0, piNode); |