changeset 9344:430707bc6f58

Merge.
author Doug Simon <doug.simon@oracle.com>
date Fri, 26 Apr 2013 22:20:20 +0200
parents cdc21fd3d389 (current diff) 52e6d0e8d6f7 (diff)
children 927e0792094b e7c396ce0f3d
files graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/reflect/Reflection_getCallerClass01.java
diffstat 15 files changed, 91 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Fri Apr 26 22:20:20 2013 +0200
@@ -34,16 +34,10 @@
     public HighTier() {
         if (GraalOptions.FullUnroll) {
             addPhase(new LoopFullUnrollPhase());
-            if (GraalOptions.OptCanonicalizer) {
-                addPhase(new CanonicalizerPhase());
-            }
         }
 
         if (GraalOptions.OptTailDuplication) {
             addPhase(new TailDuplicationPhase());
-            if (GraalOptions.OptCanonicalizer) {
-                addPhase(new CanonicalizerPhase());
-            }
         }
 
         if (GraalOptions.PartialEscapeAnalysis) {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Fri Apr 26 22:20:20 2013 +0200
@@ -47,7 +47,8 @@
     private int deletedNodeCount;
     private GraphEventLog eventLog;
 
-    InputChangedListener inputChanged;
+    NodeChangedListener inputChanged;
+    NodeChangedListener usagesDroppedZero;
     private final HashMap<CacheEntry, Node> cachedNodes = new HashMap<>();
 
     private static final class CacheEntry {
@@ -152,12 +153,12 @@
         return node;
     }
 
-    public interface InputChangedListener {
+    public interface NodeChangedListener {
 
-        void inputChanged(Node node);
+        void nodeChanged(Node node);
     }
 
-    public void trackInputChange(InputChangedListener inputChangedListener) {
+    public void trackInputChange(NodeChangedListener inputChangedListener) {
         this.inputChanged = inputChangedListener;
     }
 
@@ -165,6 +166,14 @@
         inputChanged = null;
     }
 
+    public void trackUsagesDroppedZero(NodeChangedListener usagesDroppedZeroListener) {
+        this.usagesDroppedZero = usagesDroppedZeroListener;
+    }
+
+    public void stopTrackingUsagesDroppedZero() {
+        usagesDroppedZero = null;
+    }
+
     /**
      * Adds a new node to the graph, if a <i>similar</i> node already exists in the graph, the
      * provided node will not be added to the graph but the <i>similar</i> node will be returned
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Apr 26 22:20:20 2013 +0200
@@ -25,7 +25,7 @@
 import java.lang.annotation.*;
 import java.util.*;
 
-import com.oracle.graal.graph.Graph.InputChangedListener;
+import com.oracle.graal.graph.Graph.NodeChangedListener;
 import com.oracle.graal.graph.NodeClass.*;
 import com.oracle.graal.graph.iterators.*;
 
@@ -193,12 +193,17 @@
                 assert assertTrue(result, "not found in usages, old input: %s", oldInput);
             }
             if (newInput != null) {
-                InputChangedListener inputChanged = graph.inputChanged;
+                NodeChangedListener inputChanged = graph.inputChanged;
                 if (inputChanged != null) {
-                    inputChanged.inputChanged(this);
+                    inputChanged.nodeChanged(this);
                 }
                 assert newInput.usages != null : "not yet added? " + newInput;
                 newInput.usages.add(this);
+            } else if (oldInput != null && oldInput.usages().isEmpty()) {
+                NodeChangedListener nodeChangedListener = graph.usagesDroppedZero;
+                if (nodeChangedListener != null) {
+                    nodeChangedListener.nodeChanged(oldInput);
+                }
             }
         }
     }
@@ -253,9 +258,9 @@
             boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other);
             assert assertTrue(result, "not found in inputs, usage: %s", usage);
             if (other != null) {
-                InputChangedListener inputChanged = graph.inputChanged;
+                NodeChangedListener inputChanged = graph.inputChanged;
                 if (inputChanged != null) {
-                    inputChanged.inputChanged(usage);
+                    inputChanged.nodeChanged(usage);
                 }
                 other.usages.add(usage);
             }
@@ -299,6 +304,12 @@
 
         for (Node input : inputs()) {
             removeThisFromUsages(input);
+            if (input.usages().isEmpty()) {
+                NodeChangedListener nodeChangedListener = graph.usagesDroppedZero;
+                if (nodeChangedListener != null) {
+                    nodeChangedListener.nodeChanged(input);
+                }
+            }
         }
         getNodeClass().clearInputs(this);
     }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/reflect/Reflection_getCallerClass01.java	Fri Apr 26 22:19:21 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2007, 2012, 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.jtt.reflect;
-
-import com.oracle.graal.jtt.*;
-import org.junit.*;
-
-import sun.reflect.*;
-
-/*
- */
-public final class Reflection_getCallerClass01 extends JTTTest {
-
-    public static final class Caller1 {
-
-        private Caller1() {
-        }
-
-        static String caller1(int depth) {
-            return Reflection.getCallerClass(depth).getName();
-        }
-    }
-
-    public static final class Caller2 {
-
-        private Caller2() {
-        }
-
-        static String caller2(int depth) {
-            return Caller1.caller1(depth);
-        }
-    }
-
-    public static String test(int depth) {
-        return Caller2.caller2(depth);
-    }
-
-    @Test
-    public void run0() throws Throwable {
-        runTest("test", 0);
-    }
-
-    @Test
-    public void run1() throws Throwable {
-        runTest("test", 1);
-    }
-
-    @Test
-    public void run2() throws Throwable {
-        runTest("test", 2);
-    }
-
-}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Apr 26 22:20:20 2013 +0200
@@ -22,14 +22,13 @@
  */
 package com.oracle.graal.phases.common;
 
-import java.util.*;
 import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Graph.InputChangedListener;
+import com.oracle.graal.graph.Graph.NodeChangedListener;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -49,6 +48,7 @@
     public static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits");
 
     private final CustomCanonicalizer customCanonicalizer;
+    private final Iterable<Node> workingSet;
 
     public interface CustomCanonicalizer {
 
@@ -60,12 +60,17 @@
     }
 
     public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer) {
+        this(customCanonicalizer, null);
+    }
+
+    public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer, Iterable<Node> workingSet) {
         this.customCanonicalizer = customCanonicalizer;
+        this.workingSet = workingSet;
     }
 
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
-        new Instance(context.getRuntime(), context.getAssumptions(), null, customCanonicalizer).run(graph);
+        new Instance(context.getRuntime(), context.getAssumptions(), workingSet, customCanonicalizer).run(graph);
     }
 
     public static class Instance extends Phase {
@@ -78,7 +83,6 @@
 
         private NodeWorkList workList;
         private Tool tool;
-        private List<Node> snapshotTemp;
 
         public Instance(MetaAccessProvider runtime, Assumptions assumptions) {
             this(runtime, assumptions, null, 0, null);
@@ -110,7 +114,6 @@
             this.runtime = runtime;
             this.customCanonicalizer = customCanonicalizer;
             this.initWorkingSet = workingSet;
-            this.snapshotTemp = new ArrayList<>();
         }
 
         @Override
@@ -129,19 +132,22 @@
         }
 
         private void processWorkSet(StructuredGraph graph) {
-            graph.trackInputChange(new InputChangedListener() {
+            NodeChangedListener nodeChangedListener = new NodeChangedListener() {
 
                 @Override
-                public void inputChanged(Node node) {
+                public void nodeChanged(Node node) {
                     workList.addAgain(node);
                 }
-            });
+            };
+            graph.trackInputChange(nodeChangedListener);
+            graph.trackUsagesDroppedZero(nodeChangedListener);
 
             for (Node n : workList) {
                 processNode(n, graph);
             }
 
             graph.stopTrackingInputChange();
+            graph.stopTrackingUsagesDroppedZero();
         }
 
         private void processNode(Node node, StructuredGraph graph) {
@@ -153,17 +159,9 @@
                 }
                 int mark = graph.getMark();
                 if (!tryKillUnused(node)) {
-                    node.inputs().filter(GraphUtil.isFloatingNode()).snapshotTo(snapshotTemp);
                     if (!tryCanonicalize(node, graph)) {
                         tryInferStamp(node, graph);
-                    } else {
-                        for (Node in : snapshotTemp) {
-                            if (in.isAlive() && in.usages().isEmpty()) {
-                                GraphUtil.killWithUnusedFloatingInputs(in);
-                            }
-                        }
                     }
-                    snapshotTemp.clear();
                 }
 
                 for (Node newNode : graph.getNewNodes(mark)) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Apr 26 22:20:20 2013 +0200
@@ -42,6 +42,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
 
 public class InliningUtil {
 
@@ -450,7 +451,7 @@
             if (hasSingleMethod()) {
                 inlineSingleMethod(graph, callback, replacements, assumptions);
             } else {
-                inlineMultipleMethods(graph, callback, replacements, assumptions);
+                inlineMultipleMethods(graph, callback, replacements, assumptions, runtime);
             }
         }
 
@@ -462,7 +463,7 @@
             return notRecordedTypeProbability > 0;
         }
 
