changeset 18235:bb2c3f570e26

MethodCallTargetNode: simplify interface invokes to (guarded) virtual invoke on a single implementor, if there is one.
author Josef Eisl <josef.eisl@jku.at>
date Thu, 30 Oct 2014 15:02:36 +0100
parents e2578a7a79ae
children 6a05fba906be
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java
diffstat 1 files changed, 21 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Tue Nov 04 12:02:37 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Thu Oct 30 15:02:36 2014 +0100
@@ -145,6 +145,27 @@
                     }
                 }
             }
+            ResolvedJavaType receiverType = targetMethod().getDeclaringClass();
+            if (receiverType.isInterface()) {
+                ResolvedJavaType single = receiverType.getSingleImplementor();
+                if (single != null && !single.equals(receiverType)) {
+                    ResolvedJavaMethod newResolvedMethod = single.resolveMethod(targetMethod(), invoke().getContextType(), true);
+                    // TODO (je): we can not yet deal with default methods
+                    if (newResolvedMethod != null && !newResolvedMethod.isDefault()) {
+                        ProfilingInfo profilingInfo = invoke().getContextMethod().getProfilingInfo();
+                        JavaTypeProfile profile = profilingInfo.getTypeProfile(invoke().bci());
+                        LogicNode condition = graph().unique(InstanceOfNode.create(single, receiver, profile));
+                        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));
+                        PiNode piNode = graph().unique(PiNode.create(receiver, StampFactory.declared(single), guard));
+                        arguments().set(0, piNode);
+                        setInvokeKind(InvokeKind.Virtual);
+                        setTargetMethod(newResolvedMethod);
+                    }
+                }
+            }
         }
     }