changeset 2602:0c6564c254af

new node layout: BlockBegin, BlockEnd -Dc1x.dot=regex for pdf output escape dot graph labels (<, >, &)
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 06 May 2011 10:25:37 +0200
parents 224e8b4007bd
children 01c5c0443158
files graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java graal/GraalCompiler/src/com/sun/c1x/C1XCompiler.java graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java graal/GraalCompiler/src/com/sun/c1x/graph/IR.java graal/GraalCompiler/src/com/sun/c1x/ir/Base.java graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionObject.java graal/GraalCompiler/src/com/sun/c1x/ir/Goto.java graal/GraalCompiler/src/com/sun/c1x/ir/If.java graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java graal/GraalCompiler/src/com/sun/c1x/ir/MonitorAddress.java graal/GraalCompiler/src/com/sun/c1x/ir/Return.java graal/GraalCompiler/src/com/sun/c1x/ir/Switch.java graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java graal/GraalGraph/src/com/oracle/graal/graph/vis/GraphvizPrinter.java rundacapo.sh runscimark.sh
diffstat 21 files changed, 352 insertions(+), 199 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java	Fri May 06 10:25:37 2011 +0200
@@ -166,7 +166,7 @@
      */
     public BlockMap getBlockMap(RiMethod method) {
         // PERF: cache the block map for methods that are compiled or inlined often
-        BlockMap map = new BlockMap(method, hir.numberOfBlocks());
+        BlockMap map = new BlockMap(method, hir.numberOfBlocks(), hir.graph());
         if (!map.build(C1XOptions.PhiLoopStores)) {
             throw new CiBailout("build of BlockMap failed for " + method);
         } else {
@@ -309,4 +309,5 @@
     public static C1XCompilation compilationOrNull() {
         return currentCompilation.get();
     }
+
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XCompiler.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XCompiler.java	Fri May 06 10:25:37 2011 +0200
@@ -22,8 +22,12 @@
  */
 package com.sun.c1x;
 
+import java.io.*;
 import java.util.*;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.vis.*;
+import com.oracle.graal.graph.vis.GraphvizTest.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.globalstub.*;
 import com.sun.c1x.observer.*;
@@ -125,6 +129,45 @@
         if (C1XOptions.PrintCFGToFile) {
             addCompilationObserver(new CFGPrinterObserver());
         }
+        String dot = System.getProperty("c1x.dot");
+        if (dot != null && !dot.isEmpty()) {
+            if (!dot.endsWith("$")) {
+                dot = dot + ".*";
+            }
+            if (!dot.startsWith("^")) {
+                dot = ".*" + dot;
+            }
+            final String dotPattern = dot;
+            addCompilationObserver(new CompilationObserver() {
+                private Graph graph;
+                public void compilationStarted(CompilationEvent event) {
+                }
+                public void compilationFinished(CompilationEvent event) {
+                    String name = event.getMethod().holder().name();
+                    name = name.substring(1, name.length() - 1).replace('/', '.');
+                    name = name + "." + event.getMethod().name();
+                    if (name.matches(dotPattern)) {
+                        ByteArrayOutputStream out = new ByteArrayOutputStream();
+                        GraphvizPrinter printer = new GraphvizPrinter(out);
+                        printer.begin("Simple test");
+                        printer.print(graph);
+                        printer.end();
+
+                        try {
+                            GraphvizRunner.process(GraphvizRunner.DOT_COMMAND, new ByteArrayInputStream(out.toByteArray()),
+                                            new FileOutputStream(name + ".pdf"), "pdf");
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+                public void compilationEvent(CompilationEvent event) {
+                    if (event.getStartBlock() != null) {
+                        graph = event.getStartBlock().graph();
+                    }
+                }
+            });
+        }
     }
 
     public GlobalStub lookupGlobalStub(GlobalStub.Id id) {
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Fri May 06 10:25:37 2011 +0200
@@ -560,7 +560,7 @@
             int len = x.numberOfCases();
             for (int i = 0; i < len; i++) {
                 lir.cmp(Condition.EQ, tag, x.keyAt(i));
-                lir.branch(Condition.EQ, CiKind.Int, x.suxAt(i));
+                lir.branch(Condition.EQ, CiKind.Int, x.blockSuccessor(i));
             }
             lir.jump(x.defaultSuccessor());
         } else {
@@ -825,7 +825,7 @@
             int len = x.numberOfCases();
             for (int i = 0; i < len; i++) {
                 lir.cmp(Condition.EQ, tag, i + loKey);
-                lir.branch(Condition.EQ, CiKind.Int, x.suxAt(i));
+                lir.branch(Condition.EQ, CiKind.Int, x.blockSuccessor(i));
             }
             lir.jump(x.defaultSuccessor());
         } else {
@@ -1150,11 +1150,11 @@
         if (len > 0) {
             BlockBegin defaultSux = x.defaultSuccessor();
             int key = x.keyAt(0);
-            BlockBegin sux = x.suxAt(0);
+            BlockBegin sux = x.blockSuccessor(0);
             SwitchRange range = new SwitchRange(key, sux);
             for (int i = 1; i < len; i++) {
                 int newKey = x.keyAt(i);
-                BlockBegin newSux = x.suxAt(i);
+                BlockBegin newSux = x.blockSuccessor(i);
                 if (key + 1 == newKey && sux == newSux) {
                     // still in same range
                     range.highKey = newKey;
@@ -1180,12 +1180,12 @@
         List<SwitchRange> res = new ArrayList<SwitchRange>(x.numberOfCases());
         int len = x.numberOfCases();
         if (len > 0) {
-            BlockBegin sux = x.suxAt(0);
+            BlockBegin sux = x.blockSuccessor(0);
             int key = x.lowKey();
             BlockBegin defaultSux = x.defaultSuccessor();
             SwitchRange range = new SwitchRange(key, sux);
             for (int i = 0; i < len; i++, key++) {
-                BlockBegin newSux = x.suxAt(i);
+                BlockBegin newSux = x.blockSuccessor(i);
                 if (sux == newSux) {
                     // still in same range
                     range.highKey = key;
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java	Fri May 06 10:25:37 2011 +0200
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.ir.*;
 import com.sun.c1x.util.*;
 import com.sun.cri.bytecode.*;
@@ -115,8 +116,6 @@
  *
  * If the {@code computeStoresInLoops} argument to {@code build} is true, the {@code loopBlocks} list is processed to
  * mark all local variables that are stored in the blocks in the list.
- *
- * @author Ben L. Titzer
  */
 public final class BlockMap {
 
@@ -222,12 +221,16 @@
      */
     private int blockNum;
 
+    private final Graph graph;
+
     /**
      * Creates a new BlockMap instance from bytecode of the given method .
      * @param method the compiler interface method containing the code
      * @param firstBlockNum the first block number to use when creating {@link BlockBegin} nodes
+     * @param graph
      */
-    public BlockMap(RiMethod method, int firstBlockNum) {
+    public BlockMap(RiMethod method, int firstBlockNum, Graph graph) {
+        this.graph = graph;
         byte[] code = method.code();
         this.code = code;
         firstBlock = firstBlockNum;
@@ -265,7 +268,7 @@
     BlockBegin make(int bci) {
         BlockBegin block = blockMap[bci];
         if (block == null) {
-            block = new BlockBegin(bci, blockNum++);
+            block = new BlockBegin(bci, blockNum++, graph);
             blockMap[bci] = block;
         }
         return block;
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Fri May 06 10:25:37 2011 +0200
@@ -124,18 +124,16 @@
     boolean skipBlock;                     // skip processing of the rest of this block
     private Value rootMethodSynchronizedObject;
 
-
-
-    private Graph graph = new Graph();
-
+    private final Graph graph;
 
     /**
      * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation.
      *
      * @param compilation the compilation
      * @param ir the IR to build the graph into
+     * @param graph
      */
-    public GraphBuilder(C1XCompilation compilation, IR ir) {
+    public GraphBuilder(C1XCompilation compilation, IR ir, Graph graph) {
         this.compilation = compilation;
         this.ir = ir;
         this.stats = compilation.stats;
@@ -144,6 +142,7 @@
         log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
         stream = new BytecodeStream(compilation.method.code());
         constantPool = compilation.runtime.getConstantPool(compilation.method);
+        this.graph = graph;
     }
 
     /**
@@ -163,7 +162,7 @@
         }
 
         // 1. create the start block
-        ir.startBlock = new BlockBegin(0, ir.nextBlockNumber());
+        ir.startBlock = new BlockBegin(0, ir.nextBlockNumber(), graph);
         BlockBegin startBlock = ir.startBlock;
 
         // 2. compute the block map, setup exception handlers and get the entrypoint(s)
@@ -200,7 +199,7 @@
             finishStartBlock(startBlock, stdEntry);
 
             // 4A.3 setup an exception handler to unlock the root method synchronized object
-            syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, ir.nextBlockNumber());
+            syncHandler = new BlockBegin(Instruction.SYNCHRONIZATION_ENTRY_BCI, ir.nextBlockNumber(), graph);
             syncHandler.setExceptionEntry();
             syncHandler.setBlockFlag(BlockBegin.BlockFlag.IsOnWorkList);
             syncHandler.setBlockFlag(BlockBegin.BlockFlag.DefaultExceptionHandler);
@@ -227,7 +226,7 @@
 
     private void finishStartBlock(BlockBegin startBlock, BlockBegin stdEntry) {
         assert curBlock == startBlock;
-        Base base = new Base(stdEntry);
+        Base base = new Base(stdEntry, graph);
         appendWithoutOptimization(base, 0);
         FrameState stateAfter = curState.immutableCopy(bci());
         base.setStateAfter(stateAfter);
@@ -600,7 +599,7 @@
 
     void genGoto(int fromBCI, int toBCI) {
         boolean isSafepoint = !noSafepoints() && toBCI <= fromBCI;
-        append(new Goto(blockAt(toBCI), null, isSafepoint));
+        append(new Goto(blockAt(toBCI), null, isSafepoint, graph));
     }
 
     void ifNode(Value x, Condition cond, Value y, FrameState stateBefore) {
@@ -608,7 +607,7 @@
         BlockBegin fsucc = blockAt(stream().nextBCI());
         int bci = stream().currentBCI();
         boolean isSafepoint = !noSafepoints() && tsucc.bci() <= bci || fsucc.bci() <= bci;
-        append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint));
+        append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint, graph));
     }
 
     void genIfZero(Condition cond) {
@@ -634,7 +633,7 @@
 
     void genThrow(int bci) {
         FrameState stateBefore = curState.immutableCopy(bci());
-        Throw t = new Throw(apop(), stateBefore, !noSafepoints());
+        Throw t = new Throw(apop(), stateBefore, !noSafepoints(), graph);
         appendWithoutOptimization(t, bci);
     }
 
@@ -1018,13 +1017,13 @@
             int lockNumber = curState.locksSize() - 1;
             MonitorAddress lockAddress = null;
             if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
-                lockAddress = new MonitorAddress(lockNumber);
+                lockAddress = new MonitorAddress(lockNumber, graph);
                 append(lockAddress);
             }
             append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, stateBefore, graph));
             curState.unlock();
         }
-        append(new Return(x, !noSafepoints()));
+        append(new Return(x, !noSafepoints(), graph));
     }
 
     /**
@@ -1038,7 +1037,7 @@
         int lockNumber = locksSize();
         MonitorAddress lockAddress = null;
         if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
-            lockAddress = new MonitorAddress(lockNumber);
+            lockAddress = new MonitorAddress(lockNumber, graph);
             append(lockAddress);
         }
         MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph);
@@ -1055,7 +1054,7 @@
         }
         MonitorAddress lockAddress = null;
         if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
-            lockAddress = new MonitorAddress(lockNumber);
+            lockAddress = new MonitorAddress(lockNumber, graph);
             append(lockAddress);
         }
         appendWithoutOptimization(new MonitorExit(x, lockAddress, lockNumber, null, graph), bci);
@@ -1088,7 +1087,7 @@
         list.add(blockAt(bci + offset));
         boolean isSafepoint = isBackwards && !noSafepoints();
         FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null;
-        append(new TableSwitch(ipop(), list, ts.lowKey(), stateBefore, isSafepoint));
+        append(new TableSwitch(ipop(), list, ts.lowKey(), stateBefore, isSafepoint, graph));
     }
 
     void genLookupswitch() {
@@ -1110,7 +1109,7 @@
         list.add(blockAt(bci + offset));
         boolean isSafepoint = isBackwards && !noSafepoints();
         FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null;
-        append(new LookupSwitch(ipop(), list, keys, stateBefore, isSafepoint));
+        append(new LookupSwitch(ipop(), list, keys, stateBefore, isSafepoint, graph));
     }
 
     /**
@@ -1262,7 +1261,7 @@
         curState = syncHandler.stateBefore().copy();
 
         int bci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
-        Value exception = appendWithoutOptimization(new ExceptionObject(curState.immutableCopy(bci)), bci);
+        Value exception = appendWithoutOptimization(new ExceptionObject(curState.immutableCopy(bci), graph), bci);
 
         assert lock != null;
         assert curState.locksSize() > 0 && curState.lockAt(locksSize() - 1) == lock;
@@ -1327,7 +1326,7 @@
             }
             if (nextBlock != null && nextBlock != block) {
                 // we fell through to the next block, add a goto and break
-                end = new Goto(nextBlock, null, false);
+                end = new Goto(nextBlock, null, false, graph);
                 lastInstr = lastInstr.appendNext(end, prevBCI);
                 break;
             }
@@ -1337,7 +1336,7 @@
             // push an exception object onto the stack if we are parsing an exception handler
             if (pushException) {
                 FrameState stateBefore = curState.immutableCopy(bci());
-                apush(append(new ExceptionObject(stateBefore)));
+                apush(append(new ExceptionObject(stateBefore, graph)));
                 pushException = false;
             }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Fri May 06 10:25:37 2011 +0200
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.ir.*;
@@ -61,6 +62,8 @@
      */
     private List<BlockBegin> orderedBlocks;
 
+    private final Graph graph = new Graph();
+
     /**
      * Creates a new IR instance for the specified compilation.
      * @param compilation the compilation
@@ -93,7 +96,7 @@
 
     private void buildGraph() {
         // Graph builder must set the startBlock and the osrEntryBlock
-        new GraphBuilder(compilation, this).build();
+        new GraphBuilder(compilation, this, graph).build();
         assert startBlock != null;
         verifyAndPrint("After graph building");
 
@@ -173,12 +176,12 @@
         }
 
         // create new successor and mark it for special block order treatment
-        BlockBegin newSucc = new BlockBegin(bci, nextBlockNumber());
+        BlockBegin newSucc = new BlockBegin(bci, nextBlockNumber(), graph);
 
         newSucc.setCriticalEdgeSplit(true);
 
         // This goto is not a safepoint.
-        Goto e = new Goto(target, null, false);
+        Goto e = new Goto(target, null, false, graph);
         newSucc.appendNext(e, bci);
         newSucc.setEnd(e);
         // setup states
@@ -226,8 +229,8 @@
             newBlock.addPredecessor(pred);
         }
         // this block is now disconnected; remove all its incoming and outgoing edges
-        oldBlock.blockPredecessors().clear();
-        oldBlock.end().blockSuccessors().clear();
+//        oldBlock.blockPredecessors().clear();
+//        oldBlock.end().blockSuccessors().clear();
     }
 
     /**
@@ -273,4 +276,8 @@
     public final int maxLocks() {
         return maxLocks;
     }
+
+    public Graph graph() {
+        return graph;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Base.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Base.java	Fri May 06 10:25:37 2011 +0200
@@ -22,25 +22,28 @@
  */
 package com.sun.c1x.ir;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.cri.ci.*;
 
 /**
  * The {@code Base} instruction represents the end of the entry block of the procedure that has
  * both the standard entry and the OSR entry as successors.
- *
- * @author Ben L. Titzer
  */
 public final class Base extends BlockEnd {
 
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
     /**
      * Constructs a new Base instruction.
      * @param standardEntry the standard entrypoint block
+     * @param graph
      */
-    public Base(BlockBegin standardEntry) {
-        super(CiKind.Illegal, null, false);
+    public Base(BlockBegin standardEntry, Graph graph) {
+        super(CiKind.Illegal, null, false, 1, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         assert standardEntry.isStandardEntry();
-        successors.add(standardEntry);
+        setBlockSuccessor(0, standardEntry);
     }
 
     /**
@@ -56,7 +59,7 @@
      * @return the OSR entrypoint bock, if it exists; {@code null} otherwise
      */
     public BlockBegin osrEntry() {
-        return successors.size() < 2 ? null : successors.get(0);
+        return blockSuccessorCount() < 2 ? null : blockSuccessor(0);
     }
 
     @Override
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Fri May 06 10:25:37 2011 +0200
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.*;
 import com.sun.c1x.asm.*;
 import com.sun.c1x.debug.*;
@@ -37,10 +38,12 @@
  * Denotes the beginning of a basic block, and holds information
  * about the basic block, including the successor and
  * predecessor blocks, exception handlers, liveness information, etc.
- *
- * @author Ben L. Titzer
  */
 public final class BlockBegin extends Instruction {
+
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
     private static final List<BlockBegin> NO_HANDLERS = Collections.emptyList();
 
     /**
@@ -103,9 +106,10 @@
      * Constructs a new BlockBegin at the specified bytecode index.
      * @param bci the bytecode index of the start
      * @param blockID the ID of the block
+     * @param graph
      */
-    public BlockBegin(int bci, int blockID) {
-        super(CiKind.Illegal);
+    public BlockBegin(int bci, int blockID, Graph graph) {
+        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.blockID = blockID;
         depthFirstNumber = -1;
         linearScanNumber = -1;
@@ -609,7 +613,7 @@
      * @return the number of successors
      */
     public int numberOfSux() {
-        return end.successors.size();
+        return end.blockSuccessorCount();
     }
 
     /**
@@ -618,7 +622,7 @@
      * @return the successor
      */
     public BlockBegin suxAt(int i) {
-        return end.successors.get(i);
+        return end.blockSuccessor(i);
     }
 
     /**
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Fri May 06 10:25:37 2011 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import com.sun.c1x.util.*;
+import com.oracle.graal.graph.*;
 import com.sun.c1x.value.*;
 import com.sun.cri.ci.*;
 
@@ -34,8 +34,38 @@
  */
 public abstract class BlockEnd extends Instruction {
 
+    private static final int INPUT_COUNT = 0;
+
+    private final int blockSuccessorCount;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + blockSuccessorCount;
+    }
+
+    /**
+     * The list of instructions that produce input for this instruction.
+     */
+    public BlockBegin blockSuccessor(int index) {
+        assert index >= 0 && index < blockSuccessorCount;
+        return (BlockBegin) successors().get(super.successorCount() + index);
+    }
+
+    public BlockBegin setBlockSuccessor(int index, BlockBegin n) {
+        assert index >= 0 && index < blockSuccessorCount;
+        return (BlockBegin) successors().set(super.successorCount() + index, n);
+    }
+
+    public int blockSuccessorCount() {
+        return blockSuccessorCount;
+    }
+
     BlockBegin begin;
-    final List<BlockBegin> successors;
     FrameState stateAfter;
     boolean isSafepoint;
 
@@ -46,15 +76,22 @@
      * @param isSafepoint {@code true} if this instruction is a safepoint instruction
      * @param successors the list of successor blocks. If {@code null}, a new one will be created.
      */
-    public BlockEnd(CiKind kind, FrameState stateAfter, boolean isSafepoint, List<BlockBegin> successors) {
-        super(kind);
-        this.successors = successors == null ? new ArrayList<BlockBegin>(2) : successors;
+    public BlockEnd(CiKind kind, FrameState stateAfter, boolean isSafepoint, List<BlockBegin> blockSuccessors, int inputCount, int successorCount, Graph graph) {
+        this(kind, stateAfter, isSafepoint, blockSuccessors.size(), inputCount, successorCount, graph);
+        for (int i = 0; i < blockSuccessors.size(); i++) {
+            setBlockSuccessor(i, blockSuccessors.get(i));
+        }
+    }
+
+    public BlockEnd(CiKind kind, FrameState stateAfter, boolean isSafepoint, int blockSuccessorCount, int inputCount, int successorCount, Graph graph) {
+        super(kind, inputCount + INPUT_COUNT, successorCount + blockSuccessorCount, graph);
+        this.blockSuccessorCount = blockSuccessorCount;
         setStateAfter(stateAfter);
         this.isSafepoint = isSafepoint;
     }
 
-    public BlockEnd(CiKind kind, FrameState stateAfter, boolean isSafepoint) {
-        this(kind, stateAfter, isSafepoint, null);
+    public BlockEnd(CiKind kind, FrameState stateAfter, boolean isSafepoint, Graph graph) {
+        this(kind, stateAfter, isSafepoint, 2, 0, 0, graph);
     }
 
     /**
@@ -103,7 +140,11 @@
      */
     public void substituteSuccessor(BlockBegin oldSucc, BlockBegin newSucc) {
         assert newSucc != null;
-        Util.replaceAllInList(oldSucc, newSucc, successors);
+        for (int i = 0; i < blockSuccessorCount; i++) {
+            if (blockSuccessor(i) == oldSucc) {
+                setBlockSuccessor(i, newSucc);
+            }
+        }
     }
 
     /**
@@ -111,7 +152,7 @@
      * @return the default successor
      */
     public BlockBegin defaultSuccessor() {
-        return successors.get(successors.size() - 1);
+        return blockSuccessor(blockSuccessorCount - 1);
     }
 
     /**
@@ -121,9 +162,8 @@
      * @return the index of the block in the list if found; <code>-1</code> otherwise
      */
     public int successorIndex(BlockBegin b) {
-        final int max = successors.size();
-        for (int i = 0; i < max; i++) {
-            if (successors.get(i) == b) {
+        for (int i = 0; i < blockSuccessorCount; i++) {
+            if (blockSuccessor(i) == b) {
                 return i;
             }
         }
@@ -135,15 +175,8 @@
      * @return the successor list
      */
     public List<BlockBegin> blockSuccessors() {
-        return successors;
+        List<BlockBegin> list = (List) successors().subList(super.successorCount(), super.successorCount() + blockSuccessorCount);
+        return Collections.unmodifiableList(list);
     }
 
-    /**
-     * Gets the successor at a specified index.
-     * @param index the index of the successor
-     * @return the successor
-     */
-    public BlockBegin suxAt(int index) {
-        return successors.get(index);
-    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionObject.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionObject.java	Fri May 06 10:25:37 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.sun.c1x.ir;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.value.*;
 import com.sun.cri.ci.*;
@@ -31,6 +32,9 @@
  */
 public final class ExceptionObject extends Instruction {
 
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
     /**
      * Debug info is required if safepoints are placed at exception handlers.
      */
@@ -39,9 +43,10 @@
     /**
      * Constructs a new ExceptionObject instruction.
      * @param stateBefore TODO
+     * @param graph
      */
-    public ExceptionObject(FrameState stateBefore) {
-        super(CiKind.Object);
+    public ExceptionObject(FrameState stateBefore, Graph graph) {
+        super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         setFlag(Flag.NonNull);
         this.stateBefore = stateBefore;
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Goto.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Goto.java	Fri May 06 10:25:37 2011 +0200
@@ -22,26 +22,29 @@
  */
 package com.sun.c1x.ir;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.value.*;
 import com.sun.cri.ci.*;
 
 /**
  * The {@code Goto} instruction represents the end of a block with an unconditional jump to another block.
- *
- * @author Ben L. Titzer
  */
 public final class Goto extends BlockEnd {
 
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
     /**
      * Constructs a new Goto instruction.
      * @param succ the successor block of the goto
      * @param stateAfter the frame state at the end of this block
      * @param isSafepoint {@code true} if the goto should be considered a safepoint (e.g. backward branch)
+     * @param graph
      */
-    public Goto(BlockBegin succ, FrameState stateAfter, boolean isSafepoint) {
-        super(CiKind.Illegal, stateAfter, isSafepoint);
-        successors.add(succ);
+    public Goto(BlockBegin succ, FrameState stateAfter, boolean isSafepoint, Graph graph) {
+        super(CiKind.Illegal, stateAfter, isSafepoint, 1, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        setBlockSuccessor(0, succ);
     }
 
     @Override
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/If.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/If.java	Fri May 06 10:25:37 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.sun.c1x.ir;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.util.*;
 import com.sun.c1x.value.*;
@@ -30,13 +31,47 @@
 /**
  * The {@code If} instruction represents a branch that can go one of two directions
  * depending on the outcome of a comparison.
- *
- * @author Ben L. Titzer
  */
 public final class If extends BlockEnd {
 
-    Value x;
-    Value y;
+    private static final int INPUT_COUNT = 2;
+    private static final int INPUT_X = 0;
+    private static final int INPUT_Y = 1;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * The instruction that produces the first input to this comparison.
+     */
+     public Value x() {
+        return (Value) inputs().get(super.inputCount() + INPUT_X);
+    }
+
+    public Value setX(Value n) {
+        return (Value) inputs().set(super.inputCount() + INPUT_X, n);
+    }
+
+    /**
+     * The instruction that produces the second input to this comparison.
+     */
+    public Value y() {
+        return (Value) inputs().get(super.inputCount() + INPUT_Y);
+    }
+
+    public Value setY(Value n) {
+        return (Value) inputs().set(super.inputCount() + INPUT_Y, n);
+    }
+
     Condition condition;
     boolean unorderedIsTrue;
 
@@ -44,38 +79,22 @@
      * Constructs a new If instruction.
      * @param x the instruction producing the first input to the instruction
      * @param cond the condition (comparison operation)
-     * @param unorderedIsTrue {@code true} if unordered is treated as true (floating point operations)
      * @param y the instruction that produces the second input to this instruction
      * @param trueSucc the block representing the true successor
      * @param falseSucc the block representing the false successor
      * @param stateAfter the state before the branch but after the input values have been popped
      * @param isSafepoint {@code true} if this branch should be considered a safepoint
+     * @param graph
      */
     public If(Value x, Condition cond, Value y,
-              BlockBegin trueSucc, BlockBegin falseSucc, FrameState stateAfter, boolean isSafepoint) {
-        super(CiKind.Illegal, stateAfter, isSafepoint);
-        this.x = x;
-        this.y = y;
-        condition = cond;
+              BlockBegin trueSucc, BlockBegin falseSucc, FrameState stateAfter, boolean isSafepoint, Graph graph) {
+        super(CiKind.Illegal, stateAfter, isSafepoint, 2, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         assert Util.archKindsEqual(x, y);
-        successors.add(trueSucc);
-        successors.add(falseSucc);
-    }
-
-    /**
-     * Gets the instruction that produces the first input to this comparison.
-     * @return the instruction producing the first input
-     */
-    public Value x() {
-        return x;
-    }
-
-    /**
-     * Gets the instruction that produces the second input to this comparison.
-     * @return the instruction producing the second input
-     */
-    public Value y() {
-        return y;
+        condition = cond;
+        setX(x);
+        setY(y);
+        setBlockSuccessor(0, trueSucc);
+        setBlockSuccessor(1, falseSucc);
     }
 
     /**
@@ -99,7 +118,7 @@
      * @return the true successor
      */
     public BlockBegin trueSuccessor() {
-        return successors.get(0);
+        return blockSuccessor(0);
     }
 
     /**
@@ -107,7 +126,7 @@
      * @return the false successor
      */
     public BlockBegin falseSuccessor() {
-        return successors.get(1);
+        return blockSuccessor(1);
     }
 
     /**
@@ -116,7 +135,7 @@
      * @return the corresponding successor
      */
     public BlockBegin successor(boolean istrue) {
-        return successors.get(istrue ? 0 : 1);
+        return blockSuccessor(istrue ? 0 : 1);
     }
 
     /**
@@ -133,9 +152,9 @@
      */
     public void swapOperands() {
         condition = condition.mirror();
-        Value t = x;
-        x = y;
-        y = t;
+        Value t = x();
+        setX(y());
+        setY(t);
     }
 
     /**
@@ -145,16 +164,10 @@
     public void swapSuccessors() {
         unorderedIsTrue = !unorderedIsTrue;
         condition = condition.negate();
-        BlockBegin t = successors.get(0);
-        BlockBegin f = successors.get(1);
-        successors.set(0, f);
-        successors.set(1, t);
-    }
-
-    @Override
-    public void inputValuesDo(ValueClosure closure) {
-        x = closure.apply(x);
-        y = closure.apply(y);
+        BlockBegin t = blockSuccessor(0);
+        BlockBegin f = blockSuccessor(1);
+        setBlockSuccessor(0, f);
+        setBlockSuccessor(1, t);
     }
 
     @Override
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java	Fri May 06 10:25:37 2011 +0200
@@ -26,17 +26,19 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.value.*;
 
 /**
  * The {@code LookupSwitch} instruction represents a lookup switch bytecode, which has a sorted
  * array of key values.
- *
- * @author Ben L. Titzer
  */
 public final class LookupSwitch extends Switch {
 
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
     final int[] keys;
 
     /**
@@ -46,9 +48,10 @@
      * @param keys the list of keys, sorted
      * @param stateBefore the state before the switch
      * @param isSafepoint {@code true} if this instruction is a safepoint
+     * @param graph
      */
-    public LookupSwitch(Value value, List<BlockBegin> successors, int[] keys, FrameState stateBefore, boolean isSafepoint) {
-        super(value, successors, stateBefore, isSafepoint);
+    public LookupSwitch(Value value, List<BlockBegin> successors, int[] keys, FrameState stateBefore, boolean isSafepoint, Graph graph) {
+        super(value, successors, stateBefore, isSafepoint, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.keys = keys;
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorAddress.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorAddress.java	Fri May 06 10:25:37 2011 +0200
@@ -22,20 +22,22 @@
  */
 package com.sun.c1x.ir;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.cri.ci.*;
 
 /**
  * Instruction that is used to refer to the address of an on-stack monitor.
- *
- * @author Lukas Stadler
  */
 public final class MonitorAddress extends Instruction {
 
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
     private int monitor;
 
-    public MonitorAddress(int monitor) {
-        super(CiKind.Word);
+    public MonitorAddress(int monitor, Graph graph) {
+        super(CiKind.Word, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.monitor = monitor;
         setFlag(Flag.NonNull);
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Return.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Return.java	Fri May 06 10:25:37 2011 +0200
@@ -22,42 +22,51 @@
  */
 package com.sun.c1x.ir;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.cri.ci.*;
 
 /**
  * The {@code Return} class definition.
- *
- * @author Ben L. Titzer
  */
 public final class Return extends BlockEnd {
 
-    Value result;
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_RESULT = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * The instruction that produces the result for the return.
+     */
+     public Value result() {
+        return (Value) inputs().get(super.inputCount() + INPUT_RESULT);
+    }
+
+    public Value setResult(Value n) {
+        return (Value) inputs().set(super.inputCount() + INPUT_RESULT, n);
+    }
 
     /**
      * Constructs a new Return instruction.
      * @param result the instruction producing the result for this return; {@code null} if this
      * is a void return
      * @param isSafepoint {@code true} if this instruction is a safepoint instruction
-     */
-    public Return(Value result, boolean isSafepoint) {
-        super(result == null ? CiKind.Void : result.kind, null, isSafepoint);
-        this.result = result;
-    }
-
-    /**
-     * Gets the instruction that produces the result for the return.
-     * @return the instruction producing the result
+     * @param graph
      */
-    public Value result() {
-        return result;
-    }
-
-    @Override
-    public void inputValuesDo(ValueClosure closure) {
-        if (result != null) {
-            result = closure.apply(result);
-        }
+    public Return(Value result, boolean isSafepoint, Graph graph) {
+        super(result == null ? CiKind.Void : result.kind, null, isSafepoint, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        setResult(result);
     }
 
     @Override
@@ -67,10 +76,10 @@
 
     @Override
     public void print(LogStream out) {
-        if (result == null) {
+        if (result() == null) {
             out.print("return");
         } else {
-            out.print(kind.typeChar).print("return ").print(result);
+            out.print(kind.typeChar).print("return ").print(result());
         }
     }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Switch.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Switch.java	Fri May 06 10:25:37 2011 +0200
@@ -24,17 +24,40 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.value.*;
 import com.sun.cri.ci.*;
 
 /**
  * The {@code Switch} class is the base of both lookup and table switches.
- *
- * @author Ben L. Titzer
  */
 public abstract class Switch extends BlockEnd {
 
-    Value value;
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_VALUE = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * The instruction that provides the input value to this switch.
+     */
+     public Value value() {
+        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
+    }
+
+    public Value setValue(Value n) {
+        return (Value) inputs().set(super.inputCount() + INPUT_VALUE, n);
+    }
 
     /**
      * Constructs a new Switch.
@@ -42,18 +65,11 @@
      * @param successors the list of successors of this switch
      * @param stateBefore the state before the switch
      * @param isSafepoint {@code true} if this switch is a safepoint
+     * @param graph
      */
-    public Switch(Value value, List<BlockBegin> successors, FrameState stateBefore, boolean isSafepoint) {
-        super(CiKind.Illegal, stateBefore, isSafepoint, successors);
-        this.value = value;
-    }
-
-    /**
-     * Gets the instruction that provides the input value to this switch.
-     * @return the instruction producing the input value
-     */
-    public Value value() {
-        return value;
+    public Switch(Value value, List<BlockBegin> successors, FrameState stateBefore, boolean isSafepoint, int inputCount, int successorCount, Graph graph) {
+        super(CiKind.Illegal, stateBefore, isSafepoint, successors, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+        setValue(value);
     }
 
     /**
@@ -61,15 +77,7 @@
      * @return the number of cases
      */
     public int numberOfCases() {
-        return successors.size() - 1;
+        return blockSuccessorCount() - 1;
     }
 
-    /**
-     * Iterates over the inputs to this instruction.
-     * @param closure the closure to apply
-     */
-    @Override
-    public void inputValuesDo(ValueClosure closure) {
-        value = closure.apply(value);
-    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java	Fri May 06 10:25:37 2011 +0200
@@ -26,16 +26,18 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.value.*;
 
 /**
  * The {@code TableSwitch} instruction represents a table switch.
- *
- * @author Ben L. Titzer
  */
 public final class TableSwitch extends Switch {
 
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
     final int lowKey;
 
     /**
@@ -45,9 +47,10 @@
      * @param lowKey the lowest integer key in the table
      * @param stateBefore the state before the switch
      * @param isSafepoint {@code true} if this instruction is a safepoint
+     * @param graph
      */
-    public TableSwitch(Value value, List<BlockBegin> successors, int lowKey, FrameState stateBefore, boolean isSafepoint) {
-        super(value, successors, stateBefore, isSafepoint);
+    public TableSwitch(Value value, List<BlockBegin> successors, int lowKey, FrameState stateBefore, boolean isSafepoint, Graph graph) {
+        super(value, successors, stateBefore, isSafepoint, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.lowKey = lowKey;
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java	Fri May 06 10:25:37 2011 +0200
@@ -22,18 +22,41 @@
  */
 package com.sun.c1x.ir;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.value.*;
 import com.sun.cri.ci.*;
 
 /**
  * The {@code Throw} instruction represents a throw of an exception.
- *
- * @author Ben L. Titzer
  */
 public final class Throw extends BlockEnd {
 
-    Value exception;
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_EXCEPTION = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * The instruction which produces the exception to throw.
+     */
+     public Value exception() {
+        return (Value) inputs().get(super.inputCount() + INPUT_EXCEPTION);
+    }
+
+    public Value setException(Value n) {
+        return (Value) inputs().set(super.inputCount() + INPUT_EXCEPTION, n);
+    }
 
     FrameState stateBefore;
 
@@ -42,19 +65,12 @@
      * @param exception the instruction that generates the exception to throw
      * @param stateAfter the state before the exception is thrown but after the exception object has been popped
      * @param isSafepoint {@code true} if this instruction is a safepoint instruction
+     * @param graph
      */
-    public Throw(Value exception, FrameState stateAfter, boolean isSafepoint) {
-        super(CiKind.Illegal, null, isSafepoint);
+    public Throw(Value exception, FrameState stateAfter, boolean isSafepoint, Graph graph) {
+        super(CiKind.Illegal, null, isSafepoint, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.stateBefore = stateAfter;
-        this.exception = exception;
-    }
-
-    /**
-     * Gets the instruction which produces the exception to throw.
-     * @return the instruction producing the exception
-     */
-    public Value exception() {
-        return exception;
+        setException(exception);
     }
 
     /**
@@ -76,11 +92,6 @@
     }
 
     @Override
-    public void inputValuesDo(ValueClosure closure) {
-        exception = closure.apply(exception);
-    }
-
-    @Override
     public void accept(ValueVisitor v) {
         v.visitThrow(this);
     }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/vis/GraphvizPrinter.java	Thu May 05 16:33:12 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/vis/GraphvizPrinter.java	Fri May 06 10:25:37 2011 +0200
@@ -129,6 +129,9 @@
             out.println("    <TD WIDTH=\"15\" HEIGHT=\"5\" PORT=\"in" + i + "\" BGCOLOR=\"lightgrey\"></TD>");
         }
 
+        label = label.replace("&", "&amp;");
+        label = label.replace("<", "&lt;");
+        label = label.replace(">", "&gt;");
         out.println("    </TR></TABLE></TD></TR><TR><TD BORDER=\"1\" COLSPAN=\"3\" BGCOLOR=\"" + NODE_BGCOLOR_STRING + "\">" + label + "</TD></TR>");
         out.println("    <TR><TD COLSPAN=\"2\" CELLPADDING=\"0\" ALIGN=\"RIGHT\"><TABLE BORDER=\"0\" CELLSPACING=\"2\" CELLPADDING=\"0\"><TR>");
 
--- a/rundacapo.sh	Thu May 05 16:33:12 2011 +0200
+++ b/rundacapo.sh	Fri May 06 10:25:37 2011 +0200
@@ -12,7 +12,7 @@
   exit 1;
 fi
 if [ -z "${DACAPO}" ]; then
-  echo "DACAPO is not defined. It must point to a SciMark benchmark directory."
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
   exit 1;
 fi
 ${JDK7}/bin/java -client -graal -XX:-C1XBailoutIsFatal -C1X:+QuietBailout -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar Harness $*
--- a/runscimark.sh	Thu May 05 16:33:12 2011 +0200
+++ b/runscimark.sh	Fri May 06 10:25:37 2011 +0200
@@ -12,7 +12,7 @@
   exit 1;
 fi
 if [ -z "${SCIMARK}" ]; then
-  echo "SCIMARK is not defined. It must point to a SciMark benchmark directory."
+  echo "SCIMARK is not defined. It must point to a SciMark benchmark jar."
   exit 1;
 fi
 COUNT=$1