changeset 3050:3ed1b2a5d071

Merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Mon, 20 Jun 2011 14:29:42 +0200
parents 5f417a4a944a (diff) dd6927e3862e (current diff)
children 3a7043d555e1
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java 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/alloc/LinearScan.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.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/BlockMap.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/LoopBegin.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.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/phases/Phase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java rundacapo.sh runfop.sh runtests.sh
diffstat 46 files changed, 376 insertions(+), 323 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Jun 17 19:21:53 2011 +0200
+++ b/.hgtags	Mon Jun 20 14:29:42 2011 +0200
@@ -166,3 +166,4 @@
 0930dc920c185afbf40fed9a655290b8e5b16783 hs21-b08
 611e19a16519d6fb5deea9ab565336e6e6ee475d jdk7-b139
 611e19a16519d6fb5deea9ab565336e6e6ee475d hs21-b09
+a197fd9e273c692767407654c4caf858460a413f Tested with fop, lusearch, eclipse and jtt with Xcomp flag
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java	Mon Jun 20 14:29:42 2011 +0200
@@ -95,7 +95,7 @@
         this.method = method;
         this.stats = stats == null ? new CiStatistics() : stats;
         this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method);
-        this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, graph) : null;
+        this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, false, graph) : null;
 
         if (compiler.isObserved()) {
             compiler.fireCompilationStarted(new CompilationEvent(this));
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Mon Jun 20 14:29:42 2011 +0200
@@ -38,6 +38,7 @@
 
     // inlining settings
     public static boolean Inline                             = true;
+    public static boolean CacheGraphs                        = ____;
     public static boolean InlineWithTypeCheck                = ____;
     public static int     MaximumInstructionCount            = 37000;
     public static float   MaximumInlineRatio                 = 0.90f;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Mon Jun 20 14:29:42 2011 +0200
@@ -835,10 +835,10 @@
                 if (instr instanceof Phi) {
                     Phi phi = (Phi) instr;
                     TTY.println("phi block begin: " + phi.merge());
-                    TTY.println("pred count on blockbegin: " + phi.merge().phiPointPredecessorCount());
+                    TTY.println("pred count on blockbegin: " + phi.merge().phiPredecessorCount());
                     TTY.println("phi values: " + phi.valueCount());
                     TTY.println("phi block preds:");
-                    for (Node n : phi.merge().phiPointPredecessors()) {
+                    for (Node n : phi.merge().phiPredecessors()) {
                         TTY.println(n.toString());
                     }
                 }
@@ -1914,7 +1914,7 @@
         if (state.outerFrameState() != null) {
             caller = computeFrameForState(state.outerFrameState(), opId, frameRefMap);
         }
-        return new CiFrame(caller, state.method, state.bci, values, state.localsSize(), state.stackSize(), state.locksSize());
+        return new CiFrame(caller, state.method, state.bci, state.rethrowException(), values, state.localsSize(), state.stackSize(), state.locksSize());
     }
 
     private void computeDebugInfo(IntervalWalker iw, LIRInstruction op) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Mon Jun 20 14:29:42 2011 +0200
@@ -119,6 +119,7 @@
             schedule.apply(graph);
         } catch (Throwable t) {
             // nothing to do here...
+            t.printStackTrace();
         }
 
         stream.println("  <nodes>");
@@ -239,7 +240,7 @@
 
         if (nodes.size() > 0) {
             // if this is the first block: add all locals to this block
-            if (block.getInstructions() == graph.start()) {
+            if (block.getInstructions().size() > 0  && block.getInstructions().get(0) == graph.start()) {
                 for (Node node : graph.getNodes()) {
                     if (node instanceof Local) {
                         nodes.add(node);
@@ -253,12 +254,6 @@
                     nodes.add(((Instruction) node).stateAfter());
                 }
                 if (node instanceof Merge) {
-                    Merge merge = (Merge) node;
-                    if (merge.stateAfter() != null) {
-                        nodes.add(merge.stateAfter());
-                    }
-                }
-                if (node instanceof PhiPoint) {
                     for (Node usage : node.usages()) {
                         if (usage instanceof Phi || usage instanceof LoopCounter) {
                             nodes.add(usage);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Mon Jun 20 14:29:42 2011 +0200
@@ -260,15 +260,10 @@
                 }
             }
         }
-        if (block.blockSuccessors().size() == 1 && !(block.lastInstruction() instanceof LoopEnd)) {
-            Node firstInstruction = block.blockSuccessors().get(0).firstInstruction();
-            //System.out.println("suxSz == 1, fst=" + firstInstruction);
-            if (firstInstruction instanceof LoopBegin) {
-                moveToPhi((LoopBegin) firstInstruction, block.lastInstruction());
-            }
-        }
         if (block.blockSuccessors().size() >= 1 && !block.endsWithJump()) {
-            block.lir().jump(getLIRBlock((FixedNode) block.lastInstruction().successors().get(0)));
+            NodeArray successors = block.lastInstruction().successors();
+            assert successors.size() >= 1 : "should have at least one successor : " + block.lastInstruction();
+            block.lir().jump(getLIRBlock((FixedNode) successors.get(0)));
         }
 
         if (GraalOptions.TraceLIRGeneratorLevel >= 1) {
@@ -315,7 +310,7 @@
             slot += arguments[arg].sizeInSlots();
         }
 
-        FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, compilation.graph);
+        FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, false, compilation.graph);
         for (Node node : compilation.graph.start().usages()) {
             if (node instanceof Local) {
                 Local local = (Local) node;
@@ -549,7 +544,7 @@
     }
 
     protected FrameState stateBeforeInvokeReturn(Invoke invoke) {
-        return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.kind);
+        return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind);
     }
 
     protected FrameState stateBeforeInvokeWithArguments(Invoke invoke) {
@@ -557,7 +552,7 @@
         for (int i = 0; i < invoke.argumentCount(); i++) {
             args[i] = invoke.argument(i);
         }
-        return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.kind, args);
+        return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind, args);
     }
 
     private int getBeforeInvokeBci(Invoke invoke) {
@@ -995,6 +990,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";
         DeoptimizationStub stub = new DeoptimizationStub(deoptimize.action(), lastState);
         addDeoptimizationStub(stub);
         lir.branch(Condition.TRUE, stub.label, stub.info);
@@ -1437,8 +1433,8 @@
         lir.jump(getLIRBlock(x.loopBegin()));
     }
 
