# HG changeset patch # User Josef Eisl # Date 1415615501 -3600 # Node ID 3cc813ce3cea162f27e1f3b50dd12621afffa9d9 # Parent 6b8bceeecb309c7fa3f8dc8708117ecdf177af96 MethodCallTargetNode: document the single implementor optimization. diff -r 6b8bceeecb30 -r 3cc813ce3cea graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Nov 06 12:40:28 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Mon Nov 10 11:31:41 2014 +0100 @@ -149,18 +149,31 @@ } } } + // try to turn a interface call into a virtual call ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass(); /* - * We need to check the invoke kind to avoid recursive simplification for default - * methods calls. + * We need to check the invoke kind to avoid recursive simplification for virtual + * interface methods calls. */ if (declaredReceiverType.isInterface() && !invokeKind().equals(InvokeKind.Virtual)) { ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor(); if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) { ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true); if (singleImplementorMethod != null) { + assert graph().getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal() : "Graph already fixed!"; + /** + * We have an invoke on an interface with a single implementor. We can + * replace this with an invoke virtual. + * + * To do so we need to ensure two properties: 1) the receiver must implement + * the interface (declaredReceiverType). The verifier does not prove this so + * we need a dynamic check. 2) we need to ensure that there is still only + * one implementor of this interface, i.e. that we are calling the right + * method. We could do this with an assumption but as we need an instanceof + * check anyway we can verify both properties by checking of the receiver is + * an instance of the single implementor. + */ LogicNode condition = graph().unique(InstanceOfNode.create(singleImplementor, receiver, getProfile())); - assert graph().getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal() : "Graph already fixed!"; GuardNode guard = graph().unique( GuardNode.create(condition, BeginNode.prevBegin(invoke().asNode()), DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, false, JavaConstant.NULL_OBJECT));