changeset 3222:c762ddb64bc9

Merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Mon, 18 Jul 2011 11:56:49 +0200
parents 034a4db85c59 (current diff) 9518546712e1 (diff)
children a581e5d934a9
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/extensions/InliningExample.java
diffstat 29 files changed, 715 insertions(+), 341 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Jul 14 22:22:44 2011 +0200
+++ b/.hgignore	Mon Jul 18 11:56:49 2011 +0200
@@ -21,6 +21,7 @@
 ^diff1.txt$
 ^diff2.txt$
 ^examples.jar$
+^graal/com.oracle.max.graal.examples/examples.jar$
 ^test.xml$
 java\.hprof\.txt$
 /nbproject/private/
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Mon Jul 18 11:56:49 2011 +0200
@@ -94,6 +94,7 @@
 
     // Ideal graph visualizer output settings
     public static boolean Plot                               = ____;
+    public static boolean PlotVerbose                        = ____;
     public static boolean PlotOnError                        = ____;
     public static int     PrintIdealGraphLevel               = 0;
     public static boolean PrintIdealGraphFile                = ____;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Mon Jul 18 11:56:49 2011 +0200
@@ -123,7 +123,7 @@
         IdentifyBlocksPhase schedule = null;
         try {
             schedule = new IdentifyBlocksPhase(true);
-            schedule.apply(graph, false);
+            schedule.apply(graph, false, false);
         } catch (Throwable t) {
             // nothing to do here...
             //t.printStackTrace();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Mon Jul 18 11:56:49 2011 +0200
@@ -97,6 +97,8 @@
 
         if (GraalOptions.Inline) {
             new InliningPhase(compilation, this, null).apply(compilation.graph);
+            new CanonicalizerPhase().apply(compilation.graph);
+            new DeadCodeEliminationPhase().apply(compilation.graph);
         }
 
         Graph graph = compilation.graph;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/MergeableState.java	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011, 2011, 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.max.graal.compiler.graph;
+
+import java.util.*;
+
+import com.oracle.max.graal.compiler.ir.*;
+
+public interface MergeableState <T> {
+    T clone();
+    boolean merge(Merge merge, Collection<T> withStates);
+    void loopBegin(LoopBegin loopBegin);
+    void loopEnd(LoopEnd loopEnd, T loopEndState);
+    void afterSplit(FixedNode node);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/PostOrderNodeIterator.java	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2011, 2011, 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.max.graal.compiler.graph;
+
+import java.util.*;
+
+import com.oracle.max.graal.compiler.ir.*;
+import com.oracle.max.graal.graph.*;
+
+public abstract class PostOrderNodeIterator<T extends MergeableState<T>> {
+
+    private final NodeBitMap visitedEnds;
+    private final Deque<FixedNode> nodeQueue;
+    private final HashMap<FixedNode, T> nodeStates;
+    private final FixedNode start;
+
+    protected T state;
+
+    public PostOrderNodeIterator(FixedNode start, T initialState) {
+        visitedEnds = start.graph().createNodeBitMap();
+        nodeQueue = new ArrayDeque<FixedNode>();
+        nodeStates = new HashMap<FixedNode, T>();
+        this.start = start;
+        this.state = initialState;
+    }
+
+    public void apply() {
+        FixedNode current = start;
+
+        do {
+            if (current instanceof Invoke) {
+                invoke((Invoke) current);
+                queueSuccessors(current);
+                current = nextQueuedNode();
+            } else if (current instanceof LoopBegin) {
+                state.loopBegin((LoopBegin) current);
+                nodeStates.put(current, state);
+                state = state.clone();
+                loopBegin((LoopBegin) current);
+                current = ((LoopBegin) current).next();
+                assert current != null;
+            } else if (current instanceof LoopEnd) {
+                T loopBeginState = nodeStates.get(((LoopEnd) current).loopBegin());
+                if (loopBeginState != null) {
+                    loopBeginState.loopEnd((LoopEnd) current, state);
+                }
+                loopEnd((LoopEnd) current);
+                current = nextQueuedNode();
+            } else if (current instanceof Merge) {
+                merge((Merge) current);
+                current = ((Merge) current).next();
+                assert current != null;
+            } else if (current instanceof FixedNodeWithNext) {
+                FixedNode next = ((FixedNodeWithNext) current).next();
+                node(current);
+                current = next;
+                assert current != null;
+            } else if (current instanceof EndNode) {
+                end((EndNode) current);
+                queueMerge((EndNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof Deoptimize) {
+                deoptimize((Deoptimize) current);
+                current = nextQueuedNode();
+            } else if (current instanceof Return) {
+                returnNode((Return) current);
+                current = nextQueuedNode();
+            } else if (current instanceof Unwind) {
+                unwind((Unwind) current);
+                current = nextQueuedNode();
+            } else if (current instanceof ControlSplit) {
+                controlSplit((ControlSplit) current);
+                queueSuccessors(current);
+                current = nextQueuedNode();
+            } else {
+                assert false : current.shortName();
+            }
+        } while(current != null);
+    }
+
+    private void queueSuccessors(FixedNode x) {
+        nodeStates.put(x, state);
+        for (Node node : x.successors()) {
+            if (node != null) {
+                nodeQueue.addFirst((FixedNode) node);
+            }
+        }
+    }
+
+    private FixedNode nextQueuedNode() {
+        int maxIterations = nodeQueue.size();
+        while (maxIterations-- > 0) {
+            FixedNode node = nodeQueue.removeFirst();
+            if (node instanceof Merge) {
+                Merge merge = (Merge) node;
+                state = nodeStates.get(merge.endAt(0)).clone();
+                ArrayList<T> states = new ArrayList<T>(merge.endCount() - 1);
+                for (int i = 1; i < merge.endCount(); i++) {
+                    T other = nodeStates.get(merge.endAt(i));
+                    assert other != null;
+                    states.add(other);
+                }
+                boolean ready = state.merge(merge, states);
+                if (ready) {
+                    return merge;
+                } else {
+                    nodeQueue.addLast(merge);
+                }
+            } else {
+                assert node.predecessors().size() == 1;
+                state = nodeStates.get(node.predecessors().get(0)).clone();
+                state.afterSplit(node);
+                return node;
+            }
+        }
+        return null;
+    }
+
+    private void queueMerge(EndNode end) {
+        assert !visitedEnds.isMarked(end);
+        assert !nodeStates.containsKey(end);
+        nodeStates.put(end, state);
+        visitedEnds.mark(end);
+        Merge merge = end.merge();
+        boolean endsVisited = true;
+        for (int i = 0; i < merge.endCount(); i++) {
+            if (!visitedEnds.isMarked(merge.endAt(i))) {
+                endsVisited = false;
+                break;
+            }
+        }
+        if (endsVisited) {
+            nodeQueue.add(merge);
+        }
+    }
+
+    protected abstract void node(FixedNode node);
+
+    protected void end(EndNode endNode) {
+        node(endNode);
+    }
+
+    protected void merge(Merge merge) {
+        node(merge);
+    }
+
+    protected void loopBegin(LoopBegin loopBegin) {
+        node(loopBegin);
+    }
+
+    protected void loopEnd(LoopEnd loopEnd) {
+        node(loopEnd);
+    }
+
+    protected void deoptimize(Deoptimize deoptimize) {
+        node(deoptimize);
+    }
+
+    protected void controlSplit(ControlSplit controlSplit) {
+        node(controlSplit);
+    }
+
+    protected void returnNode(Return returnNode) {
+        node(returnNode);
+    }
+
+    protected void invoke(Invoke invoke) {
+        node(invoke);
+    }
+
+    protected void unwind(Unwind unwind) {
+        node(unwind);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedNode.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedNode.java	Mon Jul 18 11:56:49 2011 +0200
@@ -50,7 +50,7 @@
     @Override
     public Map<Object, Object> getDebugProperties() {
         Map<Object, Object> properties = super.getDebugProperties();
-        properties.put("probability", String.format("%7.5f", probability));
+        properties.put("probability", String.format(Locale.ENGLISH, "%7.5f", probability));
         return properties;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java	Mon Jul 18 11:56:49 2011 +0200
@@ -26,10 +26,9 @@
 
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.graph.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.observer.*;
-import com.oracle.max.graal.compiler.phases.EscapeAnalysisPhase.MergeableState;
-import com.oracle.max.graal.compiler.phases.EscapeAnalysisPhase.PostOrderNodeIterator;
 import com.oracle.max.graal.graph.*;
 
 public class ComputeProbabilityPhase extends Phase {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java	Mon Jul 18 11:56:49 2011 +0200
@@ -39,180 +39,6 @@
 
 public class EscapeAnalysisPhase extends Phase {
 
-    public interface MergeableState <T> {
-        T clone();
-        boolean merge(Merge merge, Collection<T> withStates);
-        void loopBegin(LoopBegin loopBegin);
-        void loopEnd(LoopEnd loopEnd, T loopEndState);
-        void afterSplit(FixedNode node);
-    }
-
-    public abstract static class PostOrderNodeIterator<T extends MergeableState<T>> {
-
-        private final NodeBitMap visitedEnds;
-        private final Deque<FixedNode> nodeQueue;
-        private final HashMap<FixedNode, T> nodeStates;
-        private final FixedNode start;
-
-        protected T state;
-
-        public PostOrderNodeIterator(FixedNode start, T initialState) {
-            visitedEnds = start.graph().createNodeBitMap();
-            nodeQueue = new ArrayDeque<FixedNode>();
-            nodeStates = new HashMap<FixedNode, T>();
-            this.start = start;
-            this.state = initialState;
-        }
-
-        public void apply() {
-            FixedNode current = start;
-
-            do {
-                if (current instanceof Invoke) {
-                    invoke((Invoke) current);
-                    queueSuccessors(current);
-                    current = nextQueuedNode();
-                } else if (current instanceof LoopBegin) {
-                    state.loopBegin((LoopBegin) current);
-                    nodeStates.put(current, state);
-                    state = state.clone();
-                    loopBegin((LoopBegin) current);
-                    current = ((LoopBegin) current).next();
-                    assert current != null;
-                } else if (current instanceof LoopEnd) {
-                    T loopBeginState = nodeStates.get(((LoopEnd) current).loopBegin());
-                    if (loopBeginState != null) {
-                        loopBeginState.loopEnd((LoopEnd) current, state);
-                    }
-                    loopEnd((LoopEnd) current);
-                    current = nextQueuedNode();
-                } else if (current instanceof Merge) {
-                    merge((Merge) current);
-                    current = ((Merge) current).next();
-                    assert current != null;
-                } else if (current instanceof FixedNodeWithNext) {
-                    FixedNode next = ((FixedNodeWithNext) current).next();
-                    node(current);
-                    current = next;
-                    assert current != null;
-                } else if (current instanceof EndNode) {
-                    end((EndNode) current);
-                    queueMerge((EndNode) current);
-                    current = nextQueuedNode();
-                } else if (current instanceof Deoptimize) {
-                    deoptimize((Deoptimize) current);
-                    current = nextQueuedNode();
-                } else if (current instanceof Return) {
-                    returnNode((Return) current);
-                    current = nextQueuedNode();
-                } else if (current instanceof Unwind) {
-                    unwind((Unwind) current);
-                    current = nextQueuedNode();
-                } else if (current instanceof ControlSplit) {
-                    controlSplit((ControlSplit) current);
-                    queueSuccessors(current);
-                    current = nextQueuedNode();
-                } else {
-                    assert false : current.shortName();
-                }
-            } while(current != null);
-        }
-
-        private void queueSuccessors(FixedNode x) {
-            nodeStates.put(x, state);
-            for (Node node : x.successors()) {
-                if (node != null) {
-                    nodeQueue.addFirst((FixedNode) node);
-                }
-            }
-        }
-
-        private FixedNode nextQueuedNode() {
-            int maxIterations = nodeQueue.size();
-            while (maxIterations-- > 0) {
-                FixedNode node = nodeQueue.removeFirst();
-                if (node instanceof Merge) {
-                    Merge merge = (Merge) node;
-                    state = nodeStates.get(merge.endAt(0)).clone();
-                    ArrayList<T> states = new ArrayList<T>(merge.endCount() - 1);
-                    for (int i = 1; i < merge.endCount(); i++) {
-                        T other = nodeStates.get(merge.endAt(i));
-                        assert other != null;
-                        states.add(other);
-                    }
-                    boolean ready = state.merge(merge, states);
-                    if (ready) {
-                        return merge;
-                    } else {
-                        nodeQueue.addLast(merge);
-                    }
-                } else {
-                    assert node.predecessors().size() == 1;
-                    state = nodeStates.get(node.predecessors().get(0)).clone();
-                    state.afterSplit(node);
-                    return node;
-                }
-            }
-            return null;
-        }
-
-        private void queueMerge(EndNode end) {
-            assert !visitedEnds.isMarked(end);
-            assert !nodeStates.containsKey(end);
-            nodeStates.put(end, state);
-            visitedEnds.mark(end);
-            Merge merge = end.merge();
-            boolean endsVisited = true;
-            for (int i = 0; i < merge.endCount(); i++) {
-                if (!visitedEnds.isMarked(merge.endAt(i))) {
-                    endsVisited = false;
-                    break;
-                }
-            }
-            if (endsVisited) {
-                nodeQueue.add(merge);
-            }
-        }
-
-        protected abstract void node(FixedNode node);
-
-        protected void end(EndNode endNode) {
-            node(endNode);
-        }
-
-        protected void merge(Merge merge) {
-            node(merge);
-        }
-
-        protected void loopBegin(LoopBegin loopBegin) {
-            node(loopBegin);
-        }
-
-        protected void loopEnd(LoopEnd loopEnd) {
-            node(loopEnd);
-        }
-
-        protected void deoptimize(Deoptimize deoptimize) {
-            node(deoptimize);
-        }
-
-        protected void controlSplit(ControlSplit controlSplit) {
-            node(controlSplit);
-        }
-
-        protected void returnNode(Return returnNode) {
-            node(returnNode);
-        }
-
-        protected void invoke(Invoke invoke) {
-            node(invoke);
-        }
-
-        protected void unwind(Unwind unwind) {
-            node(unwind);
-        }
-    }
-
     public static class BlockExitState implements MergeableState<BlockExitState> {
         public final Value[] fieldState;
         public final VirtualObject virtualObject;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Mon Jul 18 11:56:49 2011 +0200
@@ -446,10 +446,10 @@
                 TTY.println("Building graph for %s, locals: %d, stack: %d", methodName(method, invoke), method.maxLocals(), method.maxStackSize());
             }
             graph = new CompilerGraph(null);
-            new GraphBuilderPhase(compilation, method, true).apply(graph);
+            new GraphBuilderPhase(compilation, method, true).apply(graph, true, false);
             if (GraalOptions.ProbabilityAnalysis) {
-                new DeadCodeEliminationPhase().apply(graph);
-                new ComputeProbabilityPhase().apply(graph);
+                new DeadCodeEliminationPhase().apply(graph, true, false);
+                new ComputeProbabilityPhase().apply(graph, true, false);
             }
         }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Mon Jul 18 11:56:49 2011 +0200
@@ -34,17 +34,17 @@
     private static final ThreadLocal<Phase> currentPhase = new ThreadLocal<Phase>();
     private final boolean shouldVerify;
 
-    public Phase() {
+    protected Phase() {
         this.name = this.getClass().getSimpleName();
         this.shouldVerify = true;
         this.detailedName = name;
     }
 
-    public Phase(String name) {
+    protected Phase(String name) {
         this(name, true);
     }
 
-    public Phase(String name, boolean shouldVerify) {
+    protected Phase(String name, boolean shouldVerify) {
         this.name = name;
         this.shouldVerify = shouldVerify;
         this.detailedName = name;
@@ -55,10 +55,10 @@
     }
 
     public final void apply(Graph graph) {
-        apply(graph, true);
+        apply(graph, true, true);
     }
 
-    public final void apply(Graph graph, boolean plotOnError) {
+    public final void apply(Graph graph, boolean plotOnError, boolean plot) {
         assert graph != null && (!shouldVerify || graph.verify());
 
         int startDeletedNodeCount = graph.getDeletedNodeCount();
@@ -104,7 +104,7 @@
             GraalMetrics.get(getName().concat(".createdNodes")).increment(createdNodeCount);
         }
         GraalCompilation compilation = GraalCompilation.compilation();
-        if (compilation.compiler.isObserved() && this.getClass() != IdentifyBlocksPhase.class) {
+        if (compilation.compiler.isObserved() && this.getClass() != IdentifyBlocksPhase.class && (plot || GraalOptions.PlotVerbose)) {
             compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After " + detailedName, graph, true, false));
         }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/extensions/InliningExample.java	Thu Jul 14 22:22:44 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, 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.max.graal.extensions;
-
-
-public class InliningExample {
-
-    public static void run() {
-        System.out.println(test());
-        long start = System.currentTimeMillis();
-        System.out.println(testFib());
-        System.out.println(System.currentTimeMillis() - start);
-    }
-
-    public static int testFib() {
-        int sum = 0;
-        for (int i = 0; i < 10000000; ++i) {
-            sum += fib(5);
-        }
-        return sum;
-    }
-
-    private static int test() {
-        return alwaysInline(30);
-    }
-
-    public static int alwaysInline(int value) {
-        if (value < 0) {
-            return neverInline(value);
-        }
-        return alwaysInline(value - 1);
-    }
-
-    public static int neverInline(int value) {
-        return value;
-    }
-
-    public static int fib(int val) {
-        if (val == 0 || val == 1) {
-            return 1;
-        }
-        return fib(val - 1) + fib(val - 2);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.examples/create_examples.xml	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project default="create_run_jar" name="Create Runnable Jar for Project com.oracle.max.graal.examples">
+    <!--this file was created by Eclipse Runnable JAR Export Wizard-->
+    <!--ANT 1.7 is required                                        -->
+    <target name="create_run_jar">
+        <jar destfile="./examples.jar" filesetmanifest="mergewithoutmain">
+            <manifest>
+                <attribute name="Main-Class" value="com.oracle.max.graal.examples.Main"/>
+                <attribute name="Class-Path" value="."/>
+            </manifest>
+            <fileset dir="bin"/>
+        </jar>
+    </target>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.examples/runexample.sh	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,23 @@
+#!/bin/bash
+if [ -z "${JDK7}" ]; then
+  echo "JDK7 is not defined."
+  exit 1;
+fi
+if [ -z "${MAXINE}" ]; then
+  echo "MAXINE is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${GRAAL}" ]; then
+  echo "GRAAL is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${DACAPO}" ]; then
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
+  exit 1;
+fi
+TEST=$1
+shift
+ant -f create_examples.xml
+COMMAND="${JDK7}/bin/java -client -d64 -graal -Xmx1g -esa -ea -G:Extend -G:CacheGraphs -XX:+PrintCompilation -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*,<init> -XX:CompileCommand=exclude,*,<clinit> -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}"
+# echo $COMMAND
+$COMMAND
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.examples/runexample_c1.sh	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,23 @@
+#!/bin/bash
+if [ -z "${JDK7}" ]; then
+  echo "JDK7 is not defined."
+  exit 1;
+fi
+if [ -z "${MAXINE}" ]; then
+  echo "MAXINE is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${GRAAL}" ]; then
+  echo "GRAAL is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${DACAPO}" ]; then
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
+  exit 1;
+fi
+TEST=$1
+shift
+ant -f create_examples.xml
+COMMAND="${JDK7G}/bin/java -client -d64 -Xmx1g -esa -XX:+PrintCFGToFile -XX:+PrintCompilation -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*,<init> -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}"
+# echo $COMMAND
+$COMMAND
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.examples/runexample_c2.sh	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,23 @@
+#!/bin/bash
+if [ -z "${JDK7}" ]; then
+  echo "JDK7 is not defined."
+  exit 1;
+fi
+if [ -z "${MAXINE}" ]; then
+  echo "MAXINE is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${GRAAL}" ]; then
+  echo "GRAAL is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${DACAPO}" ]; then
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
+  exit 1;
+fi
+TEST=$1
+shift
+ant -f create_examples.xml
+COMMAND="${JDK7G}/bin/java -d64 -Xmx1g -esa -XX:+PrintCompilation -XX:PrintIdealGraphLevel=1 -Xcomp -XX:CompileOnly=examples -XX:CompileCommand=quiet -XX:CompileCommand=exclude,*,<init> -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}"
+# echo $COMMAND
+$COMMAND
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.examples/runexamplescompare.sh	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,29 @@
+#!/bin/bash
+if [ -z "${JDK7}" ]; then
+  echo "JDK7 is not defined."
+  exit 1;
+fi
+if [ -z "${MAXINE}" ]; then
+  echo "MAXINE is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${GRAAL}" ]; then
+  echo "GRAAL is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${DACAPO}" ]; then
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
+  exit 1;
+fi
+TEST=$1
+shift
+ant -f create_examples.xml
+COMMAND="${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -G:Extend -Xcomp -XX:CompileOnly=examples $* -jar examples.jar ${TEST}"
+echo $COMMAND
+$COMMAND
+COMMAND="${JDK7}/bin/java -client -d64 -Xms1g -Xmx2g -esa -Xcomp -XX:CompileOnly=examples $* -jar examples.jar ${TEST}"
+echo $COMMAND
+$COMMAND
+COMMAND="${JDK7}/bin/java -server -d64 -Xms1g -Xmx2g -esa -Xcomp -XX:CompileOnly=examples $* -jar examples.jar ${TEST}"
+echo $COMMAND
+$COMMAND
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java	Mon Jul 18 11:56:49 2011 +0200
@@ -26,15 +26,28 @@
 import com.oracle.max.graal.examples.inlining.*;
 import com.oracle.max.graal.examples.intrinsics.*;
 import com.oracle.max.graal.examples.opt.*;
-
+import com.oracle.max.graal.examples.simple.*;
 
 public class Main {
 
     public static void main(String[] args) {
-//        InliningExample.run();
-//        SafeAddExample.run();
-//        OptimizationExample.run();
-        DeoptExample.run();
+        System.err.println("== Graal Examples ==");
+        if (args.length == 1) {
+            if (args[0].equals("simple")) {
+                SimpleExample.run();
+            } else if (args[0].equals("inlining")) {
+                InliningExample.run();
+            } else if (args[0].equals("safeadd")) {
+                SafeAddExample.run();
+            } else if (args[0].equals("opt")) {
+                OptimizationExample.run();
+            } else if (args[0].equals("deopt")) {
+                DeoptExample.run();
+            } else {
+                System.out.println("unknown example: " + args[0]);
+            }
+        } else {
+            System.out.println("usage: java " + Main.class.getSimpleName() + " <example>");
+        }
     }
-
 }
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java	Mon Jul 18 11:56:49 2011 +0200
@@ -32,20 +32,20 @@
         System.out.println();
         System.out.println("Running Deopt Example");
         long start = System.currentTimeMillis();
-        System.out.println("result1=" + test());
+        System.out.println("result1=" + new DeoptExample().test());
         System.out.println("time=" + (System.currentTimeMillis() - start) + "ms");
     }
 
-    private static int test() {
+    private int test() {
         try {
-            return testDeopt(3000000);
+            return testDeopt(90000);
         } catch (IllegalStateException e) {
             System.out.println(e.getMessage());
             return 0;
         }
     }
 
-    private static int testDeopt(int n) {
+    private int testDeopt(int n) {
         int sum = 0;
         for (int i = 0; i < n; i = SafeAddExample.safeAdd(i, 1)) {
             sum = SafeAddExample.safeAdd(sum, i);
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java	Mon Jul 18 11:56:49 2011 +0200
@@ -22,14 +22,58 @@
  */
 package com.oracle.max.graal.examples.deopt;
 
+import java.lang.reflect.*;
+
+import com.sun.cri.ri.*;
+
 
 public class DeoptHandler {
 
+    /**
+     * Deoptimization handler method for methods with a void return parameter.
+     */
+    public void handle_void(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) {
+        handle(method, bci, values, numLocals, numStack, numLocks);
+    }
 
-    public static int test(int bci, Object[] values) {
-        System.out.println("values at bci " + bci + ": ");
-        for (Object value : values) {
-            System.out.print(value + " ");
+    /**
+     * Deoptimization handler method for methods with an int return parameter.
+     */
+    public int handle_int(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) {
+        handle(method, bci, values, numLocals, numStack, numLocks);
+        return 123;
+    }
+
+    /**
+     * Deoptimization handler method for methods with an object return parameter.
+     */
+    public Object handle_object(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) {
+        handle(method, bci, values, numLocals, numStack, numLocks);
+        return null;
+    }
+
+    /**
+     * Deoptimization handler method: prints the current state of the method execution.
+     */
+    public int handle(RiMethod method, int bci, Object[] values, int numLocals, int numStack, int numLocks) {
+        System.out.printf("Deoptimization: %s@%d", method.name(), bci);
+        int p = 0;
+        System.out.print("\nArguments: ");
+        int argCount = method.signature().argumentCount(!Modifier.isStatic(method.accessFlags()));
+        for (int i = 0; i < argCount; i++) {
+            System.out.printf("%s ", values[p++]);
+        }
+        System.out.print("\nLocals: ");
+        for (int i = argCount; i < numLocals; i++) {
+            System.out.printf("%s ", values[p++]);
+        }
+        System.out.print("\nExpression stack: ");
+        for (int i = 0; i < numStack; i++) {
+            System.out.printf("%s ", values[p++]);
+        }
+        System.out.print("\nLocks: ");
+        for (int i = 0; i < numLocks; i++) {
+            System.out.printf("%s ", values[p++]);
         }
         System.out.println();
         return 2;
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java	Mon Jul 18 11:56:49 2011 +0200
@@ -22,38 +22,54 @@
  */
 package com.oracle.max.graal.examples.deopt;
 
+import java.util.*;
+
 import com.oracle.max.graal.extensions.*;
 import com.sun.cri.ci.*;
+import com.sun.cri.ci.CiVirtualObject.*;
 import com.sun.cri.ri.*;
 
 
 public class FrameModifierImpl implements FrameModifier {
+    private static DeoptHandler HANDLER = new DeoptHandler();
 
     @Override
     public CiFrame getFrame(RiRuntime runtime, CiFrame frame) {
-        try {
-            DeoptHandler.class.getMethod("test", Integer.TYPE, Object[].class);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return frame;
-        }
         if (frame.method.name().equals("testDeopt")) {
+            // get the handler method
             RiType type = runtime.getType(DeoptHandler.class);
-            RiMethod method = type.getMethod("test", "(I[Ljava/lang/Object;)I");
-            System.out.println("Size: " + method.maxLocals() + " " + method.maxStackSize());
-            RiType arrayType = runtime.getType(Object.class).arrayOf();
-            CiValue[] values = new CiValue[frame.values.length];
-            for (int i = 0; i < values.length; i++) {
-                values[i] = CiVirtualObject.proxy(runtime, frame.values[i], i + 2);
+            CiKind returnKind = frame.method.signature().returnKind();
+            String methodName = "handle_" + returnKind;
+            String methodSignature = "(Lcom/sun/cri/ri/RiMethod;I[Ljava/lang/Object;III)" + returnKind.signatureChar();
+            RiMethod handlerMethod = type.getMethod(methodName, methodSignature);
+            assert handlerMethod != null : methodName + " not found...";
+
+            // put the current state (local vars, expressions, etc.) into an array
+            CiVirtualObjectFactory factory = new CiVirtualObjectFactory(runtime);
+            ArrayList<CiValue> originalValues = new ArrayList<CiValue>();
+            for (int i = 0; i < frame.values.length; i += frame.values[i].kind.sizeInSlots()) {
+                originalValues.add(factory.proxy(frame.values[i]));
             }
-            CiVirtualObject local = CiVirtualObject.get(arrayType, values, 0);
-            CiValue[] values2 = new CiValue[method.maxLocals()];
-            values2[0] = CiConstant.forInt(frame.bci);
-            values2[1] = local;
-            for (int i = 2; i < values2.length; i++) {
-                values2[i] = CiValue.IllegalValue;
+            CiValue boxedValues = factory.arrayProxy(runtime.getType(Object[].class), originalValues.toArray(new CiValue[originalValues.size()]));
+
+            // build the list of arguments
+            CiValue[] newValues = new CiValue[handlerMethod.maxLocals()];
+            int p = 0;
+            newValues[p++] = CiConstant.forObject(HANDLER);         // receiver
+            newValues[p++] = CiConstant.forObject(frame.method);    // method that caused deoptimization
+            newValues[p++] = CiConstant.forInt(frame.bci);          // bytecode index
+            newValues[p++] = boxedValues;                           // original locals, expression stack and locks
+            newValues[p++] = CiConstant.forInt(frame.numLocals);    // number of locals
+            newValues[p++] = CiConstant.forInt(frame.numStack);     // size of expression stack
+            newValues[p++] = CiConstant.forInt(frame.numLocks);     // number of locks
+
+            // fill the rest of the local variables with zeros
+            while (p < newValues.length) {
+                newValues[p++] = CiValue.IllegalValue;
             }
-            return new CiFrame((CiFrame) frame.caller, method, 0, false, values2, method.maxLocals(), 0, 0);
+
+            // ... and return a new frame that points to the start of the handler method
+            return new CiFrame((CiFrame) frame.caller, handlerMethod, /*bci*/ 0, false, newValues, handlerMethod.maxLocals(), 0, 0);
         }
         return frame;
     }
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java	Mon Jul 18 11:56:49 2011 +0200
@@ -36,8 +36,10 @@
 
     @Override
     public void optimize(RiRuntime runtime, Graph graph) {
+        // iterate over all instanceof of SafeAddNode in the graph
         for (SafeAddNode safeAdd : graph.getNodes(SafeAddNode.class)) {
             if (!canOverflow(safeAdd)) {
+                // if an overflow is impossible: replace with normal add
                 IntegerAdd add = new IntegerAdd(CiKind.Int, safeAdd.x(), safeAdd.y(), graph);
                 safeAdd.replaceAndDelete(add);
             }
@@ -45,11 +47,15 @@
     }
 
     private boolean canOverflow(SafeAddNode safeAdd) {
+        // if this SafeAddNode always adds 1 ...
         if (safeAdd.y().isConstant() && safeAdd.y().asConstant().asLong() == 1) {
+            // ... to a phi ...
             if (safeAdd.x() instanceof Phi) {
                 Phi phi = (Phi) safeAdd.x();
+                // ... that belongs to a loop and merges into itself ...
                 if (phi.merge() instanceof LoopBegin && phi.valueAt(1) == safeAdd) {
                     LoopBegin loopBegin = (LoopBegin) phi.merge();
+                    // ... then do the heavy analysis.
                     return canOverflow(phi, loopBegin);
                 }
             }
@@ -58,14 +64,16 @@
     }
 
     private boolean canOverflow(Phi phi, LoopBegin loopBegin) {
-
         NodeBitMap nodes = LoopUtil.markUpCFG(loopBegin);
         NodeBitMap exits = LoopUtil.computeLoopExits(loopBegin, nodes);
+        // look at all loop exits:
         for (Node exit : exits) {
             TTY.println("exit: " + exit);
             Node pred = exit.predecessors().get(0);
+            // if this exit is an If node ...
             if (pred instanceof If) {
                 If ifNode = (If) pred;
+                // ... which compares ...
                 if (ifNode.compare() instanceof Compare) {
                     Compare compare = (Compare) ifNode.compare();
                     Condition cond = compare.condition();
@@ -74,6 +82,7 @@
                     if (ifNode.trueSuccessor() == pred) {
                         cond = cond.negate();
                     }
+                    // ... the phi against a value, then this phi cannot overflow.
                     if (cond == Condition.LT && x == phi) {
                         return false;
                     }
@@ -81,7 +90,6 @@
                         return false;
                     }
                 }
-
             }
         }
         TTY.println("can overflow");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/simple/SimpleExample.java	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2011, 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.max.graal.examples.simple;
+
+
+public class SimpleExample {
+
+    public static void run() {
+        System.out.println(mulAdd(1, 2, 3));
+        System.out.println(divAdd(1, 2, 3));
+    }
+
+    private static int mulAdd(int a, int b, int c) {
+        return a * b + c;
+    }
+
+    private static int divAdd(int a, int b, int c) {
+        return a / b + c;
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Thu Jul 14 22:22:44 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Mon Jul 18 11:56:49 2011 +0200
@@ -25,9 +25,7 @@
 
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.graph.Selector;
-import com.sun.hotspot.igv.data.Properties;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -52,48 +50,26 @@
     }
 
     public void apply(Diagram diagram) {
-
         for (RemoveRule r : rules) {
+            List<Figure> selected = r.getSelector().selected(diagram);
+            Set<Figure> toRemove = new HashSet<Figure>(selected);
 
-            List<Figure> list = r.getSelector().selected(diagram);
-            Set<Figure> figuresToRemove = new HashSet<Figure>();
-
-            List<Figure> protectedFigures = null;
-            if (r.getRemoveAllWithoutPredecessor()) {
-                protectedFigures = diagram.getRootFigures();
+            if (r.getRemoveOrphans()) {
+                boolean changed;
+                do {
+                    changed = false;
+                    for (Figure f : diagram.getFigures()) {
+                        if (!toRemove.contains(f)) {
+                            if (toRemove.containsAll(f.getPredecessors()) && toRemove.containsAll(f.getSuccessors())) {
+                                toRemove.add(f);
+                                changed = true;
+                            }
+                        }
+                    }
+                } while (changed);
             }
 
-            for (Figure f : list) {
-                if (r.getRemoveOnlyInputs()) {
-                    List<InputSlot> inputSlots = new ArrayList<InputSlot>();
-                    for (InputSlot is : f.getInputSlots()) {
-                        inputSlots.add(is);
-                    }
-                    for (InputSlot is : inputSlots) {
-                        f.removeSlot(is);
-                    }
-
-                    f.createInputSlot();
-                } else {
-                    figuresToRemove.add(f);
-                }
-            }
-
-            if (r.getRemoveAllWithoutPredecessor()) {
-                boolean progress = true;
-                while (progress) {
-                    List<Figure> rootFigures = diagram.getRootFigures();
-                    progress = false;
-                    for (Figure f : rootFigures) {
-                        if (!protectedFigures.contains(f)) {
-                            figuresToRemove.add(f);
-                            progress = true;
-                        }
-                    }
-                }
-            }
-
-            diagram.removeAllFigures(figuresToRemove);
+            diagram.removeAllFigures(toRemove);
         }
     }
 
@@ -104,29 +80,23 @@
     public static class RemoveRule {
 
         private Selector selector;
-        private boolean removeAllWithoutPredecessor;
-        private boolean removeOnlyInputs;
+        private boolean removeOrphans;
 
-        public RemoveRule(Selector selector, boolean b) {
-            this(selector, b, false);
+        public RemoveRule(Selector selector) {
+            this(selector, false);
         }
 
-        public RemoveRule(Selector selector, boolean removeAllWithoutPredecessor, boolean removeOnlyInputs) {
+        public RemoveRule(Selector selector, boolean removeOrphans) {
             this.selector = selector;
-            this.removeOnlyInputs = removeOnlyInputs;
-            this.removeAllWithoutPredecessor = removeAllWithoutPredecessor;
+            this.removeOrphans = removeOrphans;
         }
 
         public Selector getSelector() {
             return selector;
         }
 
-        public boolean getRemoveOnlyInputs() {
-            return removeOnlyInputs;
-        }
-
-        public boolean getRemoveAllWithoutPredecessor() {
-            return removeAllWithoutPredecessor;
+        public boolean getRemoveOrphans() {
+            return removeOrphans;
         }
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Thu Jul 14 22:22:44 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Mon Jul 18 11:56:49 2011 +0200
@@ -35,7 +35,13 @@
 
 function remove(property, regexp) {
     var f = new RemoveFilter("");
-    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), false, false));
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp))));
+    f.apply(graph);
+}
+
+function removeIncludingOrphans(property, regexp) {
+    var f = new RemoveFilter("");
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), true));
     f.apply(graph);
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalGradientColorFilter.java	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2011, 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.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Color;
+import java.awt.LinearGradientPaint;
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.image.Raster;
+import java.util.List;
+
+/**
+ * Filter that colors nodes using a customizable color gradient, based on how
+ * a numeric property is located in a specified interval.
+ * 
+ * @author Peter Hofer
+ */
+public class GraalGradientColorFilter {
+
+    public enum Mode {
+        LINEAR,
+        LOGARITHMIC
+    };
+
+    private String propertyName = "probability";
+    private float minValue = 0;
+    private float maxValue = 500;
+    private float[] fractions = {0, 0.5f, 1};
+    private Color[] colors = {Color.BLUE, Color.YELLOW, Color.RED};
+    private int shadeCount = 8;
+    private Mode mode = Mode.LOGARITHMIC;
+
+    public void apply(Diagram d) {
+        Rectangle bounds = new Rectangle(shadeCount, 1);
+        LinearGradientPaint lgp = new LinearGradientPaint(bounds.x, bounds.y, bounds.width, bounds.y, fractions, colors);
+        PaintContext context = lgp.createContext(null, bounds, bounds.getBounds2D(), AffineTransform.getTranslateInstance(0, 0), new RenderingHints(null));
+        Raster raster = context.getRaster(bounds.x, bounds.y, bounds.width, bounds.height);
+        int[] rgb = raster.getPixels(bounds.x, bounds.y, bounds.width, bounds.height, (int[]) null);
+        Color[] shades = new Color[rgb.length / 3];
+        for (int i = 0; i < shades.length; ++i) {
+            shades[i] = new Color(rgb[i * 3], rgb[i * 3 + 1], rgb[i * 3 + 2]);
+        }
+
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            String property = f.getProperties().get(propertyName);
+            if (property != null) {
+                try {
+                    float value = Float.parseFloat(property);
+
+                    Color nodeColor;
+                    if (value <= minValue) {
+                        nodeColor = colors[0];
+                    } else if (value >= maxValue) {
+                        nodeColor = colors[colors.length - 1];
+                    } else {
+                        double normalized = value - minValue;
+                        double interval = maxValue - minValue;
+                        int index;
+                        // Use Math.ceil() to make values above zero distinguishable from zero
+                        if (mode == Mode.LOGARITHMIC) {
+                            index = (int) Math.ceil(shades.length * Math.log(1 + normalized) / Math.log(1 + interval));
+                        } else if (mode == Mode.LINEAR) {
+                            index = (int) Math.ceil(shades.length * normalized / interval);
+                        } else {
+                            throw new RuntimeException("Unknown mode");
+                        }
+                        nodeColor = shades[index];
+                    }
+                    f.setColor(nodeColor);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropertyName(String propertyName) {
+        this.propertyName = propertyName;
+    }
+
+    public float getMinValue() {
+        return minValue;
+    }
+
+    public void setMinValue(float minValue) {
+        this.minValue = minValue;
+    }
+
+    public float getMaxValue() {
+        return maxValue;
+    }
+
+    public void setMaxValue(float maxValue) {
+        this.maxValue = maxValue;
+    }
+
+    public float[] getFractions() {
+        return fractions;
+    }
+
+    public void setFractions(float[] fractions) {
+        this.fractions = fractions;
+    }
+
+    public Color[] getColors() {
+        return colors;
+    }
+
+    public void setColors(Color[] colors) {
+        this.colors = colors;
+    }
+
+    public int getShadeCount() {
+        return shadeCount;
+    }
+
+    public void setShadeCount(int steps) {
+        this.shadeCount = steps;
+    }
+
+    public Mode getMode() {
+        return mode;
+    }
+
+    public void setMode(Mode mode) {
+        this.mode = mode;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/probability.filter	Mon Jul 18 11:56:49 2011 +0200
@@ -0,0 +1,9 @@
+var pf = new com.sun.hotspot.igv.graal.filters.GraalGradientColorFilter();
+pf.setMode(com.sun.hotspot.igv.graal.filters.GraalGradientColorFilter.Mode.LOGARITHMIC);
+pf.setPropertyName("probability");
+pf.setMinValue(0);
+pf.setMaxValue(500);
+pf.setColors([blue, yellow, red]);
+pf.setFractions([0, 0.5, 1]);
+pf.setShadeCount(8);
+pf.apply(graph);
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Thu Jul 14 22:22:44 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Mon Jul 18 11:56:49 2011 +0200
@@ -13,5 +13,9 @@
         <file name="Graal Slot Filter" url="filters/slots.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
+        
+        <file name="Graal Probability Filter" url="filters/probability.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
     </folder>
 </filesystem>
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter	Thu Jul 14 22:22:44 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter	Mon Jul 18 11:56:49 2011 +0200
@@ -20,5 +20,5 @@
     ), false
   )
 );
-f.addRule( new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store.")), false));
+f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store."))));
 f.apply(graph);
\ No newline at end of file