changeset 3089:05b8a7787aaf

merge
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 27 Jun 2011 17:15:12 +0200
parents be5deef7c7a0 (current diff) 33da84ebbe50 (diff)
children 536528f48708
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Instruction.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryAccess.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java
diffstat 64 files changed, 1089 insertions(+), 498 deletions(-) [+]
line wrap: on
line diff
--- a/GRAAL_README	Mon Jun 27 17:13:33 2011 +0200
+++ b/GRAAL_README	Mon Jun 27 17:15:12 2011 +0200
@@ -5,4 +5,19 @@
 - MAXINE: Pointing to a Maxine VM repository with compiled Java files.
 - GRAAL: Pointing to a Graal VM repository with compiled Java files.
 
-For starting the Graal VM, the two flags "-client -graal" have to be specified.
+In particular, the VM will look for the compiled Java files in the following directories:
+${MAXINE}/com.oracle.max.cri/bin
+${MAXINE}/com.oracle.max.base/bin
+${MAXINE}/com.oracle.max.asmdis/bin
+${MAXINE}/com.oracle.max.asm/bin
+${MAXINE}/com.oracle.max.graal.graph/bin
+${GRAAL}/graal/com.oracle.max.graal.compiler/bin
+${GRAAL}/graal/com.oracle.max.graal.runtime/bin
+${GRAAL}/graal/com.oracle.max.graal.graphviz/bin
+
+For starting the Graal VM, the two flags "-client -graal" have to be specified. Additional flags that might be useful:
+-G:Plot Sends the graphs of compiled methods via network stream to the IdealGraphVisualizer (NetBeans project at ${GRAAL}/src/share/tools/IdealGraphVisualizer that can be built and run with NetBeans 7.0, use "Graal Coloring" and "Graal Edge Coloring" filters)
+-G:Time Prints timings for the different compilation phases
+-G:Meter Prints metrics for the different compilation phases
+
+The usual HotSpot flags -Xcomp -XX:CompileOnly= -XX:CompileCommand= or -XX:+PrintCompilation can be used to control the compiled methods.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Mon Jun 27 17:15:12 2011 +0200
@@ -82,6 +82,7 @@
     }
 
     public CiResult compileMethod(RiMethod method, int osrBCI, RiXirGenerator xirGenerator, CiStatistics stats) {
+        GraalTimers.TOTAL.start();
         long startTime = 0;
         int index = GraalMetrics.CompiledMethods++;
         if (GraalOptions.PrintCompilation) {
@@ -102,6 +103,7 @@
                 long time = (System.nanoTime() - startTime) / 100000;
                 TTY.println(String.format("%3d.%dms", time / 10, time % 10));
             }
+            GraalTimers.TOTAL.stop();
         }
 
         return result;
@@ -140,7 +142,7 @@
         if (GraalOptions.PrintDOTGraphToPdf) {
             addCompilationObserver(new GraphvizPrinterObserver(true));
         }
