changeset 22040:0751fdae4e7a

Merge.
author Doug Simon <doug.simon@oracle.com>
date Sat, 20 Jun 2015 09:00:58 +0200
parents 3e7ab72bac96 (current diff) 1f07c19e7d83 (diff)
children 56c50504d60d
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CleanTypeProfileProxyPhase.java mx.graal/suite.py
diffstat 30 files changed, 94 insertions(+), 253 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java	Sat Jun 20 09:00:58 2015 +0200
@@ -40,7 +40,11 @@
     protected AbstractObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) {
         super(nonNull, alwaysNull);
         this.type = type;
-        this.exactType = exactType;
+        if (!exactType && type != null && type.isLeaf()) {
+            this.exactType = true;
+        } else {
+            this.exactType = exactType;
+        }
     }
 
     protected abstract AbstractObjectStamp copyWith(ResolvedJavaType newType, boolean newExactType, boolean newNonNull, boolean newAlwaysNull);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Sat Jun 20 09:00:58 2015 +0200
@@ -131,7 +131,7 @@
 
     protected Suites createSuites() {
         Suites ret = backend.getSuites().createSuites();
-        ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(CleanTypeProfileProxyPhase.class);
+        ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(ConvertDeoptimizeToGuardPhase.class);
         PhaseSuite.findNextPhase(iter, CanonicalizerPhase.class);
         iter.add(new Phase("ComputeLoopFrequenciesPhase") {
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java	Sat Jun 20 09:00:58 2015 +0200
@@ -41,7 +41,6 @@
             appendPhase(canonicalizer);
         }
 
-        appendPhase(new CleanTypeProfileProxyPhase(canonicalizer));
         appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER));
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Sat Jun 20 09:00:58 2015 +0200
@@ -65,8 +65,6 @@
             }
         }
 
-        appendPhase(new CleanTypeProfileProxyPhase(canonicalizer));
-
         if (OptConvertDeoptsToGuards.getValue()) {
             appendPhase(new ConvertDeoptimizeToGuardPhase());
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Sat Jun 20 09:00:58 2015 +0200
@@ -519,7 +519,7 @@
                 if (nodes.isEmpty()) {
                     // Only insert the nodes if this is the first monitorenter being lowered.
                     JavaType returnType = initCounter.getMethod().getSignature().getReturnType(initCounter.getMethod().getDeclaringClass());
-                    MethodCallTargetNode callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, initCounter.getMethod(), new ValueNode[0], returnType));
+                    MethodCallTargetNode callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, initCounter.getMethod(), new ValueNode[0], returnType, null));
                     InvokeNode invoke = graph.add(new InvokeNode(callTarget, 0));
                     invoke.setStateAfter(graph.start().stateAfter());
                     graph.addAfterFixed(graph.start(), invoke);
@@ -532,7 +532,7 @@
                         returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass());
                         String msg = "unbalanced monitors in " + graph.method().format("%H.%n(%p)") + ", count = %d";
                         ConstantNode errMsg = ConstantNode.forConstant(tool.getConstantReflection().forString(msg), providers.getMetaAccess(), graph);
-                        callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType));
+                        callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType, null));
                         invoke = graph.add(new InvokeNode(callTarget, 0));
                         FrameState stateAfter = new FrameState(null, graph.method(), BytecodeFrame.AFTER_BCI, new ValueNode[0], new ValueNode[0], 0, new ValueNode[0], null, false, false);
                         invoke.setStateAfter(graph.add(stateAfter));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Sat Jun 20 09:00:58 2015 +0200
@@ -105,15 +105,18 @@
         graph.disableInlinedMethodRecording();
 
         if (SnippetGraphUnderConstruction != null) {
-            assert SnippetGraphUnderConstruction.get() == null;
+            assert SnippetGraphUnderConstruction.get() == null : SnippetGraphUnderConstruction.get().toString() + " " + graph;
             SnippetGraphUnderConstruction.set(graph);
         }
 
-        IntrinsicContext initialIntrinsicContext = new IntrinsicContext(method, method, INLINE_AFTER_PARSING);
-        new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph);
+        try {
+            IntrinsicContext initialIntrinsicContext = new IntrinsicContext(method, method, INLINE_AFTER_PARSING);
+            new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph);
 
-        if (SnippetGraphUnderConstruction != null) {
-            SnippetGraphUnderConstruction.set(null);
+        } finally {
+            if (SnippetGraphUnderConstruction != null) {
+                SnippetGraphUnderConstruction.set(null);
+            }
         }
 
         graph.setGuardsStage(GuardsStage.FLOATING_GUARDS);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Sat Jun 20 09:00:58 2015 +0200
