changeset 11651:44d5989ae745

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 15 Sep 2013 19:03:38 +0200
parents 932252b772c3 (diff) 5507e2824bc6 (current diff)
children f091e0d6f4f3
files
diffstat 12 files changed, 123 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Sep 15 19:03:38 2013 +0200
@@ -324,6 +324,7 @@
      * @param type the unresolved type of the constant
      */
     protected void handleUnresolvedLoadConstant(JavaType type) {
+        assert !graphBuilderConfig.eagerResolving();
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.push(Kind.Object, appendConstant(Constant.NULL_OBJECT));
     }
@@ -333,6 +334,7 @@
      * @param object the object value whose type is being checked against {@code type}
      */
     protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) {
+        assert !graphBuilderConfig.eagerResolving();
         append(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), Unresolved, InvalidateRecompile));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
@@ -342,6 +344,7 @@
      * @param object the object value whose type is being checked against {@code type}
      */
     protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) {
+        assert !graphBuilderConfig.eagerResolving();
         BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode(this));
         DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         append(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1));
@@ -353,6 +356,7 @@
      * @param type the type being instantiated
      */
     protected void handleUnresolvedNewInstance(JavaType type) {
+        assert !graphBuilderConfig.eagerResolving();
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
@@ -362,6 +366,7 @@
      * @param length the length of the array
      */
     protected void handleUnresolvedNewObjectArray(JavaType type, ValueNode length) {
+        assert !graphBuilderConfig.eagerResolving();
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
@@ -371,6 +376,7 @@
      * @param dims the dimensions for the multi-array
      */
     protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) {
+        assert !graphBuilderConfig.eagerResolving();
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
@@ -380,6 +386,7 @@
      * @param receiver the object containing the field or {@code null} if {@code field} is static
      */
     protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) {
+        assert !graphBuilderConfig.eagerResolving();
         Kind kind = field.getKind();
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.push(kind.getStackKind(), appendConstant(Constant.defaultForKind(kind)));
@@ -391,6 +398,7 @@
      * @param receiver the object containing the field or {@code null} if {@code field} is static
      */
     protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) {
+        assert !graphBuilderConfig.eagerResolving();
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
     }
 
@@ -399,10 +407,12 @@
      * @param type
      */
     protected void handleUnresolvedExceptionType(Representation representation, JavaType type) {
+        assert !graphBuilderConfig.eagerResolving();
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
     }
 
     protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) {
+        assert !graphBuilderConfig.eagerResolving();
         boolean withReceiver = invokeKind != InvokeKind.Static;
         append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.popArguments(javaMethod.getSignature().getParameterSlots(withReceiver), javaMethod.getSignature().getParameterCount(withReceiver));
@@ -1662,9 +1672,9 @@
         if (initialized && graphBuilderConfig.getSkippedExceptionTypes() != null) {
             ResolvedJavaType resolvedCatchType = (ResolvedJavaType) catchType;
             for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
-                initialized &= !skippedType.isAssignableFrom(resolvedCatchType);
-                if (!initialized) {
-                    break;
+                if (skippedType.isAssignableFrom(resolvedCatchType)) {
+                    append(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
+                    return;
                 }
             }
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Sun Sep 15 19:03:38 2013 +0200
@@ -126,4 +126,9 @@
     private static boolean checkDeoptimizations(ProfilingInfo profilingInfo, DeoptimizationReason reason) {
         return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization.getValue();
     }
+
+    @Override
+    public String toString() {
+        return enabledOpts.toString();
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Sun Sep 15 19:03:38 2013 +0200
@@ -65,7 +65,7 @@
         if (truffleCompiler == null) {
             truffleCompiler = new TruffleCompilerImpl();
         }
-        return new OptimizedCallTarget(rootNode, frameDescriptor, truffleCompiler, TruffleCompilationThreshold.getValue());
+        return new OptimizedCallTarget(rootNode, frameDescriptor, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue());
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Sun Sep 15 19:03:38 2013 +0200
@@ -43,10 +43,10 @@
     private static final PrintStream OUT = TTY.out().out();
     private static final int MIN_INVOKES_AFTER_INLINING = 2;
 
-    protected OptimizedCallTarget(RootNode rootNode, FrameDescriptor descriptor, TruffleCompiler compiler, int compilationThreshold) {
+    protected OptimizedCallTarget(RootNode rootNode, FrameDescriptor descriptor, TruffleCompiler compiler, int invokeCounter, int compilationThreshold) {
         super(rootNode, descriptor);
         this.compiler = compiler;
-        this.invokeCounter = compilationThreshold >> 7;
+        this.invokeCounter = invokeCounter;
         this.loopAndInvokeCounter = compilationThreshold;
         this.originalInvokeCounter = compilationThreshold;
         this.rootNode.setCallTarget(this);
@@ -185,7 +185,7 @@
 
     @Override
     public void reportLoopCount(int count) {
-        loopAndInvokeCounter -= count;
+        loopAndInvokeCounter = Math.max(0, loopAndInvokeCounter - count);
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Sun Sep 15 19:03:38 2013 +0200
@@ -139,6 +139,8 @@
                 // Make sure frame does not escape.
                 expandTree(config, graph, newFrameNode, assumptions);
 
+                new VerifyFrameDoesNotEscapePhase().apply(graph, false);
+
                 if (TruffleInlinePrinter.getValue()) {
                     InlinePrinterProcessor.printTree();
                     InlinePrinterProcessor.reset();
@@ -167,19 +169,12 @@
                 InliningPhase inliningPhase = new InliningPhase(canonicalizer);
                 inliningPhase.apply(graph, context);
 
-                // Convert deopt to guards.
-                new ConvertDeoptimizeToGuardPhase().apply(graph);
-
-                // Canonicalize / constant propagate.
-                canonicalizer.apply(graph, context);
-
                 for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) {
                     Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage());
                     throw GraphUtil.approxSourceException(neverPartOfCompilationNode, exception);
                 }
 
                 // EA frame and clean up.
-                new VerifyFrameDoesNotEscapePhase().apply(graph, false);
                 new PartialEscapePhase(false, canonicalizer).apply(graph, context);
                 new VerifyNoIntrinsicsLeftPhase().apply(graph, false);
                 for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) {
@@ -198,12 +193,6 @@
                         }
                     }
                 }
-
-                // Convert deopt to guards.
-                new ConvertDeoptimizeToGuardPhase().apply(graph);
-
-                // Canonicalize / constant propagate.
-                canonicalizer.apply(graph, context);
             }
         });
 
