Mercurial > hg > graal-compiler
diff graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java @ 14746:7544068e1a91
Perform de-virtualization of calls only in canonicalizer and not in graph builder
author | Christian Wimmer <christian.wimmer@oracle.com> |
---|---|
date | Tue, 25 Mar 2014 13:32:32 -0700 |
parents | fd7fcd2d2072 |
children | 8db6e76cb658 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Mar 25 11:50:57 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Mar 25 13:32:32 2014 -0700 @@ -126,15 +126,28 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (!isStatic()) { + if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { + // attempt to devirtualize the call + + // check for trivial cases (e.g. final methods, nonvirtual methods) + if (targetMethod.canBeStaticallyBound()) { + invokeKind = InvokeKind.Special; + return this; + } + + // check if the exact type of the receiver can be determined ValueNode receiver = receiver(); - if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) { - if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { - ResolvedJavaMethod method = ObjectStamp.typeOrNull(receiver).resolveMethod(targetMethod); - if (method != null) { - invokeKind = InvokeKind.Special; - targetMethod = method; - } + ResolvedJavaType exact = targetMethod.getDeclaringClass().asExactType(); + if (exact == null && ObjectStamp.isExactType(receiver)) { + exact = ObjectStamp.typeOrNull(receiver); + } + if (exact != null) { + // either the holder class is exact, or the receiver object has an exact type + ResolvedJavaMethod exactMethod = exact.resolveMethod(targetMethod); + if (exactMethod != null) { + invokeKind = InvokeKind.Special; + targetMethod = exactMethod; + return this; } } }