@@ -28,7 +28,6 @@
 import static com.oracle.graal.graphbuilderconf.IntrinsicContext.CompilationContext.*;
 import static com.oracle.graal.java.BytecodeParser.Options.*;
 import static com.oracle.graal.nodes.type.StampTool.*;
-import static com.oracle.jvmci.code.TypeCheckHints.*;
 import static com.oracle.jvmci.common.JVMCIError.*;
 import static com.oracle.jvmci.meta.DeoptimizationAction.*;
 import static com.oracle.jvmci.meta.DeoptimizationReason.*;
@@ -1273,10 +1272,6 @@
         }
         if (invokeKind.hasReceiver()) {
             args[0] = emitExplicitExceptions(args[0], null);
-            if (invokeKind.isIndirect() && profilingInfo != null && this.optimisticOpts.useTypeCheckHints()) {
-                JavaTypeProfile profile = profilingInfo.getTypeProfile(bci());
-                args[0] = TypeProfileProxyNode.proxify(args[0], profile);
-            }
 
             if (args[0].isNullConstant()) {
                 append(new DeoptimizeNode(InvalidateRecompile, NullCheckException));
@@ -1311,7 +1306,11 @@
             currentInvokeKind = null;
         }
 
-        MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, targetMethod, args, returnType));
+        JavaTypeProfile profile = null;
+        if (invokeKind.isIndirect() && profilingInfo != null && this.optimisticOpts.useTypeCheckHints()) {
+            profile = profilingInfo.getTypeProfile(bci());
+        }
+        MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, targetMethod, args, returnType, profile));
 
         // be conservative if information was not recorded (could result in endless
         // recompiles otherwise)
@@ -1553,8 +1552,8 @@
         }
     }
 
