changeset 2931:89cb8a8578f9

merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Thu, 09 Jun 2011 14:44:36 +0200
parents 83233aacd876 (current diff) b78b4ae0757c (diff)
children 5f1778eb3854
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NullCheck.java
diffstat 20 files changed, 442 insertions(+), 249 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Thu Jun 09 14:44:36 2011 +0200
@@ -385,6 +385,23 @@
         emitXir(snippet, x, stateFor(x), null, true);
     }
 
+
+    @Override
+    public void visitGuardNode(GuardNode x) {
+        FrameState state = lastState;
+        assert state != null : "deoptimize instruction always needs a state";
+
+        if (deoptimizationStubs == null) {
+            deoptimizationStubs = new ArrayList<DeoptimizationStub>();
+        }
+
+        DeoptimizationStub stub = new DeoptimizationStub(state);
+        deoptimizationStubs.add(stub);
+        throw new RuntimeException();
+        //lir.branch(x.condition.negate(), stub.label, stub.info);
+    }
+
+
     @Override
     public void visitConstant(Constant x) {
         if (!canInlineAsConstant(x)) {
@@ -419,6 +436,60 @@
     }
 
     @Override
+    public void visitIf(If x) {
+        emitCompare(x.compare());
+        emitBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()));
+        assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination above";
+        lir.jump(getLIRBlock(x.defaultSuccessor()));
+    }
+
+    public void emitBranch(Compare compare, LIRBlock trueSuccessor, LIRBlock falseSucc) {
+        Condition cond = compare.condition();
+        if (compare.x().kind.isFloat() || compare.x().kind.isDouble()) {
+            LIRBlock unorderedSuccBlock = falseSucc;
+            if (compare.unorderedIsTrue()) {
+                unorderedSuccBlock = trueSuccessor;
+            }
+            lir.branch(cond, trueSuccessor, unorderedSuccBlock);
+        } else {
+            lir.branch(cond, trueSuccessor);
+        }
+    }
+
+    public void emitCompare(Compare compare) {
+        CiKind kind = compare.x().kind;
+
+        Condition cond = compare.condition();
+
+        LIRItem xitem = new LIRItem(compare.x(), this);
+        LIRItem yitem = new LIRItem(compare.y(), this);
+        LIRItem xin = xitem;
+        LIRItem yin = yitem;
+
+        if (kind.isLong()) {
+            // for longs, only conditions "eql", "neq", "lss", "geq" are valid;
+            // mirror for other conditions
+            if (cond == Condition.GT || cond == Condition.LE) {
+                cond = cond.mirror();
+                xin = yitem;
+                yin = xitem;
+            }
+            xin.setDestroysRegister();
+        }
+        xin.loadItem();
+        if (kind.isLong() && yin.result().isConstant() && yin.instruction.asConstant().asLong() == 0 && (cond == Condition.EQ || cond == Condition.NE)) {
+            // dont load item
+        } else if (kind.isLong() || kind.isFloat() || kind.isDouble()) {
+            // longs cannot handle constants at right side
+            yin.loadItem();
+        }
+
+        CiValue left = xin.result();
+        CiValue right = yin.result();
+        lir.cmp(cond, left, right);
+    }
+
+    @Override
     public void visitIfOp(Conditional i) {
         Value x = i.x();
         Value y = i.y();
@@ -457,11 +528,7 @@
     }
 
     private int getBeforeInvokeBci(Invoke invoke) {
-        /*int length = 3;
-        if (invoke.opcode() == Bytecodes.INVOKEINTERFACE) {
-            length += 2;
-        }
-        return invoke.stateAfter().bci - length;*/
+        // Cannot calculate BCI, because the invoke can have changed from e.g. invokeinterface to invokespecial because of optimizations.
         return invoke.bci;
     }
 