-        if (GraalOptions.PrintIdealGraphLevel != 0) {
+        if (GraalOptions.PrintIdealGraphLevel != 0 || GraalOptions.Plot) {
             CompilationObserver observer;
             if (GraalOptions.PrintIdealGraphFile) {
                 observer = new IdealGraphPrinterObserver();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java	Mon Jun 27 17:15:12 2011 +0200
@@ -49,7 +49,6 @@
     public static int DataPatches;
     public static int DirectCallSitesEmitted;
     public static int IndirectCallSitesEmitted;
-    public static int HIRInstructions;
     public static int LiveHIRInstructions;
     public static int LIRInstructions;
     public static int LIRVariables;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Mon Jun 27 17:15:12 2011 +0200
@@ -83,6 +83,7 @@
     public static boolean OmitDOTFrameStates                 = ____;
 
     // Ideal graph visualizer output settings
+    public static boolean Plot                               = ____;
     public static int     PrintIdealGraphLevel               = 0;
     public static boolean PrintIdealGraphFile                = ____;
     public static String  PrintIdealGraphAddress             = "127.0.0.1";
@@ -105,6 +106,7 @@
     public static boolean TraceInlining                      = ____;
     public static boolean TraceDeadCodeElimination           = ____;
     public static boolean TraceEscapeAnalysis                = ____;
+    public static boolean TraceMemoryMaps                    = ____;
     public static int     TraceBytecodeParserLevel           = 0;
     public static boolean QuietBailout                       = ____;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java	Mon Jun 27 17:15:12 2011 +0200
@@ -34,6 +34,8 @@
 public final class GraalTimers {
     private static LinkedHashMap<String, GraalTimers> map = new LinkedHashMap<String, GraalTimers>();
 
+
+    public static final GraalTimers TOTAL = get("Total compilation time");
     public static final GraalTimers COMPUTE_LINEAR_SCAN_ORDER = get("Compute Linear Scan Order");
     public static final GraalTimers LIR_CREATE = get("Create LIR");
     public static final GraalTimers LIFETIME_ANALYSIS = get("Lifetime Analysis");
@@ -73,19 +75,15 @@
     }
 
     public static void print() {
-        long total = 0;
-        for (Entry<String, GraalTimers> e : map.entrySet()) {
-            total += e.getValue().total;
-        }
-        if (total == 0) {
-            return;
-        }
 
         TTY.println();
+        TTY.println("%-30s: %7.4f s", TOTAL.name, TOTAL.total / 1000000000.0);
         for (Entry<String, GraalTimers> e : map.entrySet()) {
             GraalTimers timer = e.getValue();
-            TTY.println("%-30s: %7.4f s (%5.2f%%)", timer.name, timer.total / 1000000000.0, timer.total * 100.0 / total);
-            timer.total = 0;
+            if (timer != TOTAL) {
+                TTY.println("%-30s: %7.4f s (%5.2f%%)", timer.name, timer.total / 1000000000.0, timer.total * 100.0 / TOTAL.total);
+                timer.total = 0;
+            }
         }
         TTY.println();
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/BlockPrinter.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/BlockPrinter.java	Mon Jun 27 17:15:12 2011 +0200
@@ -45,7 +45,7 @@
     public void apply(Block block) {
         if (cfgOnly) {
             if (block.getInstructions().size() > 0) {
-                ip.printInstruction((Instruction) block.getInstructions().get(0));
+                ip.printInstruction((FixedNodeWithNext) block.getInstructions().get(0));
             } else {
                 ip.out().println("Empty block");
             }
@@ -62,8 +62,8 @@
         ip.printInstructionListingHeader();
 
         for (Node i : block.getInstructions()) {
-            if (i instanceof Instruction) {
-                ip.printInstructionListing((Instruction) i);
+            if (i instanceof FixedNodeWithNext) {
+                ip.printInstructionListing((FixedNodeWithNext) i);
             }
         }
         out.println();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java	Mon Jun 27 17:15:12 2011 +0200
@@ -409,8 +409,8 @@
         out.println("HIR");
         out.disableIndentation();
         for (Node i : block.getInstructions()) {
-            if (i instanceof Instruction) {
-                printInstructionHIR((Instruction) i);
+            if (i instanceof FixedNodeWithNext) {
+                printInstructionHIR((FixedNodeWithNext) i);
             }
         }
         out.enableIndentation();
@@ -515,16 +515,19 @@
      *
      * @param i the instruction for which HIR will be printed
      */
-    private void printInstructionHIR(Instruction i) {
+    private void printInstructionHIR(FixedNodeWithNext i) {
         out.print("bci ").print(-1).println(COLUMN_END);
         if (i.operand().isLegal()) {
             out.print("result ").print(new CFGOperandFormatter(false).format(i.operand())).println(COLUMN_END);
         }
         out.print("tid ").print(i).println(COLUMN_END);
 
-        String state = stateToString(i.stateAfter(), null);
-        if (state != null) {
-            out.print("st ").print(HOVER_START).print("st").print(HOVER_SEP).print(state).print(HOVER_END).println(COLUMN_END);
+        if (i instanceof StateSplit) {
+            StateSplit stateSplit = (StateSplit) i;
+            String state = stateToString(stateSplit.stateAfter(), null);
+            if (state != null) {
+                out.print("st ").print(HOVER_START).print("st").print(HOVER_SEP).print(state).print(HOVER_END).println(COLUMN_END);
+            }
         }
 
         out.print("instruction ");
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Mon Jun 27 17:15:12 2011 +0200
@@ -269,8 +269,8 @@
 
             // add all framestates and phis to their blocks
             for (Node node : block.getInstructions()) {
-                if (node instanceof Instruction && ((Instruction) node).stateAfter() != null) {
-                    nodes.add(((Instruction) node).stateAfter());
+                if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
+                    nodes.add(((StateSplit) node).stateAfter());
                 }
                 if (node instanceof Merge) {
                     for (Node usage : node.usages()) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/InstructionPrinter.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/InstructionPrinter.java	Mon Jun 27 17:15:12 2011 +0200
@@ -28,7 +28,7 @@
 
 /**
  * A {@link ValueVisitor} for {@linkplain #printInstruction(Value) printing}
- * an {@link Instruction} as an expression or statement.
+ * an {@link FixedNodeWithNext} as an expression or statement.
  *
  * @author Doug Simon
  */
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Mon Jun 27 17:15:12 2011 +0200
@@ -144,7 +144,7 @@
         return operand;
     }
 
-    protected CiValue load(Value val) {
+    public CiValue load(Value val) {
         CiValue result = makeOperand(val);
         if (!result.isVariableOrRegister()) {
             CiVariable operand = newVariable(val.kind);
@@ -201,6 +201,10 @@
         this.operands = new OperandPool(compilation.target);
     }
 
+    public LIRList lir() {
+        return lir;
+    }
+
     public ArrayList<DeoptimizationStub> deoptimizationStubs() {
         return deoptimizationStubs;
     }
@@ -243,8 +247,8 @@
                 TTY.println("LIRGen for " + instr);
             }
             FrameState stateAfter = null;
-            if (instr instanceof Instruction) {
-                stateAfter = ((Instruction) instr).stateAfter();
+            if (instr instanceof StateSplit) {
+                stateAfter = ((StateSplit) instr).stateAfter();
             }
             if (instr != instr.graph().start()) {
                 walkState(instr, stateAfter);
@@ -298,7 +302,7 @@
         CiCallingConvention args = compilation.frameMap().incomingArguments();
         int bci = 0;
         if (Modifier.isSynchronized(compilation.method.accessFlags())) {
-            bci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            bci = FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI;
         }
 
         boolean withReceiver = !Modifier.isStatic(compilation.method.accessFlags());
@@ -1008,7 +1012,7 @@
     @Override
     public void visitDeoptimize(Deoptimize deoptimize) {
         assert lastState != null : "deoptimize always needs a state";
-        assert lastState.bci != Instruction.SYNCHRONIZATION_ENTRY_BCI : "bci must not be -1 for deopt framestate";
+        assert lastState.bci != FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI : "bci must not be -1 for deopt framestate";
         DeoptimizationStub stub = new DeoptimizationStub(deoptimize.action(), lastState);
         addDeoptimizationStub(stub);
         lir.branch(Condition.TRUE, stub.label, stub.info);
@@ -1366,7 +1370,12 @@
         if (GraalOptions.TraceLIRVisit) {
             TTY.println("Visiting    " + instr);
         }
-        instr.accept(this);
+
+        LIRGeneratorOp op = instr.lookup(LIRGeneratorOp.class);
+        if (op != null) {
+            op.generate(instr, this);
+        }
+
         if (GraalOptions.TraceLIRVisit) {
             TTY.println("Operand for " + instr + " = " + instr.operand());
         }
@@ -1436,14 +1445,14 @@
     }
 
     @Override
-    public void visitMemoryRead(MemoryRead memRead) {
-        lir.move(new CiAddress(memRead.valueKind(), load(memRead.location()), memRead.displacement()), createResultVariable(memRead), memRead.valueKind());
+    public void visitMemoryRead(ReadNode memRead) {
+        lir.move(memRead.location().createAddress(this, memRead.object()), createResultVariable(memRead), memRead.location().getValueKind());
     }
 
 
     @Override
-    public void visitMemoryWrite(MemoryWrite memWrite) {
-        lir.move(load(memWrite.location()), new CiAddress(memWrite.valueKind(), load(memWrite.location()), memWrite.displacement()), memWrite.valueKind());
+    public void visitMemoryWrite(WriteNode memWrite) {
+        lir.move(load(memWrite.value()), memWrite.location().createAddress(this, memWrite.object()), memWrite.location().getValueKind());
     }
 
 
@@ -1669,7 +1678,7 @@
      *
      * @param instruction an instruction that produces a result value
      */
-    protected CiValue makeOperand(Value instruction) {
+    public CiValue makeOperand(Value instruction) {
         if (instruction == null) {
             return CiValue.IllegalValue;
         }
@@ -1799,4 +1808,15 @@
         lir.callRuntime(CiRuntimeCall.UnwindException, CiValue.IllegalValue, args, null);
         setNoResult(x);
     }
+
+    public interface LIRGeneratorOp extends Op {
+        void generate(Node n, LIRGenerator generator);
+    }
+
+    public static final LIRGeneratorOp DELEGATE_TO_VALUE_VISITOR = new LIRGeneratorOp() {
+        @Override
+        public void generate(Node n, LIRGenerator generator) {
+            ((Value) n).accept(generator);
+        }
+    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiSimplifier.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiSimplifier.java	Mon Jun 27 17:15:12 2011 +0200
@@ -51,7 +51,9 @@
         Phi phi = (Phi) x;
 
         if (phi.valueCount() == 1 && !cannotSimplify.isMarked(phi)) {
-            return (Value) phi.replace(phi.valueAt(0));
+            Value result = phi.valueAt(0);
+            phi.replaceAndDelete(result);
+            return result;
         }
 
         if (cannotSimplify.isMarked(phi)) {
@@ -111,7 +113,7 @@
             assert phiSubst != null : "illegal phi function";
             visited.clear(phi);
 
-            phi.replace(phiSubst);
+            phi.replaceAndDelete(phiSubst);
 
             return phiSubst;
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Mon Jun 27 17:15:12 2011 +0200
@@ -121,9 +121,9 @@
         public boolean isLoopHeader;
         public int blockID;
 
-        public Instruction firstInstruction;
+        public FixedNodeWithNext firstInstruction;
 
-        final HashSet<Block> successors = new HashSet<Block>();
+        final HashSet<Block> successors = new LinkedHashSet<Block>();
         private boolean visited;
         private boolean active;
         private int loops;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Mon Jun 27 17:15:12 2011 +0200
@@ -111,6 +111,7 @@
 
         if (GraalOptions.Lower) {
             new LoweringPhase(compilation.runtime).apply(graph);
+            new MemoryPhase().apply(graph);
         }
 
         IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true);
@@ -213,7 +214,7 @@
         return maxLocks;
     }
 
-    public Instruction getHIRStartBlock() {
-        return (Instruction) compilation.graph.start().successors().get(0);
+    public FixedNodeWithNext getHIRStartBlock() {
+        return (FixedNodeWithNext) compilation.graph.start().successors().get(0);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryMergeNode.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,47 @@
+/*
+ * 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.oracle.max.graal.compiler.ir;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+
+public abstract class AbstractMemoryMergeNode extends StateSplit {
+
+    private static final int SUCCESSOR_COUNT = 0;
+    private static final int INPUT_COUNT = 0;
+
+    public AbstractMemoryMergeNode(Graph graph) {
+        this(CiKind.Illegal, 0, 0, graph);
+    }
+
+    public AbstractMemoryMergeNode(CiKind result, int inputCount, int successorCount, Graph graph) {
+        super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    }
+
+    public List<Node> mergedNodes() {
+        return inputs().variablePart();
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java	Mon Jun 27 17:15:12 2011 +0200
@@ -28,7 +28,7 @@
 /**
  * The {@code AccessMonitor} instruction is the base class of both monitor acquisition and release.
  */
-public abstract class AccessMonitor extends StateSplit {
+public abstract class AccessMonitor extends AbstractMemoryMergeNode {
 
     private static final int INPUT_COUNT = 2;
     private static final int INPUT_OBJECT = 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,74 @@
+/*
+ * 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.oracle.max.graal.compiler.ir;
+
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+
+public abstract class AccessNode extends StateSplit {
+    private static final int INPUT_COUNT = 2;
+    private static final int INPUT_NODE = 0;
+    private static final int INPUT_GUARD = 1;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    private LocationNode location;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    public Value object() {
+        return (Value) inputs().get(super.inputCount() + INPUT_NODE);
+    }
+
+    public Value setObject(Value n) {
+        return (Value) inputs().set(super.inputCount() + INPUT_NODE, n);
+    }
+
+    public GuardNode guard() {
+        return (GuardNode) inputs().get(super.inputCount() + INPUT_GUARD);
+    }
+
+    public void setGuard(GuardNode n) {
+        inputs().set(super.inputCount() + INPUT_GUARD, n);
+    }
+
+    public LocationNode location() {
+        return location;
+    }
+
+    public AccessNode(CiKind kind, Value object, LocationNode location, int inputCount, int successorCount, Graph graph) {
+        super(kind, INPUT_COUNT + inputCount, SUCCESSOR_COUNT + successorCount, graph);
+        this.location = location;
+        setObject(object);
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("mem read from ").print(object());
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java	Mon Jun 27 17:15:12 2011 +0200
@@ -31,7 +31,7 @@
 /**
  * The {@code Anchor} instruction represents the end of a block with an unconditional jump to another block.
  */
-public final class Anchor extends Instruction {
+public final class Anchor extends FixedNodeWithNext {
 
     private static final int INPUT_COUNT = 0;
     private static final int SUCCESSOR_COUNT = 0;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionObject.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionObject.java	Mon Jun 27 17:15:12 2011 +0200
@@ -29,7 +29,7 @@
 /**
  * The {@code ExceptionObject} instruction represents the incoming exception object to an exception handler.
  */
-public final class ExceptionObject extends Instruction {
+public final class ExceptionObject extends FixedNodeWithNext {
 
     private static final int INPUT_COUNT = 0;
     private static final int SUCCESSOR_COUNT = 0;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Mon Jun 27 17:15:12 2011 +0200
@@ -27,7 +27,7 @@
 import com.sun.cri.ci.*;
 
 
-public final class FixedGuard extends Instruction {
+public final class FixedGuard extends FixedNodeWithNext {
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_NODE = 0;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedNodeWithNext.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2009, 2010, 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.ir;
+
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+public abstract class FixedNodeWithNext extends FixedNode {
+
+    private static final int INPUT_COUNT = 0;
+
+    private static final int SUCCESSOR_COUNT = 1;
+    public static final int SUCCESSOR_NEXT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * Links to next instruction in a basic block, to {@code null} if this instruction is the end of a basic block or to
+     * itself if not in a block.
+     */
+    public FixedNode next() {
+        return (FixedNode) successors().get(super.successorCount() + SUCCESSOR_NEXT);
+    }
+
+    public Node setNext(FixedNode next) {
+        return successors().set(super.successorCount() + SUCCESSOR_NEXT, next);
+    }
+
+    public static final int SYNCHRONIZATION_ENTRY_BCI = -1;
+
+    /**
+     * Constructs a new instruction with the specified value type.
+     * @param kind the value type for this instruction
+     * @param inputCount
+     * @param successorCount
+     */
+    public FixedNodeWithNext(CiKind kind, int inputCount, int successorCount, Graph graph) {
+        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Instruction.java	Mon Jun 27 17:13:33 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, 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.ir;
-
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.value.*;
-import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
-
-/**
- * Denotes an instruction node in the IR, which is a {@link Value} that
- * can be added to a basic block (whereas other {@link Value} nodes such as {@link Phi} and
- * {@link Local} cannot be added to basic blocks).
- *
- * Subclasses of instruction represent arithmetic and object operations,
- * control flow operators, phi statements, method calls, the start of basic blocks, and
- * the end of basic blocks.
- *
- * Instruction nodes are chained together in a basic block through the embedded
- * {@link Instruction#next} field. An Instruction may also have a list of {@link ExceptionHandler}s.
- */
-public abstract class Instruction extends FixedNode {
-
-    private static final int INPUT_COUNT = 0;
-
-    private static final int SUCCESSOR_COUNT = 1;
-    public static final int SUCCESSOR_NEXT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * Links to next instruction in a basic block, to {@code null} if this instruction is the end of a basic block or to
-     * itself if not in a block.
-     */
-    public FixedNode next() {
-        return (FixedNode) successors().get(super.successorCount() + SUCCESSOR_NEXT);
-    }
-
-    public Node setNext(FixedNode next) {
-        return successors().set(super.successorCount() + SUCCESSOR_NEXT, next);
-    }
-
-    public int nextIndex() {
-        return super.successorCount() + SUCCESSOR_NEXT;
-    }
-
-
-    public static final int SYNCHRONIZATION_ENTRY_BCI = -1;
-
-    /**
-     * Constructs a new instruction with the specified value type.
-     * @param kind the value type for this instruction
-     * @param inputCount
-     * @param successorCount
-     */
-    public Instruction(CiKind kind, int inputCount, int successorCount, Graph graph) {
-        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
-        GraalMetrics.HIRInstructions++;
-    }
-
-    /**
-     * Gets the state after the instruction, if it is recorded.
-     * @return the state after the instruction
-     */
-    public FrameState stateAfter() {
-        return null;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java	Mon Jun 27 17:15:12 2011 +0200
@@ -34,7 +34,7 @@
 /**
  * The {@code Invoke} instruction represents all kinds of method calls.
  */
-public final class Invoke extends StateSplit implements ExceptionEdgeInstruction {
+public final class Invoke extends AbstractMemoryMergeNode implements ExceptionEdgeInstruction {
 
     private final int argumentCount;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.oracle.max.graal.compiler.ir;
+
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+
+public final class LocationNode extends FloatingNode {
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
+    private int displacement;
+    private CiKind valueKind;
+    private Object identity;
+
+    public LocationNode(Object identity, CiKind kind, int displacement, Graph graph) {
+        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        this.displacement = displacement;
+        this.valueKind = kind;
+        this.identity = identity;
+    }
+
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
+            return null;
+        }
+        return super.lookup(clazz);
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("mem location disp is ").print(displacement);
+    }
+
+    public CiKind getValueKind() {
+        return valueKind;
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new LocationNode(identity, valueKind, displacement, into);
+    }
+
+    public CiValue createAddress(LIRGenerator lirGenerator, Value object) {
+        return new CiAddress(valueKind, lirGenerator.load(object), displacement);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LookupSwitch.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LookupSwitch.java	Mon Jun 27 17:15:12 2011 +0200
@@ -86,7 +86,7 @@
 
     @Override
     public Node copy(Graph into) {
-        LookupSwitch x = new LookupSwitch(null, Arrays.asList(new Instruction[numberOfCases() + 1]), keys.clone(), into);
+        LookupSwitch x = new LookupSwitch(null, Arrays.asList(new FixedNodeWithNext[numberOfCases() + 1]), keys.clone(), into);
         return x;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryAccess.java	Mon Jun 27 17:13:33 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * 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.oracle.max.graal.compiler.ir;
-
-import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
-
-
-public abstract class MemoryAccess extends Instruction {
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_NODE = 0;
-    private static final int INPUT_GUARD = 1;
-
-    private static final int SUCCESSOR_COUNT = 0;
-
-    private int displacement;
-    private CiKind valueKind;
-
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public Value location() {
-        return (Value) inputs().get(super.inputCount() + INPUT_NODE);
-    }
-
-    public Value setLocation(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_NODE, n);
-    }
-
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public GuardNode guard() {
-        return (GuardNode) inputs().get(super.inputCount() + INPUT_GUARD);
-    }
-
-    public void setGuard(GuardNode n) {
-        inputs().set(super.inputCount() + INPUT_GUARD, n);
-    }
-
-    public int displacement() {
-        return displacement;
-    }
-
-    public CiKind valueKind() {
-        return valueKind;
-    }
-
-    public MemoryAccess(CiKind kind, int displacement, int inputCount, int successorCount, Graph graph) {
-        super(kind.stackKind(), INPUT_COUNT + inputCount, SUCCESSOR_COUNT + successorCount, graph);
-        this.displacement = displacement;
-        this.valueKind = kind;
-    }
-
-    @Override
-    public void print(LogStream out) {
-        out.print("mem read from ").print(location());
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryMergeNode.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,55 @@
+/*
+ * 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.oracle.max.graal.compiler.ir;
+
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+
+public final class MemoryMergeNode extends AbstractMemoryMergeNode {
+
+    private static final int SUCCESSOR_COUNT = 0;
+    private static final int INPUT_COUNT = 0;
+
+    public MemoryMergeNode(Graph graph) {
+        this(CiKind.Illegal, 0, 0, graph);
+    }
+
+    public MemoryMergeNode(CiKind result, int inputCount, int successorCount, Graph graph) {
+        super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    }
+
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
+            return null;
+        }
+        return super.lookup(clazz);
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new MemoryMergeNode(into);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java	Mon Jun 27 17:13:33 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * 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.oracle.max.graal.compiler.ir;
-
-import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
-
-
-public final class MemoryRead extends MemoryAccess {
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
-
-    public MemoryRead(CiKind kind, int displacement, Graph graph) {
-        super(kind, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-    }
-
-    @Override
-    public void accept(ValueVisitor v) {
-        v.visitMemoryRead(this);
-    }
-
-    @Override
-    public void print(LogStream out) {
-        out.print("mem read from ").print(location());
-    }
-
-    @Override
-    public Node copy(Graph into) {
-        return new MemoryRead(super.kind, displacement(), into);
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java	Mon Jun 27 17:13:33 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * 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.oracle.max.graal.compiler.ir;
-
-import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.ir.NewInstance.*;
-import com.oracle.max.graal.compiler.phases.EscapeAnalysisPhase.*;
-import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
-
-
-public final class MemoryWrite extends MemoryAccess {
-
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
-    public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
-    }
-
-    public void setValue(Value v) {
-        inputs().set(super.inputCount() + INPUT_VALUE, v);
-    }
-
-    public MemoryWrite(CiKind kind, Value value, int displacement, Graph graph) {
-        super(kind, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        setValue(value);
-    }
-
-    @Override
-    public void accept(ValueVisitor v) {
-        v.visitMemoryWrite(this);
-    }
-
-    @Override
-    public void print(LogStream out) {
-        out.print("mem write to ").print(location()).print(" with value").print(value());
-    }
-
-    @Override
-    public Node copy(Graph into) {
-        return new MemoryWrite(super.kind, null, displacement(), into);
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java	Mon Jun 27 17:15:12 2011 +0200
@@ -35,8 +35,7 @@
 /**
  * The {@code NewArray} class is the base of all instructions that allocate arrays.
  */
-public abstract class NewArray extends Instruction {
-    private static final EscapeOp ESCAPE = new NewArrayEscapeOp();
+public abstract class NewArray extends FixedNodeWithNext {
 
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_LENGTH = 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadNode.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,53 @@
+/*
+ * 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.oracle.max.graal.compiler.ir;
+
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+
+public final class ReadNode extends AccessNode {
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
+
+    public ReadNode(CiKind kind, Value object, LocationNode location, Graph graph) {
+        super(kind, object, location, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    }
+
+    @Override
+    public void accept(ValueVisitor v) {
+        v.visitMemoryRead(this);
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("mem read from ").print(object());
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new ReadNode(super.kind, null, null, into);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StateSplit.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StateSplit.java	Mon Jun 27 17:15:12 2011 +0200
@@ -32,7 +32,7 @@
  * The {@code StateSplit} class is the abstract base class of all instructions
  * that store an immutable copy of the frame state.
  */
-public abstract class StateSplit extends Instruction {
+public abstract class StateSplit extends FixedNodeWithNext {
 
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_STATE_AFTER = 0;
@@ -52,7 +52,6 @@
     /**
      * The state for this instruction.
      */
-     @Override
     public FrameState stateAfter() {
         return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_AFTER);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java	Mon Jun 27 17:15:12 2011 +0200
@@ -84,7 +84,7 @@
         if (clazz == LoweringOp.class) {
             return (T) LoweringPhase.DELEGATE_TO_RUNTIME;
         }
-        return null;
+        return super.lookup(clazz);
     };
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TableSwitch.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TableSwitch.java	Mon Jun 27 17:15:12 2011 +0200
@@ -88,7 +88,7 @@
 
     @Override
     public Node copy(Graph into) {
-        TableSwitch x = new TableSwitch(null, Arrays.asList(new Instruction[numberOfCases() + 1]), lowKey, into);
+        TableSwitch x = new TableSwitch(null, Arrays.asList(new FixedNodeWithNext[numberOfCases() + 1]), lowKey, into);
         return x;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java	Mon Jun 27 17:15:12 2011 +0200
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -57,14 +58,6 @@
         this.kind = kind;
     }
 
-    ///////////////
-    // TODO: remove when Value class changes are completed
-
-    @Override
-    protected Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException();
-    }
-
     /**
      * Checks whether this value is a constant (i.e. it is of type {@link Constant}.
      * @return {@code true} if this value is a constant
@@ -160,9 +153,23 @@
      *
      * @param v the visitor to accept
      */
-    public abstract void accept(ValueVisitor v);
+    public void accept(ValueVisitor v) {
+        throw new IllegalStateException("No visit method for this node");
+    }
+
+    public void print(LogStream out) {
+        out.print(this.getClass().toString());
+    }
 
-    public abstract void print(LogStream out);
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
+            return (T) LIRGenerator.DELEGATE_TO_VALUE_VISITOR;
+        }
+        return super.lookup(clazz);
+    }
+
 
     @Override
     public Map<Object, Object> getDebugProperties() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueAnchor.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueAnchor.java	Mon Jun 27 17:15:12 2011 +0200
@@ -29,7 +29,7 @@
 /**
  * The ValueAnchor instruction keeps non-CFG nodes above a certain point in the graph.
  */
-public final class ValueAnchor extends Instruction {
+public final class ValueAnchor extends FixedNodeWithNext {
 
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_OBJECT = 0;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Mon Jun 27 17:15:12 2011 +0200
@@ -51,8 +51,8 @@
     public abstract void visitLocal(Local i);
     public abstract void visitLogic(Logic i);
     public abstract void visitLookupSwitch(LookupSwitch i);
-    public abstract void visitMemoryRead(MemoryRead i);
-    public abstract void visitMemoryWrite(MemoryWrite i);
+    public abstract void visitMemoryRead(ReadNode i);
+    public abstract void visitMemoryWrite(WriteNode i);
     public abstract void visitMonitorAddress(MonitorAddress monitorAddress);
     public abstract void visitMonitorEnter(MonitorEnter i);
     public abstract void visitMonitorExit(MonitorExit i);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteNode.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,67 @@
+/*
+ * 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.oracle.max.graal.compiler.ir;
+
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+
+public final class WriteNode extends AccessNode {
+    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;
+    }
+
+    public Value value() {
+        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
+    }
+
+    public void setValue(Value v) {
+        inputs().set(super.inputCount() + INPUT_VALUE, v);
+    }
+
+    public WriteNode(CiKind kind, Value object, Value value, LocationNode location, Graph graph) {
+        super(kind, object, location, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        setValue(value);
+    }
+
+    @Override
+    public void accept(ValueVisitor v) {
+        v.visitMemoryWrite(this);
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("mem write to ").print(object()).print(" with value").print(value());
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new WriteNode(super.kind, null, null, null, into);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/package-info.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/package-info.java	Mon Jun 27 17:15:12 2011 +0200
@@ -75,7 +75,7 @@
  *
  * <li>
  * Add a field to optionally store an {@link com.oracle.max.graal.compiler.ir.Info} object for each HIR node, and remove the
- * {@link com.oracle.max.graal.compiler.ir.Instruction#exceptionHandlers} field, the {@link com.oracle.max.graal.compiler.ir.Instruction#bci} field, and any fields to store the Java
+ * {@link com.oracle.max.graal.compiler.ir.FixedNodeWithNext#exceptionHandlers} field, the {@link com.oracle.max.graal.compiler.ir.FixedNodeWithNext#bci} field, and any fields to store the Java
  * frame state in subclasses. Benefit: saves space if most HIR nodes do not have exception handlers, a bci or Java frame
  * state. Removes virtual dispatch on accessing debug information for nodes. Allows any node, regardless of its type, to
  * have info attached.</li>
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Mon Jun 27 17:15:12 2011 +0200
@@ -41,7 +41,7 @@
             if (op != null) {
                 Node canonical = op.canonical(node);
                 if (canonical != node) {
-                    node.replace(canonical);
+                    node.replaceAndDelete(canonical);
                     nodeWorkList.replaced(canonical, node, EdgeType.USAGES);
                     //System.out.println("-->" + n + " canonicalized to " + canonical);
                     GraalMetrics.NodesCanonicalized++;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Mon Jun 27 17:15:12 2011 +0200
@@ -50,7 +50,7 @@
                 FixedNode next = merge.next();
                 EndNode endNode = merge.endAt(0);
                 merge.delete();
-                endNode.replace(next);
+                endNode.replaceAndDelete(next);
             }
         }
         // remove if nodes with constant-value comparison
@@ -95,10 +95,6 @@
         }
     }
 
-    private static boolean isCFG(Node n) {
-        return n != null && ((n instanceof Instruction) || (n instanceof ControlSplit) || n == n.graph().start());
-    }
-
     private void iterateSuccessors() {
         for (Node current : flood) {
             if (current instanceof EndNode) {
@@ -132,10 +128,10 @@
             assert loop.predecessors().size() == 1;
             for (Node usage : new ArrayList<Node>(loop.usages())) {
                 assert usage instanceof Phi;
-                usage.replace(((Phi) usage).valueAt(0));
+                usage.replaceAndDelete(((Phi) usage).valueAt(0));
             }
 
-            loop.replace(loop.next());
+            loop.replaceAndDelete(loop.next());
         }
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Mon Jun 27 17:15:12 2011 +0200
@@ -101,7 +101,7 @@
         }
     });
 
-    private Instruction lastInstr;                 // the last instruction added
+    private FixedNodeWithNext lastInstr;                 // the last instruction added
 
     private final Set<Block> blocksOnWorklist = new HashSet<Block>();
     private final Set<Block> blocksVisited = new HashSet<Block>();
@@ -169,26 +169,26 @@
         }
 
         // 1. create the start block
-        Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
+        Block startBlock = nextBlock(FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI);
         markOnWorkList(startBlock);
-        lastInstr = (Instruction) createTarget(startBlock, frameState);
+        lastInstr = (FixedNodeWithNext) createTarget(startBlock, frameState);
         graph.start().setStart(lastInstr);
 
         if (isSynchronized(method.accessFlags())) {
             // 4A.1 add a monitor enter to the start block
             methodSynchronizedObject = synchronizedObject(frameState, method);
-            genMonitorEnter(methodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI);
+            genMonitorEnter(methodSynchronizedObject, FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI);
             // 4A.2 finish the start block
             finishStartBlock(startBlock);
 
             // 4A.3 setup an exception handler to unlock the root method synchronized object
-            unwindHandler = new CiExceptionHandler(0, method.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null);
+            unwindHandler = new CiExceptionHandler(0, method.code().length, FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI, 0, null);
         } else {
             // 4B.1 simply finish the start block
             finishStartBlock(startBlock);
 
             if (createUnwind) {
-                unwindHandler = new CiExceptionHandler(0, method.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null);
+                unwindHandler = new CiExceptionHandler(0, method.code().length, FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI, 0, null);
             }
         }
 
@@ -208,7 +208,7 @@
         for (Node n : graph.getNodes()) {
             if (n instanceof Placeholder && !loopExits.isMarked(n)) {
                 Placeholder p = (Placeholder) n;
-                p.replace(p.next());
+                p.replaceAndDelete(p.next());
             }
         }
 
@@ -327,7 +327,7 @@
                     FixedNode next = p.next();
                     p.setNext(null);
                     EndNode end = new EndNode(graph);
-                    p.replace(end);
+                    p.replaceAndDelete(end);
                     merge.setNext(next);
                     merge.addEnd(end);
                     merge.setStateAfter(existingState);
@@ -385,7 +385,7 @@
     }
 
     private FixedNode handleException(Value exceptionObject, int bci) {
-        assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci";
+        assert bci == FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci";
 
         if (GraalOptions.UseExceptionProbability && method.invocationCount() > GraalOptions.MatureInvocationCount) {
             if (exceptionObject == null && method.exceptionProbability(bci) == 0) {
@@ -426,7 +426,7 @@
             if (dispatchBlock == null) {
                 assert isCatchAll(firstHandler);
                 int handlerBCI = firstHandler.handlerBCI();
-                if (handlerBCI == Instruction.SYNCHRONIZATION_ENTRY_BCI) {
+                if (handlerBCI == FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI) {
                     dispatchBlock = unwindBlock(bci);
                 } else {
                     dispatchBlock = blockFromBci[handlerBCI];
@@ -1044,7 +1044,7 @@
         MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, graph);
         appendWithBCI(monitorEnter);
         frameState.lock(x);
-        if (bci == Instruction.SYNCHRONIZATION_ENTRY_BCI) {
+        if (bci == FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI) {
             monitorEnter.setStateAfter(frameState.create(0));
         }
     }
@@ -1076,7 +1076,7 @@
         Value value = frameState.ipop();
         BytecodeTableSwitch ts = new BytecodeTableSwitch(stream(), bci);
         int max = ts.numberOfCases();
-        List<Instruction> list = new ArrayList<Instruction>(max + 1);
+        List<FixedNodeWithNext> list = new ArrayList<FixedNodeWithNext>(max + 1);
         List<Integer> offsetList = new ArrayList<Integer>(max + 1);
         for (int i = 0; i < max; i++) {
             // add all successors to the successor list
@@ -1099,7 +1099,7 @@
         Value value = frameState.ipop();
         BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci);
         int max = ls.numberOfCases();
-        List<Instruction> list = new ArrayList<Instruction>(max + 1);
+        List<FixedNodeWithNext> list = new ArrayList<FixedNodeWithNext>(max + 1);
         List<Integer> offsetList = new ArrayList<Integer>(max + 1);
         int[] keys = new int[max];
         for (int i = 0; i < max; i++) {
@@ -1129,7 +1129,7 @@
         return fixed;
     }
 
-    private Value append(Instruction x) {
+    private Value append(FixedNodeWithNext x) {
         return appendWithBCI(x);
     }
 
@@ -1137,7 +1137,7 @@
         return v;
     }
 
-    private Value appendWithBCI(Instruction x) {
+    private Value appendWithBCI(FixedNodeWithNext x) {
         assert x.predecessors().size() == 0 : "instruction should not have been appended yet";
         assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
         lastInstr.setNext(x);
@@ -1228,7 +1228,7 @@
                 // now parse the block
                 if (block.isLoopHeader) {
                     LoopBegin begin = loopBegin(block);
-                    FrameState preLoopState = block.firstInstruction.stateAfter();
+                    FrameState preLoopState = ((StateSplit) block.firstInstruction).stateAfter();
                     assert preLoopState != null;
                     FrameState duplicate = preLoopState.duplicate(preLoopState.bci);
                     begin.setStateAfter(duplicate);
@@ -1277,7 +1277,7 @@
                     merge.addEnd(begin.forwardEdge());
                     merge.setNext(begin.next());
                     merge.setStateAfter(begin.stateAfter());
-                    begin.replace(merge);
+                    begin.replaceAndDelete(merge);
                 }
             }
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Mon Jun 27 17:15:12 2011 +0200
@@ -375,7 +375,7 @@
 
         assert invoke.successors().get(0) != null : invoke;
         assert invoke.predecessors().size() == 1 : "size: " + invoke.predecessors().size();
-        Instruction pred;
+        FixedNodeWithNext pred;
         if (withReceiver) {
             FixedGuard clipNode = new FixedGuard(compilation.graph);
             clipNode.setNode(new IsNonNull(parameters[0], compilation.graph));
@@ -405,7 +405,7 @@
         }
 
         if (pred instanceof Placeholder) {
-            pred.replace(((Placeholder) pred).next());
+            pred.replaceAndDelete(((Placeholder) pred).next());
         }
 
         if (returnNode != null) {
@@ -421,7 +421,7 @@
             returnDuplicate.inputs().clearAll();
             Node n = invoke.next();
             invoke.setNext(null);
-            returnDuplicate.replace(n);
+            returnDuplicate.replaceAndDelete(n);
         }
 
         if (exceptionEdge != null) {
@@ -438,12 +438,12 @@
                 unwindDuplicate.inputs().clearAll();
                 Node n = obj.next();
                 obj.setNext(null);
-                unwindDuplicate.replace(n);
+                unwindDuplicate.replaceAndDelete(n);
             }
         } else {
             if (unwindNode != null) {
                 Unwind unwindDuplicate = (Unwind) duplicates.get(unwindNode);
-                unwindDuplicate.replace(new Deoptimize(DeoptAction.InvalidateRecompile, compilation.graph));
+                unwindDuplicate.replaceAndDelete(new Deoptimize(DeoptAction.InvalidateRecompile, compilation.graph));
             }
         }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java	Mon Jun 27 17:15:12 2011 +0200
@@ -76,11 +76,11 @@
                         Phi phi = new Phi(kind, loopBegin, graph); // (gd) assumes order on loopBegin preds - works in collab with graph builder
                         phi.addInput(c2.init());
                         phi.addInput(add);
-                        c2.replace(phi);
+                        c2.replaceAndDelete(phi);
                     } else {
                         IntegerSub sub = new IntegerSub(kind, c2.init(), c1.init(), graph);
                         IntegerAdd add = new IntegerAdd(kind, c1, sub, graph);
-                        c2.replace(add);
+                        c2.replaceAndDelete(add);
                     }
                 }
             }
@@ -131,7 +131,7 @@
                         Graph graph = loopBegin.graph();
                         LoopCounter counter = new LoopCounter(init.kind, init, stride, loopBegin, graph);
                         counters.add(counter);
-                        phi.replace(counter);
+                        phi.replaceAndDelete(counter);
                         if (loopEndState != null) {
                             loopEndState.inputs().replace(backEdge, counter);
                         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Mon Jun 27 17:15:12 2011 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.graal.compiler.phases;
 
+import java.util.*;
+
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
@@ -32,8 +34,8 @@
 
     public static final LoweringOp DELEGATE_TO_RUNTIME = new LoweringOp() {
         @Override
-        public Node lower(Node n, CiLoweringTool tool) {
-            return tool.getRuntime().lower(n, tool);
+        public void lower(Node n, CiLoweringTool tool) {
+            tool.getRuntime().lower(n, tool);
         }
     };
 
@@ -48,75 +50,53 @@
         final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false);
         s.apply(graph);
 
-        for (Block b : s.getBlocks()) {
-            final Node[] firstNodeValue = new Node[]{b.firstNode()};
+        List<Block> blocks = s.getBlocks();
+        for (final Block b : blocks) {
+            process(b);
+        }
+    }
+
+    private void process(final Block b) {
+        final CiLoweringTool loweringTool = new CiLoweringTool() {
+
+            @Override
+            public Node getGuardAnchor() {
+                return b.createAnchor();
+            }
 
-            final CiLoweringTool loweringTool = new CiLoweringTool() {
-                @Override
-                public Node getGuardAnchor() {
-                    Node firstNode = firstNodeValue[0];
-                    if (firstNode == firstNode.graph().start()) {
-                        Anchor a = new Anchor(graph);
-                        a.setNext((FixedNode) firstNode.graph().start().start());
-                        firstNode.graph().start().setStart(a);
-                        firstNodeValue[0] = a;
-                        return a;
-                    } else if (firstNode instanceof Merge) {
-                        Merge merge = (Merge) firstNode;
-                        Anchor a = new Anchor(graph);
-                        a.setNext(merge.next());
-                        merge.setNext(a);
-                        firstNodeValue[0] = a;
-                        return a;
-                    } else if (!(firstNode instanceof Anchor)) {
-                        Anchor a = new Anchor(graph);
-                        assert firstNode.predecessors().size() == 1 : firstNode;
-                        Node pred = firstNode.predecessors().get(0);
-                        int predIndex = pred.successors().indexOf(firstNode);
-                        pred.successors().set(predIndex, a);
-                        a.setNext((FixedNode) firstNode);
-                        firstNodeValue[0] = a;
-                        return a;
+            @Override
+            public RiRuntime getRuntime() {
+                return runtime;
+            }
+
+            @Override
+            public Node createGuard(Node condition) {
+                Anchor anchor = (Anchor) getGuardAnchor();
+                for (GuardNode guard : anchor.happensAfterGuards()) {
+                    if (guard.node().valueEqual(condition)) {
+                        condition.delete();
+                        return guard;
                     }
-                    return firstNode;
                 }
-
-                @Override
-                public RiRuntime getRuntime() {
-                    return runtime;
-                }
+                GuardNode newGuard = new GuardNode(anchor.graph());
+                newGuard.setAnchor(anchor);
+                newGuard.setNode((BooleanNode) condition);
+                return newGuard;
+            }
+        };
 
-                @Override
-                public Node createGuard(Node condition) {
-                    Anchor anchor = (Anchor) getGuardAnchor();
-                    for (GuardNode guard : anchor.happensAfterGuards()) {
-                        if (guard.node().valueEqual(condition)) {
-                            condition.delete();
-                            return guard;
-                        }
-                    }
-                    GuardNode newGuard = new GuardNode(graph);
-                    newGuard.setAnchor(anchor);
-                    newGuard.setNode((BooleanNode) condition);
-                    return newGuard;
-                }
-            };
-
-            for (final Node n : b.getInstructions()) {
-                if (n instanceof FixedNode) {
-                    LoweringOp op = n.lookup(LoweringOp.class);
-                    if (op != null) {
-                        Node newNode = op.lower(n, loweringTool);
-                        if (newNode != null) {
-                            n.replace(newNode);
-                        }
-                    }
+        // Lower the instructions of this block.
+        for (final Node n : b.getInstructions()) {
+            if (n instanceof FixedNode) {
+                LoweringOp op = n.lookup(LoweringOp.class);
+                if (op != null) {
+                    op.lower(n, loweringTool);
                 }
             }
         }
     }
 
     public interface LoweringOp extends Op {
-        Node lower(Node n, CiLoweringTool tool);
+        void lower(Node n, CiLoweringTool tool);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,165 @@
+/*
+ * 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.oracle.max.graal.compiler.phases;
+
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.ir.*;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.graph.*;
+
+public class MemoryPhase extends Phase {
+
+    public static class MemoryMap {
+
+        private final Block block;
+        private HashMap<Object, Node> locationToWrite;
+        private HashMap<Object, List<Node>> locationToReads;
+
+        public MemoryMap(Block b, MemoryMap memoryMap) {
+            this(b);
+        }
+
+        public MemoryMap(Block b) {
+            block = b;
+            locationToWrite = new HashMap<Object, Node>();
+            locationToReads = new HashMap<Object, List<Node>>();
+            if (GraalOptions.TraceMemoryMaps) {
+                TTY.println("Creating new memory map for block B" + b.blockID());
+            }
+        }
+
+        public void mergeWith(MemoryMap memoryMap) {
+            if (GraalOptions.TraceMemoryMaps) {
+                TTY.println("Merging with memory map of block B" + memoryMap.block.blockID());
+            }
+        }
+
+        public void createMemoryMerge(AbstractMemoryMergeNode memMerge) {
+            if (GraalOptions.TraceMemoryMaps) {
+                TTY.println("Creating memory merge at node " + memMerge.id());
+            }
+
+            for (Entry<Object, Node> writeEntry : locationToWrite.entrySet()) {
+                memMerge.mergedNodes().add(writeEntry.getValue());
+            }
+
+            for (Entry<Object, List<Node>> readEntry : locationToReads.entrySet()) {
+                memMerge.mergedNodes().addAll(readEntry.getValue());
+            }
+
+            locationToReads.clear();
+            locationToWrite.clear();
+        }
+
+        public void registerWrite(Object location, Node node) {
+            if (GraalOptions.TraceMemoryMaps) {
+                TTY.println("Register write to " + location + " at node " + node.id());
+            }
+
+            if (locationToWrite.containsKey(location)) {
+                Node prevWrite = locationToWrite.get(location);
+                node.inputs().add(prevWrite);
+            }
+
+            if (locationToReads.containsKey(location)) {
+                for (Node prevRead : locationToReads.get(location)) {
+                    node.inputs().add(prevRead);
+                }
+            }
+            locationToWrite.put(location, node);
+            locationToReads.remove(location);
+        }
+
+        public void registerRead(Object location, Node node) {
+            if (GraalOptions.TraceMemoryMaps) {
+                TTY.println("Register read to " + location + " at node " + node.id());
+            }
+
+            if (locationToWrite.containsKey(location)) {
+                Node prevWrite = locationToWrite.get(location);
+                node.inputs().add(prevWrite);
+            }
+
+            if (!locationToReads.containsKey(location)) {
+                locationToReads.put(location, new ArrayList<Node>());
+            }
+            locationToReads.get(location).add(node);
+            TTY.println("entrySet size" + locationToReads.entrySet());
+        }
+    }
+
+    @Override
+    protected void run(final Graph graph) {
+        final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false);
+        s.apply(graph);
+
+        List<Block> blocks = s.getBlocks();
+        MemoryMap[] memoryMaps = new MemoryMap[blocks.size()];
+        for (final Block b : blocks) {
+            process(b, memoryMaps);
+        }
+    }
+
+    private void process(final Block b, MemoryMap[] memoryMaps) {
+        // Visit every block at most once.
+        if (memoryMaps[b.blockID()] != null) {
+            return;
+        }
+
+        // Process predecessors before this block.
+        for (Block pred : b.getPredecessors()) {
+            process(pred, memoryMaps);
+        }
+
+        // Create initial memory map for the block.
+        MemoryMap map = null;
+        if (b.getPredecessors().size() == 0) {
+            map = new MemoryMap(b);
+        } else {
+            map = new MemoryMap(b, memoryMaps[b.getPredecessors().get(0).blockID()]);
+            for (int i = 1; i < b.getPredecessors().size(); ++i) {
+                map.mergeWith(memoryMaps[b.getPredecessors().get(0).blockID()]);
+            }
+        }
+
+        // Lower the instructions of this block.
+        for (final Node n : b.getInstructions()) {
+            // This memory merge node is not lowered => create a memory merge nevertheless.
+            if (n instanceof AbstractMemoryMergeNode) {
+                map.createMemoryMerge((AbstractMemoryMergeNode) n);
+            } else if (n instanceof ReadNode) {
+                ReadNode readNode = (ReadNode) n;
+
+            } else if (n instanceof WriteNode) {
+                WriteNode writeNode = (WriteNode) n;
+
+            }
+        }
+
+        memoryMaps[b.blockID()] = map;
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java	Mon Jun 27 17:15:12 2011 +0200
@@ -38,6 +38,7 @@
     private Block dominator;
     private Block javaBlock;
     private final List<Block> dominators = new ArrayList<Block>();
+    private Anchor anchor;
 
     private Node firstNode;
     private Node lastNode;
@@ -48,6 +49,7 @@
 
     public void setFirstNode(Node node) {
         this.firstNode = node;
+        this.anchor = null;
     }
 
     public Block javaBlock() {
@@ -62,6 +64,44 @@
         return lastNode;
     }
 
+    public Anchor createAnchor() {
+        if (anchor == null) {
+            if (firstNode instanceof Anchor) {
+                this.anchor = (Anchor) firstNode;
+            } else if (firstNode == firstNode.graph().start()) {
+                StartNode start = (StartNode) firstNode;
+                if (start.start() instanceof Anchor) {
+                    this.anchor = (Anchor) start.start();
+                } else {
+                    Anchor a = new Anchor(firstNode.graph());
+                    a.setNext((FixedNode) firstNode.graph().start().start());
+                    firstNode.graph().start().setStart(a);
+                    this.anchor = a;
+                }
+            } else if (firstNode instanceof Merge) {
+                Merge merge = (Merge) firstNode;
+                if (merge.next() instanceof Anchor) {
+                    this.anchor = (Anchor) merge.next();
+                } else {
+                    Anchor a = new Anchor(firstNode.graph());
+                    a.setNext(merge.next());
+                    merge.setNext(a);
+                    this.anchor = a;
+                }
+            } else {
+                assert !(firstNode instanceof Anchor);
+                Anchor a = new Anchor(firstNode.graph());
+                assert firstNode.predecessors().size() == 1 : firstNode;
+                Node pred = firstNode.predecessors().get(0);
+                int predIndex = pred.successors().indexOf(firstNode);
+                pred.successors().set(predIndex, a);
+                a.setNext((FixedNode) firstNode);
+                this.anchor = a;
+            }
+        }
+        return anchor;
+    }
+
     public void setLastNode(Node node) {
         this.lastNode = node;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java	Mon Jun 27 17:15:12 2011 +0200
@@ -402,7 +402,7 @@
      * @param compareConstants {@code true} if equivalent constants should be considered equivalent
      * @return {@code true} if the instructions are equivalent; {@code false} otherwise
      */
-    public static boolean equivalent(Instruction x, Instruction y, boolean compareConstants) {
+    public static boolean equivalent(FixedNodeWithNext x, FixedNodeWithNext y, boolean compareConstants) {
         if (x == y) {
             return true;
         }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java	Mon Jun 27 17:15:12 2011 +0200
@@ -31,5 +31,6 @@
     VMExits getVMExits();
     GraalCompiler getCompiler();
     RiType lookupType(String returnType, HotSpotTypeResolved accessingClass);
+    HotSpotVMConfig getConfig();
 
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java	Mon Jun 27 17:15:12 2011 +0200
@@ -86,6 +86,11 @@
     private final CiTarget target;
     private final RiXirGenerator generator;
     private final RiRegisterConfig registerConfig;
+    private final HotSpotVMConfig config;
+
+    public HotSpotVMConfig getConfig() {
+        return config;
+    }
 
     private CompilerImpl(VMEntries entries) {
 
@@ -112,7 +117,7 @@
         vmExits = exits;
 
         // initialize compiler and GraalOptions
-        HotSpotVMConfig config = vmEntries.getConfiguration();
+        config = vmEntries.getConfiguration();
         config.check();
 
         // these options are important - graal will not generate correct code without them
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Mon Jun 27 17:15:12 2011 +0200
@@ -28,6 +28,7 @@
 
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.runtime.nodes.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ci.CiTargetMethod.Call;
 import com.sun.cri.ci.CiTargetMethod.DataPatch;
@@ -241,34 +242,42 @@
     }
 
     @Override
-    public Node lower(Node n, CiLoweringTool tool) {
+    public void lower(Node n, CiLoweringTool tool) {
         if (n instanceof LoadField) {
             LoadField field = (LoadField) n;
             if (field.isVolatile()) {
-                return null;
+                return;
             }
             Graph graph = field.graph();
             int displacement = ((HotSpotField) field.field()).offset();
             assert field.kind != CiKind.Illegal;
-            MemoryRead memoryRead = new MemoryRead(field.field().kind(), displacement, graph);
+            ReadNode memoryRead = new ReadNode(field.field().kind().stackKind(), field.object(), new LocationNode(field.field(), field.field().kind(), displacement, graph), graph);
             memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
             memoryRead.setNext(field.next());
-            memoryRead.setLocation(field.object());
-            return memoryRead;
+            field.replaceAndDelete(memoryRead);
         } else if (n instanceof StoreField) {
-            return null;
-//            StoreField field = (StoreField) n;
-//            if (field.isVolatile()) {
-//                return null;
-//            }
-//            Graph graph = field.graph();
-//            int displacement = ((HotSpotField) field.field()).offset();
-//            MemoryWrite memoryWrite = new MemoryWrite(field.field().kind(), field.value(), displacement, graph);
-//            memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
-//            memoryWrite.setNext(field.next());
-//            memoryWrite.setLocation(field.object());
-//            return memoryWrite;
+            StoreField field = (StoreField) n;
+            if (field.isVolatile()) {
+                return;
+            }
+            Graph graph = field.graph();
+            int displacement = ((HotSpotField) field.field()).offset();
+            WriteNode memoryWrite = new WriteNode(CiKind.Illegal, field.object(), field.value(), new LocationNode(field.field(), field.field().kind(), displacement, graph), graph);
+            memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
+            memoryWrite.setStateAfter(field.stateAfter());
+            memoryWrite.setNext(field.next());
+
+            //MemoryMergeNode memoryMergeNode = new MemoryMergeNode(graph);
+            //memoryMergeNode.setStateAfter(field.stateAfter());
+            //tool.createMemoryMerge(memoryMergeNode);
+            if (field.field().kind() == CiKind.Object && !field.value().isNullConstant()) {
+                FieldWriteBarrier writeBarrier = new FieldWriteBarrier(field.object(), graph);
+                memoryWrite.setNext(writeBarrier);
+                writeBarrier.setNext(field.next());
+            } else {
+                memoryWrite.setNext(field.next());
+            }
+            field.replaceAndDelete(memoryWrite);
         }
-        return null;
     }
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Mon Jun 27 17:13:33 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Mon Jun 27 17:15:12 2011 +0200
@@ -72,12 +72,9 @@
 
     private static Set<String> compiledMethods = new HashSet<String>();
 
-    private static PrintStream originalOut;
-    private static PrintStream originalErr;
-
     public void startCompiler() {
-        originalOut = System.out;
-        originalErr = System.err;
+        // Make sure TTY is initialized here such that the correct System.out is used for TTY.
+        TTY.isSuppressed();
     }
 
     public void shutdownCompiler() throws Throwable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.oracle.max.graal.runtime.nodes;
+
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.ir.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.runtime.*;
+import com.sun.cri.ci.*;
+
+
+public final class FieldWriteBarrier extends FixedNodeWithNext {
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_OBJECT = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    /**
+     * The instruction that produces the object tested against null.
+     */
+     public Value object() {
+        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
+    }
+
+    public void setObject(Value n) {
+        inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    }
+
+    public FieldWriteBarrier(Value object, Graph graph) {
+        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        this.setObject(object);
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
+            return (T) new LIRGenerator.LIRGeneratorOp() {
+                @Override
+                public void generate(Node n, LIRGenerator generator) {
+                    assert n == FieldWriteBarrier.this;
+                    CiVariable temp = generator.newVariable(CiKind.Word);
+                    HotSpotVMConfig config = CompilerImpl.getInstance().getConfig();
+                    generator.lir().move(generator.makeOperand(object()), temp);
+                    generator.lir().unsignedShiftRight(temp, CiConstant.forInt(config.cardtableShift), temp, CiValue.IllegalValue);
+
+                    long startAddress = config.cardtableStartAddress;
+                    int displacement = 0;
+                    if (((int) startAddress) == startAddress) {
+                        displacement = (int) startAddress;
+                    } else {
+                        generator.lir().add(temp, CiConstant.forLong(config.cardtableStartAddress), temp);
+                    }
+                    generator.lir().move(CiConstant.FALSE, new CiAddress(CiKind.Boolean, temp, displacement), (LIRDebugInfo) null);
+                }
+            };
+        }
+        return super.lookup(clazz);
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("field write barrier ").print(object());
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new FieldWriteBarrier(null, into);
+    }
+}
--- a/runavrora.sh	Mon Jun 27 17:13:33 2011 +0200
+++ b/runavrora.sh	Mon Jun 27 17:15:12 2011 +0200
@@ -15,7 +15,6 @@
   echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
   exit 1;
 fi
-COMMAND="${JDK7G}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal -G:-QuietBailout $* Harness --preserve -n 5 avrora"
+COMMAND="${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal -G:-QuietBailout $* Harness --preserve -n 5 avrora"
 echo $COMMAND
 $COMMAND
-echo $COMMAND
--- a/runfilter.sh	Mon Jun 27 17:13:33 2011 +0200
+++ b/runfilter.sh	Mon Jun 27 17:15:12 2011 +0200
@@ -18,4 +18,4 @@
 FILTER=$1
 shift 1
 TESTDIR=${MAXINE}/com.oracle.max.vm/test
-${JDK7}/bin/java -client -d64 -graal -ea -esa -Xcomp -XX:CompileOnly=jtt -Xbootclasspath/p:"${MAXINE}/com.oracle.max.vm/bin" -Xbootclasspath/p:"${MAXINE}/com.oracle.max.base/bin" $@ test.com.sun.max.vm.compiler.JavaTester -filter=${FILTER} -verbose=1 -gen-run-scheme=false -run-scheme-package=all $@ ${TESTDIR}/jtt/bytecode ${TESTDIR}/jtt/except ${TESTDIR}/jtt/hotpath ${TESTDIR}/jtt/jdk ${TESTDIR}/jtt/lang ${TESTDIR}/jtt/loop ${TESTDIR}/jtt/micro ${TESTDIR}/jtt/optimize ${TESTDIR}/jtt/reflect ${TESTDIR}/jtt/threads
+${JDK7}/bin/java -client -d64 -graal -ea -esa -Xcomp -XX:+PrintCompilation -XX:CompileOnly=jtt -Xbootclasspath/p:"${MAXINE}/com.oracle.max.vm/bin" -Xbootclasspath/p:"${MAXINE}/com.oracle.max.base/bin" $@ test.com.sun.max.vm.compiler.JavaTester -filter=${FILTER} -verbose=1 -gen-run-scheme=false -run-scheme-package=all $@ ${TESTDIR}/jtt/bytecode ${TESTDIR}/jtt/except ${TESTDIR}/jtt/hotpath ${TESTDIR}/jtt/jdk ${TESTDIR}/jtt/lang ${TESTDIR}/jtt/loop ${TESTDIR}/jtt/micro ${TESTDIR}/jtt/optimize ${TESTDIR}/jtt/reflect ${TESTDIR}/jtt/threads
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Mon Jun 27 17:15:12 2011 +0200
@@ -283,11 +283,12 @@
       jcc(Assembler::notZero, loop);
     }
   }
-
-  if (CURRENT_ENV->dtrace_alloc_probes()) {
-    assert(obj == rax, "must be");
-    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
-  }
+  
+  // (tw) fix me
+//  if (CURRENT_ENV->dtrace_alloc_probes()) {
+//    assert(obj == rax, "must be");
+//    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
+//  }
 
   verify_oop(obj);
 }
@@ -317,10 +318,11 @@
   const Register len_zero = len;
   initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
 
-  if (CURRENT_ENV->dtrace_alloc_probes()) {
-    assert(obj == rax, "must be");
-    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
-  }
+  // (tw) fix me
+//  if (CURRENT_ENV->dtrace_alloc_probes()) {
+//    assert(obj == rax, "must be");
+//    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
+//  }
 
   verify_oop(obj);
 }
--- a/src/os/windows/vm/os_windows.cpp	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/os/windows/vm/os_windows.cpp	Mon Jun 27 17:15:12 2011 +0200
@@ -409,7 +409,6 @@
     }
   }
 
-
   if (UseVectoredExceptions) {
     // If we are using vectored exception we don't need to set a SEH
     thread->run();
--- a/src/share/tools/IdealGraphVisualizer/Graal/nbproject/genfiles.properties	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graal/nbproject/genfiles.properties	Mon Jun 27 17:15:12 2011 +0200
@@ -1,8 +1,8 @@
-build.xml.data.CRC32=abfbe04d
+build.xml.data.CRC32=2bb741e3
 build.xml.script.CRC32=3534d355
 build.xml.stylesheet.CRC32=a56c6a5b@1.45.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=abfbe04d
+nbproject/build-impl.xml.data.CRC32=2bb741e3
 nbproject/build-impl.xml.script.CRC32=2867f2d5
 nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- a/src/share/tools/IdealGraphVisualizer/Graal/nbproject/project.xml	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graal/nbproject/project.xml	Mon Jun 27 17:15:12 2011 +0200
@@ -15,6 +15,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,89 @@
+/*
+ * 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.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.OutputSlot;
+import java.awt.Color;
+import java.util.List;
+
+/**
+ * Filter that colors usage and successor edges differently.
+ * 
+ * @author Peter Hofer
+ */
+public class GraalEdgeColorFilter extends AbstractFilter {
+
+    private Color successorColor = Color.ORANGE;
+    private Color usageColor = Color.RED;
+
+    public GraalEdgeColorFilter() {
+    }
+
+    public String getName() {
+        return "Graal Edge Color Filter";
+    }
+
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+
+            int succCount = Integer.parseInt(p.get("successorCount"));
+            for (OutputSlot os : f.getOutputSlots()) {
+                Color color;
+                if (os.getPosition() < succCount) {
+                    color = successorColor;
+                } else {
+                    color = usageColor;
+                }
+
+                os.setColor(color);
+                for (Connection c : os.getConnections()) {
+                    c.setColor(color);
+                }
+            }
+        }
+    }
+
+    public Color getUsageColor() {
+        return usageColor;
+    }
+
+    public void setUsageColor(Color usageColor) {
+        this.usageColor = usageColor;
+    }
+
+    public Color getSuccessorColor() {
+        return successorColor;
+    }
+
+    public void setSuccessorColor(Color successorColor) {
+        this.successorColor = successorColor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/edgeColor.filter	Mon Jun 27 17:15:12 2011 +0200
@@ -0,0 +1,4 @@
+var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter();
+f.setUsageColor(blue);
+f.setSuccessorColor(red);
+f.apply(graph);
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Mon Jun 27 17:15:12 2011 +0200
@@ -5,5 +5,9 @@
         <file name="Graal Coloring" url="filters/color.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
+        
+        <file name="Graal Edge Coloring" url="filters/edgeColor.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
     </folder>
 </filesystem>
--- a/src/share/vm/compiler/compileBroker.cpp	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/share/vm/compiler/compileBroker.cpp	Mon Jun 27 17:15:12 2011 +0200
@@ -1534,6 +1534,12 @@
     log->stamp();
     log->end_elem();
   }
+  
+  if (UseGraal) {
+    thread->set_compiling(true); // Prevent recursive compilations while the compiler is initializing.
+    ThreadToNativeFromVM trans(JavaThread::current());
+    GraalCompiler::instance()->initialize();
+  }
 
   while (true) {
     {
--- a/src/share/vm/graal/graalCompiler.cpp	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Mon Jun 27 17:15:12 2011 +0200
@@ -41,8 +41,8 @@
 // Initialization
 void GraalCompiler::initialize() {
   if (_initialized) return;
+  _initialized = true;
   CompilerThread* THREAD = CompilerThread::current();
-  _initialized = true;
   TRACE_graal_1("GraalCompiler::initialize");
 
   VmIds::initializeObjects();
@@ -99,7 +99,7 @@
 
 // Compilation entry point for methods
 void GraalCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
-  initialize();
+  assert(_initialized, "must already be initialized");
   VM_ENTRY_MARK;
   ResourceMark rm;
   HandleMark hm;
--- a/src/share/vm/runtime/thread.cpp	Mon Jun 27 17:13:33 2011 +0200
+++ b/src/share/vm/runtime/thread.cpp	Mon Jun 27 17:15:12 2011 +0200
@@ -29,6 +29,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/scopeDesc.hpp"
 #include "compiler/compileBroker.hpp"
+#include "graal/graalCompiler.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/linkResolver.hpp"
 #include "jvmtifiles/jvmtiEnv.hpp"