@@ -259,25 +248,12 @@
 
     private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions) {
 
-        final StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions);
+        final StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer);
         Debug.scope("parseGraph", targetMethod, new Runnable() {
 
             @Override
             public void run() {
 
-                // Canonicalize / constant propagate.
-                PhaseContext context = new PhaseContext(metaAccessProvider, assumptions, replacements);
-                canonicalizer.apply(graph, context);
-
-                // Intrinsify methods.
-                new ReplaceIntrinsicsPhase(replacements).apply(graph);
-
-                // Inline trivial getter methods
-                new InlineTrivialGettersPhase(metaAccessProvider, canonicalizer).apply(graph, context);
-
-                // Convert deopt to guards.
-                new ConvertDeoptimizeToGuardPhase().apply(graph);
-
                 if (graph.hasLoops()) {
                     boolean unrolled;
                     do {
@@ -288,9 +264,9 @@
                             if (ex.counted().isConstantMaxTripCount()) {
                                 long constant = ex.counted().constantMaxTripCount();
                                 if (constant <= TruffleConstantUnrollLimit.getValue() || targetMethod.getAnnotation(ExplodeLoop.class) != null) {
+                                    PhaseContext context = new PhaseContext(metaAccessProvider, assumptions, replacements);
                                     LoopTransformations.fullUnroll(ex, context, canonicalizer);
                                     Debug.dump(graph, "After loop unrolling %d times", constant);
-                                    canonicalizer.apply(graph, context);
                                     unrolled = true;
                                     break;
                                 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Sun Sep 15 19:03:38 2013 +0200
@@ -57,7 +57,8 @@
     }
 
     private static boolean verifyFieldValue(ResolvedJavaField field, Constant constant) {
-        assert field.getAnnotation(Child.class) == null || constant.isNull() || constant.asObject() instanceof com.oracle.truffle.api.nodes.Node : "@Child field value must be a Node: " + field;
+        assert field.getAnnotation(Child.class) == null || constant.isNull() || constant.asObject() instanceof com.oracle.truffle.api.nodes.Node : "@Child field value must be a Node: " + field +
+                        ", but was: " + constant.asObject();
         return true;
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Sun Sep 15 19:03:38 2013 +0200
@@ -34,6 +34,7 @@
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -48,6 +49,7 @@
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.nodes.Node.*;
 
 /**
  * Implementation of a cache for Truffle graphs for improving partial evaluation time.
@@ -59,6 +61,7 @@
     private final OptimisticOptimizations optimisticOptimizations;
     private final Replacements replacements;
 
+    private final HashMap<ResolvedJavaMethod, StructuredGraph> rawCache = new HashMap<>();
     private final HashMap<ResolvedJavaMethod, StructuredGraph> cache = new HashMap<>();
 
     public TruffleCache(MetaAccessProvider metaAccessProvider, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations, Replacements replacements) {
@@ -68,7 +71,7 @@
         this.replacements = replacements;
     }
 
-    public StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions) {
+    public StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final CanonicalizerPhase finalCanonicalizer) {
 
         StructuredGraph resultGraph = null;
         if (cache.containsKey(method)) {
@@ -82,7 +85,7 @@
             resultGraph = Debug.sandbox("TruffleCache", new Object[]{metaAccessProvider, method}, DebugScope.getConfig(), new Callable<StructuredGraph>() {
 
                 public StructuredGraph call() {
-                    StructuredGraph newGraph = parseGraph(method);
+                    StructuredGraph newGraph = parseGraph(method).copy();
 
                     // Get stamps from actual arguments.
                     List<Stamp> stamps = new ArrayList<>();
@@ -101,15 +104,20 @@
                     }
 
                     // Set stamps into graph before optimizing.
+                    List<Node> modifiedLocals = new ArrayList<>(arguments.size());
                     for (LocalNode localNode : newGraph.getNodes(LocalNode.class)) {
                         int index = localNode.index();
                         Stamp stamp = stamps.get(index);
-                        localNode.setStamp(stamp);
+
+                        if (!stamp.equals(localNode.stamp())) {
+                            localNode.setStamp(stamp);
+                            modifiedLocals.add(localNode);
+                        }
                     }
 
                     Assumptions tmpAssumptions = new Assumptions(false);
 
-                    optimizeGraph(newGraph, tmpAssumptions);
+                    optimizeGraph(newGraph, tmpAssumptions, newGraph.getNodes().snapshot());
 
                     PhaseContext context = new PhaseContext(metaAccessProvider, tmpAssumptions, replacements);
                     PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, new CanonicalizerPhase(!AOTCompilation.getValue()));
@@ -124,6 +132,8 @@
             });
         }
 
+        // histogram.add(resultGraph);
+
         final StructuredGraph clonedResultGraph = resultGraph.copy();
 
         Debug.sandbox("TruffleCacheConstants", new Object[]{metaAccessProvider, method}, DebugScope.getConfig(), new Runnable() {
@@ -131,24 +141,64 @@
             public void run() {
 
                 Debug.dump(clonedResultGraph, "before applying constants");
+                List<Node> modifiedLocals = new ArrayList<>(arguments.size());
                 // Pass on constant arguments.
                 for (LocalNode local : clonedResultGraph.getNodes(LocalNode.class)) {
                     ValueNode arg = arguments.get(local.index());
                     if (arg.isConstant()) {
                         Constant constant = arg.asConstant();
-                        local.replaceAndDelete(ConstantNode.forConstant(constant, metaAccessProvider, clonedResultGraph));
-                    } else {
+                        ConstantNode constantNode = ConstantNode.forConstant(constant, metaAccessProvider, clonedResultGraph);
+                        local.replaceAndDelete(constantNode);
+                        modifiedLocals.add(constantNode);
+                    } else if (!local.stamp().equals(arg.stamp())) {
                         local.setStamp(arg.stamp());
+                        modifiedLocals.add(local);
                     }
                 }
                 Debug.dump(clonedResultGraph, "after applying constants");
-                optimizeGraph(clonedResultGraph, assumptions);
+                List<Node> modifiedLocalsUsages = new ArrayList<>(modifiedLocals.size() * 2);
+                for (Node local : modifiedLocals) {
+                    for (Node usage : local.usages()) {
+                        if (usage instanceof Canonicalizable) {
+                            modifiedLocalsUsages.add(usage);
+                        }
+                    }
+                }
+                optimizeGraph(clonedResultGraph, assumptions, modifiedLocalsUsages);
+
+                modifiedLocalsUsages.clear();
+                for (Node local : modifiedLocals) {
+                    for (Node usage : local.usages()) {
+                        if (usage instanceof Canonicalizable) {
+                            modifiedLocalsUsages.add(usage);
+                        }
+                    }
+                }
+
+                int newNodesMark = clonedResultGraph.getMark();
+                new ReplaceLoadFinalPhase().apply(clonedResultGraph);
+                for (Node n : clonedResultGraph.getNewNodes(newNodesMark)) {
+                    if (n instanceof Canonicalizable) {
+                        modifiedLocalsUsages.add(n);
+                    }
+                }
+                finalCanonicalizer.applyIncremental(clonedResultGraph, new PhaseContext(metaAccessProvider, assumptions, replacements), modifiedLocalsUsages);
+
+                for (Node n : clonedResultGraph.getNodes()) {
+                    if (n instanceof LoadFieldNode) {
+                        LoadFieldNode loadFieldNode = (LoadFieldNode) n;
+                        if (loadFieldNode.field().getAnnotation(Child.class) != null) {
+                            throw new RuntimeException("found remaining child load field ");
+                        }
+
+                    }
+                }
             }
         });
         return clonedResultGraph;
     }
 
-    private void optimizeGraph(StructuredGraph newGraph, Assumptions assumptions) {
+    private void optimizeGraph(StructuredGraph newGraph, Assumptions assumptions, Iterable<Node> changedNodes) {
         PhaseContext context = new PhaseContext(metaAccessProvider, assumptions, replacements);
         ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(metaAccessProvider);
         ConvertDeoptimizeToGuardPhase convertDeoptimizeToGuardPhase = new ConvertDeoptimizeToGuardPhase();
@@ -157,20 +207,21 @@
 
         int maxNodes = TruffleCompilerOptions.TruffleOperationCacheMaxNodes.getValue();
 
-        contractGraph(newGraph, conditionalEliminationPhase, convertDeoptimizeToGuardPhase, canonicalizerPhase, readEliminationPhase, context);
+        contractGraph(newGraph, conditionalEliminationPhase, convertDeoptimizeToGuardPhase, canonicalizerPhase, readEliminationPhase, changedNodes, context);
 
         while (newGraph.getNodeCount() <= maxNodes) {
 
             int mark = newGraph.getMark();
 
             expandGraph(newGraph, maxNodes);
+            NodeIterable<Node> newNodes = newGraph.getNewNodes(mark);
 
-            if (newGraph.getNewNodes(mark).count() == 0) {
+            if (newNodes.isEmpty()) {
                 // No progress => exit iterative optimization.
                 break;
             }
 
-            contractGraph(newGraph, conditionalEliminationPhase, convertDeoptimizeToGuardPhase, canonicalizerPhase, readEliminationPhase, context);
+            contractGraph(newGraph, conditionalEliminationPhase, convertDeoptimizeToGuardPhase, canonicalizerPhase, readEliminationPhase, newNodes, context);
         }
 
         if (newGraph.getNodeCount() > maxNodes && (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue() || TruffleCompilerOptions.TraceTrufflePerformanceWarnings.getValue())) {
@@ -179,11 +230,10 @@
     }
 
     private static void contractGraph(StructuredGraph newGraph, ConditionalEliminationPhase conditionalEliminationPhase, ConvertDeoptimizeToGuardPhase convertDeoptimizeToGuardPhase,
-                    CanonicalizerPhase canonicalizerPhase, EarlyReadEliminationPhase readEliminationPhase, PhaseContext context) {
-        new ReplaceLoadFinalPhase().apply(newGraph);
+                    CanonicalizerPhase canonicalizerPhase, EarlyReadEliminationPhase readEliminationPhase, Iterable<Node> newNodes, PhaseContext context) {
 
         // Canonicalize / constant propagate.
-        canonicalizerPhase.apply(newGraph, context);
+        canonicalizerPhase.applyIncremental(newGraph, context, newNodes);
 
         // Early read eliminiation
         readEliminationPhase.apply(newGraph, context);
@@ -298,12 +348,29 @@
         return invoke.asNode();
     }
 
-    private StructuredGraph parseGraph(ResolvedJavaMethod method) {
-        StructuredGraph graph = new StructuredGraph(method);
-        new GraphBuilderPhase(metaAccessProvider, config, optimisticOptimizations).apply(graph);
-        // Intrinsify methods.
-        new ReplaceIntrinsicsPhase(replacements).apply(graph);
-        return graph;
+    private StructuredGraph parseGraph(final ResolvedJavaMethod method) {
+        if (rawCache.containsKey(method)) {
+            return rawCache.get(method);
+        }
+
+        StructuredGraph resultGraph = Debug.sandbox("InnerTruffleCache", new Object[]{metaAccessProvider, method}, DebugScope.getConfig(), new Callable<StructuredGraph>() {
+
+            public StructuredGraph call() {
+                final StructuredGraph graph = new StructuredGraph(method);
+                new GraphBuilderPhase(metaAccessProvider, config, optimisticOptimizations).apply(graph);
+                // Intrinsify methods.
+                new ReplaceIntrinsicsPhase(replacements).apply(graph);
+                for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.class)) {
+                    if (d.getDeoptimizationReason() == DeoptimizationReason.Unresolved) {
+                        // Cannot store this graph.
+                        return graph;
+                    }
+                }
+                rawCache.put(method, graph);
+                return graph;
+            }
+        });
+        return resultGraph;
     }
 
     private static boolean checkArgumentStamps(StructuredGraph graph, NodeInputList<ValueNode> arguments) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Sun Sep 15 19:03:38 2013 +0200
@@ -46,6 +46,8 @@
     @Option(help = "")
     public static final OptionValue<Integer> TruffleCompilationThreshold = new OptionValue<>(1000);
     @Option(help = "")
+    public static final OptionValue<Integer> TruffleMinInvokeThreshold = new OptionValue<>(3);
+    @Option(help = "")
     public static final OptionValue<Integer> TruffleInvalidationReprofileCount = new OptionValue<>(3);
     @Option(help = "")
     public static final OptionValue<Integer> TruffleReplaceReprofileCount = new OptionValue<>(10);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/InlineTrivialGettersPhase.java	Sun Sep 15 16:40:48 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +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.truffle.phases;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.truffle.*;
-
-/**
- * Inline all trivial getters (i.e. simple field loads).
- */
-public class InlineTrivialGettersPhase extends BasePhase<PhaseContext> {
-
-    private static final int TRIVIAL_GETTER_SIZE = 5;
-    private final MetaAccessProvider metaAccessProvider;
-    private final CanonicalizerPhase canonicalizer;
-
-    public InlineTrivialGettersPhase(MetaAccessProvider metaAccessProvider, CanonicalizerPhase canonicalizer) {
-        this.metaAccessProvider = metaAccessProvider;
-        this.canonicalizer = canonicalizer;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
-        for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) {
-            if (methodCallTarget.isAlive()) {
-                InvokeKind invokeKind = methodCallTarget.invokeKind();
-                if (invokeKind == InvokeKind.Special) {
-                    ResolvedJavaMethod targetMethod = methodCallTarget.targetMethod();
-                    if (methodCallTarget.receiver().isConstant() && !methodCallTarget.receiver().isNullConstant()) {
-                        if (targetMethod.getCodeSize() == TRIVIAL_GETTER_SIZE && targetMethod.getDeclaringClass().isInitialized() && targetMethod.getName().startsWith("get")) {
-                            StructuredGraph inlineGraph = new StructuredGraph(targetMethod);
-                            new GraphBuilderPhase(metaAccessProvider, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations).apply(inlineGraph);
-                            int mark = graph.getMark();
-                            InliningUtil.inline(methodCallTarget.invoke(), inlineGraph, false);
-                            Debug.dump(graph, "After inlining trivial getter %s", targetMethod.toString());
-                            canonicalizer.applyIncremental(graph, context, mark);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java	Sun Sep 15 19:03:38 2013 +0200
@@ -42,6 +42,8 @@
                 if (!loadFieldNode.isStatic() && isCompilationFinal(loadFieldNode.field())) {
                     graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind())));
                 }
+            } else if (loadIndexedNode.array() instanceof ConstantNode) {
+                graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind())));
             }
         }
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Sun Sep 15 19:03:38 2013 +0200
@@ -75,7 +75,7 @@
             // source attribution, which would otherwise trigger this
             // exception. This method will eventually be deprecated.
             if (getSourceSection() != section) {
-                throw new IllegalStateException("Source section is already assigned.");
+                throw new IllegalStateException("Source section is already assigned. Old: " + getSourceSection() + ", new: " + section);
             }
         }
         this.sourceSection = section;
@@ -174,7 +174,7 @@
         if (this.getParent() == null) {
             throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent.");
         }
-        if (sourceSection != null) {
+        if (sourceSection != null && newNode.getSourceSection() == null) {
             // Pass on the source section to the new node.
             newNode.assignSourceSection(sourceSection);
         }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Sun Sep 15 16:40:48 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Sun Sep 15 19:03:38 2013 +0200
@@ -364,6 +364,7 @@
             if (unsafe.getObject(parent, fieldOffset) == oldChild) {
                 assert assertAssignable(nodeClass, fieldOffset, newChild);
                 unsafe.putObject(parent, fieldOffset, newChild);
+                return;
             }
         }
 
@@ -376,6 +377,7 @@
                     if (array[i] == oldChild) {
                         assert assertAssignable(nodeClass, fieldOffset, newChild);
                         array[i] = newChild;
+                        return;
                     }
                 }
             }