-        private void inlineMultipleMethods(StructuredGraph graph, InliningCallback callback, Replacements replacements, Assumptions assumptions) {
+        private void inlineMultipleMethods(StructuredGraph graph, InliningCallback callback, Replacements replacements, Assumptions assumptions, MetaAccessProvider runtime) {
             int numberOfMethods = concretes.size();
             FixedNode continuation = invoke.next();
 
@@ -564,7 +565,7 @@
                 if (opportunities > 0) {
                     metricInliningTailDuplication.increment();
                     Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities);
-                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes);
+                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new HighTierContext(runtime, assumptions, replacements));
                 }
             }
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Fri Apr 26 22:20:20 2013 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import com.oracle.graal.graph.Graph.InputChangedListener;
+import com.oracle.graal.graph.Graph.NodeChangedListener;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -49,7 +49,7 @@
         }
     }
 
-    private static class Listener implements InputChangedListener {
+    private static class Listener implements NodeChangedListener {
 
         private final Set<Node> canonicalizationRoots;
 
@@ -58,7 +58,7 @@
         }
 
         @Override
-        public void inputChanged(Node node) {
+        public void nodeChanged(Node node) {
             canonicalizationRoots.add(node);
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Apr 26 22:20:20 2013 +0200
@@ -36,13 +36,14 @@
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.tiers.*;
 
 /**
  * This class is a phase that looks for opportunities for tail duplication. The static method
- * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List)} can also be used to drive tail
- * duplication from other places, e.g., inlining.
+ * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List, PhaseContext)} can also be used
+ * to drive tail duplication from other places, e.g., inlining.
  */
-public class TailDuplicationPhase extends Phase {
+public class TailDuplicationPhase extends BasePhase<PhaseContext> {
 
     /*
      * Various metrics on the circumstances in which tail duplication was/wasn't performed.
@@ -129,14 +130,14 @@
     };
 
     @Override
-    protected void run(StructuredGraph graph) {
+    protected void run(StructuredGraph graph, PhaseContext phaseContext) {
         NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply();
 
         // A snapshot is taken here, so that new MergeNode instances aren't considered for tail
         // duplication.
         for (MergeNode merge : graph.getNodes(MergeNode.class).snapshot()) {
             if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= GraalOptions.TailDuplicationProbability) {
-                tailDuplicate(merge, DEFAULT_DECISION, null);
+                tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext);
             }
         }
     }
@@ -156,8 +157,9 @@
      *            size needs to match the merge's end count. Each entry can either be null or a
      *            {@link PiNode}, and is used to replace {@link PiNode#object()} with the
      *            {@link PiNode} in the duplicated branch that corresponds to the entry.
+     * @param phaseContext
      */
-    public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List<PiNode> replacements) {
+    public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List<PiNode> replacements, PhaseContext phaseContext) {
         assert !(merge instanceof LoopBeginNode);
         assert replacements == null || replacements.size() == merge.forwardEndCount();
         FixedNode fixed = merge;
@@ -171,14 +173,14 @@
                 metricDuplicationEnd.increment();
                 if (decision.doTransform(merge, fixedCount)) {
                     metricDuplicationEndPerformed.increment();
-                    new DuplicationOperation(merge, replacements).duplicate();
+                    new DuplicationOperation(merge, replacements).duplicate(phaseContext);
                     return true;
                 }
             } else if (merge.stateAfter() != null) {
                 metricDuplicationOther.increment();
                 if (decision.doTransform(merge, fixedCount)) {
                     metricDuplicationOtherPerformed.increment();
-                    new DuplicationOperation(merge, replacements).duplicate();
+                    new DuplicationOperation(merge, replacements).duplicate(phaseContext);
                     return true;
                 }
             }
@@ -220,10 +222,14 @@
          * <li>Determines the complete set of duplicated nodes.</li>
          * <li>Performs the actual duplication.</li>
          * </ul>
+         * 
+         * @param phaseContext
          */
-        private void duplicate() {
+        private void duplicate(PhaseContext phaseContext) {
             Debug.log("tail duplication at merge %s in %s", merge, graph.method());
 
+            int startMark = graph.getMark();
+
             ValueAnchorNode anchor = addValueAnchor();
 
             // determine the fixed nodes that should be duplicated (currently: all nodes up until
@@ -297,6 +303,7 @@
                     phi.setMerge(mergeAfter);
                 }
             }
+            new CanonicalizerPhase(null, graph.getNewNodes(startMark)).apply(graph, phaseContext);
             Debug.dump(graph, "After tail duplication at %s", merge);
         }
 
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java	Fri Apr 26 22:20:20 2013 +0200
@@ -115,7 +115,7 @@
         @Override
         public Object execute(VirtualFrame frame) {
             invocationCount++;
-            return ((TestArguments) frame.getArguments()).get(index);
+            return frame.getArguments(TestArguments.class).get(index);
         }
 
     }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java	Fri Apr 26 22:20:20 2013 +0200
@@ -35,7 +35,7 @@
  * A guest language can pass its own custom arguments when invoking a Truffle method by creating a
  * subclass of {@link Arguments}. When invoking a call target with
  * {@link CallTarget#call(Arguments)}, the arguments can be passed. A Truffle node can access the
- * arguments passed into the Truffle method by using {@link VirtualFrame#getArguments()}.
+ * arguments passed into the Truffle method by using {@link VirtualFrame#getArguments}.
  * </p>
  * 
  * <p>
@@ -97,7 +97,7 @@
         }
 
         int execute(VirtualFrame frame) {
-            return ((TestArguments) frame.getArguments()).values[index];
+            return frame.getArguments(TestArguments.class).values[index];
         }
     }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java	Fri Apr 26 22:20:20 2013 +0200
@@ -117,4 +117,10 @@
     public final String getCode() {
         return getSource().getCode().substring(charIndex, charLength);
     }
+
+    @Override
+    public String toString() {
+        return String.format("%s:%d", source.getName(), startLine);
+    }
+
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Fri Apr 26 22:20:20 2013 +0200
@@ -36,9 +36,16 @@
     FrameDescriptor getFrameDescriptor();
 
     /**
+     * Retrieves the arguments object from this frame. The runtime assumes that the arguments object
+     * is never null. Additionally, the runtime may assume that the given parameter indicating the
+     * class of the arguments object is correct. The runtime is not required to actually check the
+     * type of the arguments object. The parameter must be a value that can be reduced to a compile
+     * time constant.
+     * 
+     * @param clazz the known type of the arguments object as a compile time constant
      * @return the arguments used when calling this method
      */
-    Arguments getArguments();
+    <T extends Arguments> T getArguments(Class<T> clazz);
 
     /**
      * Read access to a local variable of type {@link Object}.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java	Fri Apr 26 22:20:20 2013 +0200
@@ -38,9 +38,10 @@
         this.arguments = arguments;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public Arguments getArguments() {
-        return arguments;
+    public <T extends Arguments> T getArguments(Class<T> clazz) {
+        return (T) arguments;
     }
 
     @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Fri Apr 26 22:20:20 2013 +0200
@@ -34,8 +34,8 @@
     }
 
     @Override
-    public Arguments getArguments() {
-        return wrapped.getArguments();
+    public <T extends Arguments> T getArguments(Class<T> clazz) {
+        return wrapped.getArguments(clazz);
     }
 
     @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Fri Apr 26 22:19:21 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Fri Apr 26 22:20:20 2013 +0200
@@ -43,9 +43,10 @@
         this.tags = new byte[descriptor.getSize()];
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public Arguments getArguments() {
-        return arguments;
+    public <T extends Arguments> T getArguments(Class<T> clazz) {
+        return (T) arguments;
     }
 
     @Override