# HG changeset patch # User Thomas Wuerthinger # Date 1379264618 -7200 # Node ID 44d5989ae7451a82d21c4d3da860048f6a0bfa73 # Parent 932252b772c379a22da50528e6fd5cd06a15fecf# Parent 5507e2824bc62cdd7bbb9262a9061d976642cbb2 Merge. diff -r 5507e2824bc6 -r 44d5989ae745 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 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; } } } diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java --- 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(); + } } diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- 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 diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- 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 diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- 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 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; } diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java --- 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; } } diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- 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 rawCache = new HashMap<>(); private final HashMap 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 arguments, final Assumptions assumptions) { + public StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList 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() { public StructuredGraph call() { - StructuredGraph newGraph = parseGraph(method); + StructuredGraph newGraph = parseGraph(method).copy(); // Get stamps from actual arguments. List stamps = new ArrayList<>(); @@ -101,15 +104,20 @@ } // Set stamps into graph before optimizing. + List 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 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 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 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 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 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() { + + 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 arguments) { diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- 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 TruffleCompilationThreshold = new OptionValue<>(1000); @Option(help = "") + public static final OptionValue TruffleMinInvokeThreshold = new OptionValue<>(3); + @Option(help = "") public static final OptionValue TruffleInvalidationReprofileCount = new OptionValue<>(3); @Option(help = "") public static final OptionValue TruffleReplaceReprofileCount = new OptionValue<>(10); diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/InlineTrivialGettersPhase.java --- 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 { - - 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); - } - } - } - } - } - } -} diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java --- 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()))); } } } diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- 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); } diff -r 5507e2824bc6 -r 44d5989ae745 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- 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; } } }