# HG changeset patch # User Christian Wimmer # Date 1395779552 25200 # Node ID 7544068e1a91f38cd9c2cf9d0fe46728ea1a3d88 # Parent 65b005b5882557a86cdfd1140390fec6075b4a5e Perform de-virtualization of calls only in canonicalizer and not in graph builder diff -r 65b005b58825 -r 7544068e1a91 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 25 11:50:57 2014 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 25 13:32:32 2014 -0700 @@ -321,6 +321,7 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + canonicalizer.apply(graph, context); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); if (loopPeeling) { new LoopTransformHighPhase().apply(graph); diff -r 65b005b58825 -r 7544068e1a91 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 25 11:50:57 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 25 13:32:32 2014 -0700 @@ -1113,7 +1113,7 @@ private void genInvokeInterface(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); - genInvokeIndirect(InvokeKind.Interface, (ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args); } else { handleUnresolvedInvoke(target, InvokeKind.Interface); } @@ -1148,7 +1148,7 @@ } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver)); if (hasReceiver) { - genInvokeIndirect(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); } else { appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); } @@ -1163,47 +1163,12 @@ assert target != null; assert target.getSignature() != null; ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); - invokeDirect((ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args); } else { handleUnresolvedInvoke(target, InvokeKind.Special); } } - private void genInvokeIndirect(InvokeKind invokeKind, ResolvedJavaMethod target, ValueNode[] args) { - ValueNode receiver = args[0]; - // attempt to devirtualize the call - ResolvedJavaType klass = target.getDeclaringClass(); - - // 0. check for trivial cases - if (target.canBeStaticallyBound()) { - // check for trivial cases (e.g. final methods, nonvirtual methods) - invokeDirect(target, args); - return; - } - // 1. check if the exact type of the receiver can be determined - ResolvedJavaType exact = klass.asExactType(); - if (exact == null && receiver.stamp() instanceof ObjectStamp) { - ObjectStamp receiverStamp = (ObjectStamp) receiver.stamp(); - if (receiverStamp.isExactType()) { - exact = receiverStamp.type(); - } - } - if (exact != null) { - // either the holder class is exact, or the receiver object has an exact type - ResolvedJavaMethod exactMethod = exact.resolveMethod(target); - if (exactMethod != null) { - invokeDirect(exactMethod, args); - return; - } - } - // devirtualization failed, produce an actual invokevirtual - appendInvoke(invokeKind, target, args); - } - - private void invokeDirect(ResolvedJavaMethod target, ValueNode[] args) { - appendInvoke(InvokeKind.Special, target, args); - } - private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) { Kind resultType = targetMethod.getSignature().getReturnKind(); if (DeoptALot.getValue()) { diff -r 65b005b58825 -r 7544068e1a91 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 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; } } }