# HG changeset patch # User Gilles Duboscq # Date 1310983009 -7200 # Node ID c762ddb64bc9d439a5944cba0aa0d39998eda7a1 # Parent 034a4db85c59afc70e88977d9a0ac911d5292413# Parent 9518546712e1fb30fef9edc699164b1b7e8cea0a Merge diff -r 034a4db85c59 -r c762ddb64bc9 .hgignore --- 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/ diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- 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 = ____; diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- 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(); diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- 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; diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/MergeableState.java --- /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 clone(); + boolean merge(Merge merge, Collection withStates); + void loopBegin(LoopBegin loopBegin); + void loopEnd(LoopEnd loopEnd, T loopEndState); + void afterSplit(FixedNode node); +} diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/PostOrderNodeIterator.java --- /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> { + + private final NodeBitMap visitedEnds; + private final Deque nodeQueue; + private final HashMap nodeStates; + private final FixedNode start; + + protected T state; + + public PostOrderNodeIterator(FixedNode start, T initialState) { + visitedEnds = start.graph().createNodeBitMap(); + nodeQueue = new ArrayDeque(); + nodeStates = new HashMap(); + 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 states = new ArrayList(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); + } +} diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedNode.java --- 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 getDebugProperties() { Map properties = super.getDebugProperties(); - properties.put("probability", String.format("%7.5f", probability)); + properties.put("probability", String.format(Locale.ENGLISH, "%7.5f", probability)); return properties; } diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java --- 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 { diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java --- 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 clone(); - boolean merge(Merge merge, Collection withStates); - void loopBegin(LoopBegin loopBegin); - void loopEnd(LoopEnd loopEnd, T loopEndState); - void afterSplit(FixedNode node); - } - - public abstract static class PostOrderNodeIterator> { - - private final NodeBitMap visitedEnds; - private final Deque nodeQueue; - private final HashMap nodeStates; - private final FixedNode start; - - protected T state; - - public PostOrderNodeIterator(FixedNode start, T initialState) { - visitedEnds = start.graph().createNodeBitMap(); - nodeQueue = new ArrayDeque(); - nodeStates = new HashMap(); - 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 states = new ArrayList(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 { public final Value[] fieldState; public final VirtualObject virtualObject; diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- 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); } } diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java --- 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 currentPhase = new ThreadLocal(); 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)); } diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/extensions/InliningExample.java --- 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); - } -} diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/create_examples.xml --- /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 @@ + + + + + + + + + + + + + + diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/runexample.sh --- /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,*, -XX:CompileCommand=exclude,*, -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" +# echo $COMMAND +$COMMAND diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/runexample_c1.sh --- /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,*, -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" +# echo $COMMAND +$COMMAND diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/runexample_c2.sh --- /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,*, -XX:CompileCommand=exclude,*,run -XX:CompileCommand=exclude,com.oracle.max.graal.examples.Main::main $* -jar examples.jar ${TEST}" +# echo $COMMAND +$COMMAND diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/runexamplescompare.sh --- /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 diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java --- 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() + " "); + } } - } diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptExample.java --- 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); diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/DeoptHandler.java --- 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; diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/deopt/FrameModifierImpl.java --- 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 originalValues = new ArrayList(); + 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; } diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java --- 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"); diff -r 034a4db85c59 -r c762ddb64bc9 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/simple/SimpleExample.java --- /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; + } +} diff -r 034a4db85c59 -r c762ddb64bc9 src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java --- 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
selected = r.getSelector().selected(diagram); + Set
toRemove = new HashSet
(selected); - List
list = r.getSelector().selected(diagram); - Set
figuresToRemove = new HashSet
(); - - List
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 inputSlots = new ArrayList(); - 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
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; } } } diff -r 034a4db85c59 -r c762ddb64bc9 src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js --- 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); } diff -r 034a4db85c59 -r c762ddb64bc9 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalGradientColorFilter.java --- /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
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; + } +} diff -r 034a4db85c59 -r c762ddb64bc9 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/probability.filter --- /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); diff -r 034a4db85c59 -r c762ddb64bc9 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml --- 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 @@ + + + + diff -r 034a4db85c59 -r c762ddb64bc9 src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter --- 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