-    protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, JavaType returnType) {
-        return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType);
+    protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, JavaType returnType, JavaTypeProfile profile) {
+        return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType, profile);
     }
 
     protected InvokeNode createInvoke(CallTargetNode callTarget, Kind resultType) {
@@ -2925,7 +2924,7 @@
     }
 
     private JavaTypeProfile getProfileForTypeCheck(ResolvedJavaType type) {
-        if (parsingIntrinsic() || profilingInfo == null || !optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) {
+        if (parsingIntrinsic() || profilingInfo == null || !optimisticOpts.useTypeCheckHints() || type.isLeaf()) {
             return null;
         } else {
             return profilingInfo.getTypeProfile(bci());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java	Sat Jun 20 09:00:02 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes;
-
-import java.util.*;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.jvmci.debug.*;
-import com.oracle.jvmci.meta.Assumptions.AssumptionResult;
-import com.oracle.jvmci.meta.*;
-
-/**
- * A node that attaches a type profile to a proxied input node.
- */
-@NodeInfo
-public final class TypeProfileProxyNode extends UnaryNode implements IterableNodeType, ValueProxy {
-
-    public static final NodeClass<TypeProfileProxyNode> TYPE = NodeClass.create(TypeProfileProxyNode.class);
-    protected final JavaTypeProfile profile;
-    protected transient ResolvedJavaType lastCheckedType;
-    protected transient JavaTypeProfile lastCheckedProfile;
-
-    public static ValueNode proxify(ValueNode object, JavaTypeProfile profile) {
-        if (StampTool.isExactType(object)) {
-            return object;
-        }
-        if (profile == null) {
-            // No profile, so create no node.
-            return object;
-        }
-        if (profile.getTypes().length == 0) {
-            // Only null profiling is not beneficial enough to keep the node around.
-            return object;
-        }
-        return object.graph().addWithoutUnique(new TypeProfileProxyNode(object, profile));
-    }
-
-    protected TypeProfileProxyNode(ValueNode value, JavaTypeProfile profile) {
-        super(TYPE, value.stamp(), value);
-        this.profile = profile;
-    }
-
-    public JavaTypeProfile getProfile() {
-        return profile;
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(getValue().stamp());
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        if (StampTool.isExactType(forValue)) {
-            // The profile is useless - we know the type!
-            return forValue;
-        } else if (forValue instanceof TypeProfileProxyNode) {
-            TypeProfileProxyNode other = (TypeProfileProxyNode) forValue;
-            JavaTypeProfile otherProfile = other.getProfile();
-            if (otherProfile == lastCheckedProfile) {
-                // We have already incorporated the knowledge about this profile => abort.
-                return this;
-            }
-            lastCheckedProfile = otherProfile;
-            JavaTypeProfile newProfile = this.profile.restrict(otherProfile);
-            if (newProfile.equals(otherProfile)) {
-                // We are useless - just use the other proxy node.
-                Debug.log("Canonicalize with other proxy node.");
-                return forValue;
-            }
-            if (newProfile != this.profile) {
-                Debug.log("Improved profile via other profile.");
-                return new TypeProfileProxyNode(forValue, newProfile);
-            }
-        } else if (StampTool.typeOrNull(forValue) != null) {
-            ResolvedJavaType type = StampTool.typeOrNull(forValue);
-            AssumptionResult<ResolvedJavaType> leafConcreteSubtype = type.findLeafConcreteSubtype();
-            if (leafConcreteSubtype != null) {
-                // Profile is useless => remove.
-                Debug.log("Profile useless, there is enough static type information available.");
-                return forValue;
-            }
-            if (Objects.equals(type, lastCheckedType)) {
-                // We have already incorporate the knowledge about this type => abort.
-                return this;
-            }
-            lastCheckedType = type;
-            JavaTypeProfile newProfile = this.profile.restrict(type, StampTool.isPointerNonNull(forValue));
-            if (newProfile != this.profile) {
-                Debug.log("Improved profile via static type information.");
-                if (newProfile.getTypes().length == 0) {
-                    // Only null profiling is not beneficial enough to keep the node around.
-                    return forValue;
-                }
-                return new TypeProfileProxyNode(forValue, newProfile);
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public ValueNode getOriginalNode() {
-        return getValue();
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Sat Jun 20 09:00:58 2015 +0200
@@ -140,7 +140,7 @@
             }
         }
 
-        if (type.isFinal() && nonNull) {
+        if (type.isLeaf() && nonNull) {
             return TypeCheckNode.create(type, object);
         }
         return null;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Sat Jun 20 09:00:58 2015 +0200
@@ -37,14 +37,17 @@
 public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Simplifiable {
     public static final NodeClass<MethodCallTargetNode> TYPE = NodeClass.create(MethodCallTargetNode.class);
     protected final JavaType returnType;
+    protected JavaTypeProfile profile;
 
-    public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) {
-        this(TYPE, invokeKind, targetMethod, arguments, returnType);
+    public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, JavaTypeProfile profile) {
+        this(TYPE, invokeKind, targetMethod, arguments, returnType, profile);
     }
 
-    protected MethodCallTargetNode(NodeClass<? extends MethodCallTargetNode> c, InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) {
+    protected MethodCallTargetNode(NodeClass<? extends MethodCallTargetNode> c, InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType,
+                    JavaTypeProfile profile) {
         super(c, arguments, targetMethod, invokeKind);
         this.returnType = returnType;
+        this.profile = profile;
     }
 
     /**
@@ -226,15 +229,8 @@
         }
     }
 
-    private JavaTypeProfile getProfile() {
-        assert !isStatic();
-        if (receiver() instanceof TypeProfileProxyNode) {
-            // get profile from TypeProfileProxy
-            return ((TypeProfileProxyNode) receiver()).getProfile();
-        }
-        // get profile from invoke()
-        ProfilingInfo profilingInfo = invoke().getContextMethod().getProfilingInfo();
-        return profilingInfo.getTypeProfile(invoke().bci());
+    public JavaTypeProfile getProfile() {
+        return profile;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java	Sat Jun 20 09:00:58 2015 +0200
@@ -149,7 +149,7 @@
             if (objectType != null) {
                 ResolvedJavaType instanceofType = type;
                 if (instanceofType.equals(objectType)) {
-                    if (objectStamp.nonNull() && (objectStamp.isExactType() || objectType.isFinal())) {
+                    if (objectStamp.nonNull() && (objectStamp.isExactType() || objectType.isLeaf())) {
                         return TriState.TRUE;
                     }
                 } else {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CleanTypeProfileProxyPhase.java	Sat Jun 20 09:00:02 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.phases.common;
-
-import com.oracle.graal.graph.Graph.NodeEventScope;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.util.*;
-import com.oracle.graal.phases.tiers.*;
-
-public class CleanTypeProfileProxyPhase extends BasePhase<PhaseContext> {
-
-    private CanonicalizerPhase canonicalizer;
-
-    public CleanTypeProfileProxyPhase(CanonicalizerPhase canonicalizer) {
-        this.canonicalizer = canonicalizer;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
-        HashSetNodeEventListener listener = new HashSetNodeEventListener();
-        try (NodeEventScope s = graph.trackNodeEvents(listener)) {
-            for (TypeProfileProxyNode proxy : graph.getNodes(TypeProfileProxyNode.TYPE)) {
-                graph.replaceFloating(proxy, proxy.getValue());
-            }
-        }
-        if (!listener.getNodes().isEmpty()) {
-            canonicalizer.applyIncremental(graph, context, listener.getNodes());
-        }
-        assert graph.getNodes(TypeProfileProxyNode.TYPE).count() == 0;
-    }
-}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sat Jun 20 09:00:58 2015 +0200
@@ -727,7 +727,7 @@
                     if (!Objects.equals(type, StampTool.typeOrNull(receiver))) {
                         ResolvedJavaMethod method = type.resolveConcreteMethod(callTarget.targetMethod(), invoke.getContextType());
                         if (method != null) {
-                            if (method.canBeStaticallyBound() || type.isFinal()) {
+                            if (method.canBeStaticallyBound() || type.isLeaf() || type.isArray()) {
                                 callTarget.setInvokeKind(InvokeKind.Special);
                                 callTarget.setTargetMethod(method);
                             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Sat Jun 20 09:00:58 2015 +0200
@@ -185,7 +185,8 @@
 
     public static void replaceInvokeCallTarget(Invoke invoke, StructuredGraph graph, InvokeKind invokeKind, ResolvedJavaMethod targetMethod) {
         MethodCallTargetNode oldCallTarget = (MethodCallTargetNode) invoke.callTarget();
-        MethodCallTargetNode newCallTarget = graph.add(new MethodCallTargetNode(invokeKind, targetMethod, oldCallTarget.arguments().toArray(new ValueNode[0]), oldCallTarget.returnType()));
+        MethodCallTargetNode newCallTarget = graph.add(new MethodCallTargetNode(invokeKind, targetMethod, oldCallTarget.arguments().toArray(new ValueNode[0]), oldCallTarget.returnType(),
+                        oldCallTarget.getProfile()));
         invoke.asNode().replaceFirstInput(oldCallTarget, newCallTarget);
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Sat Jun 20 09:00:58 2015 +0200
@@ -215,12 +215,8 @@
     }
 
     private InlineInfo getTypeCheckedInlineInfo(Invoke invoke, ResolvedJavaMethod targetMethod) {
-        JavaTypeProfile typeProfile;
-        ValueNode receiver = invoke.callTarget().arguments().get(0);
-        if (receiver instanceof TypeProfileProxyNode) {
-            TypeProfileProxyNode typeProfileProxyNode = (TypeProfileProxyNode) receiver;
-            typeProfile = typeProfileProxyNode.getProfile();
-        } else {
+        JavaTypeProfile typeProfile = ((MethodCallTargetNode) invoke.callTarget()).getProfile();
+        if (typeProfile == null) {
             InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "no type profile exists");
             return null;
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Sat Jun 20 09:00:58 2015 +0200
@@ -168,7 +168,7 @@
     }
 
     protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, JavaType returnType, @SuppressWarnings("unused") int bci) {
-        return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType);
+        return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType, null);
     }
 
     /**
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Sat Jun 20 09:00:58 2015 +0200
@@ -192,7 +192,7 @@
     }
 
     protected InvokeNode createInvoke() {
-        MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType));
+        MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType, null));
         InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
         if (stateAfter() != null) {
             invoke.setStateAfter(stateAfter().duplicate());
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ResolvedMethodHandleCallTargetNode.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ResolvedMethodHandleCallTargetNode.java	Sat Jun 20 09:00:58 2015 +0200
@@ -59,7 +59,7 @@
                     ValueNode[] originalArguments, JavaType originalReturnType) {
         if (jdkMajorVersion() >= 1 && jdkMinorVersion() >= 8 && jdkMicroVersion() >= 0 && jdkUpdateVersion() >= 60) {
             // https://bugs.openjdk.java.net/browse/JDK-8072008 is targeted for 8u60
-            return new MethodCallTargetNode(invokeKind, targetMethod, arguments, returnType);
+            return new MethodCallTargetNode(invokeKind, targetMethod, arguments, returnType, null);
         }
         return new ResolvedMethodHandleCallTargetNode(invokeKind, targetMethod, arguments, returnType, originalTargetMethod, originalArguments, originalReturnType);
     }
@@ -70,7 +70,7 @@
 
     protected ResolvedMethodHandleCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod,
                     ValueNode[] originalArguments, JavaType originalReturnType) {
-        super(TYPE, invokeKind, targetMethod, arguments, returnType);
+        super(TYPE, invokeKind, targetMethod, arguments, returnType, null);
         this.originalTargetMethod = originalTargetMethod;
         this.originalReturnType = originalReturnType;
         this.originalArguments = new NodeInputList<>(this, originalArguments);
@@ -80,7 +80,7 @@
     public void lower(LoweringTool tool) {
         InvokeKind replacementInvokeKind = originalTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special;
         MethodCallTargetNode replacement = graph().add(
-                        new MethodCallTargetNode(replacementInvokeKind, originalTargetMethod, originalArguments.toArray(new ValueNode[originalArguments.size()]), originalReturnType));
+                        new MethodCallTargetNode(replacementInvokeKind, originalTargetMethod, originalArguments.toArray(new ValueNode[originalArguments.size()]), originalReturnType, null));
 
         // Replace myself...
         this.replaceAndDelete(replacement);
--- a/jvmci/com.oracle.jvmci.code/src/com/oracle/jvmci/code/TypeCheckHints.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.code/src/com/oracle/jvmci/code/TypeCheckHints.java	Sat Jun 20 09:00:58 2015 +0200
@@ -95,7 +95,7 @@
      */
     public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) {
         this.profile = profile;
-        if (targetType != null && !canHaveSubtype(targetType)) {
+        if (targetType != null && !!targetType.isLeaf()) {
             exact = targetType;
         } else {
             if (assumptions != null) {
@@ -147,14 +147,4 @@
         hitProbability[0] = hitProb;
         return hintsBuf;
     }
-
-    /**
-     * Determines if a given type can have subtypes other than itself. This analysis is purely
-     * static; no assumptions are made.
-     *
-     * @return true if {@code type} can have subtypes
-     */
-    public static boolean canHaveSubtype(ResolvedJavaType type) {
-        return !type.getElementalType().isFinal();
-    }
 }
--- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java	Sat Jun 20 09:00:58 2015 +0200
@@ -188,7 +188,7 @@
 
     @Override
     public boolean canBeStaticallyBound() {
-        return (isFinal() || isPrivate() || isStatic() || holder.isFinal()) && isConcrete();
+        return (isFinal() || isPrivate() || isStatic() || holder.isLeaf()) && isConcrete();
     }
 
     @Override
--- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java	Sat Jun 20 09:00:58 2015 +0200
@@ -148,7 +148,7 @@
     public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
         HotSpotVMConfig config = runtime().getConfig();
         if (isArray()) {
-            return getElementalType().isFinal() ? new AssumptionResult<>(this) : null;
+            return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
         } else if (isInterface()) {
             HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
             /*
@@ -284,10 +284,7 @@
 
     @Override
     public HotSpotResolvedObjectType asExactType() {
-        if (isArray()) {
-            return getComponentType().asExactType() != null ? this : null;
-        }
-        return isFinal() ? this : null;
+        return isLeaf() ? this : null;
     }
 
     @Override
--- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Assumptions.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Assumptions.java	Sat Jun 20 09:00:58 2015 +0200
@@ -127,7 +127,7 @@
             this.subtype = subtype;
             assert context.isAbstract();
             assert subtype.isConcrete() || context.isInterface() : subtype.toString() + " : " + context.toString();
-            assert !subtype.isArray() || subtype.getElementalType().isFinal() : subtype.toString() + " : " + context.toString();
+            assert !subtype.isArray() || subtype.getElementalType().isFinalFlagSet() : subtype.toString() + " : " + context.toString();
         }
 
         @Override
--- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ModifiersProvider.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ModifiersProvider.java	Sat Jun 20 09:00:58 2015 +0200
@@ -67,9 +67,14 @@
     }
 
     /**
+     * The setting of the final modifier bit for types is somewhat confusing, so don't export
+     * isFinal by default. Subclasses like {@link ResolvedJavaField} and {@link ResolvedJavaMethod}
+     * can export it as isFinal, but {@link ResolvedJavaType} can provide a more sensible equivalent
+     * like {@link ResolvedJavaType#isLeaf}.
+     *
      * @see Modifier#isFinal(int)
      */
-    default boolean isFinal() {
+    default boolean isFinalFlagSet() {
         return Modifier.isFinal(getModifiers());
     }
 
--- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaField.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaField.java	Sat Jun 20 09:00:58 2015 +0200
@@ -39,6 +39,10 @@
      */
     int getModifiers();
 
+    default boolean isFinal() {
+        return ModifiersProvider.super.isFinalFlagSet();
+    }
+
     /**
      * Determines if this field was injected by the VM. Such a field, for example, is not derived
      * from a class file.
@@ -68,7 +72,7 @@
 
     /**
      * Returns an object representing the unique location identity of this resolved Java field.
-     * 
+     *
      * @return the location identity of the field
      */
     LocationIdentity getLocationIdentity();
--- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java	Sat Jun 20 09:00:58 2015 +0200
@@ -77,6 +77,10 @@
      */
     int getModifiers();
 
+    default boolean isFinal() {
+        return ModifiersProvider.super.isFinalFlagSet();
+    }
+
     /**
      * Determines if this method is a synthetic method as defined by the Java Language
      * Specification.
--- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaType.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaType.java	Sat Jun 20 09:00:58 2015 +0200
@@ -97,6 +97,14 @@
      */
     int getModifiers();
 
+    /*
+     * The setting of the final bit for types is a bit confusing since arrays are marked as final.
+     * This method provides a semantically equivalent test that appropriate for types.
+     */
+    default boolean isLeaf() {
+        return getElementalType().isFinalFlagSet();
+    }
+
     /**
      * Checks whether this type is initialized. If a type is initialized it implies that it was
      * {@link #isLinked() linked} and that the static initializer has run.
--- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaField.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaField.java	Sat Jun 20 09:00:58 2015 +0200
@@ -120,7 +120,8 @@
     // @formatter:off
     private static final String[] untestedApiMethods = {
         "getDeclaringClass",
-        "isInternal"
+        "isInternal",
+        "isFinal"
     };
     // @formatter:on
 
--- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java	Sat Jun 20 09:00:58 2015 +0200
@@ -403,6 +403,7 @@
         "toParameterTypes",
         "getParameterAnnotation",
         "getSpeculationLog",
+        "isFinal",
         "$jacocoInit"
     };
     // @formatter:on
--- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java	Sat Jun 20 09:00:02 2015 +0200
+++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java	Sat Jun 20 09:00:58 2015 +0200
@@ -838,6 +838,23 @@
     }
 
     @Test
+    public void isLeafTest() {
+        for (Class<?> c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            ResolvedJavaType arrayType = c != void.class ? metaAccess.lookupJavaType(getArrayClass(c)) : null;
+            if (c.isPrimitive()) {
+                assertTrue(type.isLeaf());
+                assertTrue(arrayType == null || arrayType.isLeaf());
+            } else {
+                assertTrue(c.toString(), type.isLeaf() == arrayType.isLeaf());
+                if (!c.isArray()) {
+                    assertTrue(c.toString(), type.isLeaf() == Modifier.isFinal(c.getModifiers()));
+                }
+            }
+        }
+    }
+
+    @Test
     public void findMethodTest() {
         try {
             ResolvedJavaMethod findFoo = metaAccess.lookupJavaType(D.class).findMethod("foo", metaAccess.parseMethodDescriptor("()V"));
--- a/mx.graal/suite.py	Sat Jun 20 09:00:02 2015 +0200
+++ b/mx.graal/suite.py	Sat Jun 20 09:00:58 2015 +0200
@@ -143,9 +143,9 @@
     "TRUFFLE" : {
       "path" : "lib/truffle-0.8-SNAPSHOT.jar",
       "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/nexus/content/repositories/snapshots/com/oracle/truffle/0.8-dd4050aadaf8d91301b159cb30a609d8bb99feeb-SNAPSHOT/truffle-0.8-dd4050aadaf8d91301b159cb30a609d8bb99feeb-20150616.114821-1.jar",
+        "http://lafo.ssw.uni-linz.ac.at/nexus/content/repositories/snapshots/com/oracle/truffle/0.8-d5d416ced577720b9354bfbf4092b4480af55dbb-SNAPSHOT/truffle-0.8-d5d416ced577720b9354bfbf4092b4480af55dbb-20150619.210629-1.jar",
       ],
-      "sha1" : "34be0993d8fcaa21129749a329e4bb7841cf27e1",
+      "sha1" : "0970218476e21c17b90d9f45eb5910b781b12a31",
     },
     "TRUFFLE_TCK" : {
       "path" : "lib/truffle-tck-0.8-SNAPSHOT.jar",