-    private void moveToPhi(PhiPoint merge, Node pred) {
-        int nextSuccIndex = merge.phiPointPredecessorIndex(pred);
+    private void moveToPhi(Merge merge, Node pred) {
+        int nextSuccIndex = merge.phiPredecessorIndex(pred);
         PhiResolver resolver = new PhiResolver(this);
         for (Phi phi : merge.phis()) {
             if (!phi.isDead()) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Mon Jun 20 14:29:42 2011 +0200
@@ -132,6 +132,7 @@
     public static class ExceptionBlock  extends Block {
         public RiExceptionHandler handler;
         public Block next;
+        public int deoptBci;
     }
 
     public static class DeoptBlock  extends Block {
@@ -157,6 +158,8 @@
 
     private final RiMethod method;
 
+    private final RiExceptionHandler[] exceptionHandlers;
+
     public final HashMap<Integer, BranchOverride> branchOverride;
 
     private Block[] blockMap;
@@ -169,6 +172,7 @@
      */
     public BlockMap(RiMethod method) {
         this.method = method;
+        exceptionHandlers = method.exceptionHandlers();
         this.blockMap = new Block[method.codeSize()];
         if (method.exceptionHandlers().length != 0) {
             this.canTrap = new BitSet(blockMap.length);
@@ -178,6 +182,10 @@
         branchOverride = new HashMap<Integer, BranchOverride>();
     }
 
+    public RiExceptionHandler[] exceptionHandlers() {
+        return exceptionHandlers;
+    }
+
     /**
      * Builds the block map and conservative CFG and numbers blocks.
      */
@@ -202,7 +210,7 @@
 
     private void makeExceptionEntries() {
         // start basic blocks at all exception handler blocks and mark them as exception entries
-        for (RiExceptionHandler h : method.exceptionHandlers()) {
+        for (RiExceptionHandler h : this.exceptionHandlers) {
             Block xhandler = makeBlock(h.handlerBCI());
             xhandler.isExceptionEntry = true;
         }
@@ -427,7 +435,7 @@
 
     private ExceptionBlock unwindBlock;
 
-    private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index) {
+    private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index, int bci) {
         RiExceptionHandler handler = handlers.get(index);
         if (handler.isCatchAll()) {
             return blockMap[handler.handlerBCI()];
@@ -437,10 +445,11 @@
             block = new ExceptionBlock();
             block.startBci = -1;
             block.endBci = -1;
+            block.deoptBci = bci;
             block.handler = handler;
             block.successors.add(blockMap[handler.handlerBCI()]);
             if (index < handlers.size() - 1) {
-                block.next = makeExceptionDispatch(handlers, index + 1);
+                block.next = makeExceptionDispatch(handlers, index + 1, bci);
                 block.successors.add(block.next);
             }
             exceptionDispatch.put(handler, block);
@@ -457,7 +466,7 @@
             Block block = blockMap[bci];
 
             ArrayList<RiExceptionHandler> handlers = null;
-            for (RiExceptionHandler h : method.exceptionHandlers()) {
+            for (RiExceptionHandler h : this.exceptionHandlers) {
                 if (h.startBCI() <= bci && bci < h.endBCI()) {
                     if (handlers == null) {
                         handlers = new ArrayList<RiExceptionHandler>();
@@ -469,7 +478,7 @@
                 }
             }
             if (handlers != null) {
-                Block dispatch = makeExceptionDispatch(handlers, 0);
+                Block dispatch = makeExceptionDispatch(handlers, 0, bci);
                 block.successors.add(dispatch);
             }
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Mon Jun 20 14:29:42 2011 +0200
@@ -79,11 +79,15 @@
             new GraphBuilderPhase(compilation, compilation.method, false, false).apply(compilation.graph);
 //        }
 
+        //printGraph("After GraphBuilding", compilation.graph);
+
         if (GraalOptions.TestGraphDuplication) {
             new DuplicationPhase().apply(compilation.graph);
+            //printGraph("After Duplication", compilation.graph);
         }
 
         new DeadCodeEliminationPhase().apply(compilation.graph);
+        //printGraph("After DeadCodeElimination", compilation.graph);
 
         if (GraalOptions.Inline) {
             new InliningPhase(compilation, this, GraalOptions.TraceInlining).apply(compilation.graph);
@@ -96,7 +100,6 @@
             new DeadCodeEliminationPhase().apply(graph);
         }
 
-        new LoopEdgeSplitingPhase().apply(graph);
         if (GraalOptions.OptLoops) {
             new LoopPhase().apply(graph);
         }
@@ -106,9 +109,6 @@
         IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true);
         schedule.apply(graph);
 
-        if (GraalOptions.Time) {
-            GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.start();
-        }
 
         List<Block> blocks = schedule.getBlocks();
         List<LIRBlock> lirBlocks = new ArrayList<LIRBlock>();
@@ -145,6 +145,11 @@
         assert startBlock != null;
         assert startBlock.blockPredecessors().size() == 0;
 
+
+        if (GraalOptions.Time) {
+            GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.start();
+        }
+
         ComputeLinearScanOrder clso = new ComputeLinearScanOrder(lirBlocks.size(), startBlock);
         orderedBlocks = clso.linearScanOrder();
         this.compilation.stats.loopCount = clso.numLoops();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java	Mon Jun 20 14:29:42 2011 +0200
@@ -76,7 +76,7 @@
         this.field = field;
         setObject(object);
         assert field.isResolved();
-        assert field.holder().isResolved();
+        assert field.holder().isInitialized();
     }
 
     /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java	Mon Jun 20 14:29:42 2011 +0200
@@ -27,15 +27,11 @@
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
 
-public class LoopBegin extends StateSplit implements PhiPoint{
-
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
+public class LoopBegin extends Merge{
     public LoopBegin(Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(graph);
+        this.addEnd(new EndNode(graph));
     }
 
     public LoopEnd loopEnd() {
@@ -73,34 +69,18 @@
     }
 
     @Override
-    public int phiPointPredecessorCount() {
+    public int phiPredecessorCount() {
         return 2;
     }
 
     @Override
-    public int phiPointPredecessorIndex(Node pred) {
-        Node singlePredecessor = this.singlePredecessor();
-        if (pred == singlePredecessor) {
+    public int phiPredecessorIndex(Node pred) {
+        if (pred == forwardEdge()) {
             return 0;
         } else if (pred == this.loopEnd()) {
             return 1;
-        } else if (singlePredecessor instanceof Placeholder) {
-            singlePredecessor = singlePredecessor.singlePredecessor();
-            if (pred == singlePredecessor) {
-                return 0;
-            }
         }
-        throw Util.shouldNotReachHere("unknown pred : " + pred + "(sp=" + singlePredecessor + ", le=" + this.loopEnd() + ")");
-    }
-
-    @Override
-    public Node asNode() {
-        return this;
-    }
-
-    @Override
-    public Collection<Phi> phis() {
-        return Util.filter(this.usages(), Phi.class);
+        throw Util.shouldNotReachHere("unknown pred : " + pred + "(sp=" + forwardEdge() + ", le=" + this.loopEnd() + ")");
     }
 
     public Collection<LoopCounter> counters() {
@@ -108,7 +88,18 @@
     }
 
     @Override
-    public List<Node> phiPointPredecessors() {
-        return Arrays.asList(new Node[]{this.singlePredecessor(), this.loopEnd()});
+    public List<Node> phiPredecessors() {
+        return Arrays.asList(new Node[]{this.forwardEdge(), this.loopEnd()});
+    }
+
+    public EndNode forwardEdge() {
+        return this.endAt(0);
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(loopEnd() != null);
+        assertTrue(forwardEdge() != null);
+        return true;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java	Mon Jun 20 14:29:42 2011 +0200
@@ -35,7 +35,7 @@
  * about the basic block, including the successor and
  * predecessor blocks, exception handlers, liveness information, etc.
  */
-public class Merge extends StateSplit implements PhiPoint{
+public class Merge extends StateSplit{
 
     private static final int INPUT_COUNT = 0;
 
@@ -92,6 +92,29 @@
         return (EndNode) inputs().variablePart().get(index);
     }
 
+    public Iterable<Node> mergePredecessors() {
+        return new Iterable<Node>() {
+            @Override
+            public Iterator<Node> iterator() {
+                return new Iterator<Node>() {
+                    int i = 0;
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                    @Override
+                    public Node next() {
+                        return Merge.this.endAt(i++);
+                    }
+                    @Override
+                    public boolean hasNext() {
+                        return i < Merge.this.endCount();
+                    }
+                };
+            }
+        };
+    }
+
     @Override
     public String toString() {
         StringBuilder builder = new StringBuilder();
@@ -292,34 +315,27 @@
         for (Node usage : usages()) {
             if (usage instanceof Phi) {
                 Phi phi = (Phi) usage;
-                phi.removeInput(predIndex);
+                if (!phi.isDead()) {
+                    phi.removeInput(predIndex);
+                }
             }
         }
     }
 
-    @Override
-    public int phiPointPredecessorCount() {
+    public int phiPredecessorCount() {
         return endCount();
     }
 
-    @Override
-    public int phiPointPredecessorIndex(Node pred) {
+    public int phiPredecessorIndex(Node pred) {
         EndNode end = (EndNode) pred;
         return endIndex(end);
     }
 
-    @Override
-    public Node asNode() {
-        return this;
-    }
-
-    @Override
     public Collection<Phi> phis() {
         return Util.filter(this.usages(), Phi.class);
     }
 
-    @Override
-    public List<Node> phiPointPredecessors() {
+    public List<Node> phiPredecessors() {
         return Collections.unmodifiableList(inputs().variablePart());
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Mon Jun 20 14:29:42 2011 +0200
@@ -54,24 +54,32 @@
     /**
      * The merge node for this phi.
      */
-    public PhiPoint merge() {
-        return (PhiPoint) inputs().get(super.inputCount() + INPUT_MERGE);
+    public Merge merge() {
+        return (Merge) inputs().get(super.inputCount() + INPUT_MERGE);
     }
 
-    public void setMerge(Node n) {
-        assert n instanceof PhiPoint;
+    public void setMerge(Merge n) {
         inputs().set(super.inputCount() + INPUT_MERGE, n);
     }
 
-    public Phi(CiKind kind, PhiPoint merge, Graph graph) {
+    public Phi(CiKind kind, Merge merge, Graph graph) {
         super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        setMerge(merge.asNode());
+        setMerge(merge);
     }
 
     Phi(CiKind kind, Graph graph) {
         super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
 
+    @Override
+    public boolean verify() {
+        assertTrue(merge() != null);
+        if (!isDead()) {
+            assertTrue(merge().phiPredecessorCount() == valueCount());
+        }
+        return true;
+    }
+
     /**
      * Get the instruction that produces the value associated with the i'th predecessor
      * of the join block.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/PhiPoint.java	Fri Jun 17 19:21:53 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +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 java.util.*;
-
-import com.oracle.max.graal.graph.*;
-
-/**
- * A marker interface for nodes from which Phi can hang.
- */
-public interface PhiPoint {
-    int phiPointPredecessorCount();
-    int phiPointPredecessorIndex(Node pred);
-    List<Node> phiPointPredecessors();
-    Node asNode();
-    Collection<Phi> phis();
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Mon Jun 20 14:29:42 2011 +0200
@@ -29,7 +29,6 @@
 import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
 
 
 public class DeadCodeEliminationPhase extends Phase {
@@ -46,7 +45,7 @@
 
         // remove chained Merges
         for (Merge merge : graph.getNodes(Merge.class)) {
-            if (merge.endCount() == 1 && merge.usages().size() == 0 && !(merge instanceof LoopEnd)) {
+            if (merge.endCount() == 1 && merge.usages().size() == 0 && !(merge instanceof LoopEnd || merge instanceof LoopBegin)) {
                 FixedNode next = merge.next();
                 EndNode endNode = merge.endAt(0);
                 merge.delete();
@@ -54,20 +53,20 @@
             }
         }
         // remove if nodes with constant-value comparison
-        for (If ifNode : graph.getNodes(If.class)) {
-            Compare compare = ifNode.compare();
-            if (compare.x().isConstant() && compare.y().isConstant()) {
-                CiConstant constX = compare.x().asConstant();
-                CiConstant constY = compare.y().asConstant();
-                Boolean result = compare.condition().foldCondition(constX, constY, GraalCompilation.compilation().runtime);
-                if (result != null) {
-                    Node actualSuccessor = result ? ifNode.trueSuccessor() : ifNode.falseSuccessor();
-                    ifNode.replace(actualSuccessor);
-                } else {
-                    TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind);
-                }
-            }
-        }
+//        for (If ifNode : graph.getNodes(If.class)) {
+//            Compare compare = ifNode.compare();
+//            if (compare.x().isConstant() && compare.y().isConstant()) {
+//                CiConstant constX = compare.x().asConstant();
+//                CiConstant constY = compare.y().asConstant();
+//                Boolean result = compare.condition().foldCondition(constX, constY, GraalCompilation.compilation().runtime);
+//                if (result != null) {
+//                    Node actualSuccessor = result ? ifNode.trueSuccessor() : ifNode.falseSuccessor();
+//                    ifNode.replace(actualSuccessor);
+//                } else {
+//                    TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind);
+//                }
+//            }
+//        }
 
         flood.add(graph.start());
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Mon Jun 20 14:29:42 2011 +0200
@@ -31,8 +31,10 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.graph.*;
-import com.oracle.max.graal.compiler.graph.BlockMap.*;
 import com.oracle.max.graal.compiler.graph.BlockMap.Block;
+import com.oracle.max.graal.compiler.graph.BlockMap.BranchOverride;
+import com.oracle.max.graal.compiler.graph.BlockMap.DeoptBlock;
+import com.oracle.max.graal.compiler.graph.BlockMap.ExceptionBlock;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.ir.Deoptimize.DeoptAction;
 import com.oracle.max.graal.compiler.schedule.*;
@@ -42,7 +44,7 @@
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
-import com.sun.cri.ri.RiType.*;
+import com.sun.cri.ri.RiType.Representation;
 
 /**
  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -70,6 +72,7 @@
     private final RiRuntime runtime;
     private final RiMethod method;
     private final RiConstantPool constantPool;
+    private RiExceptionHandler[] exceptionHandlers;
 
     private final BytecodeStream stream;           // the bytecode stream
     private final LogStream log;
@@ -85,7 +88,7 @@
     private Value methodSynchronizedObject;
     private CiExceptionHandler unwindHandler;
 
-    private Block unwindBlock;
+    private ExceptionBlock unwindBlock;
     private Block returnBlock;
 
     private boolean storeResultGraph;
@@ -125,7 +128,7 @@
 
         this.constantPool = runtime.getConstantPool(method);
         this.createUnwind = createUnwind;
-        this.storeResultGraph = true;
+        this.storeResultGraph = GraalOptions.CacheGraphs;
     }
 
     @Override
@@ -152,6 +155,7 @@
         BlockMap blockMap = compilation.getBlockMap(method);
         this.branchOverride = blockMap.branchOverride;
 
+        exceptionHandlers = blockMap.exceptionHandlers();
         blockList = new ArrayList<Block>(blockMap.blocks);
         blockFromBci = new Block[method.codeSize()];
         for (int i = 0; i < blockList.size(); i++) {
@@ -234,11 +238,12 @@
         return block;
     }
 
-    private Block unwindBlock() {
+    private Block unwindBlock(int bci) {
         if (unwindBlock == null) {
-            unwindBlock = new Block();
-            unwindBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
-            unwindBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            unwindBlock = new ExceptionBlock();
+            unwindBlock.startBci = -1;
+            unwindBlock.endBci = -1;
+            unwindBlock.deoptBci = bci;
             unwindBlock.blockID = nextBlockNumber();
             addToWorkList(unwindBlock);
         }
@@ -281,17 +286,23 @@
         StateSplit first = (StateSplit) target.firstInstruction;
 
         if (target.isLoopHeader && isVisited(target)) {
-            first = ((LoopBegin) target.firstInstruction.next()).loopEnd();
+            first = loopBegin(target).loopEnd();
         }
+
+        int bci = target.startBci;
+        if (target instanceof ExceptionBlock) {
+            bci = ((ExceptionBlock) target).deoptBci;
+        }
+
         FrameState existingState = first.stateAfter();
 
         if (existingState == null) {
             // copy state because it is modified
-            FrameState duplicate = newState.duplicate(target.startBci);
+            FrameState duplicate = newState.duplicate(bci);
 
             // if the block is a loop header, insert all necessary phis
             if (target.isLoopHeader && !isVisited(target)) {
-                LoopBegin loopBegin = (LoopBegin) target.firstInstruction.next();
+                LoopBegin loopBegin = loopBegin(target);
                 assert target.firstInstruction instanceof Placeholder && loopBegin != null;
                 //System.out.println("insertLoopPhis with " + target.loopHeaderState);
                 insertLoopPhis(loopBegin, loopBegin.stateAfter());
@@ -310,7 +321,7 @@
             if (first instanceof Placeholder) {
                 Placeholder p = (Placeholder) first;
                 if (p.predecessors().size() == 0) {
-                    p.setStateAfter(newState.duplicate(target.startBci));
+                    p.setStateAfter(newState.duplicate(bci));
                     return;
                 } else {
                     Merge merge = new Merge(graph);
@@ -376,7 +387,6 @@
         assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci";
 
         RiExceptionHandler firstHandler = null;
-        RiExceptionHandler[] exceptionHandlers = method.exceptionHandlers();
         // join with all potential exception handlers
         if (exceptionHandlers != null) {
             for (RiExceptionHandler handler : exceptionHandlers) {
@@ -410,7 +420,7 @@
                 assert isCatchAll(firstHandler);
                 int handlerBCI = firstHandler.handlerBCI();
                 if (handlerBCI == Instruction.SYNCHRONIZATION_ENTRY_BCI) {
-                    dispatchBlock = unwindBlock();
+                    dispatchBlock = unwindBlock(bci);
                 } else {
                     dispatchBlock = blockFromBci[handlerBCI];
                 }
@@ -428,7 +438,7 @@
                 currentNext = exception;
                 currentExceptionObject = exception;
             }
-            FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, currentExceptionObject);
+            FrameState stateWithException = entryState.duplicateWithException(bci, currentExceptionObject);
 
             currentNext.setNext(createTarget(dispatchBlock, stateWithException));
             return entry;
@@ -711,7 +721,7 @@
         } else {
             frameState.clearStack();
             frameState.apush(exception);
-            appendGoto(createTarget(unwindBlock(), frameState));
+            appendGoto(createTarget(unwindBlock(bci), frameState));
         }
     }
 
@@ -794,7 +804,7 @@
     private void genGetField(int cpi, RiField field) {
         CiKind kind = field.kind();
         Value receiver = frameState.apop();
-        if (field.isResolved()) {
+        if (field.isResolved() && field.holder().isInitialized()) {
             LoadField load = new LoadField(receiver, field, graph);
             appendOptimizedLoadField(kind, load);
         } else {
@@ -807,7 +817,7 @@
     private void genPutField(int cpi, RiField field) {
         Value value = frameState.pop(field.kind().stackKind());
         Value receiver = frameState.apop();
-        if (field.isResolved()) {
+        if (field.isResolved() && field.holder().isInitialized()) {
             StoreField store = new StoreField(receiver, field, value, graph);
             appendOptimizedStoreField(store);
         } else {
@@ -818,7 +828,7 @@
 
     private void genGetStatic(int cpi, RiField field) {
         RiType holder = field.holder();
-        boolean isInitialized = field.isResolved();
+        boolean isInitialized = field.isResolved() && field.holder().isInitialized();
         CiConstant constantValue = null;
         if (isInitialized) {
             constantValue = field.constantValue(null);
@@ -840,7 +850,7 @@
 
     private void genPutStatic(int cpi, RiField field) {
         RiType holder = field.holder();
-        Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved(), cpi);
+        Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved() && field.holder().isInitialized(), cpi);
         Value value = frameState.pop(field.kind().stackKind());
         if (container != null) {
             StoreField store = new StoreField(container, field, value, graph);
@@ -1045,11 +1055,11 @@
     }
 
     private void genJsr(int dest) {
-        throw new CiBailout("jsr/ret not supported");
+        throw new JSRNotSupportedBailout();
     }
 
     private void genRet(int localIndex) {
-        throw new CiBailout("jsr/ret not supported");
+        throw new JSRNotSupportedBailout();
     }
 
     private void genTableswitch() {
@@ -1151,7 +1161,7 @@
                 LoopEnd loopEnd = new LoopEnd(graph);
                 loopEnd.setLoopBegin(loopBegin);
                 Placeholder p = new Placeholder(graph);
-                p.setNext(loopBegin);
+                p.setNext(loopBegin.forwardEdge());
                 loopBegin.setStateAfter(stateAfter.duplicate(block.startBci));
                 block.firstInstruction = p;
             } else {
@@ -1163,7 +1173,7 @@
 
         FixedNode result = null;
         if (block.isLoopHeader && isVisited(block)) {
-            result = ((LoopBegin) block.firstInstruction.next()).loopEnd();
+            result = loopBegin(block).loopEnd();
         } else {
             result = block.firstInstruction;
         }
@@ -1171,11 +1181,15 @@
         assert result instanceof Merge || result instanceof Placeholder : result;
 
         if (result instanceof Merge) {
-            EndNode end = new EndNode(graph);
-            //end.setNext(result);
-            ((Merge) result).addEnd(end);
-            result = end;
+            if (result instanceof LoopBegin) {
+                result = ((LoopBegin) result).forwardEdge();
+            } else {
+                EndNode end = new EndNode(graph);
+                ((Merge) result).addEnd(end);
+                result = end;
+            }
         }
+        assert !(result instanceof LoopBegin || result instanceof Merge);
         return result;
     }
 
@@ -1202,7 +1216,7 @@
                 markVisited(block);
                 // now parse the block
                 if (block.isLoopHeader) {
-                    lastInstr = (LoopBegin) block.firstInstruction.next();
+                    lastInstr = loopBegin(block);
                 } else {
                     lastInstr = block.firstInstruction;
                 }
@@ -1224,8 +1238,7 @@
         }
         for (Block b : blocksVisited) {
             if (b.isLoopHeader) {
-                Instruction loopHeaderInstr = b.firstInstruction;
-                LoopBegin begin = (LoopBegin) loopHeaderInstr.next();
+                LoopBegin begin = loopBegin(b);
                 LoopEnd loopEnd = begin.loopEnd();
 
 //              This can happen with degenerated loops like this one:
@@ -1242,10 +1255,7 @@
                 } else {
                     loopEnd.delete();
                     Merge merge = new Merge(graph);
-                    EndNode end = new EndNode(graph);
-                    int nbrReplacement = begin.singlePredecessor().successors().replace(begin, end);
-                    assert nbrReplacement > 0;
-                    merge.addEnd(end);
+                    merge.addEnd(begin.forwardEdge());
                     merge.setNext(begin.next());
                     merge.setStateAfter(begin.stateAfter());
                     begin.replace(merge);
@@ -1254,6 +1264,12 @@
         }
     }
 
+    private static LoopBegin loopBegin(Block block) {
+        EndNode endNode = (EndNode) block.firstInstruction.next();
+        LoopBegin loopBegin = (LoopBegin) endNode.merge();
+        return loopBegin;
+    }
+
     private void createDeoptBlock(DeoptBlock block) {
         storeResultGraph = false;
         append(new Deoptimize(DeoptAction.InvalidateReprofile, graph));
@@ -1289,9 +1305,9 @@
             assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize();
             createUnwindBlock(block);
         } else {
-            assert frameState.stackSize() == 1;
+            assert frameState.stackSize() == 1 : frameState;
 
-            Block nextBlock = block.next == null ? unwindBlock() : block.next;
+            Block nextBlock = block.next == null ? unwindBlock(block.deoptBci) : block.next;
             if (block.handler.catchType().isResolved()) {
                 FixedNode catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState);
                 FixedNode nextDispatch = createTarget(nextBlock, frameState);
@@ -1300,16 +1316,14 @@
                 Deoptimize deopt = new Deoptimize(DeoptAction.InvalidateRecompile, graph);
                 deopt.setMessage("unresolved " + block.handler.catchType().name());
                 append(deopt);
-                FixedNode nextDispatch = createTarget(nextBlock, frameState);
-                appendGoto(nextDispatch);
             }
         }
     }
 
     private void appendGoto(FixedNode target) {
         if (lastInstr != null) {
-        lastInstr.setNext(target);
-    }
+            lastInstr.setNext(target);
+        }
     }
 
     private void iterateBytecodesForBlock(Block block) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Mon Jun 20 14:29:42 2011 +0200
@@ -411,7 +411,7 @@
 
         // adjust all frame states that were copied
         if (frameStates.size() > 0) {
-            FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, invoke.kind);
+            FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, stateAfter.rethrowException(), invoke.kind);
             for (Node node : frameStates) {
                 FrameState frameState = (FrameState) duplicates.get(node);
                 if (!frameState.isDeleted()) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopEdgeSplitingPhase.java	Fri Jun 17 19:21:53 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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.phases;
-
-import com.oracle.max.graal.compiler.ir.*;
-import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.graph.*;
-
-/**
- * Does critical edge spliting on LoopBegin.
- */
-public class LoopEdgeSplitingPhase extends Phase {
-
-    @Override
-    protected void run(Graph graph) {
-        for (LoopBegin loopBegin : graph.getNodes(LoopBegin.class)) {
-            Node pred = loopBegin.singlePredecessor();
-            if (IdentifyBlocksPhase.trueSuccessorCount(pred) > 1) {
-                Anchor anchor = new Anchor(graph);
-                anchor.setNext(loopBegin);
-                pred.successors().replace(loopBegin, anchor);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Mon Jun 20 14:29:42 2011 +0200
@@ -31,17 +31,24 @@
 
     private final String name;
     private static final ThreadLocal<Phase> currentPhase = new ThreadLocal<Phase>();
+    private final boolean shouldVerify;
 
     public Phase() {
         this.name = this.getClass().getSimpleName();
+        this.shouldVerify = true;
     }
 
     public Phase(String name) {
+        this(name, true);
+    }
+
+    public Phase(String name, boolean shouldVerify) {
         this.name = name;
+        this.shouldVerify = shouldVerify;
     }
 
     public final void apply(Graph graph) {
-        assert graph != null && graph.verify();
+        assert graph != null && (!shouldVerify || graph.verify());
 
         int startDeletedNodeCount = graph.getDeletedNodeCount();
         int startNodeCount = graph.getNodeCount();
@@ -76,7 +83,7 @@
             compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After " + getName(), graph, true, false));
         }
 
-        assert graph.verify();
+        assert !shouldVerify || graph.verify();
 
         // (Item|Graph|Phase|Value)
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java	Mon Jun 20 14:29:42 2011 +0200
@@ -33,14 +33,13 @@
 
 
 public class IdentifyBlocksPhase extends Phase {
-    private static final int MAX_DOMINATOR_ITER = 50;
     private final List<Block> blocks = new ArrayList<Block>();
     private NodeMap<Block> nodeToBlock;
     private Graph graph;
     private boolean scheduleAllNodes;
 
     public IdentifyBlocksPhase(boolean scheduleAllNodes) {
-        super(scheduleAllNodes ? "FullSchedule" : "PartSchedule");
+        super(scheduleAllNodes ? "FullSchedule" : "PartSchedule", false);
         this.scheduleAllNodes = scheduleAllNodes;
     }
 
@@ -119,7 +118,7 @@
                     Block block = null;
                     Node currentNode = n;
                     while (nodeToBlock.get(currentNode) == null) {
-                        if (block != null && IdentifyBlocksPhase.trueSuccessorCount(currentNode) > 1) {
+                        if (block != null && (currentNode instanceof ControlSplit || trueSuccessorCount(currentNode) > 1)) {
                             // We are at a split node => start a new block.
                             block = null;
                         }
@@ -128,24 +127,18 @@
                             // Either dead code or at a merge node => stop iteration.
                             break;
                         }
-                        if (currentNode instanceof LoopBegin) {
-                            block = null;
-                        }
                         currentNode = currentNode.singlePredecessor();
                     }
                 }
             }
         }
 
-        //System.out.println("identify blocks");
-//        print();
-
         // Connect blocks.
         for (Block block : blocks) {
             Node n = block.firstNode();
-            if (n instanceof Merge) {
+            if (n instanceof Merge) {
                 Merge m = (Merge) n;
-                for (Node pred : m.phiPointPredecessors()) {
+                for (Node pred : m.mergePredecessors()) {
                     Block predBlock = nodeToBlock.get(pred);
                     predBlock.addSuccessor(block);
                 }
@@ -158,8 +151,6 @@
                 }
             }
         }
-        //System.out.println("connect");
-        //print();
 
         computeDominators();
 
@@ -176,15 +167,8 @@
                 }
             }
 
-            //System.out.println("dom + cycles");
-//            print();
-
             assignLatestPossibleBlockToNodes();
-            //System.out.println("assign last");
-//            print();
             sortNodesWithinBlocks();
-            //System.out.println("sort");
-//            print();
         } else {
             computeJavaBlocks();
         }
@@ -264,7 +248,7 @@
         }
 
         if (n instanceof Phi) {
-            Block block = nodeToBlock.get(((Phi) n).merge().asNode());
+            Block block = nodeToBlock.get(((Phi) n).merge());
             nodeToBlock.set(n, block);
         }
 
@@ -272,6 +256,7 @@
             Block block = nodeToBlock.get(((LoopCounter) n).loopBegin());
             nodeToBlock.set(n, block);
         }
+
         Block block = null;
         for (Node succ : n.successors()) {
             block = getCommonDominator(block, assignLatestPossibleBlockToNode(succ));
@@ -279,23 +264,23 @@
         for (Node usage : n.usages()) {
             if (usage instanceof Phi) {
                 Phi phi = (Phi) usage;
-                PhiPoint merge = phi.merge();
-                Block mergeBlock = nodeToBlock.get(merge.asNode());
-                assert mergeBlock != null : "no block for merge " + merge.asNode().id();
+                Merge merge = phi.merge();
+                Block mergeBlock = nodeToBlock.get(merge);
+                assert mergeBlock != null : "no block for merge " + merge.id();
                 for (int i = 0; i < phi.valueCount(); ++i) {
                     if (phi.valueAt(i) == n) {
                         if (mergeBlock.getPredecessors().size() == 0) {
                             TTY.println(merge.toString());
                             TTY.println(phi.toString());
-                            TTY.println(merge.phiPointPredecessors().toString());
+                            TTY.println(merge.phiPredecessors().toString());
                             TTY.println("value count: " + phi.valueCount());
                         }
                         block = getCommonDominator(block, mergeBlock.getPredecessors().get(i));
                     }
                 }
             } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) {
-                PhiPoint merge = ((FrameState) usage).block();
-                for (Node pred : merge.phiPointPredecessors()) {
+                Merge merge = ((FrameState) usage).block();
+                for (Node pred : merge.mergePredecessors()) {
                     block = getCommonDominator(block, nodeToBlock.get(pred));
                 }
             } else if (usage instanceof LoopCounter) {
@@ -413,15 +398,13 @@
         CiBitMap visited = new CiBitMap(blocks.size());
         visited.set(dominatorRoot.blockID());
         LinkedList<Block> workList = new LinkedList<Block>();
-        workList.add(dominatorRoot);
-        int iter = 0;
-        int maxIter = MAX_DOMINATOR_ITER * blocks.size();
+        for (Block block : blocks) {
+            if (block.getPredecessors().size() == 0) {
+                workList.add(block);
+            }
+        }
+
         while (!workList.isEmpty()) {
-            if (iter++ >= maxIter) {
-                System.out.println("Reached maxIter(" + maxIter + ") !!");
-                print();
-                throw new CiBailout("Max iteration for dominator computation reached, Cycles in the block graph?");
-            }
             Block b = workList.remove();
 
             List<Block> predecessors = b.getPredecessors();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java	Mon Jun 20 14:29:42 2011 +0200
@@ -49,6 +49,8 @@
 
     protected final int locksSize;
 
+    private final boolean rethrowException;
+
     private static final int SUCCESSOR_COUNT = 0;
 
     @Override
@@ -90,19 +92,20 @@
      * @param stackSize size of the stack
      * @param lockSize number of locks
      */
-    public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, Graph graph) {
+    public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, boolean rethrowException, Graph graph) {
         super(CiKind.Illegal, localsSize + stackSize + locksSize + INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.method = method;
         this.bci = bci;
         this.localsSize = localsSize;
         this.stackSize = stackSize;
         this.locksSize = locksSize;
+        this.rethrowException = rethrowException;
         GraalMetrics.FrameStatesCreated++;
         GraalMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize;
     }
 
-    FrameState(RiMethod method, int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, Graph graph) {
-        this(method, bci, locals.length, stackSize, locks.size(), graph);
+    FrameState(RiMethod method, int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, boolean rethrowException, Graph graph) {
+        this(method, bci, locals.length, stackSize, locks.size(), rethrowException, graph);
         for (int i = 0; i < locals.length; i++) {
             setValueAt(i, locals[i]);
         }
@@ -114,6 +117,10 @@
         }
     }
 
+    public boolean rethrowException() {
+        return rethrowException;
+    }
+
     /**
      * Gets a copy of this frame state.
      */
@@ -128,7 +135,7 @@
      */
     @Override
     public FrameState duplicateWithEmptyStack(int bci) {
-        FrameState other = new FrameState(method, bci, localsSize, 0, locksSize(), graph());
+        FrameState other = new FrameState(method, bci, localsSize, 0, locksSize(), rethrowException, graph());
         for (int i = 0; i < localsSize; i++) {
             other.setValueAt(i, localAt(i));
         }
@@ -139,15 +146,19 @@
         return other;
     }
 
+    public FrameState duplicateWithException(int bci, Value exceptionObject) {
+        return duplicateModified(bci, true, CiKind.Void, exceptionObject);
+    }
+
     /**
      * Creates a copy of this frame state with one stack element of type popKind popped from the stack and the
      * values in pushedValues pushed on the stack. The pushedValues are expected to be in slot encoding: a long
      * or double is followed by a null slot.
      */
-    public FrameState duplicateModified(int bci, CiKind popKind, Value... pushedValues) {
+    public FrameState duplicateModified(int bci, boolean rethrowException, CiKind popKind, Value... pushedValues) {
         int popSlots = popKind.sizeInSlots();
         int pushSlots = pushedValues.length;
-        FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), graph());
+        FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), rethrowException, graph());
         for (int i = 0; i < localsSize; i++) {
             other.setValueAt(i, localAt(i));
         }
@@ -304,7 +315,7 @@
      * @param block the block begin for which we are creating the phi
      * @param i the index into the stack for which to create a phi
      */
-    public Phi setupPhiForStack(PhiPoint block, int i) {
+    public Phi setupPhiForStack(Merge block, int i) {
         Value p = stackAt(i);
         if (p != null) {
             if (p instanceof Phi) {
@@ -325,7 +336,7 @@
      * @param block the block begin for which we are creating the phi
      * @param i the index of the local variable for which to create the phi
      */
-    public Phi setupPhiForLocal(PhiPoint block, int i) {
+    public Phi setupPhiForLocal(Merge block, int i) {
         Value p = localAt(i);
         if (p instanceof Phi) {
             Phi phi = (Phi) p;
@@ -373,7 +384,7 @@
         }
     }
 
-    public void merge(PhiPoint block, FrameStateAccess other) {
+    public void merge(Merge block, FrameStateAccess other) {
         checkSize(other);
         for (int i = 0; i < valuesSize(); i++) {
             Value x = valueAt(i);
@@ -400,7 +411,7 @@
                     }
 
                     if (phi.valueCount() == 0) {
-                        int size = block.phiPointPredecessorCount();
+                        int size = block.phiPredecessorCount();
                         for (int j = 0; j < size; ++j) {
                             phi.addInput(x);
                         }
@@ -409,16 +420,16 @@
                         phi.addInput((x == y) ? phi : y);
                     }
 
-                    assert phi.valueCount() == block.phiPointPredecessorCount() + (block instanceof LoopBegin ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPointPredecessorCount();
+                    assert phi.valueCount() == block.phiPredecessorCount() + (block instanceof LoopBegin ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPredecessorCount();
                }
             }
         }
     }
 
-    public PhiPoint block() {
+    public Merge block() {
         for (Node n : usages()) {
-            if (n instanceof PhiPoint) {
-                return (PhiPoint) n;
+            if (n instanceof Merge) {
+                return (Merge) n;
             }
         }
         return null;
@@ -499,14 +510,9 @@
         out.print("FrameState");
     }
 
-    @Override
-    public FrameState copy() {
-        return new FrameState(method, bci, localsSize, stackSize, locksSize, graph());
-    }
-
 
     private FrameState copy(int newBci) {
-        return new FrameState(method, newBci, localsSize, stackSize, locksSize, graph());
+        return new FrameState(method, newBci, localsSize, stackSize, locksSize, rethrowException, graph());
     }
 
     @Override
@@ -538,12 +544,12 @@
             str.append(i == 0 ? "" : ", ").append(lockAt(i) == null ? "_" : lockAt(i).id());
         }
         properties.put("locks", str.toString());
+        properties.put("rethrowException", rethrowException);
         return properties;
     }
 
     @Override
     public Node copy(Graph into) {
-        FrameState x = new FrameState(method, bci, localsSize, stackSize, locksSize, into);
-        return x;
+        return new FrameState(method, bci, localsSize, stackSize, locksSize, rethrowException, into);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java	Mon Jun 20 14:29:42 2011 +0200
@@ -81,6 +81,11 @@
         this.locks = new ArrayList<Value>();
     }
 
+    @Override
+    public String toString() {
+        return String.format("FrameStateBuilder[stackSize=%d]", stackIndex);
+    }
+
     public void initializeFrom(FrameState other) {
         assert locals.length == other.localsSize() : "expected: " + locals.length + ", actual: " + other.localsSize();
         assert stack.length >= other.stackSize() : "expected: <=" + stack.length + ", actual: " + other.stackSize();
@@ -99,12 +104,12 @@
     }
 
     public FrameState create(int bci) {
-        return new FrameState(method, bci, locals, stack, stackIndex, locks, graph);
+        return new FrameState(method, bci, locals, stack, stackIndex, locks, false, graph);
     }
 
     @Override
     public FrameState duplicateWithEmptyStack(int bci) {
-        FrameState frameState = new FrameState(method, bci, locals, new Value[0], 0, locks, graph);
+        FrameState frameState = new FrameState(method, bci, locals, new Value[0], 0, locks, false, graph);
         frameState.setOuterFrameState(outerFrameState());
         return frameState;
     }
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java	Mon Jun 20 14:29:42 2011 +0200
@@ -88,7 +88,7 @@
     }
 
     public Node replace(Node other) {
-        assert !isDeleted() && (other == null || !other.isDeleted()) : "id: " + id() + ", other: " + other;
+        assert !isDeleted() && (other == null || !other.isDeleted()) && other != this : "id: " + id() + ", other: " + other;
         assert other == null || other.graph == graph;
         for (Node usage : usages) {
             usage.inputs.replaceFirstOccurrence(this, other);
@@ -165,7 +165,7 @@
         return true;
     }
 
-    public Node copy() {
+    public final Node copy() {
         return copy(graph);
     }
 
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java	Mon Jun 20 14:29:42 2011 +0200
@@ -128,7 +128,9 @@
         RiType result = typeCache.get(cpi);
         if (result == null) {
             result = compiler.getVMEntries().RiConstantPool_lookupType(vmId, cpi);
-            typeCache.add(cpi, result);
+            if (result.isResolved()) {
+                typeCache.add(cpi, result);
+            }
         }
         return result;
     }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java	Mon Jun 20 14:29:42 2011 +0200
@@ -33,7 +33,9 @@
  */
 public final class HotSpotMethodResolvedImpl extends HotSpotMethod implements HotSpotMethodResolved {
 
-    private AccessibleObject javaMirror;
+    // Do not use as a Java object!
+    @Deprecated
+    private Object javaMirror;
 
     // cached values
     private final int codeSize;
@@ -80,10 +82,7 @@
 
     @Override
     public RiExceptionHandler[] exceptionHandlers() {
-        if (exceptionHandlers == null) {
-            exceptionHandlers = compiler.getVMEntries().RiMethod_exceptionHandlers(this);
-        }
-        return exceptionHandlers;
+        return compiler.getVMEntries().RiMethod_exceptionHandlers(this);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Fri Jun 17 19:21:53 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Mon Jun 20 14:29:42 2011 +0200
@@ -29,6 +29,7 @@
 
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.graph.*;
 import com.oracle.max.graal.runtime.logging.*;
 import com.oracle.max.graal.runtime.server.*;
 import com.sun.cri.ci.*;
@@ -152,10 +153,10 @@
 
                     if (result.bailout() != null) {
                         Throwable cause = result.bailout().getCause();
-                        if (!GraalOptions.QuietBailout) {
+                        if (!GraalOptions.QuietBailout && !(result.bailout() instanceof JSRNotSupportedBailout)) {
                             StringWriter out = new StringWriter();
                             result.bailout().printStackTrace(new PrintWriter(out));
-                            TTY.println("Bailout:\n" + out.toString());
+                            TTY.println("Bailout while compiling " + method + " :\n" + out.toString());
                             if (cause != null) {
                                 Logger.info("Trace for cause: ");
                                 for (StackTraceElement e : cause.getStackTrace()) {
@@ -179,7 +180,7 @@
                 } catch (Throwable t) {
                     StringWriter out = new StringWriter();
                     t.printStackTrace(new PrintWriter(out));
-                    TTY.println("Compilation interrupted: (" + method.name() + ")\n" + out.toString());
+                    TTY.println("Compilation interrupted: (" + method + ")\n" + out.toString());
                     throw t;
                 }
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runavrora.sh	Mon Jun 20 14:29:42 2011 +0200
@@ -0,0 +1,21 @@
+#!/bin/bash
+if [ -z "${JDK7}" ]; then
+  echo "JDK7 is not defined."
+  exit 1;
+fi
+if [ -z "${MAXINE}" ]; then
+  echo "MAXINE is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${GRAAL}" ]; then
+  echo "GRAAL is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${DACAPO}" ]; then
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
+  exit 1;
+fi
+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"
+echo $COMMAND
+$COMMAND
+echo $COMMAND
--- a/rundacapo.sh	Fri Jun 17 19:21:53 2011 +0200
+++ b/rundacapo.sh	Mon Jun 20 14:29:42 2011 +0200
@@ -15,4 +15,4 @@
   echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
   exit 1;
 fi
-${JDK7}/bin/java -client -d64 -graal -G:+PrintCompilation -G:+DetailedAsserts -G:PrintIdealGraphLevel=4 "-G:PrintFilter=~.*(fill|findBundle).*"  -XX:CompileCommand=compileonly,java.io.BufferedReader::fill -XX:-GraalBailoutIsFatal -XX:+PrintCompilation -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar Harness --preserve $*
+${JDK7}/bin/java -client -d64 -graal -XX:-GraalBailoutIsFatal -XX:MaxPermSize=512m -XX:+PrintCompilation -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar Harness --preserve $*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runeclipse.sh	Mon Jun 20 14:29:42 2011 +0200
@@ -0,0 +1,21 @@
+#!/bin/bash
+if [ -z "${JDK7}" ]; then
+  echo "JDK7 is not defined."
+  exit 1;
+fi
+if [ -z "${MAXINE}" ]; then
+  echo "MAXINE is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${GRAAL}" ]; then
+  echo "GRAAL is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${DACAPO}" ]; then
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
+  exit 1;
+fi
+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 eclipse"
+echo $COMMAND
+$COMMAND
+echo $COMMAND
--- a/runfop.sh	Fri Jun 17 19:21:53 2011 +0200
+++ b/runfop.sh	Mon Jun 20 14:29:42 2011 +0200
@@ -15,4 +15,4 @@
   echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
   exit 1;
 fi
-${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar $* Harness --preserve -n 5 fop 
+${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal $* Harness --preserve -n 5 fop 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runlusearch.sh	Mon Jun 20 14:29:42 2011 +0200
@@ -0,0 +1,21 @@
+#!/bin/bash
+if [ -z "${JDK7}" ]; then
+  echo "JDK7 is not defined."
+  exit 1;
+fi
+if [ -z "${MAXINE}" ]; then
+  echo "MAXINE is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${GRAAL}" ]; then
+  echo "GRAAL is not defined. It must point to a maxine repository directory."
+  exit 1;
+fi
+if [ -z "${DACAPO}" ]; then
+  echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
+  exit 1;
+fi
+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 lusearch"
+echo $COMMAND
+$COMMAND
+echo $COMMAND
--- a/runtests.sh	Fri Jun 17 19:21:53 2011 +0200
+++ b/runtests.sh	Mon Jun 20 14:29:42 2011 +0200
@@ -12,4 +12,4 @@
   exit 1;
 fi
 TESTDIR=${MAXINE}/com.oracle.max.vm/test
-${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 -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 -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/share/vm/c1/c1_IR.hpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/c1/c1_IR.hpp	Mon Jun 20 14:29:42 2011 +0200
@@ -237,7 +237,7 @@
     // reexecute allowed only for the topmost frame
     bool reexecute = topmost ? should_reexecute() : false;
     bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
-    recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
+    recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, false, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
   }
 };
 
--- a/src/share/vm/c1/c1_LIRAssembler.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -405,7 +405,7 @@
     if (s == NULL)  break;
     IRScope* scope = s->scope();
     //Always pass false for reexecute since these ScopeDescs are never used for deopt
-    debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/);
+    debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/, false/*rethrow_exception*/);
   }
 
   debug_info->end_non_safepoint(pc_offset);
--- a/src/share/vm/code/debugInfoRec.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/code/debugInfoRec.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -283,6 +283,7 @@
                                               ciMethod*   method,
                                               int         bci,
                                               bool        reexecute,
+                                              bool        rethrow_exception,
                                               bool        is_method_handle_invoke,
                                               bool        return_oop,
                                               DebugToken* locals,
@@ -298,6 +299,7 @@
 
   // Record flags into pcDesc.
   last_pd->set_should_reexecute(reexecute);
+  last_pd->set_rethrow_exception(rethrow_exception);
   last_pd->set_is_method_handle_invoke(is_method_handle_invoke);
   last_pd->set_return_oop(return_oop);
 
--- a/src/share/vm/code/debugInfoRec.hpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/code/debugInfoRec.hpp	Mon Jun 20 14:29:42 2011 +0200
@@ -101,6 +101,7 @@
                       ciMethod*   method,
                       int         bci,
                       bool        reexecute,
+                      bool        rethrow_exception,
                       bool        is_method_handle_invoke = false,
                       bool        return_oop = false,
                       DebugToken* locals      = NULL,
--- a/src/share/vm/code/nmethod.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/code/nmethod.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -1079,7 +1079,7 @@
   PcDesc* pd = pc_desc_at(pc);
   guarantee(pd != NULL, "scope must be present");
   return new ScopeDesc(this, pd->scope_decode_offset(),
-                       pd->obj_decode_offset(), pd->should_reexecute(),
+                       pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
                        pd->return_oop());
 }
 
@@ -2267,7 +2267,7 @@
   PcDesc* pd = pc_desc_at(ic->end_of_call());
   assert(pd != NULL, "PcDesc must exist");
   for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
-                                     pd->obj_decode_offset(), pd->should_reexecute(),
+                                     pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
                                      pd->return_oop());
        !sd->is_top(); sd = sd->sender()) {
     sd->verify();
@@ -2533,7 +2533,7 @@
   PcDesc* p = pc_desc_near(begin+1);
   if (p != NULL && p->real_pc(this) <= end) {
     return new ScopeDesc(this, p->scope_decode_offset(),
-                         p->obj_decode_offset(), p->should_reexecute(),
+                         p->obj_decode_offset(), p->should_reexecute(), p->rethrow_exception(),
                          p->return_oop());
   }
   return NULL;
--- a/src/share/vm/code/pcDesc.hpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/code/pcDesc.hpp	Mon Jun 20 14:29:42 2011 +0200
@@ -43,6 +43,7 @@
     int word;
     struct {
       unsigned int reexecute: 1;
+      unsigned int rethrow_exception: 1;
       unsigned int is_method_handle_invoke: 1;
       unsigned int return_oop: 1;
     } bits;
@@ -71,6 +72,8 @@
   // Flags
   bool     should_reexecute()              const { return _flags.bits.reexecute; }
   void set_should_reexecute(bool z)              { _flags.bits.reexecute = z;    }
+  bool     rethrow_exception()              const { return _flags.bits.rethrow_exception; }
+  void set_rethrow_exception(bool z)              { _flags.bits.rethrow_exception = z;    }
 
   // Does pd refer to the same information as pd?
   bool is_same_info(const PcDesc* pd) {
--- a/src/share/vm/code/scopeDesc.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/code/scopeDesc.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -31,21 +31,23 @@
 #include "runtime/handles.inline.hpp"
 
 
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(obj_decode_offset);
   _reexecute     = reexecute;
   _return_oop    = return_oop;
+  _rethrow_exception = rethrow_exception;
   decode_body();
 }
 
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(DebugInformationRecorder::serialized_null);
   _reexecute     = reexecute;
   _return_oop    = return_oop;
+  _rethrow_exception = rethrow_exception;
   decode_body();
 }
 
@@ -55,6 +57,7 @@
   _decode_offset = parent->_sender_decode_offset;
   _objects       = parent->_objects;
   _reexecute     = false; //reexecute only applies to the first scope
+  _rethrow_exception = false;
   _return_oop    = false;
   decode_body();
 }
--- a/src/share/vm/code/scopeDesc.hpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/code/scopeDesc.hpp	Mon Jun 20 14:29:42 2011 +0200
@@ -60,17 +60,18 @@
 class ScopeDesc : public ResourceObj {
  public:
   // Constructor
-  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop);
+  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // Calls above, giving default value of "serialized_null" to the
   // "obj_decode_offset" argument.  (We don't use a default argument to
   // avoid a .hpp-.hpp dependency.)
-  ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop);
+  ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // JVM state
   methodHandle method()   const { return _method; }
   int          bci()      const { return _bci;    }
   bool should_reexecute() const { return _reexecute; }
+  bool rethrow_exception() const { return _rethrow_exception; }
   bool return_oop()       const { return _return_oop; }
 
   GrowableArray<ScopeValue*>*   locals();
@@ -97,6 +98,7 @@
   methodHandle  _method;
   int           _bci;
   bool          _reexecute;
+  bool          _rethrow_exception;
   bool          _return_oop;
 
   // Decoding offsets
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -496,9 +496,14 @@
     DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions);
     DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors);
 
-    _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, locals_token, expressions_token, monitors_token);
+    bool throw_exception = false;
+    if (CiFrame::rethrowException(frame)) {
+      throw_exception = true;
+    }
+
+    _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token);
   } else {
-    _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, NULL, NULL, NULL);
+    _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, false, NULL, NULL, NULL);
   }
 }
 
--- a/src/share/vm/graal/graalCompiler.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -206,23 +206,24 @@
   instanceKlass::cast(HotSpotMethodResolved::klass())->initialize(CHECK_NULL);
   Handle obj = instanceKlass::cast(HotSpotMethodResolved::klass())->allocate_instance(CHECK_NULL);
   assert(obj() != NULL, "must succeed in allocating instance");
-
+  
   HotSpotMethodResolved::set_compiler(obj, VMExits::compilerInstance()());
-  oop reflected = getReflectedMethod(method(), CHECK_NULL);
-  HotSpotMethodResolved::set_javaMirror(obj, reflected);
+  // (tw) Cannot use reflection here, because the compiler thread could dead lock with the running application.
+  // oop reflected = getReflectedMethod(method(), CHECK_NULL);
+  HotSpotMethodResolved::set_javaMirror(obj, method());
   HotSpotMethodResolved::set_name(obj, name());
-
+  
   KlassHandle klass = method->method_holder();
   Handle holder_name = VmIds::toString<Handle>(klass->name(), CHECK_NULL);
   oop holder = GraalCompiler::createHotSpotTypeResolved(klass, holder_name, CHECK_NULL);
   HotSpotMethodResolved::set_holder(obj, holder);
-
+  
   HotSpotMethodResolved::set_codeSize(obj, method->code_size());
   HotSpotMethodResolved::set_accessFlags(obj, method->access_flags().as_int());
   HotSpotMethodResolved::set_maxLocals(obj, method->max_locals());
   HotSpotMethodResolved::set_maxStackSize(obj, method->max_stack());
   HotSpotMethodResolved::set_invocationCount(obj, method->invocation_count());
-
+  
   method->set_graal_mirror(obj());
   return obj();
 }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Jun 20 14:29:42 2011 +0200
@@ -63,7 +63,7 @@
     oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/max/graal/runtime/Compiler;") \
     oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;")                        \
     oop_field(HotSpotMethodResolved, holder, "Lcom/sun/cri/ri/RiType;")                 \
-    oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/reflect/AccessibleObject;") \
+    oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/Object;")                  \
     int_field(HotSpotMethodResolved, codeSize)                                          \
     int_field(HotSpotMethodResolved, accessFlags)                                       \
     int_field(HotSpotMethodResolved, maxLocals)                                         \
@@ -153,6 +153,7 @@
     int_field(CiFrame, numLocals)                                                       \
     int_field(CiFrame, numStack)                                                        \
     int_field(CiFrame, numLocks)                                                        \
+    boolean_field(CiFrame, rethrowException)                                            \
   end_class                                                                             \
   start_class(CiCodePos)                                                                \
     oop_field(CiCodePos, caller, "Lcom/sun/cri/ci/CiCodePos;")                          \
--- a/src/share/vm/graal/graalVMEntries.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/graal/graalVMEntries.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -39,7 +39,10 @@
 methodOop getMethodFromHotSpotMethod(oop hotspot_method) {
   oop reflected = HotSpotMethodResolved::javaMirror(hotspot_method);
   assert(reflected != NULL, "NULL not expected");
+  return (methodOop)reflected;
 
+  // (tw) Cannot use reflection code, because then the compiler can dead lock with the user application (test using -Xcomp).
+  /*
   // method is a handle to a java.lang.reflect.Method object
   oop mirror     = NULL;
   int slot       = 0;
@@ -58,7 +61,7 @@
 //  assert(instanceKlass::cast(k)->is_initialized(), "only initialized classes expected");
   methodOop m = instanceKlass::cast(k)->method_with_idnum(slot);
   assert(m != NULL, "deleted method?");
-  return m;
+  return m;*/
 }
 
 oop getReflectedMethod(methodOop method, TRAPS) {
@@ -368,7 +371,6 @@
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jlong vmId, jint index, jbyte byteCode) {
   TRACE_graal_3("VMEntries::RiConstantPool_lookupMethod");
   VM_ENTRY_MARK;
-
   index = GraalCompiler::to_cp_index_u2(index);
   constantPoolHandle cp = VmIds::get<constantPoolOop>(vmId);
 
--- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -251,7 +251,7 @@
 
     address scopes_data = nm->scopes_data_begin();
     for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) {
-      ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop());
+      ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->rethrow_exception(), pcd->return_oop());
       ScopeDesc *sd  = &sc0;
       while( !sd->is_top() ) { sd = sd->sender(); }
       int bci = sd->bci();
--- a/src/share/vm/runtime/deoptimization.cpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Mon Jun 20 14:29:42 2011 +0200
@@ -1223,17 +1223,32 @@
 
 //    tty->print_cr("trap_request: %08x, cpi: %i, pc: %016x", trap_request, unloaded_class_index, fr.pc());
 
+    
     Events::log("Uncommon trap occurred @" INTPTR_FORMAT " unloaded_class_index = %d", fr.pc(), (int) trap_request);
     vframe*  vf  = vframe::new_vframe(&fr, &reg_map, thread);
     compiledVFrame* cvf = compiledVFrame::cast(vf);
-
+    
     nmethod* nm = cvf->code();
+    ScopeDesc*      trap_scope  = cvf->scope();
+    
+    if (TraceDeoptimization) {
+      tty->print_cr("Deoptimization: bci=%d pc=%d, relative_pc=%d, method=%s", trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name()->as_C_string());
+    }
 
-    ScopeDesc*      trap_scope  = cvf->scope();
     methodHandle    trap_method = trap_scope->method();
     int             trap_bci    = trap_scope->bci();
     Bytecodes::Code trap_bc     = trap_method->java_code_at(trap_bci);
 
+    if (trap_scope->rethrow_exception()) {
+      if (TraceDeoptimization) {
+        tty->print_cr("Exception to be rethrown in the interpreter");
+      }
+      GrowableArray<ScopeValue*>* expressions = trap_scope->expressions();
+      ScopeValue* topOfStack = expressions->top();
+      Handle topOfStackObj = cvf->create_stack_value(topOfStack)->get_obj();
+      THREAD->set_pending_exception(topOfStackObj(), NULL, 0);
+    }
+    
     // Record this event in the histogram.
     gather_statistics(reason, action, trap_bc);
 
--- a/src/share/vm/runtime/vframe_hp.hpp	Fri Jun 17 19:21:53 2011 +0200
+++ b/src/share/vm/runtime/vframe_hp.hpp	Mon Jun 20 14:29:42 2011 +0200
@@ -66,7 +66,7 @@
   // Returns SynchronizationEntryBCI or bci() (used for synchronization)
   int raw_bci() const;
 
- protected:
+ //protected:
   ScopeDesc* _scope;