@@ -594,7 +661,7 @@
             int len = x.numberOfCases();
             for (int i = 0; i < len; i++) {
                 lir.cmp(Condition.EQ, tag, x.keyAt(i));
-                lir.branch(Condition.EQ, CiKind.Int, getLIRBlock(x.blockSuccessor(i)));
+                lir.branch(Condition.EQ, getLIRBlock(x.blockSuccessor(i)));
             }
             lir.jump(getLIRBlock(x.defaultSuccessor()));
         } else {
@@ -603,6 +670,9 @@
     }
 
     protected LIRBlock getLIRBlock(Instruction b) {
+        if (b == null) {
+            return null;
+        }
         LIRBlock result = ir.valueToBlock.get(b);
         if (result == null) {
             TTY.println("instruction without lir block: " + b);
@@ -611,7 +681,7 @@
     }
 
     @Override
-    public void visitNullCheck(NullCheck x) {
+    public void visitNullCheck(FixedNullCheck x) {
         CiValue value = load(x.object());
         LIRDebugInfo info = stateFor(x);
         lir.nullCheck(value, info);
@@ -856,7 +926,7 @@
             int len = x.numberOfCases();
             for (int i = 0; i < len; i++) {
                 lir.cmp(Condition.EQ, tag, i + loKey);
-                lir.branch(Condition.EQ, CiKind.Int, getLIRBlock(x.blockSuccessor(i)));
+                lir.branch(Condition.EQ, getLIRBlock(x.blockSuccessor(i)));
             }
             lir.jump(getLIRBlock(x.defaultSuccessor()));
         } else {
@@ -991,18 +1061,18 @@
             LIRBlock dest = oneRange.sux;
             if (lowKey == highKey) {
                 lir.cmp(Condition.EQ, value, lowKey);
-                lir.branch(Condition.EQ, CiKind.Int, dest);
+                lir.branch(Condition.EQ, dest);
             } else if (highKey - lowKey == 1) {
                 lir.cmp(Condition.EQ, value, lowKey);
-                lir.branch(Condition.EQ, CiKind.Int, dest);
+                lir.branch(Condition.EQ, dest);
                 lir.cmp(Condition.EQ, value, highKey);
-                lir.branch(Condition.EQ, CiKind.Int, dest);
+                lir.branch(Condition.EQ, dest);
             } else {
                 Label l = new Label();
                 lir.cmp(Condition.LT, value, lowKey);
                 lir.branch(Condition.LT, l);
                 lir.cmp(Condition.LE, value, highKey);
-                lir.branch(Condition.LE, CiKind.Int, dest);
+                lir.branch(Condition.LE, dest);
                 lir.branchDestination(l);
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ClipNode.java	Thu Jun 09 14:44:36 2011 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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 ClipNode extends Instruction {
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_NODE = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    /**
+     * The instruction that produces the object tested against null.
+     */
+     public FloatingNode node() {
+        return (FloatingNode) inputs().get(super.inputCount() + INPUT_NODE);
+    }
+
+    public FloatingNode setNode(FloatingNode n) {
+        return (FloatingNode) inputs().set(super.inputCount() + INPUT_NODE, n);
+    }
+
+    public ClipNode(Graph graph) {
+        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    }
+
+    @Override
+    public void accept(ValueVisitor v) {
+        // Do nothing.
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("clip node ").print(node());
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new ClipNode(into);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedNullCheck.java	Thu Jun 09 14:44:36 2011 +0200
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2009, 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.util.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.bytecode.*;
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
+
+/**
+ * The {@code NullCheck} class represents an explicit null check instruction.
+ */
+public final class FixedNullCheck extends Instruction {
+
+    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;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * The instruction that produces the object tested against null.
+     */
+     public Value object() {
+        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
+    }
+
+    public Value setObject(Value n) {
+        return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    }
+
+    /**
+     * Constructs a new NullCheck instruction.
+     * @param object the instruction producing the object to check against null
+     * @param stateBefore the state before executing the null check
+     * @param graph
+     */
+    public FixedNullCheck(Value object, Graph graph) {
+        super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        assert object == null || object.kind == CiKind.Object;
+        setObject(object);
+    }
+
+    @Override
+    public void accept(ValueVisitor v) {
+        v.visitNullCheck(this);
+    }
+
+    @Override
+    public int valueNumber() {
+        return Util.hash1(Bytecodes.IFNONNULL, object());
+    }
+
+    @Override
+    public boolean valueEqual(Node i) {
+        if (i instanceof FixedNullCheck) {
+            FixedNullCheck o = (FixedNullCheck) i;
+            return object() == o.object();
+        }
+        return false;
+    }
+
+    @Override
+    public RiType declaredType() {
+        // null check does not alter the type of the object
+        return object().declaredType();
+    }
+
+    @Override
+    public RiType exactType() {
+        // null check does not alter the type of the object
+        return object().exactType();
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("null_check(").print(object()).print(')');
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new FixedNullCheck(null, into);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Thu Jun 09 14:44:36 2011 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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 GuardNode extends Instruction {
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_NODE = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    /**
+     * The instruction that produces the object tested against null.
+     */
+     public FloatingNode node() {
+        return (FloatingNode) inputs().get(super.inputCount() + INPUT_NODE);
+    }
+
+    public FloatingNode setNode(FloatingNode n) {
+        return (FloatingNode) inputs().set(super.inputCount() + INPUT_NODE, n);
+    }
+
+    public GuardNode(Graph graph) {
+        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    }
+
+    @Override
+    public void accept(ValueVisitor v) {
+        v.visitGuardNode(this);
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("clip node ").print(node());
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new GuardNode(into);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NullCheck.java	Thu Jun 09 14:44:24 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2009, 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.util.*;
-import com.oracle.max.graal.graph.*;
-import com.sun.cri.bytecode.*;
-import com.sun.cri.ci.*;
-import com.sun.cri.ri.*;
-
-/**
- * The {@code NullCheck} class represents an explicit null check instruction.
- */
-public final class NullCheck extends Instruction {
-
-    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;
-    }
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
-    }
-
-    public Value setObject(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n);
-    }
-
-    /**
-     * Constructs a new NullCheck instruction.
-     * @param object the instruction producing the object to check against null
-     * @param stateBefore the state before executing the null check
-     * @param graph
-     */
-    public NullCheck(Value object, Graph graph) {
-        super(object.kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        setObject(object);
-    }
-
-    // for copying
-    private NullCheck(CiKind kind, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-    }
-
-    @Override
-    public void accept(ValueVisitor v) {
-        v.visitNullCheck(this);
-    }
-
-    @Override
-    public int valueNumber() {
-        return Util.hash1(Bytecodes.IFNONNULL, object());
-    }
-
-    @Override
-    public boolean valueEqual(Node i) {
-        if (i instanceof NullCheck) {
-            NullCheck o = (NullCheck) i;
-            return object() == o.object();
-        }
-        return false;
-    }
-
-    @Override
-    public RiType declaredType() {
-        // null check does not alter the type of the object
-        return object().declaredType();
-    }
-
-    @Override
-    public RiType exactType() {
-        // null check does not alter the type of the object
-        return object().exactType();
-    }
-
-    @Override
-    public void print(LogStream out) {
-        out.print("null_check(").print(object()).print(')');
-    }
-
-    @Override
-    public Node copy(Graph into) {
-        NullCheck x = new NullCheck(kind, into);
-        return x;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Thu Jun 09 14:44:36 2011 +0200
@@ -58,7 +58,7 @@
     public abstract void visitNewMultiArray(NewMultiArray i);
     public abstract void visitNewObjectArray(NewObjectArray i);
     public abstract void visitNewTypeArray(NewTypeArray i);
-    public abstract void visitNullCheck(NullCheck i);
+    public abstract void visitNullCheck(FixedNullCheck i);
     public abstract void visitPhi(Phi i);
     public abstract void visitRegisterFinalizer(RegisterFinalizer i);
     public abstract void visitReturn(Return i);
@@ -72,4 +72,5 @@
     public abstract void visitLoopBegin(LoopBegin loopBegin);
     public abstract void visitLoopEnd(LoopEnd loopEnd);
     public abstract void visitValueAnchor(ValueAnchor valueAnchor);
+    public abstract void visitGuardNode(GuardNode guardNode);
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java	Thu Jun 09 14:44:36 2011 +0200
@@ -34,7 +34,6 @@
 public class LIRBranch extends LIRInstruction {
 
     private Condition cond;
-    private CiKind kind;
     private Label label;
 
     /**
@@ -73,19 +72,17 @@
      * @param block
      *
      */
-    public LIRBranch(Condition cond, CiKind kind, LIRBlock block) {
+    public LIRBranch(Condition cond, LIRBlock block) {
         super(LIROpcode.Branch, CiValue.IllegalValue, null, false);
         this.cond = cond;
-        this.kind = kind;
         this.label = block.label();
         this.block = block;
         this.unorderedBlock = null;
     }
 
-    public LIRBranch(Condition cond, CiKind kind, LIRBlock block, LIRBlock ublock) {
+    public LIRBranch(Condition cond, LIRBlock block, LIRBlock ublock) {
         super(LIROpcode.CondFloatBranch, CiValue.IllegalValue, null, false);
         this.cond = cond;
-        this.kind = kind;
         this.label = block.label();
         this.block = block;
         this.unorderedBlock = ublock;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java	Thu Jun 09 14:44:36 2011 +0200
@@ -245,7 +245,7 @@
     }
 
     public void jump(LIRBlock block) {
-        append(new LIRBranch(Condition.TRUE, CiKind.Illegal, block));
+        append(new LIRBranch(Condition.TRUE, block));
     }
 
     public void branch(Condition cond, Label lbl) {
@@ -256,14 +256,12 @@
         append(new LIRBranch(cond, lbl, info));
     }
 
-    public void branch(Condition cond, CiKind kind, LIRBlock block) {
-        assert kind != CiKind.Float && kind != CiKind.Double : "no fp comparisons";
-        append(new LIRBranch(cond, kind, block));
+    public void branch(Condition cond, LIRBlock block) {
+        append(new LIRBranch(cond, block));
     }
 
-    public void branch(Condition cond, CiKind kind, LIRBlock block, LIRBlock unordered) {
-        assert kind == CiKind.Float || kind == CiKind.Double : "fp comparisons only";
-        append(new LIRBranch(cond, kind, block, unordered));
+    public void branch(Condition cond, LIRBlock block, LIRBlock unordered) {
+        append(new LIRBranch(cond, block, unordered));
     }
 
     public void tableswitch(CiValue index, int lowKey, LIRBlock defaultTargets, LIRBlock[] targets) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jun 09 14:44:36 2011 +0200
@@ -680,7 +680,7 @@
 
     private void genThrow(int bci) {
         Value exception = frameState.apop();
-        append(new NullCheck(exception, graph));
+        append(new FixedNullCheck(exception, graph));
 
         Instruction entry = handleException(exception, bci);
         if (entry != null) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jun 09 14:44:36 2011 +0200
@@ -233,7 +233,7 @@
         assert invoke.predecessors().size() == 1 : "size: " + invoke.predecessors().size();
         Instruction pred;
         if (withReceiver) {
-            pred = new NullCheck(parameters[0], compilation.graph);
+            pred = new FixedNullCheck(parameters[0], compilation.graph);
         } else {
             pred = new Merge(compilation.graph);
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Thu Jun 09 14:44:36 2011 +0200
@@ -471,53 +471,6 @@
     }
 
     @Override
-    public void visitIf(If x) {
-        CiKind kind = x.compare().x().kind;
-
-        Condition cond = x.compare().condition();
-
-        LIRItem xitem = new LIRItem(x.compare().x(), this);
-        LIRItem yitem = new LIRItem(x.compare().y(), this);
-        LIRItem xin = xitem;
-        LIRItem yin = yitem;
-
-        if (kind.isLong()) {
-            // for longs, only conditions "eql", "neq", "lss", "geq" are valid;
-            // mirror for other conditions
-            if (cond == Condition.GT || cond == Condition.LE) {
-                cond = cond.mirror();
-                xin = yitem;
-                yin = xitem;
-            }
-            xin.setDestroysRegister();
-        }
-        xin.loadItem();
-        if (kind.isLong() && yin.result().isConstant() && yin.instruction.asConstant().asLong() == 0 && (cond == Condition.EQ || cond == Condition.NE)) {
-            // dont load item
-        } else if (kind.isLong() || kind.isFloat() || kind.isDouble()) {
-            // longs cannot handle constants at right side
-            yin.loadItem();
-        }
-
-        setNoResult(x);
-
-        CiValue left = xin.result();
-        CiValue right = yin.result();
-        lir.cmp(cond, left, right);
-        if (x.compare().x().kind.isFloat() || x.compare().x().kind.isDouble()) {
-            Instruction unorderedSucc = x.falseSuccessor();
-            if (x.compare().unorderedIsTrue()) {
-                unorderedSucc = x.trueSuccessor();
-            }
-            lir.branch(cond, right.kind, getLIRBlock(x.trueSuccessor()), getLIRBlock(unorderedSucc));
-        } else {
-            lir.branch(cond, right.kind, getLIRBlock(x.trueSuccessor()));
-        }
-        assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination above";
-        lir.jump(getLIRBlock(x.defaultSuccessor()));
-    }
-
-    @Override
     public void visitExceptionDispatch(ExceptionDispatch x) {
         // TODO ls: this needs some more work...
 
@@ -530,7 +483,7 @@
         CiValue result = emitXir(snippet, x, stateFor(x), null, true);
 
         lir.cmp(Condition.EQ, result, CiConstant.TRUE);
-        lir.branch(Condition.EQ, CiKind.Boolean, getLIRBlock(x.catchSuccessor()));
+        lir.branch(Condition.EQ, getLIRBlock(x.catchSuccessor()));
 
         lir.jump(getLIRBlock(x.otherSuccessor()));
     }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExits.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExits.java	Thu Jun 09 14:44:36 2011 +0200
@@ -57,6 +57,7 @@
 
     CiConstant createCiConstantObject(Object object);
 
-    void shutdownCompiler();
+    void shutdownCompiler() throws Throwable;
 
+    void startCompiler();
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Thu Jun 09 14:44:24 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Thu Jun 09 14:44:36 2011 +0200
@@ -71,20 +71,48 @@
 
     private static Set<String> compiledMethods = new HashSet<String>();
 
-    public void shutdownCompiler() {
+    private static PrintStream originalOut;
+    private static PrintStream originalErr;
+
+    public void startCompiler() {
+        originalOut = System.out;
+        originalErr = System.err;
+        TTY.println("startCompiler: " + originalOut);
+    }
+
+    public void shutdownCompiler() throws Throwable {
         compileMethods = false;
 
-        if (GraalOptions.Meter) {
-            GraalMetrics.print();
-        }
-        if (GraalOptions.Time) {
-            GraalTimers.print();
-        }
-        if (PrintGCStats) {
-            printGCStats();
-        }
+        new Sandbox() {
+
+            @Override
+            public void run() {
+                if (GraalOptions.Meter) {
+
+                    GraalMetrics.print();
+                }
+                if (GraalOptions.Time) {
+                    GraalTimers.print();
+                }
+                if (PrintGCStats) {
+                    printGCStats();
+                }
+            }
+        }.start();
     }
 
+    public abstract class Sandbox {
+
+        public void start() throws Throwable {
+            PrintStream oldOut = System.out;
+            PrintStream oldErr = System.err;
+            run();
+            System.setOut(oldOut);
+            System.setErr(oldErr);
+        }
+
+        protected abstract void run() throws Throwable;
+    }
 
     public static void printGCStats() {
         long totalGarbageCollections = 0;
@@ -107,51 +135,56 @@
     }
 
     @Override
-    public void compileMethod(long methodVmId, String name, int entryBCI) throws Throwable {
+    public void compileMethod(final long methodVmId, final String name, final int entryBCI) throws Throwable {
         if (!compileMethods) {
             return;
         }
 
-        try {
-            HotSpotMethodResolved riMethod = new HotSpotMethodResolved(compiler, methodVmId, name);
-            CiResult result = compiler.getCompiler().compileMethod(riMethod, -1, null, null);
-            if (LogCompiledMethods) {
-                String qualifiedName = CiUtil.toJavaName(riMethod.holder()) + "::" + riMethod.name();
-                compiledMethods.add(qualifiedName);
-            }
+        new Sandbox() {
+            @Override
+            public void run() throws Throwable {
+                try {
+                    HotSpotMethodResolved riMethod = new HotSpotMethodResolved(compiler, methodVmId, name);
+                    CiResult result = compiler.getCompiler().compileMethod(riMethod, -1, null, null);
+                    if (LogCompiledMethods) {
+                        String qualifiedName = CiUtil.toJavaName(riMethod.holder()) + "::" + riMethod.name();
+                        compiledMethods.add(qualifiedName);
+                    }
 
-            if (result.bailout() != null) {
-                Throwable cause = result.bailout().getCause();
-                if (!GraalOptions.QuietBailout) {
+                    if (result.bailout() != null) {
+                        Throwable cause = result.bailout().getCause();
+                        if (!GraalOptions.QuietBailout) {
+                            StringWriter out = new StringWriter();
+                            result.bailout().printStackTrace(new PrintWriter(out));
+                            TTY.println("Bailout:\n" + out.toString());
+                            if (cause != null) {
+                                Logger.info("Trace for cause: ");
+                                for (StackTraceElement e : cause.getStackTrace()) {
+                                    String current = e.getClassName() + "::" + e.getMethodName();
+                                    String type = "";
+                                    if (compiledMethods.contains(current)) {
+                                        type = "compiled";
+                                    }
+                                    Logger.info(String.format("%-10s %3d %s", type, e.getLineNumber(), current));
+                                }
+                            }
+                        }
+                        String s = result.bailout().getMessage();
+                        if (cause != null) {
+                            s = cause.getMessage();
+                        }
+                        compiler.getVMEntries().recordBailout(s);
+                    } else {
+                        HotSpotTargetMethod.installMethod(compiler, riMethod, result.targetMethod());
+                    }
+                } catch (Throwable t) {
                     StringWriter out = new StringWriter();
-                    result.bailout().printStackTrace(new PrintWriter(out));
-                    TTY.println("Bailout:\n" + out.toString());
-                    if (cause != null) {
-                        Logger.info("Trace for cause: ");
-                        for (StackTraceElement e : cause.getStackTrace()) {
-                            String current = e.getClassName() + "::" + e.getMethodName();
-                            String type = "";
-                            if (compiledMethods.contains(current)) {
-                                type = "compiled";
-                            }
-                            Logger.info(String.format("%-10s %3d %s", type, e.getLineNumber(), current));
-                        }
-                    }
+                    t.printStackTrace(new PrintWriter(out));
+                    TTY.println("Compilation interrupted: (" + name + ")\n" + out.toString());
+                    throw t;
                 }
-                String s = result.bailout().getMessage();
-                if (cause != null) {
-                    s = cause.getMessage();
-                }
-                compiler.getVMEntries().recordBailout(s);
-            } else {
-                HotSpotTargetMethod.installMethod(compiler, riMethod, result.targetMethod());
             }
-        } catch (Throwable t) {
-            StringWriter out = new StringWriter();
-            t.printStackTrace(new PrintWriter(out));
-            TTY.println("Compilation interrupted: (" + name + ")\n" + out.toString());
-            throw t;
-        }
+        }.start();
     }
 
     @Override
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 09 14:44:24 2011 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 09 14:44:36 2011 +0200
@@ -296,6 +296,7 @@
   template(com_sun_cri_ci_CiConstant,                 "com/sun/cri/ci/CiConstant")                                      \
   template(com_sun_cri_ci_CiKind,                     "com/sun/cri/ci/CiKind")                                          \
   template(com_sun_cri_ci_CiRuntimeCall,              "com/sun/cri/ci/CiRuntimeCall")                                   \
+  template(startCompiler_name,                        "startCompiler")                                                  \
   template(shutdownCompiler_name,                     "shutdownCompiler")                                               \
   template(compileMethod_name,                        "compileMethod")                                                  \
   template(compileMethod_signature,                   "(JLjava/lang/String;I)V")                                        \
--- a/src/share/vm/graal/graalCompiler.cpp	Thu Jun 09 14:44:24 2011 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Thu Jun 09 14:44:36 2011 +0200
@@ -68,6 +68,7 @@
   {
     VM_ENTRY_MARK;
     HandleMark hm;
+    VMExits::initializeCompiler();
     VMExits::setDefaultOptions();
     for (int i = 0; i < Arguments::num_graal_args(); ++i) {
       const char* arg = Arguments::graal_args_array()[i];
@@ -78,8 +79,6 @@
         vm_abort(false);
       }
     }
-
-    VMExits::initializeCompiler();
   }
 }
 
--- a/src/share/vm/graal/graalVMExits.cpp	Thu Jun 09 14:44:24 2011 +0200
+++ b/src/share/vm/graal/graalVMExits.cpp	Thu Jun 09 14:44:36 2011 +0200
@@ -73,6 +73,8 @@
   JavaValue result(T_VOID);
   JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::initialize_name(), vmSymbols::void_method_signature(), Thread::current());
   check_pending_exception("Couldn't initialize compiler");
+
+  startCompiler();
 }
 
 jboolean VMExits::setOption(Handle option) {
@@ -119,6 +121,14 @@
   check_pending_exception("Error while calling shutdownCompiler");
 }
 
+void VMExits::startCompiler() {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::startCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling startCompiler");
+}
 
 oop VMExits::createRiMethodResolved(jlong vmId, Handle name, TRAPS) {
   assert(!name.is_null(), "just checking");
--- a/src/share/vm/graal/graalVMExits.hpp	Thu Jun 09 14:44:24 2011 +0200
+++ b/src/share/vm/graal/graalVMExits.hpp	Thu Jun 09 14:44:36 2011 +0200
@@ -55,6 +55,9 @@
 
   // public abstract void shutdownCompiler();
   static void shutdownCompiler();
+  
+  // public abstract void startCompiler();
+  static void startCompiler();
 
   // public abstract RiMethod createRiMethodResolved(long vmId, String name);
   static oop createRiMethodResolved(jlong vmId, Handle name, TRAPS);
--- a/src/share/vm/prims/jni.cpp	Thu Jun 09 14:44:24 2011 +0200
+++ b/src/share/vm/prims/jni.cpp	Thu Jun 09 14:44:36 2011 +0200
@@ -29,6 +29,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "interpreter/linkResolver.hpp"
+#include "graal/graalCompiler.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "memory/oopFactory.hpp"
--- a/src/share/vm/runtime/java.cpp	Thu Jun 09 14:44:24 2011 +0200
+++ b/src/share/vm/runtime/java.cpp	Thu Jun 09 14:44:36 2011 +0200
@@ -30,6 +30,7 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "interpreter/bytecodeHistogram.hpp"
+#include "graal/graalCompiler.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/universe.hpp"
@@ -418,6 +419,10 @@
   #define BEFORE_EXIT_DONE    2
   static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
 
+  if (UseGraal) {
+    GraalCompiler::instance()->exit();
+  }
+
   // Note: don't use a Mutex to guard the entire before_exit(), as
   // JVMTI post_thread_end_event and post_vm_death_event will run native code.
   // A CAS or OSMutex would work just fine but then we need to manipulate
--- a/src/share/vm/runtime/thread.cpp	Thu Jun 09 14:44:24 2011 +0200
+++ b/src/share/vm/runtime/thread.cpp	Thu Jun 09 14:44:36 2011 +0200
@@ -29,7 +29,6 @@
 #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"
@@ -3660,9 +3659,6 @@
     thread->invoke_shutdown_hooks();
   }
 
-  if (UseGraal) {
-    GraalCompiler::instance()->exit();
-  }
   before_exit(thread);
 
   thread->exit(true);