changeset 4205:2af849af1723

moved graphbuilder into the graal.java project.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 03 Jan 2012 18:22:10 +0100
parents 4df4499e0289
children 430b5db3e6f8
files 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/graphbuilder/BlockMap.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeLookupSwitch.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeStream.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeSwitch.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeTableSwitch.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/Bytecodes.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/Bytes.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/FrameStateBuilder.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/GraphBuilderConfiguration.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/GraphBuilderPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/JsrNotSupportedBailout.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/JsrScope.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/package-info.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/util/InliningUtil.java graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotSignature.java graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/VMExitsNative.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BlockMap.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeLookupSwitch.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeStream.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeSwitch.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeTableSwitch.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytecodes.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytes.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/FrameStateBuilder.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderConfiguration.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrNotSupportedBailout.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrScope.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/package-info.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java mx/projects src/share/vm/runtime/arguments.cpp
diffstat 38 files changed, 4717 insertions(+), 4701 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Tue Jan 03 18:22:10 2012 +0100
@@ -40,7 +40,6 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.alloc.*;
 import com.oracle.max.graal.compiler.alloc.OperandPool.VariableFlag;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.stub.*;
@@ -695,15 +694,25 @@
 
             if (stackIndex == 0 && !isStatic) {
                 // Current argument is receiver.
-                stackIndex += FrameStateBuilder.stackSlots(CiKind.Object);
+                stackIndex += stackSlots(CiKind.Object);
             } else {
-                stackIndex += FrameStateBuilder.stackSlots(signature.argumentKindAt(argumentIndex, false));
+                stackIndex += stackSlots(signature.argumentKindAt(argumentIndex, false));
                 argumentIndex++;
             }
         }
         return stack;
     }
 
+
+    public static int stackSlots(CiKind kind) {
+        return isTwoSlot(kind) ? 2 : 1;
+    }
+
+    public static boolean isTwoSlot(CiKind kind) {
+        assert kind != CiKind.Void && kind != CiKind.Illegal;
+        return kind == CiKind.Long || kind == CiKind.Double;
+    }
+
     @Override
     public void emitInvoke(Invoke x) {
         MethodCallTargetNode callTarget = x.callTarget();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BlockMap.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,631 +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.graphbuilder;
-
-import static com.oracle.max.graal.compiler.graphbuilder.Bytecodes.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.nodes.*;
-
-/**
- * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow
- * graph. Note that this class serves a similar role to C1's {@code BlockListBuilder}, but makes fewer assumptions about
- * what the compiler interface provides. It builds all basic blocks for the control flow graph without requiring the
- * compiler interface to provide a bitmap of the beginning of basic blocks. It makes two linear passes; one over the
- * bytecodes to build block starts and successor lists, and one pass over the block map to build the CFG.
- *
- * Note that the CFG built by this class is <i>not</i> connected to the actual {@code BlockBegin} instances; this class
- * does, however, compute and assign the reverse postorder number of the blocks. This comment needs refinement. (MJJ)
- *
- * <H2>More Details on {@link BlockMap#build}</H2>
- *
- * If the method has any exception handlers the {@linkplain #exceptionMap exception map} will be created (TBD).
- *
- * The bytecodes are then scanned linearly looking for bytecodes that contain control transfers, e.g., {@code GOTO},
- * {@code RETURN}, {@code IFGE}, and creating the corresponding entries in {@link #successorMap} and {@link #blockMap}.
- * In addition, if {@link #exceptionMap} is not null, entries are made for any bytecode that can cause an exception.
- * More TBD.
- *
- * Observe that this process finds bytecodes that terminate basic blocks, so the {@link #moveSuccessorLists} method is
- * called to reassign the successors to the {@code BlockBegin} node that actually starts the block.
- *
- * <H3>Example</H3>
- *
- * Consider the following source code:
- *
- * <pre>
- * <code>
- *     public static int test(int arg1, int arg2) {
- *         int x = 0;
- *         while (arg2 > 0) {
- *             if (arg1 > 0) {
- *                 x += 1;
- *             } else if (arg1 < 0) {
- *                 x -= 1;
- *             }
- *         }
- *         return x;
- *     }
- * </code>
- * </pre>
- *
- * This is translated by javac to the following bytecode:
- *
- * <pre>
- * <code>
- *    0:   iconst_0
- *    1:   istore_2
- *    2:   goto    22
- *    5:   iload_0
- *    6:   ifle    15
- *    9:   iinc    2, 1
- *    12:  goto    22
- *    15:  iload_0
- *    16:  ifge    22
- *    19:  iinc    2, -1
- *    22:  iload_1
- *    23:  ifgt    5
- *    26:  iload_2
- *    27:  ireturn
- *    </code>
- * </pre>
- *
- * There are seven basic blocks in this method, 0..2, 5..6, 9..12, 15..16, 19..19, 22..23 and 26..27. Therefore, before
- * the call to {@code moveSuccessorLists}, the {@code blockMap} array has {@code BlockBegin} nodes at indices 0, 5, 9,
- * 15, 19, 22 and 26. The {@code successorMap} array has entries at 2, 6, 12, 16, 23, 27 corresponding to the control
- * transfer bytecodes. The entry at index 6, for example, is a length two array of {@code BlockBegin} nodes for indices
- * 9 and 15, which are the successors for the basic block 5..6. After the call to {@code moveSuccessors}, {@code
- * successorMap} has entries at 0, 5, 9, 15, 19, 22 and 26, i.e, matching {@code blockMap}.
- * <p>
- * Next the blocks are numbered using <a href="http://en.wikipedia.org/wiki/Depth-first_search#Vertex_orderings">reverse
- * post-order</a>. For the above example this results in the numbering 2, 4, 7, 5, 6, 3, 8. Also loop header blocks are
- * detected during the traversal by detecting a repeat visit to a block that is still being processed. This causes the
- * block to be flagged as a loop header and also added to the {@link #loopBlocks} list. The {@code loopBlocks} list
- * contains the blocks at 0, 5, 9, 15, 19, 22, with 22 as the loop header. (N.B. the loop header block is added multiple
- * (4) times to this list). (Should 0 be in? It's not inside the loop).
- *
- * If the {@code computeStoresInLoops} argument to {@code build} is true, the {@code loopBlocks} list is processed to
- * mark all local variables that are stored in the blocks in the list.
- */
-public final class BlockMap {
-
-    public static class Block implements Cloneable {
-        public int startBci;
-        public int endBci;
-        public boolean isExceptionEntry;
-        public boolean isLoopHeader;
-        public int blockID;
-
-        public FixedWithNextNode firstInstruction;
-
-        public ArrayList<Block> successors = new ArrayList<>(2);
-        public int normalSuccessors;
-
-        private boolean visited;
-        private boolean active;
-        public long loops;
-
-        public HashMap<JsrScope, Block> jsrAlternatives;
-        public JsrScope jsrScope = JsrScope.EMPTY_SCOPE;
-        public Block jsrSuccessor;
-        public int jsrReturnBci;
-        public Block retSuccessor;
-        public boolean endsWithRet = false;
-
-        public Block copy() {
-            try {
-                Block block = (Block) super.clone();
-                block.successors = new ArrayList<>(successors);
-                return block;
-            } catch (CloneNotSupportedException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    public static class ExceptionBlock extends Block {
-        public RiExceptionHandler handler;
-        public int deoptBci;
-    }
-
-    public static class DeoptBlock extends Block {
-        public DeoptBlock(int startBci) {
-            this.startBci = startBci;
-        }
-    }
-
-    /**
-     * The blocks found in this method, in reverse postorder.
-     */
-    public final List<Block> blocks;
-
-    public final RiResolvedMethod method;
-
-    private final RiExceptionHandler[] exceptionHandlers;
-
-    private Block[] blockMap;
-
-    public final BitSet canTrap;
-
-    public boolean hasJsrBytecodes;
-
-    public Block startBlock;
-
-    public final boolean useBranchPrediction;
-
-    /**
-     * Creates a new BlockMap instance from bytecode of the given method .
-     * @param method the compiler interface method containing the code
-     */
-    public BlockMap(RiResolvedMethod method, boolean useBranchPrediction) {
-        this.method = method;
-        exceptionHandlers = method.exceptionHandlers();
-        this.blockMap = new Block[method.codeSize()];
-        this.canTrap = new BitSet(blockMap.length);
-        this.blocks = new ArrayList<>();
-        this.useBranchPrediction = useBranchPrediction;
-    }
-
-    public RiExceptionHandler[] exceptionHandlers() {
-        return exceptionHandlers;
-    }
-
-    /**
-     * Builds the block map and conservative CFG and numbers blocks.
-     */
-    public void build() {
-        makeExceptionEntries();
-        iterateOverBytecodes();
-        addExceptionEdges();
-        if (hasJsrBytecodes) {
-            if (!GraalOptions.SupportJsrBytecodes) {
-                throw new JsrNotSupportedBailout("jsr/ret parsing disabled");
-            }
-            createJsrAlternatives(blockMap[0]);
-        }
-        computeBlockOrder();
-
-        initializeBlockIds();
-
-        startBlock = blockMap[0];
-
-        // Discard big arrays so that they can be GCed
-        blockMap = null;
-    }
-
-    private void initializeBlockIds() {
-        for (int i = 0; i < blocks.size(); i++) {
-            blocks.get(i).blockID = i;
-        }
-    }
-
-    private void makeExceptionEntries() {
-        // start basic blocks at all exception handler blocks and mark them as exception entries
-        for (RiExceptionHandler h : this.exceptionHandlers) {
-            Block xhandler = makeBlock(h.handlerBCI());
-            xhandler.isExceptionEntry = true;
-        }
-    }
-
-    private void iterateOverBytecodes() {
-        // iterate over the bytecodes top to bottom.
-        // mark the entrypoints of basic blocks and build lists of successors for
-        // all bytecodes that end basic blocks (i.e. goto, ifs, switches, throw, jsr, returns, ret)
-        byte[] code = method.code();
-        Block current = null;
-        int bci = 0;
-        while (bci < code.length) {
-            if (current == null || blockMap[bci] != null) {
-                Block b = makeBlock(bci);
-                if (current != null) {
-                    setSuccessors(current.endBci, b);
-                }
-                current = b;
-            }
-            blockMap[bci] = current;
-            current.endBci = bci;
-
-            int opcode = Bytes.beU1(code, bci);
-            switch (opcode) {
-                case IRETURN: // fall through
-                case LRETURN: // fall through
-                case FRETURN: // fall through
-                case DRETURN: // fall through
-                case ARETURN: // fall through
-                case RETURN: {
-                    current = null;
-                    break;
-                }
-                case ATHROW: {
-                    current = null;
-                    canTrap.set(bci);
-                    break;
-                }
-                case IFEQ:      // fall through
-                case IFNE:      // fall through
-                case IFLT:      // fall through
-                case IFGE:      // fall through
-                case IFGT:      // fall through
-                case IFLE:      // fall through
-                case IF_ICMPEQ: // fall through
-                case IF_ICMPNE: // fall through
-                case IF_ICMPLT: // fall through
-                case IF_ICMPGE: // fall through
-                case IF_ICMPGT: // fall through
-                case IF_ICMPLE: // fall through
-                case IF_ACMPEQ: // fall through
-                case IF_ACMPNE: // fall through
-                case IFNULL:    // fall through
-                case IFNONNULL: {
-                    current = null;
-                    double probability = useBranchPrediction ? method.branchProbability(bci) : -1;
-
-                    Block b1 = probability == 0.0 ? new DeoptBlock(bci + Bytes.beS2(code, bci + 1)) : makeBlock(bci + Bytes.beS2(code, bci + 1));
-                    Block b2 = probability == 1.0 ? new DeoptBlock(bci + 3) : makeBlock(bci + 3);
-                    setSuccessors(bci, b1, b2);
-                    break;
-                }
-                case GOTO:
-                case GOTO_W: {
-                    current = null;
-                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == GOTO_W);
-                    Block b1 = makeBlock(target);
-                    setSuccessors(bci, b1);
-                    break;
-                }
-                case TABLESWITCH: {
-                    current = null;
-                    BytecodeTableSwitch sw = new BytecodeTableSwitch(code, bci);
-                    setSuccessors(bci, makeSwitchSuccessors(sw));
-                    break;
-                }
-                case LOOKUPSWITCH: {
-                    current = null;
-                    BytecodeLookupSwitch sw = new BytecodeLookupSwitch(code, bci);
-                    setSuccessors(bci, makeSwitchSuccessors(sw));
-                    break;
-                }
-                case JSR:
-                case JSR_W: {
-                    hasJsrBytecodes = true;
-                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == JSR_W);
-                    if (target == 0) {
-                        throw new JsrNotSupportedBailout("jsr target bci 0 not allowed");
-                    }
-                    Block b1 = makeBlock(target);
-                    current.jsrSuccessor = b1;
-                    current.jsrReturnBci = bci + lengthOf(opcode);
-                    current = null;
-                    setSuccessors(bci, b1);
-                    break;
-                }
-                case RET: {
-                    current.endsWithRet = true;
-                    current = null;
-                    break;
-                }
-                case WIDE: {
-                    int opcode2 = Bytes.beU1(code, bci);
-                    switch (opcode2) {
-                        case RET: {
-                            current.endsWithRet = true;
-                            current = null;
-                            break;
-                        }
-                    }
-                    break;
-                }
-                case INVOKEINTERFACE:
-                case INVOKESPECIAL:
-                case INVOKESTATIC:
-                case INVOKEVIRTUAL: {
-                    current = null;
-                    int target = bci + lengthOf(code, bci);
-                    Block b1 = makeBlock(target);
-                    setSuccessors(bci, b1);
-                    canTrap.set(bci);
-                    break;
-                }
-                default: {
-                    if (canTrap(opcode, bci)) {
-                        canTrap.set(bci);
-                    }
-                }
-            }
-            bci += lengthOf(code, bci);
-        }
-    }
-
-    public boolean canTrap(int opcode, int bci) {
-        switch (opcode) {
-            case INVOKESTATIC:
-            case INVOKESPECIAL:
-            case INVOKEVIRTUAL:
-            case INVOKEINTERFACE: {
-                return true;
-            }
-            case IASTORE:
-            case LASTORE:
-            case FASTORE:
-            case DASTORE:
-            case AASTORE:
-            case BASTORE:
-            case CASTORE:
-            case SASTORE:
-            case IALOAD:
-            case LALOAD:
-            case FALOAD:
-            case DALOAD:
-            case AALOAD:
-            case BALOAD:
-            case CALOAD:
-            case SALOAD:
-            case PUTFIELD:
-            case GETFIELD: {
-                if (GraalOptions.AllowExplicitExceptionChecks) {
-                    return method.exceptionProbability(bci) > 0;
-                }
-            }
-        }
-        return false;
-    }
-
-    private Block makeBlock(int startBci) {
-        Block oldBlock = blockMap[startBci];
-        if (oldBlock == null) {
-            Block newBlock = new Block();
-            newBlock.startBci = startBci;
-            blockMap[startBci] = newBlock;
-            return newBlock;
-
-        } else if (oldBlock.startBci != startBci) {
-            // Backward branch into the middle of an already processed block.
-            // Add the correct fall-through successor.
-            Block newBlock = new Block();
-            newBlock.startBci = startBci;
-            newBlock.endBci = oldBlock.endBci;
-            newBlock.successors.addAll(oldBlock.successors);
-            newBlock.normalSuccessors = oldBlock.normalSuccessors;
-
-            oldBlock.endBci = startBci - 1;
-            oldBlock.successors.clear();
-            oldBlock.successors.add(newBlock);
-            oldBlock.normalSuccessors = 1;
-
-            for (int i = startBci; i <= newBlock.endBci; i++) {
-                blockMap[i] = newBlock;
-            }
-            return newBlock;
-
-        } else {
-            return oldBlock;
-        }
-    }
-
-    private Block[] makeSwitchSuccessors(BytecodeSwitch tswitch) {
-        int max = tswitch.numberOfCases();
-        Block[] successors = new Block[max + 1];
-        for (int i = 0; i < max; i++) {
-            successors[i] = makeBlock(tswitch.targetAt(i));
-        }
-        successors[max] = makeBlock(tswitch.defaultTarget());
-        return successors;
-    }
-
-    private void setSuccessors(int predBci, Block... successors) {
-        Block predecessor = blockMap[predBci];
-        assert predecessor.successors.size() == 0;
-        for (Block sux : successors) {
-            if (sux.isExceptionEntry) {
-                throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow");
-            }
-            predecessor.successors.add(sux);
-        }
-        predecessor.normalSuccessors = successors.length;
-    }
-
-    private final HashSet<Block> jsrVisited = new HashSet<>();
-
-    private void createJsrAlternatives(Block block) {
-        jsrVisited.add(block);
-        JsrScope scope = block.jsrScope;
-
-        if (block.endsWithRet) {
-            block.retSuccessor = blockMap[scope.nextReturnAddress()];
-            block.successors.add(block.retSuccessor);
-            assert block.retSuccessor != block.jsrSuccessor;
-        }
-
-        if (block.jsrSuccessor != null || !scope.isEmpty()) {
-            for (int i = 0; i < block.successors.size(); i++) {
-                Block successor = block.successors.get(i);
-                JsrScope nextScope = scope;
-                if (successor == block.jsrSuccessor) {
-                    nextScope = scope.push(block.jsrReturnBci);
-                }
-                if (successor == block.retSuccessor) {
-                    nextScope = scope.pop();
-                }
-                if (!successor.jsrScope.isEmpty()) {
-                    throw new JsrNotSupportedBailout("unstructured control flow  (" + successor.jsrScope + " " + nextScope + ")");
-                }
-                if (!nextScope.isEmpty()) {
-                    Block clone;
-                    if (successor.jsrAlternatives != null && successor.jsrAlternatives.containsKey(nextScope)) {
-                        clone = successor.jsrAlternatives.get(nextScope);
-                    } else {
-                        if (successor.jsrAlternatives == null) {
-                            successor.jsrAlternatives = new HashMap<>();
-                        }
-                        clone = successor.copy();
-                        clone.jsrScope = nextScope;
-                        successor.jsrAlternatives.put(nextScope, clone);
-                    }
-                    block.successors.set(i, clone);
-                    if (successor == block.jsrSuccessor) {
-                        block.jsrSuccessor = clone;
-                    }
-                    if (successor == block.retSuccessor) {
-                        block.retSuccessor = clone;
-                    }
-                }
-            }
-        }
-        for (Block successor : block.successors) {
-            if (!jsrVisited.contains(successor)) {
-                createJsrAlternatives(successor);
-            }
-        }
-    }
-
-    private HashMap<RiExceptionHandler, ExceptionBlock> exceptionDispatch = new HashMap<>();
-
-    private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index, int bci) {
-        RiExceptionHandler handler = handlers.get(index);
-        if (handler.isCatchAll()) {
-            return blockMap[handler.handlerBCI()];
-        }
-        ExceptionBlock block = exceptionDispatch.get(handler);
-        if (block == null) {
-            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.successors.add(makeExceptionDispatch(handlers, index + 1, bci));
-            }
-            exceptionDispatch.put(handler, block);
-        }
-        return block;
-    }
-
-    private void addExceptionEdges() {
-        for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) {
-            Block block = blockMap[bci];
-
-            ArrayList<RiExceptionHandler> handlers = null;
-            for (RiExceptionHandler h : this.exceptionHandlers) {
-                if (h.startBCI() <= bci && bci < h.endBCI()) {
-                    if (handlers == null) {
-                        handlers = new ArrayList<>();
-                    }
-                    handlers.add(h);
-                    if (h.isCatchAll()) {
-                        break;
-                    }
-                }
-            }
-            if (handlers != null) {
-                Block dispatch = makeExceptionDispatch(handlers, 0, bci);
-                block.successors.add(dispatch);
-            }
-        }
-    }
-
-    private void computeBlockOrder() {
-        long loop = computeBlockOrder(blockMap[0]);
-
-        if (loop != 0) {
-            // There is a path from a loop end to the method entry that does not pass the loop header.
-            // Therefore, the loop is non reducible (has more than one entry).
-            // We don't want to compile such methods because the IR only supports structured loops.
-            throw new CiBailout("Non-reducible loop");
-        }
-
-        // Convert postorder to the desired reverse postorder.
-        Collections.reverse(blocks);
-    }
-
-    /**
-     * The next available loop number.
-     */
-    private int nextLoop;
-
-    /**
-     * Mark the block as a loop header, using the next available loop number.
-     * Also checks for corner cases that we don't want to compile.
-     */
-    private void makeLoopHeader(Block block) {
-        if (!block.isLoopHeader) {
-            block.isLoopHeader = true;
-
-            if (block.isExceptionEntry) {
-                // Loops that are implicitly formed by an exception handler lead to all sorts of corner cases.
-                // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
-                throw new CiBailout("Loop formed by an exception handler");
-            }
-            if (nextLoop >= Long.SIZE) {
-                // This restriction can be removed by using a fall-back to a BitSet in case we have more than 32 loops
-                // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
-                throw new CiBailout("Too many loops in method");
-            }
-
-            assert block.loops == 0;
-            block.loops = (long) 1 << (long) nextLoop;
-            nextLoop++;
-        }
-        assert Long.bitCount(block.loops) == 1;
-    }
-
-    /**
-     * Depth-first traversal of the control flow graph. The flag {@linkplain Block#visited} is used to
-     * visit every block only once. The flag {@linkplain Block#active} is used to detect cycles (backward
-     * edges).
-     */
-    private long computeBlockOrder(Block block) {
-        if (block.visited) {
-            if (block.active) {
-                // Reached block via backward branch.
-                makeLoopHeader(block);
-            }
-            // Return cached loop information for this block.
-            return block.loops;
-        }
-
-        block.visited = true;
-        block.active = true;
-
-        int loops = 0;
-        for (Block successor : block.successors) {
-            // Recursively process successors.
-            loops |= computeBlockOrder(successor);
-        }
-
-        if (block.isLoopHeader) {
-            assert Long.bitCount(block.loops) == 1;
-            loops &= ~block.loops;
-        }
-
-        block.loops = loops;
-        block.active = false;
-        blocks.add(block);
-
-        return loops;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeLookupSwitch.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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.graphbuilder;
-
-/**
- * A utility for processing {@link Bytecodes#LOOKUPSWITCH} bytecodes.
- */
-class BytecodeLookupSwitch extends BytecodeSwitch {
-    private static final int OFFSET_TO_NUMBER_PAIRS = 4;
-    private static final int OFFSET_TO_FIRST_PAIR_MATCH = 8;
-    private static final int OFFSET_TO_FIRST_PAIR_OFFSET = 12;
-    private static final int PAIR_SIZE = 8;
-
-    /**
-     * Constructor for a {@link BytecodeStream}.
-     * @param stream the {@code BytecodeStream} containing the switch instruction
-     * @param bci the index in the stream of the switch instruction
-     */
-    public BytecodeLookupSwitch(BytecodeStream stream, int bci) {
-        super(stream, bci);
-    }
-
-    /**
-     * Constructor for a bytecode array.
-     * @param code the bytecode array containing the switch instruction.
-     * @param bci the index in the array of the switch instruction
-     */
-    public BytecodeLookupSwitch(byte[] code, int bci) {
-        super(code, bci);
-    }
-
-    @Override
-    public int defaultOffset() {
-        return readWord(alignedBci);
-    }
-
-    @Override
-    public int offsetAt(int i) {
-        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_OFFSET + PAIR_SIZE * i);
-    }
-
-    @Override
-    public int keyAt(int i) {
-        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * i);
-    }
-
-    @Override
-    public int numberOfCases() {
-        return readWord(alignedBci + OFFSET_TO_NUMBER_PAIRS);
-    }
-
-    @Override
-    public int size() {
-        return alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * numberOfCases() - bci;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeStream.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +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.graphbuilder;
-
-/**
- * A utility class that makes iterating over bytecodes and reading operands
- * simpler and less error prone. For example, it handles the {@link Bytecodes#WIDE} instruction
- * and wide variants of instructions internally.
- */
-public final class BytecodeStream {
-
-    private final byte[] code;
-    private int opcode;
-    private int curBCI;
-    private int nextBCI;
-
-    /**
-     * Creates a new {@code BytecodeStream} for the specified bytecode.
-     * @param code the array of bytes that contains the bytecode
-     */
-    public BytecodeStream(byte[] code) {
-        assert code != null;
-        this.code = code;
-        setBCI(0);
-    }
-
-    /**
-     * Advances to the next bytecode.
-     */
-    public void next() {
-        setBCI(nextBCI);
-    }
-
-    /**
-     * Gets the next bytecode index (no side-effects).
-     * @return the next bytecode index
-     */
-    public int nextBCI() {
-        return nextBCI;
-    }
-
-    /**
-     * Gets the current bytecode index.
-     * @return the current bytecode index
-     */
-    public int currentBCI() {
-        return curBCI;
-    }
-
-    /**
-     * Gets the bytecode index of the end of the code.
-     * @return the index of the end of the code
-     */
-    public int endBCI() {
-        return code.length;
-    }
-
-    /**
-     * Gets the current opcode. This method will never return the
-     * {@link Bytecodes#WIDE WIDE} opcode, but will instead
-     * return the opcode that is modified by the {@code WIDE} opcode.
-     * @return the current opcode; {@link Bytecodes#END} if at or beyond the end of the code
-     */
-    public int currentBC() {
-        if (opcode == Bytecodes.WIDE) {
-            return Bytes.beU1(code, curBCI + 1);
-        } else {
-            return opcode;
-        }
-    }
-
-    /**
-     * Reads the index of a local variable for one of the load or store instructions.
-     * The WIDE modifier is handled internally.
-     * @return the index of the local variable
-     */
-    public int readLocalIndex() {
-        // read local variable index for load/store
-        if (opcode == Bytecodes.WIDE) {
-            return Bytes.beU2(code, curBCI + 2);
-        }
-        return Bytes.beU1(code, curBCI + 1);
-    }
-
-    /**
-     * Read the delta for an {@link Bytecodes#IINC} bytecode.
-     * @return the delta for the {@code IINC}
-     */
-    public int readIncrement() {
-        // read the delta for the iinc bytecode
-        if (opcode == Bytecodes.WIDE) {
-            return Bytes.beS2(code, curBCI + 4);
-        }
-        return Bytes.beS1(code, curBCI + 2);
-    }
-
-    /**
-     * Read the destination of a {@link Bytecodes#GOTO} or {@code IF} instructions.
-     * @return the destination bytecode index
-     */
-    public int readBranchDest() {
-        // reads the destination for a branch bytecode
-        return curBCI + Bytes.beS2(code, curBCI + 1);
-    }
-
-    /**
-     * Read the destination of a {@link Bytecodes#GOTO_W} or {@link Bytecodes#JSR_W} instructions.
-     * @return the destination bytecode index
-     */
-    public int readFarBranchDest() {
-        // reads the destination for a wide branch bytecode
-        return curBCI + Bytes.beS4(code, curBCI + 1);
-    }
-
-    /**
-     * Read a signed 4-byte integer from the bytecode stream at the specified bytecode index.
-     * @param bci the bytecode index
-     * @return the integer value
-     */
-    public int readInt(int bci) {
-        // reads a 4-byte signed value
-        return Bytes.beS4(code, bci);
-    }
-
-    /**
-     * Reads an unsigned, 1-byte value from the bytecode stream at the specified bytecode index.
-     * @param bci the bytecode index
-     * @return the byte
-     */
-    public int readUByte(int bci) {
-        return Bytes.beU1(code, bci);
-    }
-
-    /**
-     * Reads a constant pool index for the current instruction.
-     * @return the constant pool index
-     */
-    public char readCPI() {
-        if (opcode == Bytecodes.LDC) {
-            return (char) Bytes.beU1(code, curBCI + 1);
-        }
-        return (char) Bytes.beU2(code, curBCI + 1);
-    }
-
-    /**
-     * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH).
-     * @return the byte
-     */
-    public byte readByte() {
-        return code[curBCI + 1];
-    }
-
-    /**
-     * Reads a signed, 2-byte short for the current instruction (e.g. SIPUSH).
-     * @return the short value
-     */
-    public short readShort() {
-        return (short) Bytes.beS2(code, curBCI + 1);
-    }
-
-    /**
-     * Sets the bytecode index to the specified value.
-     * If {@code bci} is beyond the end of the array, {@link #currentBC} will return
-     * {@link Bytecodes#END} and other methods may throw {@link ArrayIndexOutOfBoundsException}.
-     * @param bci the new bytecode index
-     */
-    public void setBCI(int bci) {
-        curBCI = bci;
-        if (curBCI < code.length) {
-            opcode = Bytes.beU1(code, bci);
-            nextBCI = bci + Bytecodes.lengthOf(code, bci);
-        } else {
-            opcode = Bytecodes.END;
-            nextBCI = curBCI;
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeSwitch.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +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.graphbuilder;
-
-/**
- * An abstract class that provides the state and methods common to {@link Bytecodes#LOOKUPSWITCH}
- * and {@link Bytecodes#TABLESWITCH} instructions.
- */
-public abstract class BytecodeSwitch {
-    /**
-     * The {@link BytecodeStream} containing bytecode array or {@code null} if {@link #code} is not {@code null}.
-     */
-    private final BytecodeStream stream;
-    /**
-     * The bytecode array or {@code null} if {@link #stream} is not {@code null}.
-     */
-    private final byte[] code;
-    /**
-     * Index of start of switch instruction.
-     */
-    protected final int bci;
-    /**
-     * Index of the start of the additional data for the switch instruction, aligned to a multiple of four from the method start.
-     */
-    protected final int alignedBci;
-
-    /**
-     * Constructor for a {@link BytecodeStream}.
-     * @param stream the {@code BytecodeStream} containing the switch instruction
-     * @param bci the index in the stream of the switch instruction
-     */
-    public BytecodeSwitch(BytecodeStream stream, int bci) {
-        this.alignedBci = (bci + 4) & 0xfffffffc;
-        this.stream = stream;
-        this.code = null;
-        this.bci = bci;
-    }
-
-    /**
-     * Constructor for a bytecode array.
-     * @param code the bytecode array containing the switch instruction.
-     * @param bci the index in the array of the switch instruction
-     */
-    public BytecodeSwitch(byte[] code, int bci) {
-        this.alignedBci = (bci + 4) & 0xfffffffc;
-        this.stream = null;
-        this.code = code;
-        this.bci = bci;
-    }
-
-    /**
-     * Gets the current bytecode index.
-     * @return the current bytecode index
-     */
-    public int bci() {
-        return bci;
-    }
-
-    /**
-     * Gets the index of the instruction denoted by the {@code i}'th switch target.
-     * @param i index of the switch target
-     * @return the index of the instruction denoted by the {@code i}'th switch target
-     */
-    public int targetAt(int i) {
-        return bci + offsetAt(i);
-    }
-
-    /**
-     * Gets the index of the instruction for the default switch target.
-     * @return the index of the instruction for the default switch target
-     */
-    public int defaultTarget() {
-        return bci + defaultOffset();
-    }
-
-    /**
-     * Gets the offset from the start of the switch instruction to the default switch target.
-     * @return the offset to the default switch target
-     */
-    public abstract int defaultOffset();
-
-    /**
-     * Gets the key at {@code i}'th switch target index.
-     * @param i the switch target index
-     * @return the key at {@code i}'th switch target index
-     */
-    public abstract int keyAt(int i);
-
-    /**
-     * Gets the offset from the start of the switch instruction for the {@code i}'th switch target.
-     * @param i the switch target index
-     * @return the offset to the {@code i}'th switch target
-     */
-    public abstract int offsetAt(int i);
-
-    /**
-     * Gets the number of switch targets.
-     * @return the number of switch targets
-     */
-    public abstract int numberOfCases();
-
-    /**
-     * Gets the total size in bytes of the switch instruction.
-     * @return the total size in bytes of the switch instruction
-     */
-    public abstract int size();
-
-    /**
-     * Reads the signed value at given bytecode index.
-     * @param readBci the start index of the value to retrieve
-     * @return the signed, 4-byte value in the bytecode array starting at {@code bci}
-     */
-    protected int readWord(int readBci) {
-        if (code != null) {
-            return Bytes.beS4(code, readBci);
-        }
-        return stream.readInt(readBci);
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/BytecodeTableSwitch.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +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.graphbuilder;
-
-/**
- * A utility for processing {@link Bytecodes#TABLESWITCH} bytecodes.
- */
-public class BytecodeTableSwitch extends BytecodeSwitch {
-    private static final int OFFSET_TO_LOW_KEY = 4;
-    private static final int OFFSET_TO_HIGH_KEY = 8;
-    private static final int OFFSET_TO_FIRST_JUMP_OFFSET = 12;
-    private static final int JUMP_OFFSET_SIZE = 4;
-
-    /**
-     * Constructor for a {@link BytecodeStream}.
-     * @param stream the {@code BytecodeStream} containing the switch instruction
-     * @param bci the index in the stream of the switch instruction
-     */
-    public BytecodeTableSwitch(BytecodeStream stream, int bci) {
-        super(stream, bci);
-    }
-
-    /**
-     * Constructor for a bytecode array.
-     * @param code the bytecode array containing the switch instruction.
-     * @param bci the index in the array of the switch instruction
-     */
-    public BytecodeTableSwitch(byte[] code, int bci) {
-        super(code, bci);
-    }
-
-    /**
-     * Gets the low key of the table switch.
-     * @return the low key
-     */
-    public int lowKey() {
-        return readWord(alignedBci + OFFSET_TO_LOW_KEY);
-    }
-
-    /**
-     * Gets the high key of the table switch.
-     * @return the high key
-     */
-    public int highKey() {
-        return readWord(alignedBci + OFFSET_TO_HIGH_KEY);
-    }
-
-    @Override
-    public int keyAt(int i) {
-        return lowKey() + i;
-    }
-
-    @Override
-    public int defaultOffset() {
-        return readWord(alignedBci);
-    }
-
-    @Override
-    public int offsetAt(int i) {
-        return readWord(alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * i);
-    }
-
-    @Override
-    public int numberOfCases() {
-        return highKey() - lowKey() + 1;
-    }
-
-    @Override
-    public int size() {
-        return alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * numberOfCases() - bci;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/Bytecodes.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,961 +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.graphbuilder;
-
-import static com.oracle.max.graal.compiler.graphbuilder.Bytecodes.Flags.*;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.regex.*;
-
-/**
- * The definitions of the bytecodes that are valid input to the compiler and
- * related utility methods. This comprises two groups: the standard Java
- * bytecodes defined by <a href=
- * "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html">
- * Java Virtual Machine Specification</a>, and a set of <i>extended</i>
- * bytecodes that support low-level programming, for example, memory barriers.
- *
- * The extended bytecodes are one or three bytes in size. The one-byte bytecodes
- * follow the values in the standard set, with no gap. The three-byte extended
- * bytecodes share a common first byte and carry additional instruction-specific
- * information in the second and third bytes.
- */
-public class Bytecodes {
-    public static final int NOP                  =   0; // 0x00
-    public static final int ACONST_NULL          =   1; // 0x01
-    public static final int ICONST_M1            =   2; // 0x02
-    public static final int ICONST_0             =   3; // 0x03
-    public static final int ICONST_1             =   4; // 0x04
-    public static final int ICONST_2             =   5; // 0x05
-    public static final int ICONST_3             =   6; // 0x06
-    public static final int ICONST_4             =   7; // 0x07
-    public static final int ICONST_5             =   8; // 0x08
-    public static final int LCONST_0             =   9; // 0x09
-    public static final int LCONST_1             =  10; // 0x0A
-    public static final int FCONST_0             =  11; // 0x0B
-    public static final int FCONST_1             =  12; // 0x0C
-    public static final int FCONST_2             =  13; // 0x0D
-    public static final int DCONST_0             =  14; // 0x0E
-    public static final int DCONST_1             =  15; // 0x0F
-    public static final int BIPUSH               =  16; // 0x10
-    public static final int SIPUSH               =  17; // 0x11
-    public static final int LDC                  =  18; // 0x12
-    public static final int LDC_W                =  19; // 0x13
-    public static final int LDC2_W               =  20; // 0x14
-    public static final int ILOAD                =  21; // 0x15
-    public static final int LLOAD                =  22; // 0x16
-    public static final int FLOAD                =  23; // 0x17
-    public static final int DLOAD                =  24; // 0x18
-    public static final int ALOAD                =  25; // 0x19
-    public static final int ILOAD_0              =  26; // 0x1A
-    public static final int ILOAD_1              =  27; // 0x1B
-    public static final int ILOAD_2              =  28; // 0x1C
-    public static final int ILOAD_3              =  29; // 0x1D
-    public static final int LLOAD_0              =  30; // 0x1E
-    public static final int LLOAD_1              =  31; // 0x1F
-    public static final int LLOAD_2              =  32; // 0x20
-    public static final int LLOAD_3              =  33; // 0x21
-    public static final int FLOAD_0              =  34; // 0x22
-    public static final int FLOAD_1              =  35; // 0x23
-    public static final int FLOAD_2              =  36; // 0x24
-    public static final int FLOAD_3              =  37; // 0x25
-    public static final int DLOAD_0              =  38; // 0x26
-    public static final int DLOAD_1              =  39; // 0x27
-    public static final int DLOAD_2              =  40; // 0x28
-    public static final int DLOAD_3              =  41; // 0x29
-    public static final int ALOAD_0              =  42; // 0x2A
-    public static final int ALOAD_1              =  43; // 0x2B
-    public static final int ALOAD_2              =  44; // 0x2C
-    public static final int ALOAD_3              =  45; // 0x2D
-    public static final int IALOAD               =  46; // 0x2E
-    public static final int LALOAD               =  47; // 0x2F
-    public static final int FALOAD               =  48; // 0x30
-    public static final int DALOAD               =  49; // 0x31
-    public static final int AALOAD               =  50; // 0x32
-    public static final int BALOAD               =  51; // 0x33
-    public static final int CALOAD               =  52; // 0x34
-    public static final int SALOAD               =  53; // 0x35
-    public static final int ISTORE               =  54; // 0x36
-    public static final int LSTORE               =  55; // 0x37
-    public static final int FSTORE               =  56; // 0x38
-    public static final int DSTORE               =  57; // 0x39
-    public static final int ASTORE               =  58; // 0x3A
-    public static final int ISTORE_0             =  59; // 0x3B
-    public static final int ISTORE_1             =  60; // 0x3C
-    public static final int ISTORE_2             =  61; // 0x3D
-    public static final int ISTORE_3             =  62; // 0x3E
-    public static final int LSTORE_0             =  63; // 0x3F
-    public static final int LSTORE_1             =  64; // 0x40
-    public static final int LSTORE_2             =  65; // 0x41
-    public static final int LSTORE_3             =  66; // 0x42
-    public static final int FSTORE_0             =  67; // 0x43
-    public static final int FSTORE_1             =  68; // 0x44
-    public static final int FSTORE_2             =  69; // 0x45
-    public static final int FSTORE_3             =  70; // 0x46
-    public static final int DSTORE_0             =  71; // 0x47
-    public static final int DSTORE_1             =  72; // 0x48
-    public static final int DSTORE_2             =  73; // 0x49
-    public static final int DSTORE_3             =  74; // 0x4A
-    public static final int ASTORE_0             =  75; // 0x4B
-    public static final int ASTORE_1             =  76; // 0x4C
-    public static final int ASTORE_2             =  77; // 0x4D
-    public static final int ASTORE_3             =  78; // 0x4E
-    public static final int IASTORE              =  79; // 0x4F
-    public static final int LASTORE              =  80; // 0x50
-    public static final int FASTORE              =  81; // 0x51
-    public static final int DASTORE              =  82; // 0x52
-    public static final int AASTORE              =  83; // 0x53
-    public static final int BASTORE              =  84; // 0x54
-    public static final int CASTORE              =  85; // 0x55
-    public static final int SASTORE              =  86; // 0x56
-    public static final int POP                  =  87; // 0x57
-    public static final int POP2                 =  88; // 0x58
-    public static final int DUP                  =  89; // 0x59
-    public static final int DUP_X1               =  90; // 0x5A
-    public static final int DUP_X2               =  91; // 0x5B
-    public static final int DUP2                 =  92; // 0x5C
-    public static final int DUP2_X1              =  93; // 0x5D
-    public static final int DUP2_X2              =  94; // 0x5E
-    public static final int SWAP                 =  95; // 0x5F
-    public static final int IADD                 =  96; // 0x60
-    public static final int LADD                 =  97; // 0x61
-    public static final int FADD                 =  98; // 0x62
-    public static final int DADD                 =  99; // 0x63
-    public static final int ISUB                 = 100; // 0x64
-    public static final int LSUB                 = 101; // 0x65
-    public static final int FSUB                 = 102; // 0x66
-    public static final int DSUB                 = 103; // 0x67
-    public static final int IMUL                 = 104; // 0x68
-    public static final int LMUL                 = 105; // 0x69
-    public static final int FMUL                 = 106; // 0x6A
-    public static final int DMUL                 = 107; // 0x6B
-    public static final int IDIV                 = 108; // 0x6C
-    public static final int LDIV                 = 109; // 0x6D
-    public static final int FDIV                 = 110; // 0x6E
-    public static final int DDIV                 = 111; // 0x6F
-    public static final int IREM                 = 112; // 0x70
-    public static final int LREM                 = 113; // 0x71
-    public static final int FREM                 = 114; // 0x72
-    public static final int DREM                 = 115; // 0x73
-    public static final int INEG                 = 116; // 0x74
-    public static final int LNEG                 = 117; // 0x75
-    public static final int FNEG                 = 118; // 0x76
-    public static final int DNEG                 = 119; // 0x77
-    public static final int ISHL                 = 120; // 0x78
-    public static final int LSHL                 = 121; // 0x79
-    public static final int ISHR                 = 122; // 0x7A
-    public static final int LSHR                 = 123; // 0x7B
-    public static final int IUSHR                = 124; // 0x7C
-    public static final int LUSHR                = 125; // 0x7D
-    public static final int IAND                 = 126; // 0x7E
-    public static final int LAND                 = 127; // 0x7F
-    public static final int IOR                  = 128; // 0x80
-    public static final int LOR                  = 129; // 0x81
-    public static final int IXOR                 = 130; // 0x82
-    public static final int LXOR                 = 131; // 0x83
-    public static final int IINC                 = 132; // 0x84
-    public static final int I2L                  = 133; // 0x85
-    public static final int I2F                  = 134; // 0x86
-    public static final int I2D                  = 135; // 0x87
-    public static final int L2I                  = 136; // 0x88
-    public static final int L2F                  = 137; // 0x89
-    public static final int L2D                  = 138; // 0x8A
-    public static final int F2I                  = 139; // 0x8B
-    public static final int F2L                  = 140; // 0x8C
-    public static final int F2D                  = 141; // 0x8D
-    public static final int D2I                  = 142; // 0x8E
-    public static final int D2L                  = 143; // 0x8F
-    public static final int D2F                  = 144; // 0x90
-    public static final int I2B                  = 145; // 0x91
-    public static final int I2C                  = 146; // 0x92
-    public static final int I2S                  = 147; // 0x93
-    public static final int LCMP                 = 148; // 0x94
-    public static final int FCMPL                = 149; // 0x95
-    public static final int FCMPG                = 150; // 0x96
-    public static final int DCMPL                = 151; // 0x97
-    public static final int DCMPG                = 152; // 0x98
-    public static final int IFEQ                 = 153; // 0x99
-    public static final int IFNE                 = 154; // 0x9A
-    public static final int IFLT                 = 155; // 0x9B
-    public static final int IFGE                 = 156; // 0x9C
-    public static final int IFGT                 = 157; // 0x9D
-    public static final int IFLE                 = 158; // 0x9E
-    public static final int IF_ICMPEQ            = 159; // 0x9F
-    public static final int IF_ICMPNE            = 160; // 0xA0
-    public static final int IF_ICMPLT            = 161; // 0xA1
-    public static final int IF_ICMPGE            = 162; // 0xA2
-    public static final int IF_ICMPGT            = 163; // 0xA3
-    public static final int IF_ICMPLE            = 164; // 0xA4
-    public static final int IF_ACMPEQ            = 165; // 0xA5
-    public static final int IF_ACMPNE            = 166; // 0xA6
-    public static final int GOTO                 = 167; // 0xA7
-    public static final int JSR                  = 168; // 0xA8
-    public static final int RET                  = 169; // 0xA9
-    public static final int TABLESWITCH          = 170; // 0xAA
-    public static final int LOOKUPSWITCH         = 171; // 0xAB
-    public static final int IRETURN              = 172; // 0xAC
-    public static final int LRETURN              = 173; // 0xAD
-    public static final int FRETURN              = 174; // 0xAE
-    public static final int DRETURN              = 175; // 0xAF
-    public static final int ARETURN              = 176; // 0xB0
-    public static final int RETURN               = 177; // 0xB1
-    public static final int GETSTATIC            = 178; // 0xB2
-    public static final int PUTSTATIC            = 179; // 0xB3
-    public static final int GETFIELD             = 180; // 0xB4
-    public static final int PUTFIELD             = 181; // 0xB5
-    public static final int INVOKEVIRTUAL        = 182; // 0xB6
-    public static final int INVOKESPECIAL        = 183; // 0xB7
-    public static final int INVOKESTATIC         = 184; // 0xB8
-    public static final int INVOKEINTERFACE      = 185; // 0xB9
-    public static final int XXXUNUSEDXXX         = 186; // 0xBA
-    public static final int NEW                  = 187; // 0xBB
-    public static final int NEWARRAY             = 188; // 0xBC
-    public static final int ANEWARRAY            = 189; // 0xBD
-    public static final int ARRAYLENGTH          = 190; // 0xBE
-    public static final int ATHROW               = 191; // 0xBF
-    public static final int CHECKCAST            = 192; // 0xC0
-    public static final int INSTANCEOF           = 193; // 0xC1
-    public static final int MONITORENTER         = 194; // 0xC2
-    public static final int MONITOREXIT          = 195; // 0xC3
-    public static final int WIDE                 = 196; // 0xC4
-    public static final int MULTIANEWARRAY       = 197; // 0xC5
-    public static final int IFNULL               = 198; // 0xC6
-    public static final int IFNONNULL            = 199; // 0xC7
-    public static final int GOTO_W               = 200; // 0xC8
-    public static final int JSR_W                = 201; // 0xC9
-    public static final int BREAKPOINT           = 202; // 0xCA
-
-    public static final int ILLEGAL = 255;
-    public static final int END = 256;
-
-    /**
-     * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
-     * <pre>
-     *     for (int opcode = 0; opcode <= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
-     *         //
-     *     }
-     * </pre>
-     */
-    public static final int LAST_JVM_OPCODE = JSR_W;
-
-    /**
-     * A collection of flags describing various bytecode attributes.
-     */
-    static class Flags {
-
-        /**
-         * Denotes an instruction that ends a basic block and does not let control flow fall through to its lexical successor.
-         */
-        static final int STOP = 0x00000001;
-
-        /**
-         * Denotes an instruction that ends a basic block and may let control flow fall through to its lexical successor.
-         * In practice this means it is a conditional branch.
-         */
-        static final int FALL_THROUGH = 0x00000002;
-
-        /**
-         * Denotes an instruction that has a 2 or 4 byte operand that is an offset to another instruction in the same method.
-         * This does not include the {@link Bytecodes#TABLESWITCH} or {@link Bytecodes#LOOKUPSWITCH} instructions.
-         */
-        static final int BRANCH = 0x00000004;
-
-        /**
-         * Denotes an instruction that reads the value of a static or instance field.
-         */
-        static final int FIELD_READ = 0x00000008;
-
-        /**
-         * Denotes an instruction that writes the value of a static or instance field.
-         */
-        static final int FIELD_WRITE = 0x00000010;
-
-        /**
-         * Denotes an instruction that is not defined in the JVM specification.
-         */
-        static final int EXTENSION = 0x00000020;
-
-        /**
-         * Denotes an instruction that can cause a trap.
-         */
-        static final int TRAP        = 0x00000080;
-        /**
-         * Denotes an instruction that is commutative.
-         */
-        static final int COMMUTATIVE = 0x00000100;
-        /**
-         * Denotes an instruction that is associative.
-         */
-        static final int ASSOCIATIVE = 0x00000200;
-        /**
-         * Denotes an instruction that loads an operand.
-         */
-        static final int LOAD        = 0x00000400;
-        /**
-         * Denotes an instruction that stores an operand.
-         */
-        static final int STORE       = 0x00000800;
-        /**
-         * Denotes the 4 INVOKE* instructions.
-         */
-        static final int INVOKE       = 0x00001000;
-    }
-
-    // Performs a sanity check that none of the flags overlap.
-    static {
-        int allFlags = 0;
-        try {
-            for (Field field : Flags.class.getDeclaredFields()) {
-                int flagsFilter = Modifier.FINAL | Modifier.STATIC;
-                if ((field.getModifiers() & flagsFilter) == flagsFilter) {
-                    assert field.getType() == int.class : "Only " + field;
-                    final int flag = field.getInt(null);
-                    assert flag != 0;
-                    assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag";
-                    allFlags |= flag;
-                }
-            }
-        } catch (Exception e) {
-            throw new InternalError(e.toString());
-        }
-    }
-
-    /**
-     * A array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic.
-     * This will include the root instruction for the three-byte extended instructions.
-     */
-    private static final String[] nameArray = new String[256];
-
-    /**
-     * A array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction.
-     */
-    private static final int[] flagsArray = new int[256];
-
-    /**
-     * A array that maps from a bytecode value to the length in bytes for the corresponding instruction.
-     */
-    private static final int[] lengthArray = new int[256];
-
-    // Checkstyle: stop
-    static {
-        def(NOP                 , "nop"             , "b"    );
-        def(ACONST_NULL         , "aconst_null"     , "b"    );
-        def(ICONST_M1           , "iconst_m1"       , "b"    );
-        def(ICONST_0            , "iconst_0"        , "b"    );
-        def(ICONST_1            , "iconst_1"        , "b"    );
-        def(ICONST_2            , "iconst_2"        , "b"    );
-        def(ICONST_3            , "iconst_3"        , "b"    );
-        def(ICONST_4            , "iconst_4"        , "b"    );
-        def(ICONST_5            , "iconst_5"        , "b"    );
-        def(LCONST_0            , "lconst_0"        , "b"    );
-        def(LCONST_1            , "lconst_1"        , "b"    );
-        def(FCONST_0            , "fconst_0"        , "b"    );
-        def(FCONST_1            , "fconst_1"        , "b"    );
-        def(FCONST_2            , "fconst_2"        , "b"    );
-        def(DCONST_0            , "dconst_0"        , "b"    );
-        def(DCONST_1            , "dconst_1"        , "b"    );
-        def(BIPUSH              , "bipush"          , "bc"   );
-        def(SIPUSH              , "sipush"          , "bcc"  );
-        def(LDC                 , "ldc"             , "bi"   , TRAP);
-        def(LDC_W               , "ldc_w"           , "bii"  , TRAP);
-        def(LDC2_W              , "ldc2_w"          , "bii"  , TRAP);
-        def(ILOAD               , "iload"           , "bi"   , LOAD);
-        def(LLOAD               , "lload"           , "bi"   , LOAD);
-        def(FLOAD               , "fload"           , "bi"   , LOAD);
-        def(DLOAD               , "dload"           , "bi"   , LOAD);
-        def(ALOAD               , "aload"           , "bi"   , LOAD);
-        def(ILOAD_0             , "iload_0"         , "b"    , LOAD);
-        def(ILOAD_1             , "iload_1"         , "b"    , LOAD);
-        def(ILOAD_2             , "iload_2"         , "b"    , LOAD);
-        def(ILOAD_3             , "iload_3"         , "b"    , LOAD);
-        def(LLOAD_0             , "lload_0"         , "b"    , LOAD);
-        def(LLOAD_1             , "lload_1"         , "b"    , LOAD);
-        def(LLOAD_2             , "lload_2"         , "b"    , LOAD);
-        def(LLOAD_3             , "lload_3"         , "b"    , LOAD);
-        def(FLOAD_0             , "fload_0"         , "b"    , LOAD);
-        def(FLOAD_1             , "fload_1"         , "b"    , LOAD);
-        def(FLOAD_2             , "fload_2"         , "b"    , LOAD);
-        def(FLOAD_3             , "fload_3"         , "b"    , LOAD);
-        def(DLOAD_0             , "dload_0"         , "b"    , LOAD);
-        def(DLOAD_1             , "dload_1"         , "b"    , LOAD);
-        def(DLOAD_2             , "dload_2"         , "b"    , LOAD);
-        def(DLOAD_3             , "dload_3"         , "b"    , LOAD);
-        def(ALOAD_0             , "aload_0"         , "b"    , LOAD);
-        def(ALOAD_1             , "aload_1"         , "b"    , LOAD);
-        def(ALOAD_2             , "aload_2"         , "b"    , LOAD);
-        def(ALOAD_3             , "aload_3"         , "b"    , LOAD);
-        def(IALOAD              , "iaload"          , "b"    , TRAP);
-        def(LALOAD              , "laload"          , "b"    , TRAP);
-        def(FALOAD              , "faload"          , "b"    , TRAP);
-        def(DALOAD              , "daload"          , "b"    , TRAP);
-        def(AALOAD              , "aaload"          , "b"    , TRAP);
-        def(BALOAD              , "baload"          , "b"    , TRAP);
-        def(CALOAD              , "caload"          , "b"    , TRAP);
-        def(SALOAD              , "saload"          , "b"    , TRAP);
-        def(ISTORE              , "istore"          , "bi"   , STORE);
-        def(LSTORE              , "lstore"          , "bi"   , STORE);
-        def(FSTORE              , "fstore"          , "bi"   , STORE);
-        def(DSTORE              , "dstore"          , "bi"   , STORE);
-        def(ASTORE              , "astore"          , "bi"   , STORE);
-        def(ISTORE_0            , "istore_0"        , "b"    , STORE);
-        def(ISTORE_1            , "istore_1"        , "b"    , STORE);
-        def(ISTORE_2            , "istore_2"        , "b"    , STORE);
-        def(ISTORE_3            , "istore_3"        , "b"    , STORE);
-        def(LSTORE_0            , "lstore_0"        , "b"    , STORE);
-        def(LSTORE_1            , "lstore_1"        , "b"    , STORE);
-        def(LSTORE_2            , "lstore_2"        , "b"    , STORE);
-        def(LSTORE_3            , "lstore_3"        , "b"    , STORE);
-        def(FSTORE_0            , "fstore_0"        , "b"    , STORE);
-        def(FSTORE_1            , "fstore_1"        , "b"    , STORE);
-        def(FSTORE_2            , "fstore_2"        , "b"    , STORE);
-        def(FSTORE_3            , "fstore_3"        , "b"    , STORE);
-        def(DSTORE_0            , "dstore_0"        , "b"    , STORE);
-        def(DSTORE_1            , "dstore_1"        , "b"    , STORE);
-        def(DSTORE_2            , "dstore_2"        , "b"    , STORE);
-        def(DSTORE_3            , "dstore_3"        , "b"    , STORE);
-        def(ASTORE_0            , "astore_0"        , "b"    , STORE);
-        def(ASTORE_1            , "astore_1"        , "b"    , STORE);
-        def(ASTORE_2            , "astore_2"        , "b"    , STORE);
-        def(ASTORE_3            , "astore_3"        , "b"    , STORE);
-        def(IASTORE             , "iastore"         , "b"    , TRAP);
-        def(LASTORE             , "lastore"         , "b"    , TRAP);
-        def(FASTORE             , "fastore"         , "b"    , TRAP);
-        def(DASTORE             , "dastore"         , "b"    , TRAP);
-        def(AASTORE             , "aastore"         , "b"    , TRAP);
-        def(BASTORE             , "bastore"         , "b"    , TRAP);
-        def(CASTORE             , "castore"         , "b"    , TRAP);
-        def(SASTORE             , "sastore"         , "b"    , TRAP);
-        def(POP                 , "pop"             , "b"    );
-        def(POP2                , "pop2"            , "b"    );
-        def(DUP                 , "dup"             , "b"    );
-        def(DUP_X1              , "dup_x1"          , "b"    );
-        def(DUP_X2              , "dup_x2"          , "b"    );
-        def(DUP2                , "dup2"            , "b"    );
-        def(DUP2_X1             , "dup2_x1"         , "b"    );
-        def(DUP2_X2             , "dup2_x2"         , "b"    );
-        def(SWAP                , "swap"            , "b"    );
-        def(IADD                , "iadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LADD                , "ladd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(FADD                , "fadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(DADD                , "dadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(ISUB                , "isub"            , "b"    );
-        def(LSUB                , "lsub"            , "b"    );
-        def(FSUB                , "fsub"            , "b"    );
-        def(DSUB                , "dsub"            , "b"    );
-        def(IMUL                , "imul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LMUL                , "lmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(FMUL                , "fmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(DMUL                , "dmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IDIV                , "idiv"            , "b"    , TRAP);
-        def(LDIV                , "ldiv"            , "b"    , TRAP);
-        def(FDIV                , "fdiv"            , "b"    );
-        def(DDIV                , "ddiv"            , "b"    );
-        def(IREM                , "irem"            , "b"    , TRAP);
-        def(LREM                , "lrem"            , "b"    , TRAP);
-        def(FREM                , "frem"            , "b"    );
-        def(DREM                , "drem"            , "b"    );
-        def(INEG                , "ineg"            , "b"    );
-        def(LNEG                , "lneg"            , "b"    );
-        def(FNEG                , "fneg"            , "b"    );
-        def(DNEG                , "dneg"            , "b"    );
-        def(ISHL                , "ishl"            , "b"    );
-        def(LSHL                , "lshl"            , "b"    );
-        def(ISHR                , "ishr"            , "b"    );
-        def(LSHR                , "lshr"            , "b"    );
-        def(IUSHR               , "iushr"           , "b"    );
-        def(LUSHR               , "lushr"           , "b"    );
-        def(IAND                , "iand"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LAND                , "land"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IOR                 , "ior"             , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LOR                 , "lor"             , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IXOR                , "ixor"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(LXOR                , "lxor"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
-        def(IINC                , "iinc"            , "bic"  , LOAD | STORE);
-        def(I2L                 , "i2l"             , "b"    );
-        def(I2F                 , "i2f"             , "b"    );
-        def(I2D                 , "i2d"             , "b"    );
-        def(L2I                 , "l2i"             , "b"    );
-        def(L2F                 , "l2f"             , "b"    );
-        def(L2D                 , "l2d"             , "b"    );
-        def(F2I                 , "f2i"             , "b"    );
-        def(F2L                 , "f2l"             , "b"    );
-        def(F2D                 , "f2d"             , "b"    );
-        def(D2I                 , "d2i"             , "b"    );
-        def(D2L                 , "d2l"             , "b"    );
-        def(D2F                 , "d2f"             , "b"    );
-        def(I2B                 , "i2b"             , "b"    );
-        def(I2C                 , "i2c"             , "b"    );
-        def(I2S                 , "i2s"             , "b"    );
-        def(LCMP                , "lcmp"            , "b"    );
-        def(FCMPL               , "fcmpl"           , "b"    );
-        def(FCMPG               , "fcmpg"           , "b"    );
-        def(DCMPL               , "dcmpl"           , "b"    );
-        def(DCMPG               , "dcmpg"           , "b"    );
-        def(IFEQ                , "ifeq"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFNE                , "ifne"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFLT                , "iflt"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFGE                , "ifge"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFGT                , "ifgt"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFLE                , "ifle"            , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ICMPNE           , "if_icmpne"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ICMPLT           , "if_icmplt"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPGE           , "if_icmpge"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ICMPLE           , "if_icmple"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ACMPNE           , "if_acmpne"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(GOTO                , "goto"            , "boo"  , STOP | BRANCH);
-        def(JSR                 , "jsr"             , "boo"  , STOP | BRANCH);
-        def(RET                 , "ret"             , "bi"   , STOP);
-        def(TABLESWITCH         , "tableswitch"     , ""     , STOP);
-        def(LOOKUPSWITCH        , "lookupswitch"    , ""     , STOP);
-        def(IRETURN             , "ireturn"         , "b"    , TRAP | STOP);
-        def(LRETURN             , "lreturn"         , "b"    , TRAP | STOP);
-        def(FRETURN             , "freturn"         , "b"    , TRAP | STOP);
-        def(DRETURN             , "dreturn"         , "b"    , TRAP | STOP);
-        def(ARETURN             , "areturn"         , "b"    , TRAP | STOP);
-        def(RETURN              , "return"          , "b"    , TRAP | STOP);
-        def(GETSTATIC           , "getstatic"       , "bjj"  , TRAP | FIELD_READ);
-        def(PUTSTATIC           , "putstatic"       , "bjj"  , TRAP | FIELD_WRITE);
-        def(GETFIELD            , "getfield"        , "bjj"  , TRAP | FIELD_READ);
-        def(PUTFIELD            , "putfield"        , "bjj"  , TRAP | FIELD_WRITE);
-        def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , TRAP | INVOKE);
-        def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , TRAP | INVOKE);
-        def(INVOKESTATIC        , "invokestatic"    , "bjj"  , TRAP | INVOKE);
-        def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", TRAP | INVOKE);
-        def(XXXUNUSEDXXX        , "xxxunusedxxx"    , ""     );
-        def(NEW                 , "new"             , "bii"  , TRAP);
-        def(NEWARRAY            , "newarray"        , "bc"   , TRAP);
-        def(ANEWARRAY           , "anewarray"       , "bii"  , TRAP);
-        def(ARRAYLENGTH         , "arraylength"     , "b"    , TRAP);
-        def(ATHROW              , "athrow"          , "b"    , TRAP | STOP);
-        def(CHECKCAST           , "checkcast"       , "bii"  , TRAP);
-        def(INSTANCEOF          , "instanceof"      , "bii"  , TRAP);
-        def(MONITORENTER        , "monitorenter"    , "b"    , TRAP);
-        def(MONITOREXIT         , "monitorexit"     , "b"    , TRAP);
-        def(WIDE                , "wide"            , ""     );
-        def(MULTIANEWARRAY      , "multianewarray"  , "biic" , TRAP);
-        def(IFNULL              , "ifnull"          , "boo"  , FALL_THROUGH | BRANCH);
-        def(IFNONNULL           , "ifnonnull"       , "boo"  , FALL_THROUGH | BRANCH);
-        def(GOTO_W              , "goto_w"          , "boooo", STOP | BRANCH);
-        def(JSR_W               , "jsr_w"           , "boooo", STOP | BRANCH);
-        def(BREAKPOINT          , "breakpoint"      , "b"    , TRAP);
-    }
-    // Checkstyle: resume
-
-    /**
-     * Determines if an opcode is commutative.
-     * @param opcode the opcode to check
-     * @return {@code true} iff commutative
-     */
-    public static boolean isCommutative(int opcode) {
-        return (flagsArray[opcode & 0xff] & COMMUTATIVE) != 0;
-    }
-
-    /**
-     * Gets the length of an instruction denoted by a given opcode.
-     *
-     * @param opcode an instruction opcode
-     * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a
-     *         variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned.
-     */
-    public static int lengthOf(int opcode) {
-        return lengthArray[opcode & 0xff];
-    }
-
-    /**
-     * Gets the length of an instruction at a given position in a given bytecode array.
-     * This methods handles variable length and {@linkplain #WIDE widened} instructions.
-     *
-     * @param code an array of bytecode
-     * @param bci the position in {@code code} of an instruction's opcode
-     * @return the length of the instruction at position {@code bci} in {@code code}
-     */
-    public static int lengthOf(byte[] code, int bci) {
-        int opcode = Bytes.beU1(code, bci);
-        int length = Bytecodes.lengthArray[opcode & 0xff];
-        if (length == 0) {
-            switch (opcode) {
-                case TABLESWITCH: {
-                    return new BytecodeTableSwitch(code, bci).size();
-                }
-                case LOOKUPSWITCH: {
-                    return new BytecodeLookupSwitch(code, bci).size();
-                }
-                case WIDE: {
-                    int opc = Bytes.beU1(code, bci + 1);
-                    if (opc == RET) {
-                        return 4;
-                    } else if (opc == IINC) {
-                        return 6;
-                    } else {
-                        return 4; // a load or store bytecode
-                    }
-                }
-                default:
-                    throw new Error("unknown variable-length bytecode: " + opcode);
-            }
-        }
-        return length;
-    }
-
-    /**
-     * Gets the lower-case mnemonic for a given opcode.
-     *
-     * @param opcode an opcode
-     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode
-     */
-    public static String nameOf(int opcode) throws IllegalArgumentException {
-        String name = nameArray[opcode & 0xff];
-        if (name == null) {
-            return "<illegal opcode: " + opcode + ">";
-        }
-        return name;
-    }
-
-    /**
-     * Allocation-free version of {@linkplain #nameOf(int)}.
-     * @param opcode an opcode.
-     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode.
-     */
-    public static String baseNameOf(int opcode) {
-        String name = nameArray[opcode & 0xff];
-        if (name == null) {
-            return "<illegal opcode>";
-        }
-        return name;
-    }
-
-    /**
-     * Gets the opcode corresponding to a given mnemonic.
-     *
-     * @param name an opcode mnemonic
-     * @return the opcode corresponding to {@code mnemonic}
-     * @throws IllegalArgumentException if {@code name} does not denote a valid opcode
-     */
-    public static int valueOf(String name) {
-        for (int opcode = 0; opcode < nameArray.length; ++opcode) {
-            if (name.equalsIgnoreCase(nameArray[opcode])) {
-                return opcode;
-            }
-        }
-        throw new IllegalArgumentException("No opcode for " + name);
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that can cause an implicit exception.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise
-     */
-    public static boolean canTrap(int opcode) {
-        return (flagsArray[opcode & 0xff] & TRAP) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise
-     */
-    public static boolean isLoad(int opcode) {
-        return (flagsArray[opcode & 0xff] & LOAD) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall
-     * through to its lexical successor.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} properly ends a basic block
-     */
-    public static boolean isStop(int opcode) {
-        return (flagsArray[opcode & 0xff] & STOP) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that stores a value to a local variable
-     * after popping it from the operand stack.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
-     */
-    public static boolean isInvoke(int opcode) {
-        return (flagsArray[opcode & 0xff] & INVOKE) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that stores a value to a local variable
-     * after popping it from the operand stack.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
-     */
-    public static boolean isStore(int opcode) {
-        return (flagsArray[opcode & 0xff] & STORE) != 0;
-    }
-
-    /**
-     * Determines if a given opcode is an instruction that delimits a basic block.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} delimits a basic block
-     */
-    public static boolean isBlockEnd(int opcode) {
-        return (flagsArray[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0;
-    }
-
-    /**
-     * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another
-     * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} is a branch instruction with a single operand
-     */
-    public static boolean isBranch(int opcode) {
-        return (flagsArray[opcode & 0xff] & BRANCH) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes a conditional branch.
-     * @param opcode
-     * @return {@code true} iff {@code opcode} is a conditional branch
-     */
-    public static boolean isConditionalBranch(int opcode) {
-        return (flagsArray[opcode & 0xff] & FALL_THROUGH) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes a standard bytecode. A standard bytecode is
-     * defined in the JVM specification.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} is a standard bytecode
-     */
-    public static boolean isStandard(int opcode) {
-        return (flagsArray[opcode & 0xff] & EXTENSION) == 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an extended bytecode.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} if {@code opcode} is an extended bytecode
-     */
-    public static boolean isExtended(int opcode) {
-        return (flagsArray[opcode & 0xff] & EXTENSION) != 0;
-    }
-
-    /**
-     * Determines if a given opcode is a three-byte extended bytecode.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} if {@code (opcode & ~0xff) != 0}
-     */
-    public static boolean isThreeByteExtended(int opcode) {
-        return (opcode & ~0xff) != 0;
-    }
-
-    /**
-     * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an
-     * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned
-     * instead.
-     *
-     * @param op an opcode
-     * @return the arithmetic operator name
-     */
-    public static String operator(int op) {
-        // Checkstyle: stop
-        switch (op) {
-            // arithmetic ops
-            case IADD : // fall through
-            case LADD : // fall through
-            case FADD : // fall through
-            case DADD : return "+";
-            case ISUB : // fall through
-            case LSUB : // fall through
-            case FSUB : // fall through
-            case DSUB : return "-";
-            case IMUL : // fall through
-            case LMUL : // fall through
-            case FMUL : // fall through
-            case DMUL : return "*";
-            case IDIV : // fall through
-            case LDIV : // fall through
-            case FDIV : // fall through
-            case DDIV : return "/";
-            case IREM : // fall through
-            case LREM : // fall through
-            case FREM : // fall through
-            case DREM : return "%";
-            // shift ops
-            case ISHL : // fall through
-            case LSHL : return "<<";
-            case ISHR : // fall through
-            case LSHR : return ">>";
-            case IUSHR: // fall through
-            case LUSHR: return ">>>";
-            // logic ops
-            case IAND : // fall through
-            case LAND : return "&";
-            case IOR  : // fall through
-            case LOR  : return "|";
-            case IXOR : // fall through
-            case LXOR : return "^";
-        }
-        // Checkstyle: resume
-        return nameOf(op);
-    }
-
-    /**
-     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
-     *
-     * @param name instruction name (should be lower case)
-     * @param format encodes the length of the instruction
-     * @param flagsArray the set of {@link Flags} associated with the instruction
-     */
-    private static void def(int opcode, String name, String format) {
-        def(opcode, name, format, 0);
-    }
-
-    /**
-     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
-     *
-     * @param name instruction name (lower case)
-     * @param format encodes the length of the instruction
-     * @param flags the set of {@link Flags} associated with the instruction
-     */
-    private static void def(int opcode, String name, String format, int flags) {
-        assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode];
-        nameArray[opcode] = name;
-        int instructionLength = format.length();
-        lengthArray[opcode] = instructionLength;
-        Bytecodes.flagsArray[opcode] = flags;
-
-        assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch";
-    }
-
-    /**
-     * Utility for ensuring that the extended opcodes are contiguous and follow on directly
-     * from the standard JVM opcodes. If these conditions do not hold for the input source
-     * file, then it is modified 'in situ' to fix the problem.
-     *
-     * @param args {@code args[0]} is the path to this source file
-     */
-    public static void main(String[] args) throws Exception {
-        Method findWorkspaceDirectory = Class.forName("com.sun.max.ide.JavaProject").getDeclaredMethod("findWorkspaceDirectory");
-        File base = new File((File) findWorkspaceDirectory.invoke(null), "com.oracle.max.cri/src");
-        File file = new File(base, Bytecodes.class.getName().replace('.', File.separatorChar) + ".java").getAbsoluteFile();
-
-        Pattern opcodeDecl = Pattern.compile("(\\s*public static final int )(\\w+)(\\s*=\\s*)(\\d+)(;.*)");
-
-        BufferedReader br = new BufferedReader(new FileReader(file));
-        CharArrayWriter buffer = new CharArrayWriter((int) file.length());
-        PrintWriter out = new PrintWriter(buffer);
-        String line;
-        int lastExtendedOpcode = BREAKPOINT;
-        boolean modified = false;
-        int section = 0;
-        while ((line = br.readLine()) != null) {
-            if (section == 0) {
-                if (line.equals("    // Start extended bytecodes")) {
-                    section = 1;
-                }
-            } else if (section == 1) {
-                if (line.equals("    // End extended bytecodes")) {
-                    section = 2;
-                } else {
-                    Matcher matcher = opcodeDecl.matcher(line);
-                    if (matcher.matches()) {
-                        String name = matcher.group(2);
-                        String value = matcher.group(4);
-                        int opcode = Integer.parseInt(value);
-                        if (nameArray[opcode] == null || !nameArray[opcode].equalsIgnoreCase(name)) {
-                            throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + nameArray[opcode]);
-                        }
-                        if (opcode != lastExtendedOpcode + 1) {
-                            System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")");
-                            opcode = lastExtendedOpcode + 1;
-                            line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4));
-                            modified = true;
-                        }
-
-                        if (opcode >= 256) {
-                            throw new RuntimeException("Exceeded maximum opcode value with " + name);
-                        }
-
-                        lastExtendedOpcode = opcode;
-                    }
-                }
-            }
-
-            out.println(line);
-        }
-        if (section == 0) {
-            throw new RuntimeException("Did not find line starting extended bytecode declarations:\n\n    // Start extended bytecodes");
-        } else if (section == 1) {
-            throw new RuntimeException("Did not find line ending extended bytecode declarations:\n\n    // End extended bytecodes");
-        }
-
-        if (modified) {
-            out.flush();
-            FileWriter fileWriter = new FileWriter(file);
-            fileWriter.write(buffer.toCharArray());
-            fileWriter.close();
-
-            System.out.println("Modified: " + file);
-        }
-
-
-        // Uncomment to print out visitor method declarations:
-//        for (int opcode = 0; opcode < flags.length; ++opcode) {
-//            if (isExtension(opcode)) {
-//                String visitorParams = length(opcode) == 1 ? "" : "int index";
-//                System.out.println("@Override");
-//                System.out.println("protected void " + name(opcode) + "(" + visitorParams + ") {");
-//                System.out.println("}");
-//                System.out.println();
-//            }
-//        }
-
-        // Uncomment to print out visitor method declarations:
-//        for (int opcode = 0; opcode < flags.length; ++opcode) {
-//            if (isExtension(opcode)) {
-//                System.out.println("case " + name(opcode).toUpperCase() + ": {");
-//                String arg = "";
-//                int length = length(opcode);
-//                if (length == 2) {
-//                    arg = "readUnsigned1()";
-//                } else if (length == 3) {
-//                    arg = "readUnsigned2()";
-//                }
-//                System.out.println("    bytecodeVisitor." + name(opcode) + "(" + arg + ");");
-//                System.out.println("    break;");
-//                System.out.println("}");
-//            }
-//        }
-
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/Bytes.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +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.graphbuilder;
-
-/**
- * A collection of utility methods for dealing with bytes, particularly in byte arrays.
- */
-public class Bytes {
-    /**
-     * Gets a signed 1-byte value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the signed 1-byte value at index {@code bci} in array {@code data}
-     */
-    public static int beS1(byte[] data, int bci) {
-        return data[bci];
-    }
-
-    /**
-     * Gets a signed 2-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the signed 2-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beS2(byte[] data, int bci) {
-        return (data[bci] << 8) | (data[bci + 1] & 0xff);
-    }
-
-    /**
-     * Gets an unsigned 1-byte value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the unsigned 1-byte value at index {@code bci} in array {@code data}
-     */
-    public static int beU1(byte[] data, int bci) {
-        return data[bci] & 0xff;
-    }
-
-    /**
-     * Gets an unsigned 2-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the unsigned 2-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beU2(byte[] data, int bci) {
-        return ((data[bci] & 0xff) << 8) | (data[bci + 1] & 0xff);
-    }
-
-    /**
-     * Gets a signed 4-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the signed 4-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beS4(byte[] data, int bci) {
-        return (data[bci] << 24) | ((data[bci + 1] & 0xff) << 16) | ((data[bci + 2] & 0xff) << 8) | (data[bci + 3] & 0xff);
-    }
-
-    /**
-     * Gets either a signed 2-byte or a signed 4-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @param fourByte if true, this method will return a 4-byte value
-     * @return the signed 2 or 4-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beSVar(byte[] data, int bci, boolean fourByte) {
-        if (fourByte) {
-            return beS4(data, bci);
-        } else {
-            return beS2(data, bci);
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/FrameStateBuilder.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,532 +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.graphbuilder;
-
-import static com.oracle.max.graal.nodes.ValueUtil.*;
-import static java.lang.reflect.Modifier.*;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.nodes.*;
-import com.oracle.max.graal.nodes.PhiNode.PhiType;
-import com.oracle.max.graal.nodes.spi.*;
-import com.oracle.max.graal.nodes.type.*;
-
-
-public class FrameStateBuilder implements FrameStateAccess {
-
-    private final StructuredGraph graph;
-
-    private final ValueNode[] locals;
-    private final ValueNode[] stack;
-    private final ArrayList<MonitorObject> locks;
-
-    private int stackIndex;
-    private boolean rethrowException;
-
-    private final RiResolvedMethod method;
-
-    public FrameStateBuilder(RiResolvedMethod method, int maxLocals, int maxStackSize, StructuredGraph graph) {
-        assert graph != null;
-        this.method = method;
-        this.graph = graph;
-        this.locals = new ValueNode[maxLocals];
-        // we always need at least one stack slot (for exceptions)
-        int stackSize = Math.max(1, maxStackSize);
-        this.stack = new ValueNode[stackSize];
-
-        int javaIndex = 0;
-        int index = 0;
-        if (!isStatic(method.accessFlags())) {
-            // add the receiver
-            LocalNode local = graph.unique(new LocalNode(javaIndex, StampFactory.declaredNonNull(method.holder())));
-            storeLocal(javaIndex, local);
-            javaIndex = 1;
-            index = 1;
-        }
-        RiSignature sig = method.signature();
-        int max = sig.argumentCount(false);
-        RiType accessingClass = method.holder();
-        for (int i = 0; i < max; i++) {
-            RiType type = sig.argumentTypeAt(i, accessingClass);
-            CiKind kind = type.kind(false).stackKind();
-            Stamp stamp;
-            if (kind == CiKind.Object && type instanceof RiResolvedType) {
-                RiResolvedType resolvedType = (RiResolvedType) type;
-                stamp = StampFactory.declared(resolvedType);
-            } else {
-                stamp = StampFactory.forKind(kind);
-            }
-            LocalNode local = graph.unique(new LocalNode(index, stamp));
-            storeLocal(javaIndex, local);
-            javaIndex += stackSlots(kind);
-            index++;
-        }
-        this.locks = new ArrayList<>();
-    }
-
-    @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();
-
-        this.stackIndex = other.stackSize();
-        for (int i = 0; i < other.localsSize(); i++) {
-            locals[i] = other.localAt(i);
-        }
-        for (int i = 0; i < other.stackSize(); i++) {
-            stack[i] = other.stackAt(i);
-        }
-        locks.clear();
-        for (int i = 0; i < other.locksSize(); i++) {
-            locks.add(other.lockAt(i));
-        }
-        this.rethrowException = other.rethrowException();
-    }
-
-    public FrameState create(int bci) {
-        return graph.add(new FrameState(method, bci, locals, stack, stackIndex, locks, rethrowException));
-    }
-
-    public FrameState duplicateWithException(int bci, ValueNode exceptionObject) {
-        FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[]{exceptionObject}, 1, locks, true));
-        frameState.setOuterFrameState(outerFrameState());
-        return frameState;
-    }
-
-    /**
-     * Pushes an instruction onto the stack with the expected type.
-     * @param kind the type expected for this instruction
-     * @param x the instruction to push onto the stack
-     */
-    public void push(CiKind kind, ValueNode x) {
-        assert kind != CiKind.Void;
-        xpush(assertKind(kind, x));
-        if (isTwoSlot(kind)) {
-            xpush(null);
-        }
-    }
-
-    /**
-     * Pushes a value onto the stack without checking the type.
-     * @param x the instruction to push onto the stack
-     */
-    public void xpush(ValueNode x) {
-        assert x == null || !x.isDeleted();
-        assert x == null || (x.kind() != CiKind.Void && x.kind() != CiKind.Illegal) : "unexpected value: " + x;
-        stack[stackIndex++] = x;
-    }
-
-    /**
-     * Pushes a value onto the stack and checks that it is an int.
-     * @param x the instruction to push onto the stack
-     */
-    public void ipush(ValueNode x) {
-        xpush(assertInt(x));
-    }
-
-    /**
-     * Pushes a value onto the stack and checks that it is a float.
-     * @param x the instruction to push onto the stack
-     */
-    public void fpush(ValueNode x) {
-        xpush(assertFloat(x));
-    }
-
-    /**
-     * Pushes a value onto the stack and checks that it is an object.
-     * @param x the instruction to push onto the stack
-     */
-    public void apush(ValueNode x) {
-        xpush(assertObject(x));
-    }
-
-    /**
-     * Pushes a value onto the stack and checks that it is a JSR return address.
-     * @param x the instruction to push onto the stack
-     */
-    public void jpush(ValueNode x) {
-        xpush(assertJsr(x));
-    }
-
-    /**
-     * Pushes a value onto the stack and checks that it is a long.
-     *
-     * @param x the instruction to push onto the stack
-     */
-    public void lpush(ValueNode x) {
-        xpush(assertLong(x));
-        xpush(null);
-    }
-
-    /**
-     * Pushes a value onto the stack and checks that it is a double.
-     * @param x the instruction to push onto the stack
-     */
-    public void dpush(ValueNode x) {
-        xpush(assertDouble(x));
-        xpush(null);
-    }
-
-    public void pushReturn(CiKind kind, ValueNode x) {
-        if (kind != CiKind.Void) {
-            push(kind.stackKind(), x);
-        }
-    }
-
-    /**
-     * Pops an instruction off the stack with the expected type.
-     * @param kind the expected type
-     * @return the instruction on the top of the stack
-     */
-    public ValueNode pop(CiKind kind) {
-        assert kind != CiKind.Void;
-        if (isTwoSlot(kind)) {
-            xpop();
-        }
-        return assertKind(kind, xpop());
-    }
-
-    /**
-     * Pops a value off of the stack without checking the type.
-     * @return x the instruction popped off the stack
-     */
-    public ValueNode xpop() {
-        ValueNode result = stack[--stackIndex];
-        assert result == null || !result.isDeleted();
-        return result;
-    }
-
-    /**
-     * Pops a value off of the stack and checks that it is an int.
-     * @return x the instruction popped off the stack
-     */
-    public ValueNode ipop() {
-        return assertInt(xpop());
-    }
-
-    /**
-     * Pops a value off of the stack and checks that it is a float.
-     * @return x the instruction popped off the stack
-     */
-    public ValueNode fpop() {
-        return assertFloat(xpop());
-    }
-
-    /**
-     * Pops a value off of the stack and checks that it is an object.
-     * @return x the instruction popped off the stack
-     */
-    public ValueNode apop() {
-        return assertObject(xpop());
-    }
-
-    /**
-     * Pops a value off of the stack and checks that it is a JSR return address.
-     * @return x the instruction popped off the stack
-     */
-    public ValueNode jpop() {
-        return assertJsr(xpop());
-    }
-
-    /**
-     * Pops a value off of the stack and checks that it is a long.
-     * @return x the instruction popped off the stack
-     */
-    public ValueNode lpop() {
-        assertHigh(xpop());
-        return assertLong(xpop());
-    }
-
-    /**
-     * Pops a value off of the stack and checks that it is a double.
-     * @return x the instruction popped off the stack
-     */
-    public ValueNode dpop() {
-        assertHigh(xpop());
-        return assertDouble(xpop());
-    }
-
-    /**
-     * Pop the specified number of slots off of this stack and return them as an array of instructions.
-     * @param size the number of arguments off of the stack
-     * @return an array containing the arguments off of the stack
-     */
-    public ValueNode[] popArguments(int slotSize, int argSize) {
-        int base = stackIndex - slotSize;
-        ValueNode[] r = new ValueNode[argSize];
-        int argIndex = 0;
-        int stackindex = 0;
-        while (stackindex < slotSize) {
-            ValueNode element = stack[base + stackindex];
-            assert element != null;
-            r[argIndex++] = element;
-            stackindex += stackSlots(element.kind());
-        }
-        stackIndex = base;
-        return r;
-    }
-
-    /**
-     * Peeks an element from the operand stack.
-     * @param argumentNumber The number of the argument, relative from the top of the stack (0 = top).
-     *        Long and double arguments only count as one argument, i.e., null-slots are ignored.
-     * @return The peeked argument.
-     */
-    public ValueNode peek(int argumentNumber) {
-        int idx = stackSize() - 1;
-        for (int i = 0; i < argumentNumber; i++) {
-            if (stackAt(idx) == null) {
-                idx--;
-                assert isTwoSlot(stackAt(idx).kind());
-            }
-            idx--;
-        }
-        return stackAt(idx);
-    }
-
-    /**
-     * Truncates this stack to the specified size.
-     * @param size the size to truncate to
-     */
-    public void truncateStack(int size) {
-        stackIndex = size;
-        assert stackIndex >= 0;
-    }
-
-    /**
-     * Clears all values on this stack.
-     */
-    public void clearStack() {
-        stackIndex = 0;
-    }
-
-    /**
-     * Loads the local variable at the specified index.
-     *
-     * @param i the index of the local variable to load
-     * @return the instruction that produced the specified local
-     */
-    public ValueNode loadLocal(int i) {
-        ValueNode x = locals[i];
-        if (x != null) {
-            if (x instanceof PhiNode) {
-                assert ((PhiNode) x).type() == PhiType.Value;
-                if (x.isDeleted()) {
-                    return null;
-                }
-            }
-            assert !isTwoSlot(x.kind()) || locals[i + 1] == null || locals[i + 1] instanceof PhiNode;
-        }
-        return x;
-    }
-
-    /**
-     * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word},
-     * then the next local variable index is also overwritten.
-     *
-     * @param i the index at which to store
-     * @param x the instruction which produces the value for the local
-     */
-    public void storeLocal(int i, ValueNode x) {
-        assert x == null || (x.kind() != CiKind.Void && x.kind() != CiKind.Illegal) : "unexpected value: " + x;
-        locals[i] = x;
-        if (isTwoSlot(x.kind())) {
-            // (tw) if this was a double word then kill i+1
-            locals[i + 1] = null;
-        }
-        if (i > 0) {
-            // if there was a double word at i - 1, then kill it
-            ValueNode p = locals[i - 1];
-            if (p != null && isTwoSlot(p.kind())) {
-                locals[i - 1] = null;
-            }
-        }
-    }
-
-    /**
-     * Locks a new object within the specified IRScope.
-     * @param scope the IRScope in which this locking operation occurs
-     * @param obj the object being locked
-     */
-    public void lock(MonitorObject obj) {
-        assert obj == null || (obj.kind() != CiKind.Void && obj.kind() != CiKind.Illegal) : "unexpected value: " + obj;
-        locks.add(obj);
-    }
-
-    /**
-     * Unlock the lock on the top of the stack.
-     */
-    public void unlock(MonitorObject obj) {
-        assert locks.get(locks.size() - 1) == obj;
-        locks.remove(locks.size() - 1);
-    }
-
-    /**
-     * Get the value on the stack at the specified stack index.
-     *
-     * @param i the index into the stack, with {@code 0} being the bottom of the stack
-     * @return the instruction at the specified position in the stack
-     */
-    public final ValueNode stackAt(int i) {
-        return stack[i];
-    }
-
-    /**
-     * Gets the value in the local variables at the specified index.
-     *
-     * @param i the index into the locals
-     * @return the instruction that produced the value for the specified local
-     */
-    public final ValueNode localAt(int i) {
-        return locals[i];
-    }
-
-    /**
-     * Retrieves the lock at the specified index in the lock stack.
-     * @param i the index into the lock stack
-     * @return the instruction which produced the object at the specified location in the lock stack
-     */
-    public final MonitorObject lockAt(int i) {
-        return locks.get(i);
-    }
-
-    /**
-     * Returns the size of the local variables.
-     *
-     * @return the size of the local variables
-     */
-    public int localsSize() {
-        return locals.length;
-    }
-
-    /**
-     * Gets number of locks held by this frame state.
-     */
-    public int locksSize() {
-        return locks.size();
-    }
-
-    /**
-     * Gets the current size (height) of the stack.
-     */
-    public int stackSize() {
-        return stackIndex;
-    }
-
-    public Iterator<ValueNode> locals() {
-        return new ValueArrayIterator(locals);
-    }
-
-    public Iterator<ValueNode> stack() {
-        return new ValueArrayIterator(locals);
-    }
-
-    public List<MonitorObject> locks() {
-        return Collections.unmodifiableList(locks);
-    }
-
-
-    private static class ValueArrayIterator implements Iterator<ValueNode> {
-        private final ValueNode[] array;
-        private int index;
-
-        public ValueArrayIterator(ValueNode[] array, int length) {
-            assert length <= array.length;
-            this.array = array;
-            this.index = 0;
-        }
-
-        public ValueArrayIterator(ValueNode[] array) {
-            this(array, array.length);
-        }
-
-        @Override
-        public boolean hasNext() {
-            return index < array.length;
-        }
-
-        @Override
-        public ValueNode next() {
-            return array[index++];
-        }
-
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException("cannot remove from array");
-        }
-
-    }
-
-
-    @Override
-    public FrameState duplicate(int bci) {
-        return create(bci);
-    }
-
-    @Override
-    public ValueNode valueAt(int i) {
-        if (i < locals.length) {
-            return locals[i];
-        } else if (i < locals.length + stackIndex) {
-            return stack[i - locals.length];
-        } else {
-            return locks.get(i - locals.length - stack.length);
-        }
-    }
-
-    @Override
-    public FrameState outerFrameState() {
-        return null;
-    }
-
-    public FrameState duplicateWithoutStack(int bci) {
-        FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[0], 0, locks, false));
-        frameState.setOuterFrameState(outerFrameState());
-        return frameState;
-    }
-
-    @Override
-    public boolean rethrowException() {
-        return rethrowException;
-    }
-
-    public void setRethrowException(boolean b) {
-        rethrowException = b;
-    }
-
-    public static int stackSlots(CiKind kind) {
-        return isTwoSlot(kind) ? 2 : 1;
-    }
-
-    public static boolean isTwoSlot(CiKind kind) {
-        assert kind != CiKind.Void && kind != CiKind.Illegal;
-        return kind == CiKind.Long || kind == CiKind.Double;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/GraphBuilderConfiguration.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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.graphbuilder;
-
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.phases.*;
-
-public class GraphBuilderConfiguration {
-    private final boolean useBranchPrediction;
-    private final boolean eagerResolving;
-    private final PhasePlan plan;
-
-    public GraphBuilderConfiguration(boolean useBranchPrediction, boolean eagerResolving, PhasePlan plan) {
-        this.useBranchPrediction = useBranchPrediction;
-        this.eagerResolving = eagerResolving;
-        this.plan = plan;
-    }
-
-    public boolean useBranchPrediction() {
-        return useBranchPrediction;
-    }
-
-    public boolean eagerResolving() {
-        return eagerResolving;
-    }
-
-    public PhasePlan plan() {
-        return plan;
-    }
-
-    public static GraphBuilderConfiguration getDefault() {
-        return getDefault(null);
-    }
-
-    public static GraphBuilderConfiguration getDefault(PhasePlan plan) {
-        return new GraphBuilderConfiguration(GraalOptions.UseBranchPrediction, false, plan);
-    }
-
-    public static GraphBuilderConfiguration getDeoptFreeDefault() {
-        return getDeoptFreeDefault(null);
-    }
-
-    public static GraphBuilderConfiguration getDeoptFreeDefault(PhasePlan plan) {
-        return new GraphBuilderConfiguration(false, true, plan);
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/GraphBuilderPhase.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1749 +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.graphbuilder;
-
-import static com.oracle.max.graal.compiler.graphbuilder.Bytecodes.*;
-import static java.lang.reflect.Modifier.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.*;
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.graphbuilder.BlockMap.Block;
-import com.oracle.max.graal.compiler.graphbuilder.BlockMap.DeoptBlock;
-import com.oracle.max.graal.compiler.graphbuilder.BlockMap.ExceptionBlock;
-import com.oracle.max.graal.compiler.phases.*;
-import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.compiler.util.*;
-import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.nodes.*;
-import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
-import com.oracle.max.graal.nodes.PhiNode.PhiType;
-import com.oracle.max.graal.nodes.calc.*;
-import com.oracle.max.graal.nodes.extended.*;
-import com.oracle.max.graal.nodes.java.*;
-import com.oracle.max.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.max.graal.nodes.spi.*;
-
-/**
- * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
- */
-public final class GraphBuilderPhase extends Phase {
-
-    /**
-     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
-     * the bytecode instructions as they are parsed.
-     */
-    public static final int TRACELEVEL_INSTRUCTIONS = 1;
-
-    /**
-     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
-     * the frame state before each bytecode instruction as it is parsed.
-     */
-    public static final int TRACELEVEL_STATE = 2;
-
-    private StructuredGraph currentGraph;
-
-    private final CiStatistics stats;
-    private final RiRuntime runtime;
-    private RiConstantPool constantPool;
-    private RiExceptionHandler[] exceptionHandlers;
-    private RiResolvedMethod method;
-
-    private BytecodeStream stream;           // the bytecode stream
-    private final LogStream log;
-
-    private FrameStateBuilder frameState;          // the current execution state
-    private Block currentBlock;
-
-    private int nextBlockNumber;
-
-    private ValueNode methodSynchronizedObject;
-    private ExceptionBlock unwindBlock;
-    private Block returnBlock;
-
-    // the worklist of blocks, sorted by depth first number
-    private final PriorityQueue<Block> workList = new PriorityQueue<>(10, new Comparator<Block>() {
-        public int compare(Block o1, Block o2) {
-            return o1.blockID - o2.blockID;
-        }
-    });
-
-    private FixedWithNextNode lastInstr;                 // the last instruction added
-
-    private Set<Block> blocksOnWorklist;
-    private Set<Block> blocksVisited;
-
-    private BitSet canTrapBitSet;
-
-    public static final Map<RiMethod, StructuredGraph> cachedGraphs = new WeakHashMap<>();
-
-    private final GraphBuilderConfiguration config;
-
-    public GraphBuilderPhase(RiRuntime runtime) {
-        this(runtime, null);
-    }
-
-    public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats) {
-        this(runtime, stats, GraphBuilderConfiguration.getDefault());
-    }
-
-    public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats, GraphBuilderConfiguration config) {
-        this.config = config;
-        this.runtime = runtime;
-        this.stats = stats;
-        this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        method = graph.method();
-        assert method.code() != null : "method must contain bytecodes: " + method;
-        this.stream = new BytecodeStream(method.code());
-        this.constantPool = method.getConstantPool();
-        this.blocksOnWorklist = new HashSet<>();
-        this.blocksVisited = new HashSet<>();
-        unwindBlock = null;
-        returnBlock = null;
-        methodSynchronizedObject = null;
-        exceptionHandlers = null;
-        assert graph != null;
-        this.currentGraph = graph;
-        this.frameState = new FrameStateBuilder(method, method.maxLocals(), method.maxStackSize(), graph);
-        build();
-    }
-
-    @Override
-    protected String getDetailedName() {
-        return getName() + " " + CiUtil.format("%H.%n(%p):%r", method);
-    }
-
-    private BlockMap createBlockMap() {
-        BlockMap map = new BlockMap(method, config.useBranchPrediction());
-        map.build();
-        if (stats != null) {
-            stats.bytecodeCount += method.code().length;
-        }
-
-        if (currentContext.isObserved()) {
-            String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method);
-            currentContext.observable.fireCompilationEvent(label, map);
-        }
-        return map;
-    }
-
-    private void build() {
-        if (log != null) {
-            log.println();
-            log.println("Compiling " + method);
-        }
-
-        // compute the block map, setup exception handlers and get the entrypoint(s)
-        BlockMap blockMap = createBlockMap();
-        this.canTrapBitSet = blockMap.canTrap;
-
-        exceptionHandlers = blockMap.exceptionHandlers();
-        if (stats != null) {
-            stats.blockCount += blockMap.blocks.size();
-        }
-        nextBlockNumber = blockMap.blocks.size();
-
-        lastInstr = currentGraph.start();
-        if (isSynchronized(method.accessFlags())) {
-            // add a monitor enter to the start block
-            currentGraph.start().setStateAfter(frameState.create(FrameState.BEFORE_BCI));
-            methodSynchronizedObject = synchronizedObject(frameState, method);
-            lastInstr = genMonitorEnter(methodSynchronizedObject);
-        }
-
-        // finish the start block
-        ((AbstractStateSplit) lastInstr).setStateAfter(frameState.create(0));
-        if (blockMap.startBlock.isLoopHeader) {
-            appendGoto(createTarget(blockMap.startBlock, frameState));
-        } else {
-            blockMap.startBlock.firstInstruction = lastInstr;
-        }
-        addToWorkList(blockMap.startBlock);
-
-        iterateAllBlocks();
-        connectLoopEndToBegin();
-
-        // remove Placeholders (except for loop exits)
-        for (PlaceholderNode n : currentGraph.getNodes(PlaceholderNode.class)) {
-            n.replaceAndDelete(n.next());
-        }
-
-        // remove dead FrameStates
-        for (Node n : currentGraph.getNodes(FrameState.class)) {
-            if (n.usages().size() == 0 && n.predecessor() == null) {
-                n.safeDelete();
-            }
-        }
-
-        if (GraalOptions.CacheGraphs && !currentGraph.hasNode(DeoptimizeNode.class)) {
-            cachedGraphs.put(method, currentGraph.copy());
-        }
-    }
-
-    private int nextBlockNumber() {
-        if (stats != null) {
-            stats.blockCount++;
-        }
-        return nextBlockNumber++;
-    }
-
-    private Block unwindBlock(int bci) {
-        if (unwindBlock == null) {
-            unwindBlock = new ExceptionBlock();
-            unwindBlock.startBci = -1;
-            unwindBlock.endBci = -1;
-            unwindBlock.deoptBci = bci;
-            unwindBlock.blockID = nextBlockNumber();
-            addToWorkList(unwindBlock);
-        }
-        return unwindBlock;
-    }
-
-    private Block returnBlock(int bci) {
-        if (returnBlock == null) {
-            returnBlock = new Block();
-            returnBlock.startBci = bci;
-            returnBlock.endBci = bci;
-            returnBlock.blockID = nextBlockNumber();
-            addToWorkList(returnBlock);
-        }
-        return returnBlock;
-    }
-
-    private void markOnWorkList(Block block) {
-        blocksOnWorklist.add(block);
-    }
-
-    private boolean isOnWorkList(Block block) {
-        return blocksOnWorklist.contains(block);
-    }
-
-    private void markVisited(Block block) {
-        blocksVisited.add(block);
-    }
-
-    private boolean isVisited(Block block) {
-        return blocksVisited.contains(block);
-    }
-
-    public void mergeOrClone(Block target, FrameStateAccess newState) {
-        AbstractStateSplit first = (AbstractStateSplit) target.firstInstruction;
-
-        if (target.isLoopHeader && isVisited(target)) {
-            first = (AbstractStateSplit) loopBegin(target).loopEnd().predecessor();
-        }
-
-        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
-            first.setStateAfter(newState.duplicate(bci));
-        } else {
-            if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
-                // stacks or locks do not match--bytecodes would not verify
-                TTY.println(existingState.toString());
-                TTY.println(newState.duplicate(0).toString());
-                throw new CiBailout("stack or locks do not match");
-            }
-            assert existingState.localsSize() == newState.localsSize();
-            assert existingState.stackSize() == newState.stackSize();
-
-            if (first instanceof PlaceholderNode) {
-                PlaceholderNode p = (PlaceholderNode) first;
-                if (p.predecessor() == null) {
-                    p.setStateAfter(newState.duplicate(bci));
-                    return;
-                } else {
-                    MergeNode merge = currentGraph.add(new MergeNode());
-                    FixedNode next = p.next();
-                    EndNode end = currentGraph.add(new EndNode());
-                    p.setNext(end);
-                    merge.setNext(next);
-                    merge.addEnd(end);
-                    merge.setStateAfter(existingState);
-                    p.setStateAfter(existingState.duplicate(bci));
-                    if (!(next instanceof LoopEndNode)) {
-                        target.firstInstruction = merge;
-                    }
-                    first = merge;
-                }
-            }
-
-            existingState.merge((MergeNode) first, newState);
-        }
-    }
-
-    public BytecodeStream stream() {
-        return stream;
-    }
-
-    public int bci() {
-        return stream.currentBCI();
-    }
-
-    private void loadLocal(int index, CiKind kind) {
-        frameState.push(kind, frameState.loadLocal(index));
-    }
-
-    private void storeLocal(CiKind kind, int index) {
-        frameState.storeLocal(index, frameState.pop(kind));
-    }
-
-    public static boolean covers(RiExceptionHandler handler, int bci) {
-        return handler.startBCI() <= bci && bci < handler.endBCI();
-    }
-
-    public static boolean isCatchAll(RiExceptionHandler handler) {
-        return handler.catchTypeCPI() == 0;
-    }
-
-    private BeginNode handleException(ValueNode exceptionObject, int bci) {
-        assert bci == FrameState.BEFORE_BCI || bci == bci() : "invalid bci";
-
-        if (GraalOptions.UseExceptionProbability && method.invocationCount() > GraalOptions.MatureInvocationCount) {
-            if (bci != FrameState.BEFORE_BCI && exceptionObject == null && method.exceptionProbability(bci) == 0) {
-                return null;
-            }
-        }
-
-        RiExceptionHandler firstHandler = null;
-        // join with all potential exception handlers
-        if (exceptionHandlers != null) {
-            for (RiExceptionHandler handler : exceptionHandlers) {
-                if (covers(handler, bci)) {
-                    firstHandler = handler;
-                    break;
-                }
-            }
-        }
-
-        Block dispatchBlock = null;
-        if (firstHandler == null) {
-            dispatchBlock = unwindBlock(bci);
-        } else {
-            for (int i = currentBlock.normalSuccessors; i < currentBlock.successors.size(); i++) {
-                Block block = currentBlock.successors.get(i);
-                if (block instanceof ExceptionBlock && ((ExceptionBlock) block).handler == firstHandler) {
-                    dispatchBlock = block;
-                    break;
-                }
-                if (isCatchAll(firstHandler) && block.startBci == firstHandler.handlerBCI()) {
-                    dispatchBlock = block;
-                    break;
-                }
-            }
-        }
-
-        BeginNode p = currentGraph.add(new BeginNode());
-        p.setStateAfter(frameState.duplicateWithoutStack(bci));
-
-        ValueNode currentExceptionObject;
-        ExceptionObjectNode newObj = null;
-        if (exceptionObject == null) {
-            newObj = currentGraph.add(new ExceptionObjectNode());
-            currentExceptionObject = newObj;
-        } else {
-            currentExceptionObject = exceptionObject;
-        }
-        FrameState stateWithException = frameState.duplicateWithException(bci, currentExceptionObject);
-        if (newObj != null) {
-            newObj.setStateAfter(stateWithException);
-        }
-        FixedNode target = createTarget(dispatchBlock, stateWithException);
-        if (exceptionObject == null) {
-            ExceptionObjectNode eObj = (ExceptionObjectNode) currentExceptionObject;
-            eObj.setNext(target);
-            p.setNext(eObj);
-        } else {
-            p.setNext(target);
-        }
-        return p;
-    }
-
-    private void genLoadConstant(int cpi) {
-        Object con = constantPool.lookupConstant(cpi);
-
-        if (con instanceof RiType) {
-            // this is a load of class constant which might be unresolved
-            RiType riType = (RiType) con;
-            if (riType instanceof RiResolvedType) {
-                frameState.push(CiKind.Object, append(ConstantNode.forCiConstant(((RiResolvedType) riType).getEncoding(Representation.JavaClass), runtime, currentGraph)));
-            } else {
-                append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-                frameState.push(CiKind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
-            }
-        } else if (con instanceof CiConstant) {
-            CiConstant constant = (CiConstant) con;
-            frameState.push(constant.kind.stackKind(), appendConstant(constant));
-        } else {
-            throw new Error("lookupConstant returned an object of incorrect type");
-        }
-    }
-
-    private void genLoadIndexed(CiKind kind) {
-        emitExplicitExceptions(frameState.peek(1), frameState.peek(0));
-
-        ValueNode index = frameState.ipop();
-        ValueNode array = frameState.apop();
-        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
-        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, length, kind)));
-        frameState.push(kind.stackKind(), v);
-    }
-
-    private void genStoreIndexed(CiKind kind) {
-        emitExplicitExceptions(frameState.peek(2), frameState.peek(1));
-
-        ValueNode value = frameState.pop(kind.stackKind());
-        ValueNode index = frameState.ipop();
-        ValueNode array = frameState.apop();
-        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
-        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, length, kind, value));
-        append(result);
-    }
-
-    private void stackOp(int opcode) {
-        switch (opcode) {
-            case POP: {
-                frameState.xpop();
-                break;
-            }
-            case POP2: {
-                frameState.xpop();
-                frameState.xpop();
-                break;
-            }
-            case DUP: {
-                ValueNode w = frameState.xpop();
-                frameState.xpush(w);
-                frameState.xpush(w);
-                break;
-            }
-            case DUP_X1: {
-                ValueNode w1 = frameState.xpop();
-                ValueNode w2 = frameState.xpop();
-                frameState.xpush(w1);
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                break;
-            }
-            case DUP_X2: {
-                ValueNode w1 = frameState.xpop();
-                ValueNode w2 = frameState.xpop();
-                ValueNode w3 = frameState.xpop();
-                frameState.xpush(w1);
-                frameState.xpush(w3);
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                break;
-            }
-            case DUP2: {
-                ValueNode w1 = frameState.xpop();
-                ValueNode w2 = frameState.xpop();
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                break;
-            }
-            case DUP2_X1: {
-                ValueNode w1 = frameState.xpop();
-                ValueNode w2 = frameState.xpop();
-                ValueNode w3 = frameState.xpop();
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                frameState.xpush(w3);
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                break;
-            }
-            case DUP2_X2: {
-                ValueNode w1 = frameState.xpop();
-                ValueNode w2 = frameState.xpop();
-                ValueNode w3 = frameState.xpop();
-                ValueNode w4 = frameState.xpop();
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                frameState.xpush(w4);
-                frameState.xpush(w3);
-                frameState.xpush(w2);
-                frameState.xpush(w1);
-                break;
-            }
-            case SWAP: {
-                ValueNode w1 = frameState.xpop();
-                ValueNode w2 = frameState.xpop();
-                frameState.xpush(w1);
-                frameState.xpush(w2);
-                break;
-            }
-            default:
-                throw Util.shouldNotReachHere();
-        }
-
-    }
-
-    private void genArithmeticOp(CiKind result, int opcode, boolean canTrap) {
-        ValueNode y = frameState.pop(result);
-        ValueNode x = frameState.pop(result);
-        boolean isStrictFP = isStrict(method.accessFlags());
-        ArithmeticNode v;
-        switch(opcode){
-            case IADD:
-            case LADD: v = new IntegerAddNode(result, x, y); break;
-            case FADD:
-            case DADD: v = new FloatAddNode(result, x, y, isStrictFP); break;
-            case ISUB:
-            case LSUB: v = new IntegerSubNode(result, x, y); break;
-            case FSUB:
-            case DSUB: v = new FloatSubNode(result, x, y, isStrictFP); break;
-            case IMUL:
-            case LMUL: v = new IntegerMulNode(result, x, y); break;
-            case FMUL:
-            case DMUL: v = new FloatMulNode(result, x, y, isStrictFP); break;
-            case IDIV:
-            case LDIV: v = new IntegerDivNode(result, x, y); break;
-            case FDIV:
-            case DDIV: v = new FloatDivNode(result, x, y, isStrictFP); break;
-            case IREM:
-            case LREM: v = new IntegerRemNode(result, x, y); break;
-            case FREM:
-            case DREM: v = new FloatRemNode(result, x, y, isStrictFP); break;
-            default:
-                throw new CiBailout("should not reach");
-        }
-        ValueNode result1 = append(currentGraph.unique(v));
-        if (canTrap) {
-            append(currentGraph.add(new ValueAnchorNode(result1)));
-        }
-        frameState.push(result, result1);
-    }
-
-    private void genNegateOp(CiKind kind) {
-        frameState.push(kind, append(currentGraph.unique(new NegateNode(frameState.pop(kind)))));
-    }
-
-    private void genShiftOp(CiKind kind, int opcode) {
-        ValueNode s = frameState.ipop();
-        ValueNode x = frameState.pop(kind);
-        ShiftNode v;
-        switch(opcode){
-            case ISHL:
-            case LSHL: v = new LeftShiftNode(kind, x, s); break;
-            case ISHR:
-            case LSHR: v = new RightShiftNode(kind, x, s); break;
-            case IUSHR:
-            case LUSHR: v = new UnsignedRightShiftNode(kind, x, s); break;
-            default:
-                throw new CiBailout("should not reach");
-        }
-        frameState.push(kind, append(currentGraph.unique(v)));
-    }
-
-    private void genLogicOp(CiKind kind, int opcode) {
-        ValueNode y = frameState.pop(kind);
-        ValueNode x = frameState.pop(kind);
-        LogicNode v;
-        switch(opcode){
-            case IAND:
-            case LAND: v = new AndNode(kind, x, y); break;
-            case IOR:
-            case LOR: v = new OrNode(kind, x, y); break;
-            case IXOR:
-            case LXOR: v = new XorNode(kind, x, y); break;
-            default:
-                throw new CiBailout("should not reach");
-        }
-        frameState.push(kind, append(currentGraph.unique(v)));
-    }
-
-    private void genCompareOp(CiKind kind, boolean isUnorderedLess) {
-        ValueNode y = frameState.pop(kind);
-        ValueNode x = frameState.pop(kind);
-        frameState.ipush(append(currentGraph.unique(new NormalizeCompareNode(x, y, isUnorderedLess))));
-    }
-
-    private void genConvert(ConvertNode.Op opcode) {
-        ValueNode input = frameState.pop(opcode.from.stackKind());
-        frameState.push(opcode.to.stackKind(), append(currentGraph.unique(new ConvertNode(opcode, input))));
-    }
-
-    private void genIncrement() {
-        int index = stream().readLocalIndex();
-        int delta = stream().readIncrement();
-        ValueNode x = frameState.localAt(index);
-        ValueNode y = append(ConstantNode.forInt(delta, currentGraph));
-        frameState.storeLocal(index, append(currentGraph.unique(new IntegerAddNode(CiKind.Int, x, y))));
-    }
-
-    private void genGoto() {
-        appendGoto(createTarget(currentBlock.successors.get(0), frameState));
-        assert currentBlock.normalSuccessors == 1;
-    }
-
-    private void ifNode(ValueNode x, Condition cond, ValueNode y) {
-        assert !x.isDeleted() && !y.isDeleted();
-        double probability = method.branchProbability(bci());
-        if (probability < 0) {
-            if (GraalOptions.TraceProbability) {
-                TTY.println("missing probability in " + method + " at bci " + bci());
-            }
-            probability = 0.5;
-        }
-
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new CompareNode(x, cond, y)), probability));
-        append(ifNode);
-        ifNode.setTrueSuccessor(BeginNode.begin(createTarget(currentBlock.successors.get(0), frameState)));
-        ifNode.setFalseSuccessor(BeginNode.begin(createTarget(currentBlock.successors.get(1), frameState)));
-
-        assert currentBlock.normalSuccessors == 2 : currentBlock.normalSuccessors;
-    }
-
-    private void genIfZero(Condition cond) {
-        ValueNode y = appendConstant(CiConstant.INT_0);
-        ValueNode x = frameState.ipop();
-        ifNode(x, cond, y);
-    }
-
-    private void genIfNull(Condition cond) {
-        ValueNode y = appendConstant(CiConstant.NULL_OBJECT);
-        ValueNode x = frameState.apop();
-        ifNode(x, cond, y);
-    }
-
-    private void genIfSame(CiKind kind, Condition cond) {
-        ValueNode y = frameState.pop(kind);
-        ValueNode x = frameState.pop(kind);
-        assert !x.isDeleted() && !y.isDeleted();
-        ifNode(x, cond, y);
-    }
-
-    private void genThrow(int bci) {
-        ValueNode exception = frameState.apop();
-        FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false))));
-        append(node);
-        append(handleException(exception, bci));
-    }
-
-    private RiType lookupType(int cpi, int bytecode) {
-        eagerResolving(cpi, bytecode);
-        RiType result = constantPool.lookupType(cpi, bytecode);
-        assert !config.eagerResolving() || result instanceof RiResolvedType;
-        return result;
-    }
-
-    private RiMethod lookupMethod(int cpi, int opcode) {
-        eagerResolving(cpi, opcode);
-        RiMethod result = constantPool.lookupMethod(cpi, opcode);
-        assert !config.eagerResolving() || ((result instanceof RiResolvedMethod) && ((RiResolvedMethod) result).holder().isInitialized());
-        return result;
-    }
-
-    private RiField lookupField(int cpi, int opcode) {
-        eagerResolving(cpi, opcode);
-        RiField result = constantPool.lookupField(cpi, opcode);
-        assert !config.eagerResolving() || (result instanceof RiResolvedField && ((RiResolvedField) result).holder().isInitialized());
-        return result;
-    }
-
-    private void eagerResolving(int cpi, int bytecode) {
-        if (config.eagerResolving()) {
-            constantPool.loadReferencedType(cpi, bytecode);
-        }
-    }
-
-    private void genCheckCast() {
-        int cpi = stream().readCPI();
-        RiType type = lookupType(cpi, CHECKCAST);
-        boolean initialized = type instanceof RiResolvedType;
-        if (initialized) {
-            ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, true);
-            ValueNode object = frameState.apop();
-            AnchorNode anchor = currentGraph.add(new AnchorNode());
-            append(anchor);
-            CheckCastNode checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object));
-            append(currentGraph.add(new ValueAnchorNode(checkCast)));
-            frameState.apush(checkCast);
-        } else {
-            ValueNode object = frameState.apop();
-            append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(object, Condition.EQ, ConstantNode.forObject(null, runtime, currentGraph))))));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
-        }
-    }
-
-    private void genInstanceOf() {
-        int cpi = stream().readCPI();
-        RiType type = lookupType(cpi, INSTANCEOF);
-        ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, type instanceof RiResolvedType);
-        ValueNode object = frameState.apop();
-        if (typeInstruction != null) {
-            frameState.ipush(append(MaterializeNode.create(currentGraph.unique(new InstanceOfNode(typeInstruction, (RiResolvedType) type, object, false)), currentGraph)));
-        } else {
-            frameState.ipush(appendConstant(CiConstant.INT_0));
-        }
-    }
-
-    void genNewInstance(int cpi) {
-        RiType type = lookupType(cpi, NEW);
-        if (type instanceof RiResolvedType) {
-            NewInstanceNode n = currentGraph.add(new NewInstanceNode((RiResolvedType) type));
-            frameState.apush(append(n));
-        } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
-        }
-    }
-
-    /**
-     * Gets the kind of array elements for the array type code that appears
-     * in a {@link Bytecodes#NEWARRAY} bytecode.
-     * @param code the array type code
-     * @return the kind from the array type code
-     */
-    public static CiKind arrayTypeCodeToKind(int code) {
-        // Checkstyle: stop
-        switch (code) {
-            case 4:  return CiKind.Boolean;
-            case 5:  return CiKind.Char;
-            case 6:  return CiKind.Float;
-            case 7:  return CiKind.Double;
-            case 8:  return CiKind.Byte;
-            case 9:  return CiKind.Short;
-            case 10: return CiKind.Int;
-            case 11: return CiKind.Long;
-            default: throw new IllegalArgumentException("unknown array type code: " + code);
-        }
-        // Checkstyle: resume
-    }
-
-    private void genNewTypeArray(int typeCode) {
-        CiKind kind = arrayTypeCodeToKind(typeCode);
-        RiResolvedType elementType = runtime.asRiType(kind);
-        NewTypeArrayNode nta = currentGraph.add(new NewTypeArrayNode(frameState.ipop(), elementType));
-        frameState.apush(append(nta));
-    }
-
-    private void genNewObjectArray(int cpi) {
-        RiType type = lookupType(cpi, ANEWARRAY);
-        ValueNode length = frameState.ipop();
-        if (type instanceof RiResolvedType) {
-            NewArrayNode n = currentGraph.add(new NewObjectArrayNode((RiResolvedType) type, length));
-            frameState.apush(append(n));
-        } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
-        }
-
-    }
-
-    private void genNewMultiArray(int cpi) {
-        RiType type = lookupType(cpi, MULTIANEWARRAY);
-        int rank = stream().readUByte(bci() + 3);
-        ValueNode[] dims = new ValueNode[rank];
-        for (int i = rank - 1; i >= 0; i--) {
-            dims[i] = frameState.ipop();
-        }
-        if (type instanceof RiResolvedType) {
-            FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((RiResolvedType) type, dims));
-            frameState.apush(append(n));
-        } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
-        }
-    }
-
-    private void genGetField(RiField field) {
-        emitExplicitExceptions(frameState.peek(0), null);
-
-        CiKind kind = field.kind(false);
-        ValueNode receiver = frameState.apop();
-        if ((field instanceof RiResolvedField) && ((RiResolvedField) field).holder().isInitialized()) {
-            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (RiResolvedField) field));
-            appendOptimizedLoadField(kind, load);
-        } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-            frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
-        }
-    }
-
-    public static class ExceptionInfo {
-
-        public final FixedWithNextNode exceptionEdge;
-        public final ValueNode exception;
-
-        public ExceptionInfo(FixedWithNextNode exceptionEdge, ValueNode exception) {
-            this.exceptionEdge = exceptionEdge;
-            this.exception = exception;
-        }
-    }
-
-    private ExceptionInfo emitNullCheck(ValueNode receiver) {
-        PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode());
-        PlaceholderNode falseSucc = currentGraph.add(new PlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(receiver, false)), trueSucc, falseSucc, 1));
-
-        append(ifNode);
-        lastInstr = trueSucc;
-
-        if (GraalOptions.OmitHotExceptionStacktrace) {
-            ValueNode exception = ConstantNode.forObject(new NullPointerException(), runtime, currentGraph);
-            return new ExceptionInfo(falseSucc, exception);
-        } else {
-            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateNullPointerException));
-            call.setStateAfter(frameState.duplicate(bci()));
-            falseSucc.setNext(call);
-            return new ExceptionInfo(call, call);
-        }
-    }
-
-    private ExceptionInfo emitBoundsCheck(ValueNode index, ValueNode length) {
-        PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode());
-        PlaceholderNode falseSucc = currentGraph.add(new PlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new CompareNode(index, Condition.BT, length)), trueSucc, falseSucc, 1));
-
-        append(ifNode);
-        lastInstr = trueSucc;
-
-        if (GraalOptions.OmitHotExceptionStacktrace) {
-            ValueNode exception = ConstantNode.forObject(new ArrayIndexOutOfBoundsException(), runtime, currentGraph);
-            return new ExceptionInfo(falseSucc, exception);
-        } else {
-            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateOutOfBoundsException, new ValueNode[] {index}));
-            call.setStateAfter(frameState.duplicate(bci()));
-            falseSucc.setNext(call);
-            return new ExceptionInfo(call, call);
-        }
-    }
-
-    private void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) {
-        assert receiver != null;
-
-        if (canTrapBitSet.get(bci()) && GraalOptions.AllowExplicitExceptionChecks) {
-            ArrayList<ExceptionInfo> exceptions = new ArrayList<>(2);
-            exceptions.add(emitNullCheck(receiver));
-            if (outOfBoundsIndex != null) {
-                ArrayLengthNode length = currentGraph.add(new ArrayLengthNode(receiver));
-                append(length);
-                exceptions.add(emitBoundsCheck(outOfBoundsIndex, length));
-            }
-            final ExceptionInfo exception;
-            if (exceptions.size() == 1) {
-                exception = exceptions.get(0);
-            } else {
-                assert exceptions.size() > 1;
-                MergeNode merge = currentGraph.add(new MergeNode());
-                PhiNode phi = currentGraph.unique(new PhiNode(CiKind.Object, merge, PhiType.Value));
-                for (ExceptionInfo info : exceptions) {
-                    EndNode end = currentGraph.add(new EndNode());
-                    info.exceptionEdge.setNext(end);
-                    merge.addEnd(end);
-                    phi.addInput(info.exception);
-                }
-                merge.setStateAfter(frameState.duplicate(bci()));
-                exception = new ExceptionInfo(merge, phi);
-            }
-
-            FixedNode entry = handleException(exception.exception, bci());
-            if (entry != null) {
-                exception.exceptionEdge.setNext(entry);
-            } else {
-                exception.exceptionEdge.setNext(createTarget(unwindBlock(bci()), frameState.duplicateWithException(bci(), exception.exception)));
-            }
-            if (GraalOptions.Meter) {
-                currentContext.metrics.ExplicitExceptions++;
-            }
-        }
-    }
-
-    private void genPutField(RiField field) {
-        emitExplicitExceptions(frameState.peek(1), null);
-
-        ValueNode value = frameState.pop(field.kind(false).stackKind());
-        ValueNode receiver = frameState.apop();
-        if (field instanceof RiResolvedField && ((RiResolvedField) field).holder().isInitialized()) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (RiResolvedField) field, value));
-            appendOptimizedStoreField(store);
-        } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-        }
-    }
-
-    private void genGetStatic(RiField field) {
-        RiType holder = field.holder();
-        boolean isInitialized = (field instanceof RiResolvedField) && ((RiResolvedType) holder).isInitialized();
-        CiConstant constantValue = null;
-        if (isInitialized) {
-            constantValue = ((RiResolvedField) field).constantValue(null);
-        }
-        if (constantValue != null) {
-            frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue));
-        } else {
-            ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized);
-            CiKind kind = field.kind(false);
-            if (container != null) {
-                LoadFieldNode load = currentGraph.add(new LoadFieldNode(container, (RiResolvedField) field));
-                appendOptimizedLoadField(kind, load);
-            } else {
-                // deopt will be generated by genTypeOrDeopt, not needed here
-                frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
-            }
-        }
-    }
-
-    private void genPutStatic(RiField field) {
-        RiType holder = field.holder();
-        ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field instanceof RiResolvedField && ((RiResolvedType) holder).isInitialized());
-        ValueNode value = frameState.pop(field.kind(false).stackKind());
-        if (container != null) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(container, (RiResolvedField) field, value));
-            appendOptimizedStoreField(store);
-        } else {
-            // deopt will be generated by genTypeOrDeopt, not needed here
-        }
-    }
-
-    private ConstantNode genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized) {
-        if (initialized) {
-            return appendConstant(((RiResolvedType) holder).getEncoding(representation));
-        } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-            return null;
-        }
-    }
-
-    private void appendOptimizedStoreField(StoreFieldNode store) {
-        append(store);
-    }
-
-    private void appendOptimizedLoadField(CiKind kind, LoadFieldNode load) {
-        // append the load to the instruction
-        ValueNode optimized = append(load);
-        frameState.push(kind.stackKind(), optimized);
-    }
-
-    private void genInvokeStatic(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
-            RiResolvedMethod resolvedTarget = (RiResolvedMethod) target;
-            RiResolvedType holder = resolvedTarget.holder();
-            if (!holder.isInitialized() && GraalOptions.ResolveClassBeforeStaticInvoke) {
-                genInvokeDeopt(target, false);
-            } else {
-                ValueNode[] args = frameState.popArguments(resolvedTarget.signature().argumentSlots(false), resolvedTarget.signature().argumentCount(false));
-                appendInvoke(InvokeKind.Static, resolvedTarget, args);
-            }
-        } else {
-            genInvokeDeopt(target, false);
-        }
-    }
-
-    private void genInvokeInterface(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
-            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
-            genInvokeIndirect(InvokeKind.Interface, (RiResolvedMethod) target, args);
-        } else {
-            genInvokeDeopt(target, true);
-        }
-    }
-
-    private void genInvokeVirtual(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
-            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
-            genInvokeIndirect(InvokeKind.Virtual, (RiResolvedMethod) target, args);
-        } else {
-            genInvokeDeopt(target, true);
-        }
-
-    }
-
-    private void genInvokeSpecial(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
-            assert target != null;
-            assert target.signature() != null;
-            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
-            invokeDirect((RiResolvedMethod) target, args);
-        } else {
-            genInvokeDeopt(target, true);
-        }
-    }
-
-    private void genInvokeDeopt(RiMethod unresolvedTarget, boolean withReceiver) {
-        append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
-        frameState.popArguments(unresolvedTarget.signature().argumentSlots(withReceiver), unresolvedTarget.signature().argumentCount(withReceiver));
-        CiKind kind = unresolvedTarget.signature().returnKind(false);
-        if (kind != CiKind.Void) {
-            frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
-        }
-    }
-
-    private void genInvokeIndirect(InvokeKind invokeKind, RiResolvedMethod target, ValueNode[] args) {
-        ValueNode receiver = args[0];
-        // attempt to devirtualize the call
-        RiResolvedType klass = target.holder();
-
-        // 0. check for trivial cases
-        if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) {
-            // check for trivial cases (e.g. final methods, nonvirtual methods)
-            invokeDirect(target, args);
-            return;
-        }
-        // 1. check if the exact type of the receiver can be determined
-        RiResolvedType exact = getExactType(klass, receiver);
-        if (exact != null) {
-            // either the holder class is exact, or the receiver object has an exact type
-            invokeDirect(exact.resolveMethodImpl(target), args);
-            return;
-        }
-        // devirtualization failed, produce an actual invokevirtual
-        appendInvoke(invokeKind, target, args);
-    }
-
-    private void invokeDirect(RiResolvedMethod target, ValueNode[] args) {
-        appendInvoke(InvokeKind.Special, target, args);
-    }
-
-    private void appendInvoke(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] args) {
-        CiKind resultType = targetMethod.signature().returnKind(false);
-        if (GraalOptions.DeoptALot) {
-            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptAction.None));
-            deoptimize.setMessage("invoke " + targetMethod.name());
-            append(deoptimize);
-            frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
-        } else {
-            MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, targetMethod.signature().returnType(method.holder())));
-            BeginNode exceptionEdge = handleException(null, bci());
-            ValueNode result;
-            if (exceptionEdge != null) {
-                InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
-                result = append(invoke);
-                frameState.pushReturn(resultType, result);
-                Block nextBlock = currentBlock.successors.get(0);
-                invoke.setNext(createTarget(nextBlock, frameState));
-                invoke.setStateAfter(frameState.create(nextBlock.startBci));
-            } else {
-                result = appendWithBCI(currentGraph.add(new InvokeNode(callTarget, bci())));
-                frameState.pushReturn(resultType, result);
-            }
-        }
-    }
-
-    private RiResolvedType getExactType(RiResolvedType staticType, ValueNode receiver) {
-        RiResolvedType exact = staticType.exactType();
-        if (exact == null) {
-            exact = receiver.exactType();
-            if (exact == null) {
-                if (receiver.isConstant()) {
-                    exact = runtime.getTypeOf(receiver.asConstant());
-                }
-                if (exact == null) {
-                    RiType declared = receiver.declaredType();
-                    if (declared instanceof RiResolvedType) {
-                        exact = ((RiResolvedType) declared).exactType();
-                    }
-                }
-            }
-        }
-        return exact;
-    }
-
-    private void callRegisterFinalizer() {
-        // append a call to the finalizer registration
-        append(currentGraph.add(new RegisterFinalizerNode(frameState.loadLocal(0))));
-    }
-
-    private void genReturn(ValueNode x) {
-        frameState.clearStack();
-        if (x != null) {
-            frameState.push(x.kind(), x);
-        }
-        appendGoto(createTarget(returnBlock(bci()), frameState));
-    }
-
-    private MonitorEnterNode genMonitorEnter(ValueNode x) {
-        MonitorObject monitorObject = currentGraph.add(new MonitorObject(x));
-        MonitorEnterNode monitorEnter = currentGraph.add(new MonitorEnterNode(monitorObject));
-        frameState.lock(monitorObject);
-        appendWithBCI(monitorEnter);
-        return monitorEnter;
-    }
-
-    private MonitorExitNode genMonitorExit(ValueNode x) {
-        if (frameState.locksSize() <= 0) {
-            throw new CiBailout("monitor stack underflow");
-        }
-        MonitorObject monitorObject = frameState.lockAt(frameState.locksSize() - 1);
-
-        // We only compile methods with balanced monitors.  However, x might be a phi function
-        // that can be optimized away later on, so we have to disable the check for phi functions.
-        assert x == monitorObject.owner() || x instanceof PhiNode;
-
-        MonitorExitNode monitorExit = currentGraph.add(new MonitorExitNode(monitorObject));
-        appendWithBCI(monitorExit);
-        frameState.unlock(monitorObject);
-        return monitorExit;
-    }
-
-    private void genJsr(int dest) {
-        Block successor = currentBlock.jsrSuccessor;
-        assert successor.startBci == dest : successor.startBci + " != " + dest + " @" + bci();
-        JsrScope scope = currentBlock.jsrScope;
-        if (!successor.jsrScope.pop().equals(scope)) {
-            throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
-        }
-        if (successor.jsrScope.nextReturnAddress() != stream().nextBCI()) {
-            throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
-        }
-        frameState.push(CiKind.Jsr, ConstantNode.forJsr(stream().nextBCI(), currentGraph));
-        appendGoto(createTarget(successor, frameState));
-    }
-
-    private void genRet(int localIndex) {
-        Block successor = currentBlock.retSuccessor;
-        ValueNode local = frameState.loadLocal(localIndex);
-        JsrScope scope = currentBlock.jsrScope;
-        int retAddress = scope.nextReturnAddress();
-        append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(local, Condition.EQ, ConstantNode.forJsr(retAddress, currentGraph))))));
-        if (!successor.jsrScope.equals(scope.pop())) {
-            throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
-        }
-        appendGoto(createTarget(successor, frameState));
-    }
-
-    private void genTableswitch() {
-        int bci = bci();
-        ValueNode value = frameState.ipop();
-        BytecodeTableSwitch ts = new BytecodeTableSwitch(stream(), bci);
-
-        int nofCases = ts.numberOfCases() + 1; // including default case
-        assert currentBlock.normalSuccessors == nofCases;
-
-        TableSwitchNode tableSwitch = currentGraph.add(new TableSwitchNode(value, ts.lowKey(), switchProbability(nofCases, bci)));
-        for (int i = 0; i < nofCases; ++i) {
-            tableSwitch.setBlockSuccessor(i, BeginNode.begin(createTarget(currentBlock.successors.get(i), frameState)));
-        }
-        append(tableSwitch);
-    }
-
-    private double[] switchProbability(int numberOfCases, int bci) {
-        double[] prob = method.switchProbability(bci);
-        if (prob != null) {
-            assert prob.length == numberOfCases;
-        } else {
-            if (GraalOptions.TraceProbability) {
-                TTY.println("Missing probability (switch) in " + method + " at bci " + bci);
-            }
-            prob = new double[numberOfCases];
-            for (int i = 0; i < numberOfCases; i++) {
-                prob[i] = 1.0d / numberOfCases;
-            }
-        }
-        return prob;
-    }
-
-    private void genLookupswitch() {
-        int bci = bci();
-        ValueNode value = frameState.ipop();
-        BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci);
-
-        int nofCases = ls.numberOfCases() + 1; // including default case
-        assert currentBlock.normalSuccessors == nofCases;
-
-        int[] keys = new int[nofCases - 1];
-        for (int i = 0; i < nofCases - 1; ++i) {
-            keys[i] = ls.keyAt(i);
-        }
-        LookupSwitchNode lookupSwitch = currentGraph.add(new LookupSwitchNode(value, keys, switchProbability(nofCases, bci)));
-        for (int i = 0; i < nofCases; ++i) {
-            lookupSwitch.setBlockSuccessor(i, BeginNode.begin(createTarget(currentBlock.successors.get(i), frameState)));
-        }
-        append(lookupSwitch);
-    }
-
-    private ConstantNode appendConstant(CiConstant constant) {
-        return ConstantNode.forCiConstant(constant, runtime, currentGraph);
-    }
-
-    private ValueNode append(FixedNode fixed) {
-        lastInstr.setNext(fixed);
-        lastInstr = null;
-        return fixed;
-    }
-
-    private ValueNode append(FixedWithNextNode x) {
-        return appendWithBCI(x);
-    }
-
-    private static ValueNode append(ValueNode v) {
-        return v;
-    }
-
-    private ValueNode appendWithBCI(FixedWithNextNode x) {
-        assert x.predecessor() == null : "instruction should not have been appended yet";
-        assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
-        lastInstr.setNext(x);
-        lastInstr = x;
-        return x;
-    }
-
-    private FixedNode createTarget(Block block, FrameStateAccess stateAfter) {
-        assert block != null && stateAfter != null;
-        assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null :
-            "non-loop block must be iterated after all its predecessors. startBci=" + block.startBci + ", " + block.getClass().getSimpleName() + ", " + block.firstInstruction.next();
-
-        if (block.isExceptionEntry) {
-            assert stateAfter.stackSize() == 1;
-        }
-
-        if (block.firstInstruction == null) {
-            if (block.isLoopHeader) {
-                LoopBeginNode loopBegin = currentGraph.add(new LoopBeginNode());
-                loopBegin.addEnd(currentGraph.add(new EndNode()));
-                LoopEndNode loopEnd = currentGraph.add(new LoopEndNode());
-                loopEnd.setLoopBegin(loopBegin);
-                PlaceholderNode pBegin = currentGraph.add(new PlaceholderNode());
-                pBegin.setNext(loopBegin.forwardEdge());
-                PlaceholderNode pEnd = currentGraph.add(new PlaceholderNode());
-                pEnd.setNext(loopEnd);
-                loopBegin.setStateAfter(stateAfter.duplicate(block.startBci));
-                block.firstInstruction = pBegin;
-            } else {
-                block.firstInstruction = currentGraph.add(new PlaceholderNode());
-            }
-        }
-        mergeOrClone(block, stateAfter);
-        addToWorkList(block);
-
-        FixedNode result = null;
-        if (block.isLoopHeader && isVisited(block)) {
-            result = (FixedNode) loopBegin(block).loopEnd().predecessor();
-        } else {
-            result = block.firstInstruction;
-        }
-
-        assert result instanceof MergeNode || result instanceof PlaceholderNode : result;
-        if (result instanceof MergeNode) {
-            if (result instanceof LoopBeginNode) {
-                result = ((LoopBeginNode) result).forwardEdge();
-            } else {
-                EndNode end = currentGraph.add(new EndNode());
-                ((MergeNode) result).addEnd(end);
-                PlaceholderNode p = currentGraph.add(new PlaceholderNode());
-                int bci = block.startBci;
-                if (block instanceof ExceptionBlock) {
-                    bci = ((ExceptionBlock) block).deoptBci;
-                }
-                p.setStateAfter(stateAfter.duplicate(bci));
-                p.setNext(end);
-                result = p;
-            }
-        }
-        assert !(result instanceof LoopBeginNode || result instanceof MergeNode);
-        return result;
-    }
-
-    private ValueNode synchronizedObject(FrameStateAccess state, RiResolvedMethod target) {
-        if (isStatic(target.accessFlags())) {
-            return append(ConstantNode.forCiConstant(target.holder().getEncoding(Representation.JavaClass), runtime, currentGraph));
-        } else {
-            return state.localAt(0);
-        }
-    }
-
-    private void iterateAllBlocks() {
-        Block block;
-        while ((block = removeFromWorkList()) != null) {
-            // remove blocks that have no predecessors by the time it their bytecodes are parsed
-            if (block.firstInstruction == null) {
-                markVisited(block);
-                continue;
-            }
-
-            if (!isVisited(block)) {
-                markVisited(block);
-                // now parse the block
-                if (block.isLoopHeader) {
-                    LoopBeginNode begin = loopBegin(block);
-                    FrameState preLoopState = ((StateSplit) block.firstInstruction).stateAfter();
-                    assert preLoopState != null;
-                    FrameState duplicate = preLoopState.duplicate(preLoopState.bci);
-                    begin.setStateAfter(duplicate);
-                    duplicate.insertLoopPhis(begin);
-                    lastInstr = begin;
-                } else {
-                    lastInstr = block.firstInstruction;
-                }
-                frameState.initializeFrom(((StateSplit) lastInstr).stateAfter());
-                assert lastInstr.next() == null : "instructions already appended at block " + block.blockID;
-
-                if (block == returnBlock) {
-                    createReturn();
-                } else if (block == unwindBlock) {
-                    createUnwind();
-                } else if (block instanceof ExceptionBlock) {
-                    createExceptionDispatch((ExceptionBlock) block);
-                } else if (block instanceof DeoptBlock) {
-                    createDeopt();
-                } else {
-                    frameState.setRethrowException(false);
-                    iterateBytecodesForBlock(block);
-                }
-            }
-        }
-    }
-
-    private void connectLoopEndToBegin() {
-        for (LoopBeginNode begin : currentGraph.getNodes(LoopBeginNode.class)) {
-            LoopEndNode loopEnd = begin.loopEnd();
-            AbstractStateSplit loopEndStateSplit = (AbstractStateSplit) loopEnd.predecessor();
-            if (loopEndStateSplit.stateAfter() != null) {
-                begin.stateAfter().mergeLoop(begin, loopEndStateSplit.stateAfter());
-            } else {
-//              This can happen with degenerated loops like this one:
-//              for (;;) {
-//                  try {
-//                      break;
-//                  } catch (UnresolvedException iioe) {
-//                  }
-//              }
-                // Delete the phis (all of them must have exactly one input).
-                for (PhiNode phi : begin.phis().snapshot()) {
-                    assert phi.valueCount() == 1;
-                    begin.stateAfter().deleteRedundantPhi(phi, phi.firstValue());
-                }
-
-                // Delete the loop end.
-                loopEndStateSplit.safeDelete();
-                loopEnd.safeDelete();
-
-                // Remove the loop begin.
-                EndNode loopEntryEnd = begin.forwardEdge();
-                FixedNode beginSucc = begin.next();
-                FrameState stateAfter = begin.stateAfter();
-                stateAfter.delete();
-                begin.safeDelete();
-                loopEntryEnd.replaceAndDelete(beginSucc);
-            }
-        }
-    }
-
-    private static LoopBeginNode loopBegin(Block block) {
-        EndNode endNode = (EndNode) block.firstInstruction.next();
-        LoopBeginNode loopBegin = (LoopBeginNode) endNode.merge();
-        return loopBegin;
-    }
-
-    private void createDeopt() {
-        append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile)));
-    }
-
-    private void createUnwind() {
-        synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
-        UnwindNode unwindNode = currentGraph.add(new UnwindNode(frameState.apop()));
-        append(unwindNode);
-    }
-
-    private void createReturn() {
-        if (method.isConstructor() && method.holder().superType() == null) {
-            callRegisterFinalizer();
-        }
-        CiKind returnKind = method.signature().returnKind(false).stackKind();
-        ValueNode x = returnKind == CiKind.Void ? null : frameState.pop(returnKind);
-        assert frameState.stackSize() == 0;
-
-        // TODO (gd) remove this when FloatingRead is fixed
-        if (Modifier.isSynchronized(method.accessFlags())) {
-            append(currentGraph.add(new ValueAnchorNode(x)));
-        }
-
-        synchronizedEpilogue(FrameState.AFTER_BCI);
-        ReturnNode returnNode = currentGraph.add(new ReturnNode(x));
-        append(returnNode);
-    }
-
-    private void synchronizedEpilogue(int bci) {
-        if (Modifier.isSynchronized(method.accessFlags())) {
-            MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject);
-            monitorExit.setStateAfter(frameState.create(bci));
-        }
-    }
-
-    private void createExceptionDispatch(ExceptionBlock block) {
-        if (block.handler == null) {
-            assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize();
-            createUnwind();
-        } else {
-            assert frameState.stackSize() == 1 : frameState;
-
-            RiType catchType = block.handler.catchType();
-            ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, catchType, (catchType instanceof RiResolvedType) && ((RiResolvedType) catchType).isInitialized());
-            if (typeInstruction != null) {
-                Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
-                FixedNode catchSuccessor = createTarget(block.successors.get(0), frameState);
-                FixedNode nextDispatch = createTarget(nextBlock, frameState);
-                ValueNode exception = frameState.stackAt(0);
-                IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode(typeInstruction, (RiResolvedType) catchType, exception, false)), catchSuccessor, nextDispatch, 0.5));
-                append(ifNode);
-            }
-        }
-    }
-
-    private void appendGoto(FixedNode target) {
-        if (lastInstr != null) {
-            lastInstr.setNext(target);
-        }
-    }
-
-    private void iterateBytecodesForBlock(Block block) {
-        assert frameState != null;
-
-        currentBlock = block;
-
-        int endBCI = stream.endBCI();
-
-        stream.setBCI(block.startBci);
-        int bci = block.startBci;
-        while (bci < endBCI) {
-            // read the opcode
-            int opcode = stream.currentBC();
-            traceState();
-            traceInstruction(bci, opcode, bci == block.startBci);
-            processBytecode(bci, opcode);
-
-            if (lastInstr == null || IdentifyBlocksPhase.isBlockEnd(lastInstr) || lastInstr.next() != null) {
-                break;
-            }
-
-            stream.next();
-            bci = stream.currentBCI();
-            if (lastInstr instanceof StateSplit) {
-                StateSplit stateSplit = (StateSplit) lastInstr;
-                if (stateSplit.stateAfter() == null && stateSplit.needsStateAfter()) {
-                    stateSplit.setStateAfter(frameState.create(bci));
-                }
-            }
-            if (bci < endBCI) {
-                if (bci > block.endBci) {
-                    assert !block.successors.get(0).isExceptionEntry;
-                    assert block.normalSuccessors == 1;
-                    // we fell through to the next block, add a goto and break
-                    appendGoto(createTarget(block.successors.get(0), frameState));
-                    break;
-                }
-            }
-        }
-    }
-
-    private void traceState() {
-        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) {
-            log.println(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
-            for (int i = 0; i < frameState.localsSize(); ++i) {
-                ValueNode value = frameState.localAt(i);
-                log.println(String.format("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
-            }
-            for (int i = 0; i < frameState.stackSize(); ++i) {
-                ValueNode value = frameState.stackAt(i);
-                log.println(String.format("|   stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
-            }
-            for (int i = 0; i < frameState.locksSize(); ++i) {
-                ValueNode value = frameState.lockAt(i);
-                log.println(String.format("|   lock[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
-            }
-        }
-    }
-
-    private void processBytecode(int bci, int opcode) {
-        int cpi;
-
-        // Checkstyle: stop
-        switch (opcode) {
-            case NOP            : /* nothing to do */ break;
-            case ACONST_NULL    : frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); break;
-            case ICONST_M1      : frameState.ipush(appendConstant(CiConstant.INT_MINUS_1)); break;
-            case ICONST_0       : frameState.ipush(appendConstant(CiConstant.INT_0)); break;
-            case ICONST_1       : frameState.ipush(appendConstant(CiConstant.INT_1)); break;
-            case ICONST_2       : frameState.ipush(appendConstant(CiConstant.INT_2)); break;
-            case ICONST_3       : frameState.ipush(appendConstant(CiConstant.INT_3)); break;
-            case ICONST_4       : frameState.ipush(appendConstant(CiConstant.INT_4)); break;
-            case ICONST_5       : frameState.ipush(appendConstant(CiConstant.INT_5)); break;
-            case LCONST_0       : frameState.lpush(appendConstant(CiConstant.LONG_0)); break;
-            case LCONST_1       : frameState.lpush(appendConstant(CiConstant.LONG_1)); break;
-            case FCONST_0       : frameState.fpush(appendConstant(CiConstant.FLOAT_0)); break;
-            case FCONST_1       : frameState.fpush(appendConstant(CiConstant.FLOAT_1)); break;
-            case FCONST_2       : frameState.fpush(appendConstant(CiConstant.FLOAT_2)); break;
-            case DCONST_0       : frameState.dpush(appendConstant(CiConstant.DOUBLE_0)); break;
-            case DCONST_1       : frameState.dpush(appendConstant(CiConstant.DOUBLE_1)); break;
-            case BIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readByte()))); break;
-            case SIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readShort()))); break;
-            case LDC            : // fall through
-            case LDC_W          : // fall through
-            case LDC2_W         : genLoadConstant(stream.readCPI()); break;
-            case ILOAD          : loadLocal(stream.readLocalIndex(), CiKind.Int); break;
-            case LLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Long); break;
-            case FLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Float); break;
-            case DLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Double); break;
-            case ALOAD          : loadLocal(stream.readLocalIndex(), CiKind.Object); break;
-            case ILOAD_0        : // fall through
-            case ILOAD_1        : // fall through
-            case ILOAD_2        : // fall through
-            case ILOAD_3        : loadLocal(opcode - ILOAD_0, CiKind.Int); break;
-            case LLOAD_0        : // fall through
-            case LLOAD_1        : // fall through
-            case LLOAD_2        : // fall through
-            case LLOAD_3        : loadLocal(opcode - LLOAD_0, CiKind.Long); break;
-            case FLOAD_0        : // fall through
-            case FLOAD_1        : // fall through
-            case FLOAD_2        : // fall through
-            case FLOAD_3        : loadLocal(opcode - FLOAD_0, CiKind.Float); break;
-            case DLOAD_0        : // fall through
-            case DLOAD_1        : // fall through
-            case DLOAD_2        : // fall through
-            case DLOAD_3        : loadLocal(opcode - DLOAD_0, CiKind.Double); break;
-            case ALOAD_0        : // fall through
-            case ALOAD_1        : // fall through
-            case ALOAD_2        : // fall through
-            case ALOAD_3        : loadLocal(opcode - ALOAD_0, CiKind.Object); break;
-            case IALOAD         : genLoadIndexed(CiKind.Int   ); break;
-            case LALOAD         : genLoadIndexed(CiKind.Long  ); break;
-            case FALOAD         : genLoadIndexed(CiKind.Float ); break;
-            case DALOAD         : genLoadIndexed(CiKind.Double); break;
-            case AALOAD         : genLoadIndexed(CiKind.Object); break;
-            case BALOAD         : genLoadIndexed(CiKind.Byte  ); break;
-            case CALOAD         : genLoadIndexed(CiKind.Char  ); break;
-            case SALOAD         : genLoadIndexed(CiKind.Short ); break;
-            case ISTORE         : storeLocal(CiKind.Int, stream.readLocalIndex()); break;
-            case LSTORE         : storeLocal(CiKind.Long, stream.readLocalIndex()); break;
-            case FSTORE         : storeLocal(CiKind.Float, stream.readLocalIndex()); break;
-            case DSTORE         : storeLocal(CiKind.Double, stream.readLocalIndex()); break;
-            case ASTORE         : storeLocal(CiKind.Object, stream.readLocalIndex()); break;
-            case ISTORE_0       : // fall through
-            case ISTORE_1       : // fall through
-            case ISTORE_2       : // fall through
-            case ISTORE_3       : storeLocal(CiKind.Int, opcode - ISTORE_0); break;
-            case LSTORE_0       : // fall through
-            case LSTORE_1       : // fall through
-            case LSTORE_2       : // fall through
-            case LSTORE_3       : storeLocal(CiKind.Long, opcode - LSTORE_0); break;
-            case FSTORE_0       : // fall through
-            case FSTORE_1       : // fall through
-            case FSTORE_2       : // fall through
-            case FSTORE_3       : storeLocal(CiKind.Float, opcode - FSTORE_0); break;
-            case DSTORE_0       : // fall through
-            case DSTORE_1       : // fall through
-            case DSTORE_2       : // fall through
-            case DSTORE_3       : storeLocal(CiKind.Double, opcode - DSTORE_0); break;
-            case ASTORE_0       : // fall through
-            case ASTORE_1       : // fall through
-            case ASTORE_2       : // fall through
-            case ASTORE_3       : storeLocal(CiKind.Object, opcode - ASTORE_0); break;
-            case IASTORE        : genStoreIndexed(CiKind.Int   ); break;
-            case LASTORE        : genStoreIndexed(CiKind.Long  ); break;
-            case FASTORE        : genStoreIndexed(CiKind.Float ); break;
-            case DASTORE        : genStoreIndexed(CiKind.Double); break;
-            case AASTORE        : genStoreIndexed(CiKind.Object); break;
-            case BASTORE        : genStoreIndexed(CiKind.Byte  ); break;
-            case CASTORE        : genStoreIndexed(CiKind.Char  ); break;
-            case SASTORE        : genStoreIndexed(CiKind.Short ); break;
-            case POP            : // fall through
-            case POP2           : // fall through
-            case DUP            : // fall through
-            case DUP_X1         : // fall through
-            case DUP_X2         : // fall through
-            case DUP2           : // fall through
-            case DUP2_X1        : // fall through
-            case DUP2_X2        : // fall through
-            case SWAP           : stackOp(opcode); break;
-            case IADD           : // fall through
-            case ISUB           : // fall through
-            case IMUL           : genArithmeticOp(CiKind.Int, opcode, false); break;
-            case IDIV           : // fall through
-            case IREM           : genArithmeticOp(CiKind.Int, opcode, true); break;
-            case LADD           : // fall through
-            case LSUB           : // fall through
-            case LMUL           : genArithmeticOp(CiKind.Long, opcode, false); break;
-            case LDIV           : // fall through
-            case LREM           : genArithmeticOp(CiKind.Long, opcode, true); break;
-            case FADD           : // fall through
-            case FSUB           : // fall through
-            case FMUL           : // fall through
-            case FDIV           : // fall through
-            case FREM           : genArithmeticOp(CiKind.Float, opcode, false); break;
-            case DADD           : // fall through
-            case DSUB           : // fall through
-            case DMUL           : // fall through
-            case DDIV           : // fall through
-            case DREM           : genArithmeticOp(CiKind.Double, opcode, false); break;
-            case INEG           : genNegateOp(CiKind.Int); break;
-            case LNEG           : genNegateOp(CiKind.Long); break;
-            case FNEG           : genNegateOp(CiKind.Float); break;
-            case DNEG           : genNegateOp(CiKind.Double); break;
-            case ISHL           : // fall through
-            case ISHR           : // fall through
-            case IUSHR          : genShiftOp(CiKind.Int, opcode); break;
-            case IAND           : // fall through
-            case IOR            : // fall through
-            case IXOR           : genLogicOp(CiKind.Int, opcode); break;
-            case LSHL           : // fall through
-            case LSHR           : // fall through
-            case LUSHR          : genShiftOp(CiKind.Long, opcode); break;
-            case LAND           : // fall through
-            case LOR            : // fall through
-            case LXOR           : genLogicOp(CiKind.Long, opcode); break;
-            case IINC           : genIncrement(); break;
-            case I2L            : genConvert(ConvertNode.Op.I2L); break;
-            case I2F            : genConvert(ConvertNode.Op.I2F); break;
-            case I2D            : genConvert(ConvertNode.Op.I2D); break;
-            case L2I            : genConvert(ConvertNode.Op.L2I); break;
-            case L2F            : genConvert(ConvertNode.Op.L2F); break;
-            case L2D            : genConvert(ConvertNode.Op.L2D); break;
-            case F2I            : genConvert(ConvertNode.Op.F2I); break;
-            case F2L            : genConvert(ConvertNode.Op.F2L); break;
-            case F2D            : genConvert(ConvertNode.Op.F2D); break;
-            case D2I            : genConvert(ConvertNode.Op.D2I); break;
-            case D2L            : genConvert(ConvertNode.Op.D2L); break;
-            case D2F            : genConvert(ConvertNode.Op.D2F); break;
-            case I2B            : genConvert(ConvertNode.Op.I2B); break;
-            case I2C            : genConvert(ConvertNode.Op.I2C); break;
-            case I2S            : genConvert(ConvertNode.Op.I2S); break;
-            case LCMP           : genCompareOp(CiKind.Long, false); break;
-            case FCMPL          : genCompareOp(CiKind.Float, true); break;
-            case FCMPG          : genCompareOp(CiKind.Float, false); break;
-            case DCMPL          : genCompareOp(CiKind.Double, true); break;
-            case DCMPG          : genCompareOp(CiKind.Double, false); break;
-            case IFEQ           : genIfZero(Condition.EQ); break;
-            case IFNE           : genIfZero(Condition.NE); break;
-            case IFLT           : genIfZero(Condition.LT); break;
-            case IFGE           : genIfZero(Condition.GE); break;
-            case IFGT           : genIfZero(Condition.GT); break;
-            case IFLE           : genIfZero(Condition.LE); break;
-            case IF_ICMPEQ      : genIfSame(CiKind.Int, Condition.EQ); break;
-            case IF_ICMPNE      : genIfSame(CiKind.Int, Condition.NE); break;
-            case IF_ICMPLT      : genIfSame(CiKind.Int, Condition.LT); break;
-            case IF_ICMPGE      : genIfSame(CiKind.Int, Condition.GE); break;
-            case IF_ICMPGT      : genIfSame(CiKind.Int, Condition.GT); break;
-            case IF_ICMPLE      : genIfSame(CiKind.Int, Condition.LE); break;
-            case IF_ACMPEQ      : genIfSame(CiKind.Object, Condition.EQ); break;
-            case IF_ACMPNE      : genIfSame(CiKind.Object, Condition.NE); break;
-            case GOTO           : genGoto(); break;
-            case JSR            : genJsr(stream.readBranchDest()); break;
-            case RET            : genRet(stream.readLocalIndex()); break;
-            case TABLESWITCH    : genTableswitch(); break;
-            case LOOKUPSWITCH   : genLookupswitch(); break;
-            case IRETURN        : genReturn(frameState.ipop()); break;
-            case LRETURN        : genReturn(frameState.lpop()); break;
-            case FRETURN        : genReturn(frameState.fpop()); break;
-            case DRETURN        : genReturn(frameState.dpop()); break;
-            case ARETURN        : genReturn(frameState.apop()); break;
-            case RETURN         : genReturn(null); break;
-            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(lookupField(cpi, opcode)); break;
-            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(lookupField(cpi, opcode)); break;
-            case GETFIELD       : cpi = stream.readCPI(); genGetField(lookupField(cpi, opcode)); break;
-            case PUTFIELD       : cpi = stream.readCPI(); genPutField(lookupField(cpi, opcode)); break;
-            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(lookupMethod(cpi, opcode)); break;
-            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break;
-            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
-            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
-            case NEW            : genNewInstance(stream.readCPI()); break;
-            case NEWARRAY       : genNewTypeArray(stream.readLocalIndex()); break;
-            case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
-            case ARRAYLENGTH    : genArrayLength(); break;
-            case ATHROW         : genThrow(stream.currentBCI()); break;
-            case CHECKCAST      : genCheckCast(); break;
-            case INSTANCEOF     : genInstanceOf(); break;
-            case MONITORENTER   : genMonitorEnter(frameState.apop()); break;
-            case MONITOREXIT    : genMonitorExit(frameState.apop()); break;
-            case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break;
-            case IFNULL         : genIfNull(Condition.EQ); break;
-            case IFNONNULL      : genIfNull(Condition.NE); break;
-            case GOTO_W         : genGoto(); break;
-            case JSR_W          : genJsr(stream.readFarBranchDest()); break;
-            case BREAKPOINT:
-                throw new CiBailout("concurrent setting of breakpoint");
-            default:
-                throw new CiBailout("Unsupported opcode " + opcode + " (" + nameOf(opcode) + ") [bci=" + bci + "]");
-        }
-        // Checkstyle: resume
-    }
-
-    private void traceInstruction(int bci, int opcode, boolean blockStart) {
-        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_INSTRUCTIONS && !TTY.isSuppressed()) {
-            StringBuilder sb = new StringBuilder(40);
-            sb.append(blockStart ? '+' : '|');
-            if (bci < 10) {
-                sb.append("  ");
-            } else if (bci < 100) {
-                sb.append(' ');
-            }
-            sb.append(bci).append(": ").append(Bytecodes.nameOf(opcode));
-            for (int i = bci + 1; i < stream.nextBCI(); ++i) {
-                sb.append(' ').append(stream.readUByte(i));
-            }
-            if (!currentBlock.jsrScope.isEmpty()) {
-                sb.append(' ').append(currentBlock.jsrScope);
-            }
-            log.println(sb.toString());
-        }
-    }
-
-    private void genArrayLength() {
-        frameState.ipush(append(currentGraph.add(new ArrayLengthNode(frameState.apop()))));
-    }
-
-    /**
-     * Adds a block to the worklist, if it is not already in the worklist.
-     * This method will keep the worklist topologically stored (i.e. the lower
-     * DFNs are earlier in the list).
-     * @param block the block to add to the work list
-     */
-    private void addToWorkList(Block block) {
-        if (!isOnWorkList(block)) {
-            markOnWorkList(block);
-            sortIntoWorkList(block);
-        }
-    }
-
-    private void sortIntoWorkList(Block top) {
-        workList.offer(top);
-    }
-
-    /**
-     * Removes the next block from the worklist. The list is sorted topologically, so the
-     * block with the lowest depth first number in the list will be removed and returned.
-     * @return the next block from the worklist; {@code null} if there are no blocks
-     * in the worklist
-     */
-    private Block removeFromWorkList() {
-        return workList.poll();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/JsrNotSupportedBailout.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.graal.compiler.graphbuilder;
-
-import com.oracle.max.cri.ci.*;
-
-
-public class JsrNotSupportedBailout extends CiBailout{
-    private static final long serialVersionUID = -7476925652727154272L;
-
-    public JsrNotSupportedBailout(String reason) {
-        super(reason);
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/JsrScope.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +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.graphbuilder;
-
-public class JsrScope {
-
-    public static final JsrScope EMPTY_SCOPE = new JsrScope();
-
-    private final long scope;
-
-    private JsrScope(long scope) {
-        this.scope = scope;
-    }
-
-    public JsrScope() {
-        this.scope = 0;
-    }
-
-    public int nextReturnAddress() {
-        return (int) (scope & 0xffff);
-    }
-
-    public JsrScope push(int jsrReturnBci) {
-        if ((scope & 0xffff000000000000L) != 0) {
-            throw new JsrNotSupportedBailout("only four jsr nesting levels are supported");
-        }
-        return new JsrScope((scope << 16) | jsrReturnBci);
-    }
-
-    public boolean isEmpty() {
-        return scope == 0;
-    }
-
-    public JsrScope pop() {
-        return new JsrScope(scope >>> 16);
-    }
-
-    @Override
-    public int hashCode() {
-        return (int) (scope ^ (scope >>> 32));
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        return obj != null && getClass() == obj.getClass() && scope == ((JsrScope) obj).scope;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        long tmp = scope;
-        sb.append(" [");
-        while (tmp != 0) {
-            sb.append(", ").append(tmp & 0xffff);
-            tmp = tmp >>> 16;
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graphbuilder/package-info.java	Tue Jan 03 17:53:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2010, 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.graphbuilder;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Tue Jan 03 18:22:10 2012 +0100
@@ -28,7 +28,6 @@
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.compiler.util.InliningUtil.InlineInfo;
@@ -213,7 +212,9 @@
         if (GraalOptions.ParseBeforeInlining) {
             if (!parsedMethods.containsKey(method)) {
                 StructuredGraph newGraph = new StructuredGraph(method);
-                new GraphBuilderPhase(runtime, null).apply(newGraph, currentContext, false);
+                if (plan != null) {
+                    plan.runPhases(PhasePosition.AFTER_PARSING, newGraph, currentContext);
+                }
                 new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph, currentContext, false);
                 count = graphComplexity(newGraph);
                 parsedMethods.put(method, count);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Tue Jan 03 18:22:10 2012 +0100
@@ -29,7 +29,6 @@
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.cri.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
@@ -110,17 +109,17 @@
 
         @Override
         public Node inline(StructuredGraph compilerGraph, GraalRuntime runtime, InliningCallback callback) {
-            StructuredGraph graph = GraphBuilderPhase.cachedGraphs.get(concrete);
-            if (graph != null) {
-                if (GraalOptions.TraceInlining) {
-                    TTY.println("Reusing graph for %s", methodName(concrete, invoke));
-                }
-            } else {
+            StructuredGraph graph = null; // TODO: Solve graph caching differently! GraphBuilderPhase.cachedGraphs.get(concrete);
+//            if (graph != null) {
+//                if (GraalOptions.TraceInlining) {
+//                    TTY.println("Reusing graph for %s", methodName(concrete, invoke));
+//                }
+//            } else {
                 if (GraalOptions.TraceInlining) {
                     TTY.println("Building graph for %s, locals: %d, stack: %d", methodName(concrete, invoke), concrete.maxLocals(), concrete.maxStackSize());
                 }
                 graph = callback.buildGraph(concrete);
-            }
+//            }
 
             return InliningUtil.inline(invoke, graph, true);
         }
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotSignature.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotSignature.java	Tue Jan 03 18:22:10 2012 +0100
@@ -26,8 +26,8 @@
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.hotspot.ri.*;
+import com.oracle.max.graal.java.*;
 
 /**
  * Represents a method signature.
@@ -35,7 +35,7 @@
 public class HotSpotSignature extends CompilerObject implements RiSignature {
 
     /**
-     * 
+     *
      */
     private static final long serialVersionUID = -2890917956072366116L;
     private final List<String> arguments = new ArrayList<>();
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/VMExitsNative.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/VMExitsNative.java	Tue Jan 03 18:22:10 2012 +0100
@@ -31,11 +31,11 @@
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.*;
 import com.oracle.max.graal.hotspot.ri.*;
 import com.oracle.max.graal.hotspot.server.*;
+import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.snippets.*;
 
 /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BlockMap.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,631 @@
+/*
+ * 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.java;
+
+import static com.oracle.max.graal.java.Bytecodes.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow
+ * graph. Note that this class serves a similar role to C1's {@code BlockListBuilder}, but makes fewer assumptions about
+ * what the compiler interface provides. It builds all basic blocks for the control flow graph without requiring the
+ * compiler interface to provide a bitmap of the beginning of basic blocks. It makes two linear passes; one over the
+ * bytecodes to build block starts and successor lists, and one pass over the block map to build the CFG.
+ *
+ * Note that the CFG built by this class is <i>not</i> connected to the actual {@code BlockBegin} instances; this class
+ * does, however, compute and assign the reverse postorder number of the blocks. This comment needs refinement. (MJJ)
+ *
+ * <H2>More Details on {@link BlockMap#build}</H2>
+ *
+ * If the method has any exception handlers the {@linkplain #exceptionMap exception map} will be created (TBD).
+ *
+ * The bytecodes are then scanned linearly looking for bytecodes that contain control transfers, e.g., {@code GOTO},
+ * {@code RETURN}, {@code IFGE}, and creating the corresponding entries in {@link #successorMap} and {@link #blockMap}.
+ * In addition, if {@link #exceptionMap} is not null, entries are made for any bytecode that can cause an exception.
+ * More TBD.
+ *
+ * Observe that this process finds bytecodes that terminate basic blocks, so the {@link #moveSuccessorLists} method is
+ * called to reassign the successors to the {@code BlockBegin} node that actually starts the block.
+ *
+ * <H3>Example</H3>
+ *
+ * Consider the following source code:
+ *
+ * <pre>
+ * <code>
+ *     public static int test(int arg1, int arg2) {
+ *         int x = 0;
+ *         while (arg2 > 0) {
+ *             if (arg1 > 0) {
+ *                 x += 1;
+ *             } else if (arg1 < 0) {
+ *                 x -= 1;
+ *             }
+ *         }
+ *         return x;
+ *     }
+ * </code>
+ * </pre>
+ *
+ * This is translated by javac to the following bytecode:
+ *
+ * <pre>
+ * <code>
+ *    0:   iconst_0
+ *    1:   istore_2
+ *    2:   goto    22
+ *    5:   iload_0
+ *    6:   ifle    15
+ *    9:   iinc    2, 1
+ *    12:  goto    22
+ *    15:  iload_0
+ *    16:  ifge    22
+ *    19:  iinc    2, -1
+ *    22:  iload_1
+ *    23:  ifgt    5
+ *    26:  iload_2
+ *    27:  ireturn
+ *    </code>
+ * </pre>
+ *
+ * There are seven basic blocks in this method, 0..2, 5..6, 9..12, 15..16, 19..19, 22..23 and 26..27. Therefore, before
+ * the call to {@code moveSuccessorLists}, the {@code blockMap} array has {@code BlockBegin} nodes at indices 0, 5, 9,
+ * 15, 19, 22 and 26. The {@code successorMap} array has entries at 2, 6, 12, 16, 23, 27 corresponding to the control
+ * transfer bytecodes. The entry at index 6, for example, is a length two array of {@code BlockBegin} nodes for indices
+ * 9 and 15, which are the successors for the basic block 5..6. After the call to {@code moveSuccessors}, {@code
+ * successorMap} has entries at 0, 5, 9, 15, 19, 22 and 26, i.e, matching {@code blockMap}.
+ * <p>
+ * Next the blocks are numbered using <a href="http://en.wikipedia.org/wiki/Depth-first_search#Vertex_orderings">reverse
+ * post-order</a>. For the above example this results in the numbering 2, 4, 7, 5, 6, 3, 8. Also loop header blocks are
+ * detected during the traversal by detecting a repeat visit to a block that is still being processed. This causes the
+ * block to be flagged as a loop header and also added to the {@link #loopBlocks} list. The {@code loopBlocks} list
+ * contains the blocks at 0, 5, 9, 15, 19, 22, with 22 as the loop header. (N.B. the loop header block is added multiple
+ * (4) times to this list). (Should 0 be in? It's not inside the loop).
+ *
+ * If the {@code computeStoresInLoops} argument to {@code build} is true, the {@code loopBlocks} list is processed to
+ * mark all local variables that are stored in the blocks in the list.
+ */
+public final class BlockMap {
+
+    public static class Block implements Cloneable {
+        public int startBci;
+        public int endBci;
+        public boolean isExceptionEntry;
+        public boolean isLoopHeader;
+        public int blockID;
+
+        public FixedWithNextNode firstInstruction;
+
+        public ArrayList<Block> successors = new ArrayList<>(2);
+        public int normalSuccessors;
+
+        private boolean visited;
+        private boolean active;
+        public long loops;
+
+        public HashMap<JsrScope, Block> jsrAlternatives;
+        public JsrScope jsrScope = JsrScope.EMPTY_SCOPE;
+        public Block jsrSuccessor;
+        public int jsrReturnBci;
+        public Block retSuccessor;
+        public boolean endsWithRet = false;
+
+        public Block copy() {
+            try {
+                Block block = (Block) super.clone();
+                block.successors = new ArrayList<>(successors);
+                return block;
+            } catch (CloneNotSupportedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public static class ExceptionBlock extends Block {
+        public RiExceptionHandler handler;
+        public int deoptBci;
+    }
+
+    public static class DeoptBlock extends Block {
+        public DeoptBlock(int startBci) {
+            this.startBci = startBci;
+        }
+    }
+
+    /**
+     * The blocks found in this method, in reverse postorder.
+     */
+    public final List<Block> blocks;
+
+    public final RiResolvedMethod method;
+
+    private final RiExceptionHandler[] exceptionHandlers;
+
+    private Block[] blockMap;
+
+    public final BitSet canTrap;
+
+    public boolean hasJsrBytecodes;
+
+    public Block startBlock;
+
+    public final boolean useBranchPrediction;
+
+    /**
+     * Creates a new BlockMap instance from bytecode of the given method .
+     * @param method the compiler interface method containing the code
+     */
+    public BlockMap(RiResolvedMethod method, boolean useBranchPrediction) {
+        this.method = method;
+        exceptionHandlers = method.exceptionHandlers();
+        this.blockMap = new Block[method.codeSize()];
+        this.canTrap = new BitSet(blockMap.length);
+        this.blocks = new ArrayList<>();
+        this.useBranchPrediction = useBranchPrediction;
+    }
+
+    public RiExceptionHandler[] exceptionHandlers() {
+        return exceptionHandlers;
+    }
+
+    /**
+     * Builds the block map and conservative CFG and numbers blocks.
+     */
+    public void build() {
+        makeExceptionEntries();
+        iterateOverBytecodes();
+        addExceptionEdges();
+        if (hasJsrBytecodes) {
+            if (!GraalOptions.SupportJsrBytecodes) {
+                throw new JsrNotSupportedBailout("jsr/ret parsing disabled");
+            }
+            createJsrAlternatives(blockMap[0]);
+        }
+        computeBlockOrder();
+
+        initializeBlockIds();
+
+        startBlock = blockMap[0];
+
+        // Discard big arrays so that they can be GCed
+        blockMap = null;
+    }
+
+    private void initializeBlockIds() {
+        for (int i = 0; i < blocks.size(); i++) {
+            blocks.get(i).blockID = i;
+        }
+    }
+
+    private void makeExceptionEntries() {
+        // start basic blocks at all exception handler blocks and mark them as exception entries
+        for (RiExceptionHandler h : this.exceptionHandlers) {
+            Block xhandler = makeBlock(h.handlerBCI());
+            xhandler.isExceptionEntry = true;
+        }
+    }
+
+    private void iterateOverBytecodes() {
+        // iterate over the bytecodes top to bottom.
+        // mark the entrypoints of basic blocks and build lists of successors for
+        // all bytecodes that end basic blocks (i.e. goto, ifs, switches, throw, jsr, returns, ret)
+        byte[] code = method.code();
+        Block current = null;
+        int bci = 0;
+        while (bci < code.length) {
+            if (current == null || blockMap[bci] != null) {
+                Block b = makeBlock(bci);
+                if (current != null) {
+                    setSuccessors(current.endBci, b);
+                }
+                current = b;
+            }
+            blockMap[bci] = current;
+            current.endBci = bci;
+
+            int opcode = Bytes.beU1(code, bci);
+            switch (opcode) {
+                case IRETURN: // fall through
+                case LRETURN: // fall through
+                case FRETURN: // fall through
+                case DRETURN: // fall through
+                case ARETURN: // fall through
+                case RETURN: {
+                    current = null;
+                    break;
+                }
+                case ATHROW: {
+                    current = null;
+                    canTrap.set(bci);
+                    break;
+                }
+                case IFEQ:      // fall through
+                case IFNE:      // fall through
+                case IFLT:      // fall through
+                case IFGE:      // fall through
+                case IFGT:      // fall through
+                case IFLE:      // fall through
+                case IF_ICMPEQ: // fall through
+                case IF_ICMPNE: // fall through
+                case IF_ICMPLT: // fall through
+                case IF_ICMPGE: // fall through
+                case IF_ICMPGT: // fall through
+                case IF_ICMPLE: // fall through
+                case IF_ACMPEQ: // fall through
+                case IF_ACMPNE: // fall through
+                case IFNULL:    // fall through
+                case IFNONNULL: {
+                    current = null;
+                    double probability = useBranchPrediction ? method.branchProbability(bci) : -1;
+
+                    Block b1 = probability == 0.0 ? new DeoptBlock(bci + Bytes.beS2(code, bci + 1)) : makeBlock(bci + Bytes.beS2(code, bci + 1));
+                    Block b2 = probability == 1.0 ? new DeoptBlock(bci + 3) : makeBlock(bci + 3);
+                    setSuccessors(bci, b1, b2);
+                    break;
+                }
+                case GOTO:
+                case GOTO_W: {
+                    current = null;
+                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == GOTO_W);
+                    Block b1 = makeBlock(target);
+                    setSuccessors(bci, b1);
+                    break;
+                }
+                case TABLESWITCH: {
+                    current = null;
+                    BytecodeTableSwitch sw = new BytecodeTableSwitch(code, bci);
+                    setSuccessors(bci, makeSwitchSuccessors(sw));
+                    break;
+                }
+                case LOOKUPSWITCH: {
+                    current = null;
+                    BytecodeLookupSwitch sw = new BytecodeLookupSwitch(code, bci);
+                    setSuccessors(bci, makeSwitchSuccessors(sw));
+                    break;
+                }
+                case JSR:
+                case JSR_W: {
+                    hasJsrBytecodes = true;
+                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == JSR_W);
+                    if (target == 0) {
+                        throw new JsrNotSupportedBailout("jsr target bci 0 not allowed");
+                    }
+                    Block b1 = makeBlock(target);
+                    current.jsrSuccessor = b1;
+                    current.jsrReturnBci = bci + lengthOf(opcode);
+                    current = null;
+                    setSuccessors(bci, b1);
+                    break;
+                }
+                case RET: {
+                    current.endsWithRet = true;
+                    current = null;
+                    break;
+                }
+                case WIDE: {
+                    int opcode2 = Bytes.beU1(code, bci);
+                    switch (opcode2) {
+                        case RET: {
+                            current.endsWithRet = true;
+                            current = null;
+                            break;
+                        }
+                    }
+                    break;
+                }
+                case INVOKEINTERFACE:
+                case INVOKESPECIAL:
+                case INVOKESTATIC:
+                case INVOKEVIRTUAL: {
+                    current = null;
+                    int target = bci + lengthOf(code, bci);
+                    Block b1 = makeBlock(target);
+                    setSuccessors(bci, b1);
+                    canTrap.set(bci);
+                    break;
+                }
+                default: {
+                    if (canTrap(opcode, bci)) {
+                        canTrap.set(bci);
+                    }
+                }
+            }
+            bci += lengthOf(code, bci);
+        }
+    }
+
+    public boolean canTrap(int opcode, int bci) {
+        switch (opcode) {
+            case INVOKESTATIC:
+            case INVOKESPECIAL:
+            case INVOKEVIRTUAL:
+            case INVOKEINTERFACE: {
+                return true;
+            }
+            case IASTORE:
+            case LASTORE:
+            case FASTORE:
+            case DASTORE:
+            case AASTORE:
+            case BASTORE:
+            case CASTORE:
+            case SASTORE:
+            case IALOAD:
+            case LALOAD:
+            case FALOAD:
+            case DALOAD:
+            case AALOAD:
+            case BALOAD:
+            case CALOAD:
+            case SALOAD:
+            case PUTFIELD:
+            case GETFIELD: {
+                if (GraalOptions.AllowExplicitExceptionChecks) {
+                    return method.exceptionProbability(bci) > 0;
+                }
+            }
+        }
+        return false;
+    }
+
+    private Block makeBlock(int startBci) {
+        Block oldBlock = blockMap[startBci];
+        if (oldBlock == null) {
+            Block newBlock = new Block();
+            newBlock.startBci = startBci;
+            blockMap[startBci] = newBlock;
+            return newBlock;
+
+        } else if (oldBlock.startBci != startBci) {
+            // Backward branch into the middle of an already processed block.
+            // Add the correct fall-through successor.
+            Block newBlock = new Block();
+            newBlock.startBci = startBci;
+            newBlock.endBci = oldBlock.endBci;
+            newBlock.successors.addAll(oldBlock.successors);
+            newBlock.normalSuccessors = oldBlock.normalSuccessors;
+
+            oldBlock.endBci = startBci - 1;
+            oldBlock.successors.clear();
+            oldBlock.successors.add(newBlock);
+            oldBlock.normalSuccessors = 1;
+
+            for (int i = startBci; i <= newBlock.endBci; i++) {
+                blockMap[i] = newBlock;
+            }
+            return newBlock;
+
+        } else {
+            return oldBlock;
+        }
+    }
+
+    private Block[] makeSwitchSuccessors(BytecodeSwitch tswitch) {
+        int max = tswitch.numberOfCases();
+        Block[] successors = new Block[max + 1];
+        for (int i = 0; i < max; i++) {
+            successors[i] = makeBlock(tswitch.targetAt(i));
+        }
+        successors[max] = makeBlock(tswitch.defaultTarget());
+        return successors;
+    }
+
+    private void setSuccessors(int predBci, Block... successors) {
+        Block predecessor = blockMap[predBci];
+        assert predecessor.successors.size() == 0;
+        for (Block sux : successors) {
+            if (sux.isExceptionEntry) {
+                throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow");
+            }
+            predecessor.successors.add(sux);
+        }
+        predecessor.normalSuccessors = successors.length;
+    }
+
+    private final HashSet<Block> jsrVisited = new HashSet<>();
+
+    private void createJsrAlternatives(Block block) {
+        jsrVisited.add(block);
+        JsrScope scope = block.jsrScope;
+
+        if (block.endsWithRet) {
+            block.retSuccessor = blockMap[scope.nextReturnAddress()];
+            block.successors.add(block.retSuccessor);
+            assert block.retSuccessor != block.jsrSuccessor;
+        }
+
+        if (block.jsrSuccessor != null || !scope.isEmpty()) {
+            for (int i = 0; i < block.successors.size(); i++) {
+                Block successor = block.successors.get(i);
+                JsrScope nextScope = scope;
+                if (successor == block.jsrSuccessor) {
+                    nextScope = scope.push(block.jsrReturnBci);
+                }
+                if (successor == block.retSuccessor) {
+                    nextScope = scope.pop();
+                }
+                if (!successor.jsrScope.isEmpty()) {
+                    throw new JsrNotSupportedBailout("unstructured control flow  (" + successor.jsrScope + " " + nextScope + ")");
+                }
+                if (!nextScope.isEmpty()) {
+                    Block clone;
+                    if (successor.jsrAlternatives != null && successor.jsrAlternatives.containsKey(nextScope)) {
+                        clone = successor.jsrAlternatives.get(nextScope);
+                    } else {
+                        if (successor.jsrAlternatives == null) {
+                            successor.jsrAlternatives = new HashMap<>();
+                        }
+                        clone = successor.copy();
+                        clone.jsrScope = nextScope;
+                        successor.jsrAlternatives.put(nextScope, clone);
+                    }
+                    block.successors.set(i, clone);
+                    if (successor == block.jsrSuccessor) {
+                        block.jsrSuccessor = clone;
+                    }
+                    if (successor == block.retSuccessor) {
+                        block.retSuccessor = clone;
+                    }
+                }
+            }
+        }
+        for (Block successor : block.successors) {
+            if (!jsrVisited.contains(successor)) {
+                createJsrAlternatives(successor);
+            }
+        }
+    }
+
+    private HashMap<RiExceptionHandler, ExceptionBlock> exceptionDispatch = new HashMap<>();
+
+    private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index, int bci) {
+        RiExceptionHandler handler = handlers.get(index);
+        if (handler.isCatchAll()) {
+            return blockMap[handler.handlerBCI()];
+        }
+        ExceptionBlock block = exceptionDispatch.get(handler);
+        if (block == null) {
+            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.successors.add(makeExceptionDispatch(handlers, index + 1, bci));
+            }
+            exceptionDispatch.put(handler, block);
+        }
+        return block;
+    }
+
+    private void addExceptionEdges() {
+        for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) {
+            Block block = blockMap[bci];
+
+            ArrayList<RiExceptionHandler> handlers = null;
+            for (RiExceptionHandler h : this.exceptionHandlers) {
+                if (h.startBCI() <= bci && bci < h.endBCI()) {
+                    if (handlers == null) {
+                        handlers = new ArrayList<>();
+                    }
+                    handlers.add(h);
+                    if (h.isCatchAll()) {
+                        break;
+                    }
+                }
+            }
+            if (handlers != null) {
+                Block dispatch = makeExceptionDispatch(handlers, 0, bci);
+                block.successors.add(dispatch);
+            }
+        }
+    }
+
+    private void computeBlockOrder() {
+        long loop = computeBlockOrder(blockMap[0]);
+
+        if (loop != 0) {
+            // There is a path from a loop end to the method entry that does not pass the loop header.
+            // Therefore, the loop is non reducible (has more than one entry).
+            // We don't want to compile such methods because the IR only supports structured loops.
+            throw new CiBailout("Non-reducible loop");
+        }
+
+        // Convert postorder to the desired reverse postorder.
+        Collections.reverse(blocks);
+    }
+
+    /**
+     * The next available loop number.
+     */
+    private int nextLoop;
+
+    /**
+     * Mark the block as a loop header, using the next available loop number.
+     * Also checks for corner cases that we don't want to compile.
+     */
+    private void makeLoopHeader(Block block) {
+        if (!block.isLoopHeader) {
+            block.isLoopHeader = true;
+
+            if (block.isExceptionEntry) {
+                // Loops that are implicitly formed by an exception handler lead to all sorts of corner cases.
+                // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
+                throw new CiBailout("Loop formed by an exception handler");
+            }
+            if (nextLoop >= Long.SIZE) {
+                // This restriction can be removed by using a fall-back to a BitSet in case we have more than 32 loops
+                // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
+                throw new CiBailout("Too many loops in method");
+            }
+
+            assert block.loops == 0;
+            block.loops = (long) 1 << (long) nextLoop;
+            nextLoop++;
+        }
+        assert Long.bitCount(block.loops) == 1;
+    }
+
+    /**
+     * Depth-first traversal of the control flow graph. The flag {@linkplain Block#visited} is used to
+     * visit every block only once. The flag {@linkplain Block#active} is used to detect cycles (backward
+     * edges).
+     */
+    private long computeBlockOrder(Block block) {
+        if (block.visited) {
+            if (block.active) {
+                // Reached block via backward branch.
+                makeLoopHeader(block);
+            }
+            // Return cached loop information for this block.
+            return block.loops;
+        }
+
+        block.visited = true;
+        block.active = true;
+
+        int loops = 0;
+        for (Block successor : block.successors) {
+            // Recursively process successors.
+            loops |= computeBlockOrder(successor);
+        }
+
+        if (block.isLoopHeader) {
+            assert Long.bitCount(block.loops) == 1;
+            loops &= ~block.loops;
+        }
+
+        block.loops = loops;
+        block.active = false;
+        blocks.add(block);
+
+        return loops;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeLookupSwitch.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.java;
+
+/**
+ * A utility for processing {@link Bytecodes#LOOKUPSWITCH} bytecodes.
+ */
+class BytecodeLookupSwitch extends BytecodeSwitch {
+    private static final int OFFSET_TO_NUMBER_PAIRS = 4;
+    private static final int OFFSET_TO_FIRST_PAIR_MATCH = 8;
+    private static final int OFFSET_TO_FIRST_PAIR_OFFSET = 12;
+    private static final int PAIR_SIZE = 8;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeLookupSwitch(BytecodeStream stream, int bci) {
+        super(stream, bci);
+    }
+
+    /**
+     * Constructor for a bytecode array.
+     * @param code the bytecode array containing the switch instruction.
+     * @param bci the index in the array of the switch instruction
+     */
+    public BytecodeLookupSwitch(byte[] code, int bci) {
+        super(code, bci);
+    }
+
+    @Override
+    public int defaultOffset() {
+        return readWord(alignedBci);
+    }
+
+    @Override
+    public int offsetAt(int i) {
+        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_OFFSET + PAIR_SIZE * i);
+    }
+
+    @Override
+    public int keyAt(int i) {
+        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * i);
+    }
+
+    @Override
+    public int numberOfCases() {
+        return readWord(alignedBci + OFFSET_TO_NUMBER_PAIRS);
+    }
+
+    @Override
+    public int size() {
+        return alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * numberOfCases() - bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeStream.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,197 @@
+/*
+ * 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.java;
+
+/**
+ * A utility class that makes iterating over bytecodes and reading operands
+ * simpler and less error prone. For example, it handles the {@link Bytecodes#WIDE} instruction
+ * and wide variants of instructions internally.
+ */
+public final class BytecodeStream {
+
+    private final byte[] code;
+    private int opcode;
+    private int curBCI;
+    private int nextBCI;
+
+    /**
+     * Creates a new {@code BytecodeStream} for the specified bytecode.
+     * @param code the array of bytes that contains the bytecode
+     */
+    public BytecodeStream(byte[] code) {
+        assert code != null;
+        this.code = code;
+        setBCI(0);
+    }
+
+    /**
+     * Advances to the next bytecode.
+     */
+    public void next() {
+        setBCI(nextBCI);
+    }
+
+    /**
+     * Gets the next bytecode index (no side-effects).
+     * @return the next bytecode index
+     */
+    public int nextBCI() {
+        return nextBCI;
+    }
+
+    /**
+     * Gets the current bytecode index.
+     * @return the current bytecode index
+     */
+    public int currentBCI() {
+        return curBCI;
+    }
+
+    /**
+     * Gets the bytecode index of the end of the code.
+     * @return the index of the end of the code
+     */
+    public int endBCI() {
+        return code.length;
+    }
+
+    /**
+     * Gets the current opcode. This method will never return the
+     * {@link Bytecodes#WIDE WIDE} opcode, but will instead
+     * return the opcode that is modified by the {@code WIDE} opcode.
+     * @return the current opcode; {@link Bytecodes#END} if at or beyond the end of the code
+     */
+    public int currentBC() {
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beU1(code, curBCI + 1);
+        } else {
+            return opcode;
+        }
+    }
+
+    /**
+     * Reads the index of a local variable for one of the load or store instructions.
+     * The WIDE modifier is handled internally.
+     * @return the index of the local variable
+     */
+    public int readLocalIndex() {
+        // read local variable index for load/store
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beU2(code, curBCI + 2);
+        }
+        return Bytes.beU1(code, curBCI + 1);
+    }
+
+    /**
+     * Read the delta for an {@link Bytecodes#IINC} bytecode.
+     * @return the delta for the {@code IINC}
+     */
+    public int readIncrement() {
+        // read the delta for the iinc bytecode
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beS2(code, curBCI + 4);
+        }
+        return Bytes.beS1(code, curBCI + 2);
+    }
+
+    /**
+     * Read the destination of a {@link Bytecodes#GOTO} or {@code IF} instructions.
+     * @return the destination bytecode index
+     */
+    public int readBranchDest() {
+        // reads the destination for a branch bytecode
+        return curBCI + Bytes.beS2(code, curBCI + 1);
+    }
+
+    /**
+     * Read the destination of a {@link Bytecodes#GOTO_W} or {@link Bytecodes#JSR_W} instructions.
+     * @return the destination bytecode index
+     */
+    public int readFarBranchDest() {
+        // reads the destination for a wide branch bytecode
+        return curBCI + Bytes.beS4(code, curBCI + 1);
+    }
+
+    /**
+     * Read a signed 4-byte integer from the bytecode stream at the specified bytecode index.
+     * @param bci the bytecode index
+     * @return the integer value
+     */
+    public int readInt(int bci) {
+        // reads a 4-byte signed value
+        return Bytes.beS4(code, bci);
+    }
+
+    /**
+     * Reads an unsigned, 1-byte value from the bytecode stream at the specified bytecode index.
+     * @param bci the bytecode index
+     * @return the byte
+     */
+    public int readUByte(int bci) {
+        return Bytes.beU1(code, bci);
+    }
+
+    /**
+     * Reads a constant pool index for the current instruction.
+     * @return the constant pool index
+     */
+    public char readCPI() {
+        if (opcode == Bytecodes.LDC) {
+            return (char) Bytes.beU1(code, curBCI + 1);
+        }
+        return (char) Bytes.beU2(code, curBCI + 1);
+    }
+
+    /**
+     * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH).
+     * @return the byte
+     */
+    public byte readByte() {
+        return code[curBCI + 1];
+    }
+
+    /**
+     * Reads a signed, 2-byte short for the current instruction (e.g. SIPUSH).
+     * @return the short value
+     */
+    public short readShort() {
+        return (short) Bytes.beS2(code, curBCI + 1);
+    }
+
+    /**
+     * Sets the bytecode index to the specified value.
+     * If {@code bci} is beyond the end of the array, {@link #currentBC} will return
+     * {@link Bytecodes#END} and other methods may throw {@link ArrayIndexOutOfBoundsException}.
+     * @param bci the new bytecode index
+     */
+    public void setBCI(int bci) {
+        curBCI = bci;
+        if (curBCI < code.length) {
+            opcode = Bytes.beU1(code, bci);
+            nextBCI = bci + Bytecodes.lengthOf(code, bci);
+        } else {
+            opcode = Bytecodes.END;
+            nextBCI = curBCI;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeSwitch.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,139 @@
+/*
+ * 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.java;
+
+/**
+ * An abstract class that provides the state and methods common to {@link Bytecodes#LOOKUPSWITCH}
+ * and {@link Bytecodes#TABLESWITCH} instructions.
+ */
+public abstract class BytecodeSwitch {
+    /**
+     * The {@link BytecodeStream} containing bytecode array or {@code null} if {@link #code} is not {@code null}.
+     */
+    private final BytecodeStream stream;
+    /**
+     * The bytecode array or {@code null} if {@link #stream} is not {@code null}.
+     */
+    private final byte[] code;
+    /**
+     * Index of start of switch instruction.
+     */
+    protected final int bci;
+    /**
+     * Index of the start of the additional data for the switch instruction, aligned to a multiple of four from the method start.
+     */
+    protected final int alignedBci;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeSwitch(BytecodeStream stream, int bci) {
+        this.alignedBci = (bci + 4) & 0xfffffffc;
+        this.stream = stream;
+        this.code = null;
+        this.bci = bci;
+    }
+
+    /**
+     * Constructor for a bytecode array.
+     * @param code the bytecode array containing the switch instruction.
+     * @param bci the index in the array of the switch instruction
+     */
+    public BytecodeSwitch(byte[] code, int bci) {
+        this.alignedBci = (bci + 4) & 0xfffffffc;
+        this.stream = null;
+        this.code = code;
+        this.bci = bci;
+    }
+
+    /**
+     * Gets the current bytecode index.
+     * @return the current bytecode index
+     */
+    public int bci() {
+        return bci;
+    }
+
+    /**
+     * Gets the index of the instruction denoted by the {@code i}'th switch target.
+     * @param i index of the switch target
+     * @return the index of the instruction denoted by the {@code i}'th switch target
+     */
+    public int targetAt(int i) {
+        return bci + offsetAt(i);
+    }
+
+    /**
+     * Gets the index of the instruction for the default switch target.
+     * @return the index of the instruction for the default switch target
+     */
+    public int defaultTarget() {
+        return bci + defaultOffset();
+    }
+
+    /**
+     * Gets the offset from the start of the switch instruction to the default switch target.
+     * @return the offset to the default switch target
+     */
+    public abstract int defaultOffset();
+
+    /**
+     * Gets the key at {@code i}'th switch target index.
+     * @param i the switch target index
+     * @return the key at {@code i}'th switch target index
+     */
+    public abstract int keyAt(int i);
+
+    /**
+     * Gets the offset from the start of the switch instruction for the {@code i}'th switch target.
+     * @param i the switch target index
+     * @return the offset to the {@code i}'th switch target
+     */
+    public abstract int offsetAt(int i);
+
+    /**
+     * Gets the number of switch targets.
+     * @return the number of switch targets
+     */
+    public abstract int numberOfCases();
+
+    /**
+     * Gets the total size in bytes of the switch instruction.
+     * @return the total size in bytes of the switch instruction
+     */
+    public abstract int size();
+
+    /**
+     * Reads the signed value at given bytecode index.
+     * @param readBci the start index of the value to retrieve
+     * @return the signed, 4-byte value in the bytecode array starting at {@code bci}
+     */
+    protected int readWord(int readBci) {
+        if (code != null) {
+            return Bytes.beS4(code, readBci);
+        }
+        return stream.readInt(readBci);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeTableSwitch.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.java;
+
+/**
+ * A utility for processing {@link Bytecodes#TABLESWITCH} bytecodes.
+ */
+public class BytecodeTableSwitch extends BytecodeSwitch {
+    private static final int OFFSET_TO_LOW_KEY = 4;
+    private static final int OFFSET_TO_HIGH_KEY = 8;
+    private static final int OFFSET_TO_FIRST_JUMP_OFFSET = 12;
+    private static final int JUMP_OFFSET_SIZE = 4;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeTableSwitch(BytecodeStream stream, int bci) {
+        super(stream, bci);
+    }
+
+    /**
+     * Constructor for a bytecode array.
+     * @param code the bytecode array containing the switch instruction.
+     * @param bci the index in the array of the switch instruction
+     */
+    public BytecodeTableSwitch(byte[] code, int bci) {
+        super(code, bci);
+    }
+
+    /**
+     * Gets the low key of the table switch.
+     * @return the low key
+     */
+    public int lowKey() {
+        return readWord(alignedBci + OFFSET_TO_LOW_KEY);
+    }
+
+    /**
+     * Gets the high key of the table switch.
+     * @return the high key
+     */
+    public int highKey() {
+        return readWord(alignedBci + OFFSET_TO_HIGH_KEY);
+    }
+
+    @Override
+    public int keyAt(int i) {
+        return lowKey() + i;
+    }
+
+    @Override
+    public int defaultOffset() {
+        return readWord(alignedBci);
+    }
+
+    @Override
+    public int offsetAt(int i) {
+        return readWord(alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * i);
+    }
+
+    @Override
+    public int numberOfCases() {
+        return highKey() - lowKey() + 1;
+    }
+
+    @Override
+    public int size() {
+        return alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * numberOfCases() - bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytecodes.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,961 @@
+/*
+ * 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.java;
+
+import static com.oracle.max.graal.java.Bytecodes.Flags.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.regex.*;
+
+/**
+ * The definitions of the bytecodes that are valid input to the compiler and
+ * related utility methods. This comprises two groups: the standard Java
+ * bytecodes defined by <a href=
+ * "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html">
+ * Java Virtual Machine Specification</a>, and a set of <i>extended</i>
+ * bytecodes that support low-level programming, for example, memory barriers.
+ *
+ * The extended bytecodes are one or three bytes in size. The one-byte bytecodes
+ * follow the values in the standard set, with no gap. The three-byte extended
+ * bytecodes share a common first byte and carry additional instruction-specific
+ * information in the second and third bytes.
+ */
+public class Bytecodes {
+    public static final int NOP                  =   0; // 0x00
+    public static final int ACONST_NULL          =   1; // 0x01
+    public static final int ICONST_M1            =   2; // 0x02
+    public static final int ICONST_0             =   3; // 0x03
+    public static final int ICONST_1             =   4; // 0x04
+    public static final int ICONST_2             =   5; // 0x05
+    public static final int ICONST_3             =   6; // 0x06
+    public static final int ICONST_4             =   7; // 0x07
+    public static final int ICONST_5             =   8; // 0x08
+    public static final int LCONST_0             =   9; // 0x09
+    public static final int LCONST_1             =  10; // 0x0A
+    public static final int FCONST_0             =  11; // 0x0B
+    public static final int FCONST_1             =  12; // 0x0C
+    public static final int FCONST_2             =  13; // 0x0D
+    public static final int DCONST_0             =  14; // 0x0E
+    public static final int DCONST_1             =  15; // 0x0F
+    public static final int BIPUSH               =  16; // 0x10
+    public static final int SIPUSH               =  17; // 0x11
+    public static final int LDC                  =  18; // 0x12
+    public static final int LDC_W                =  19; // 0x13
+    public static final int LDC2_W               =  20; // 0x14
+    public static final int ILOAD                =  21; // 0x15
+    public static final int LLOAD                =  22; // 0x16
+    public static final int FLOAD                =  23; // 0x17
+    public static final int DLOAD                =  24; // 0x18
+    public static final int ALOAD                =  25; // 0x19
+    public static final int ILOAD_0              =  26; // 0x1A
+    public static final int ILOAD_1              =  27; // 0x1B
+    public static final int ILOAD_2              =  28; // 0x1C
+    public static final int ILOAD_3              =  29; // 0x1D
+    public static final int LLOAD_0              =  30; // 0x1E
+    public static final int LLOAD_1              =  31; // 0x1F
+    public static final int LLOAD_2              =  32; // 0x20
+    public static final int LLOAD_3              =  33; // 0x21
+    public static final int FLOAD_0              =  34; // 0x22
+    public static final int FLOAD_1              =  35; // 0x23
+    public static final int FLOAD_2              =  36; // 0x24
+    public static final int FLOAD_3              =  37; // 0x25
+    public static final int DLOAD_0              =  38; // 0x26
+    public static final int DLOAD_1              =  39; // 0x27
+    public static final int DLOAD_2              =  40; // 0x28
+    public static final int DLOAD_3              =  41; // 0x29
+    public static final int ALOAD_0              =  42; // 0x2A
+    public static final int ALOAD_1              =  43; // 0x2B
+    public static final int ALOAD_2              =  44; // 0x2C
+    public static final int ALOAD_3              =  45; // 0x2D
+    public static final int IALOAD               =  46; // 0x2E
+    public static final int LALOAD               =  47; // 0x2F
+    public static final int FALOAD               =  48; // 0x30
+    public static final int DALOAD               =  49; // 0x31
+    public static final int AALOAD               =  50; // 0x32
+    public static final int BALOAD               =  51; // 0x33
+    public static final int CALOAD               =  52; // 0x34
+    public static final int SALOAD               =  53; // 0x35
+    public static final int ISTORE               =  54; // 0x36
+    public static final int LSTORE               =  55; // 0x37
+    public static final int FSTORE               =  56; // 0x38
+    public static final int DSTORE               =  57; // 0x39
+    public static final int ASTORE               =  58; // 0x3A
+    public static final int ISTORE_0             =  59; // 0x3B
+    public static final int ISTORE_1             =  60; // 0x3C
+    public static final int ISTORE_2             =  61; // 0x3D
+    public static final int ISTORE_3             =  62; // 0x3E
+    public static final int LSTORE_0             =  63; // 0x3F
+    public static final int LSTORE_1             =  64; // 0x40
+    public static final int LSTORE_2             =  65; // 0x41
+    public static final int LSTORE_3             =  66; // 0x42
+    public static final int FSTORE_0             =  67; // 0x43
+    public static final int FSTORE_1             =  68; // 0x44
+    public static final int FSTORE_2             =  69; // 0x45
+    public static final int FSTORE_3             =  70; // 0x46
+    public static final int DSTORE_0             =  71; // 0x47
+    public static final int DSTORE_1             =  72; // 0x48
+    public static final int DSTORE_2             =  73; // 0x49
+    public static final int DSTORE_3             =  74; // 0x4A
+    public static final int ASTORE_0             =  75; // 0x4B
+    public static final int ASTORE_1             =  76; // 0x4C
+    public static final int ASTORE_2             =  77; // 0x4D
+    public static final int ASTORE_3             =  78; // 0x4E
+    public static final int IASTORE              =  79; // 0x4F
+    public static final int LASTORE              =  80; // 0x50
+    public static final int FASTORE              =  81; // 0x51
+    public static final int DASTORE              =  82; // 0x52
+    public static final int AASTORE              =  83; // 0x53
+    public static final int BASTORE              =  84; // 0x54
+    public static final int CASTORE              =  85; // 0x55
+    public static final int SASTORE              =  86; // 0x56
+    public static final int POP                  =  87; // 0x57
+    public static final int POP2                 =  88; // 0x58
+    public static final int DUP                  =  89; // 0x59
+    public static final int DUP_X1               =  90; // 0x5A
+    public static final int DUP_X2               =  91; // 0x5B
+    public static final int DUP2                 =  92; // 0x5C
+    public static final int DUP2_X1              =  93; // 0x5D
+    public static final int DUP2_X2              =  94; // 0x5E
+    public static final int SWAP                 =  95; // 0x5F
+    public static final int IADD                 =  96; // 0x60
+    public static final int LADD                 =  97; // 0x61
+    public static final int FADD                 =  98; // 0x62
+    public static final int DADD                 =  99; // 0x63
+    public static final int ISUB                 = 100; // 0x64
+    public static final int LSUB                 = 101; // 0x65
+    public static final int FSUB                 = 102; // 0x66
+    public static final int DSUB                 = 103; // 0x67
+    public static final int IMUL                 = 104; // 0x68
+    public static final int LMUL                 = 105; // 0x69
+    public static final int FMUL                 = 106; // 0x6A
+    public static final int DMUL                 = 107; // 0x6B
+    public static final int IDIV                 = 108; // 0x6C
+    public static final int LDIV                 = 109; // 0x6D
+    public static final int FDIV                 = 110; // 0x6E
+    public static final int DDIV                 = 111; // 0x6F
+    public static final int IREM                 = 112; // 0x70
+    public static final int LREM                 = 113; // 0x71
+    public static final int FREM                 = 114; // 0x72
+    public static final int DREM                 = 115; // 0x73
+    public static final int INEG                 = 116; // 0x74
+    public static final int LNEG                 = 117; // 0x75
+    public static final int FNEG                 = 118; // 0x76
+    public static final int DNEG                 = 119; // 0x77
+    public static final int ISHL                 = 120; // 0x78
+    public static final int LSHL                 = 121; // 0x79
+    public static final int ISHR                 = 122; // 0x7A
+    public static final int LSHR                 = 123; // 0x7B
+    public static final int IUSHR                = 124; // 0x7C
+    public static final int LUSHR                = 125; // 0x7D
+    public static final int IAND                 = 126; // 0x7E
+    public static final int LAND                 = 127; // 0x7F
+    public static final int IOR                  = 128; // 0x80
+    public static final int LOR                  = 129; // 0x81
+    public static final int IXOR                 = 130; // 0x82
+    public static final int LXOR                 = 131; // 0x83
+    public static final int IINC                 = 132; // 0x84
+    public static final int I2L                  = 133; // 0x85
+    public static final int I2F                  = 134; // 0x86
+    public static final int I2D                  = 135; // 0x87
+    public static final int L2I                  = 136; // 0x88
+    public static final int L2F                  = 137; // 0x89
+    public static final int L2D                  = 138; // 0x8A
+    public static final int F2I                  = 139; // 0x8B
+    public static final int F2L                  = 140; // 0x8C
+    public static final int F2D                  = 141; // 0x8D
+    public static final int D2I                  = 142; // 0x8E
+    public static final int D2L                  = 143; // 0x8F
+    public static final int D2F                  = 144; // 0x90
+    public static final int I2B                  = 145; // 0x91
+    public static final int I2C                  = 146; // 0x92
+    public static final int I2S                  = 147; // 0x93
+    public static final int LCMP                 = 148; // 0x94
+    public static final int FCMPL                = 149; // 0x95
+    public static final int FCMPG                = 150; // 0x96
+    public static final int DCMPL                = 151; // 0x97
+    public static final int DCMPG                = 152; // 0x98
+    public static final int IFEQ                 = 153; // 0x99
+    public static final int IFNE                 = 154; // 0x9A
+    public static final int IFLT                 = 155; // 0x9B
+    public static final int IFGE                 = 156; // 0x9C
+    public static final int IFGT                 = 157; // 0x9D
+    public static final int IFLE                 = 158; // 0x9E
+    public static final int IF_ICMPEQ            = 159; // 0x9F
+    public static final int IF_ICMPNE            = 160; // 0xA0
+    public static final int IF_ICMPLT            = 161; // 0xA1
+    public static final int IF_ICMPGE            = 162; // 0xA2
+    public static final int IF_ICMPGT            = 163; // 0xA3
+    public static final int IF_ICMPLE            = 164; // 0xA4
+    public static final int IF_ACMPEQ            = 165; // 0xA5
+    public static final int IF_ACMPNE            = 166; // 0xA6
+    public static final int GOTO                 = 167; // 0xA7
+    public static final int JSR                  = 168; // 0xA8
+    public static final int RET                  = 169; // 0xA9
+    public static final int TABLESWITCH          = 170; // 0xAA
+    public static final int LOOKUPSWITCH         = 171; // 0xAB
+    public static final int IRETURN              = 172; // 0xAC
+    public static final int LRETURN              = 173; // 0xAD
+    public static final int FRETURN              = 174; // 0xAE
+    public static final int DRETURN              = 175; // 0xAF
+    public static final int ARETURN              = 176; // 0xB0
+    public static final int RETURN               = 177; // 0xB1
+    public static final int GETSTATIC            = 178; // 0xB2
+    public static final int PUTSTATIC            = 179; // 0xB3
+    public static final int GETFIELD             = 180; // 0xB4
+    public static final int PUTFIELD             = 181; // 0xB5
+    public static final int INVOKEVIRTUAL        = 182; // 0xB6
+    public static final int INVOKESPECIAL        = 183; // 0xB7
+    public static final int INVOKESTATIC         = 184; // 0xB8
+    public static final int INVOKEINTERFACE      = 185; // 0xB9
+    public static final int XXXUNUSEDXXX         = 186; // 0xBA
+    public static final int NEW                  = 187; // 0xBB
+    public static final int NEWARRAY             = 188; // 0xBC
+    public static final int ANEWARRAY            = 189; // 0xBD
+    public static final int ARRAYLENGTH          = 190; // 0xBE
+    public static final int ATHROW               = 191; // 0xBF
+    public static final int CHECKCAST            = 192; // 0xC0
+    public static final int INSTANCEOF           = 193; // 0xC1
+    public static final int MONITORENTER         = 194; // 0xC2
+    public static final int MONITOREXIT          = 195; // 0xC3
+    public static final int WIDE                 = 196; // 0xC4
+    public static final int MULTIANEWARRAY       = 197; // 0xC5
+    public static final int IFNULL               = 198; // 0xC6
+    public static final int IFNONNULL            = 199; // 0xC7
+    public static final int GOTO_W               = 200; // 0xC8
+    public static final int JSR_W                = 201; // 0xC9
+    public static final int BREAKPOINT           = 202; // 0xCA
+
+    public static final int ILLEGAL = 255;
+    public static final int END = 256;
+
+    /**
+     * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
+     * <pre>
+     *     for (int opcode = 0; opcode <= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
+     *         //
+     *     }
+     * </pre>
+     */
+    public static final int LAST_JVM_OPCODE = JSR_W;
+
+    /**
+     * A collection of flags describing various bytecode attributes.
+     */
+    static class Flags {
+
+        /**
+         * Denotes an instruction that ends a basic block and does not let control flow fall through to its lexical successor.
+         */
+        static final int STOP = 0x00000001;
+
+        /**
+         * Denotes an instruction that ends a basic block and may let control flow fall through to its lexical successor.
+         * In practice this means it is a conditional branch.
+         */
+        static final int FALL_THROUGH = 0x00000002;
+
+        /**
+         * Denotes an instruction that has a 2 or 4 byte operand that is an offset to another instruction in the same method.
+         * This does not include the {@link Bytecodes#TABLESWITCH} or {@link Bytecodes#LOOKUPSWITCH} instructions.
+         */
+        static final int BRANCH = 0x00000004;
+
+        /**
+         * Denotes an instruction that reads the value of a static or instance field.
+         */
+        static final int FIELD_READ = 0x00000008;
+
+        /**
+         * Denotes an instruction that writes the value of a static or instance field.
+         */
+        static final int FIELD_WRITE = 0x00000010;
+
+        /**
+         * Denotes an instruction that is not defined in the JVM specification.
+         */
+        static final int EXTENSION = 0x00000020;
+
+        /**
+         * Denotes an instruction that can cause a trap.
+         */
+        static final int TRAP        = 0x00000080;
+        /**
+         * Denotes an instruction that is commutative.
+         */
+        static final int COMMUTATIVE = 0x00000100;
+        /**
+         * Denotes an instruction that is associative.
+         */
+        static final int ASSOCIATIVE = 0x00000200;
+        /**
+         * Denotes an instruction that loads an operand.
+         */
+        static final int LOAD        = 0x00000400;
+        /**
+         * Denotes an instruction that stores an operand.
+         */
+        static final int STORE       = 0x00000800;
+        /**
+         * Denotes the 4 INVOKE* instructions.
+         */
+        static final int INVOKE       = 0x00001000;
+    }
+
+    // Performs a sanity check that none of the flags overlap.
+    static {
+        int allFlags = 0;
+        try {
+            for (Field field : Flags.class.getDeclaredFields()) {
+                int flagsFilter = Modifier.FINAL | Modifier.STATIC;
+                if ((field.getModifiers() & flagsFilter) == flagsFilter) {
+                    assert field.getType() == int.class : "Only " + field;
+                    final int flag = field.getInt(null);
+                    assert flag != 0;
+                    assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag";
+                    allFlags |= flag;
+                }
+            }
+        } catch (Exception e) {
+            throw new InternalError(e.toString());
+        }
+    }
+
+    /**
+     * A array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic.
+     * This will include the root instruction for the three-byte extended instructions.
+     */
+    private static final String[] nameArray = new String[256];
+
+    /**
+     * A array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction.
+     */
+    private static final int[] flagsArray = new int[256];
+
+    /**
+     * A array that maps from a bytecode value to the length in bytes for the corresponding instruction.
+     */
+    private static final int[] lengthArray = new int[256];
+
+    // Checkstyle: stop
+    static {
+        def(NOP                 , "nop"             , "b"    );
+        def(ACONST_NULL         , "aconst_null"     , "b"    );
+        def(ICONST_M1           , "iconst_m1"       , "b"    );
+        def(ICONST_0            , "iconst_0"        , "b"    );
+        def(ICONST_1            , "iconst_1"        , "b"    );
+        def(ICONST_2            , "iconst_2"        , "b"    );
+        def(ICONST_3            , "iconst_3"        , "b"    );
+        def(ICONST_4            , "iconst_4"        , "b"    );
+        def(ICONST_5            , "iconst_5"        , "b"    );
+        def(LCONST_0            , "lconst_0"        , "b"    );
+        def(LCONST_1            , "lconst_1"        , "b"    );
+        def(FCONST_0            , "fconst_0"        , "b"    );
+        def(FCONST_1            , "fconst_1"        , "b"    );
+        def(FCONST_2            , "fconst_2"        , "b"    );
+        def(DCONST_0            , "dconst_0"        , "b"    );
+        def(DCONST_1            , "dconst_1"        , "b"    );
+        def(BIPUSH              , "bipush"          , "bc"   );
+        def(SIPUSH              , "sipush"          , "bcc"  );
+        def(LDC                 , "ldc"             , "bi"   , TRAP);
+        def(LDC_W               , "ldc_w"           , "bii"  , TRAP);
+        def(LDC2_W              , "ldc2_w"          , "bii"  , TRAP);
+        def(ILOAD               , "iload"           , "bi"   , LOAD);
+        def(LLOAD               , "lload"           , "bi"   , LOAD);
+        def(FLOAD               , "fload"           , "bi"   , LOAD);
+        def(DLOAD               , "dload"           , "bi"   , LOAD);
+        def(ALOAD               , "aload"           , "bi"   , LOAD);
+        def(ILOAD_0             , "iload_0"         , "b"    , LOAD);
+        def(ILOAD_1             , "iload_1"         , "b"    , LOAD);
+        def(ILOAD_2             , "iload_2"         , "b"    , LOAD);
+        def(ILOAD_3             , "iload_3"         , "b"    , LOAD);
+        def(LLOAD_0             , "lload_0"         , "b"    , LOAD);
+        def(LLOAD_1             , "lload_1"         , "b"    , LOAD);
+        def(LLOAD_2             , "lload_2"         , "b"    , LOAD);
+        def(LLOAD_3             , "lload_3"         , "b"    , LOAD);
+        def(FLOAD_0             , "fload_0"         , "b"    , LOAD);
+        def(FLOAD_1             , "fload_1"         , "b"    , LOAD);
+        def(FLOAD_2             , "fload_2"         , "b"    , LOAD);
+        def(FLOAD_3             , "fload_3"         , "b"    , LOAD);
+        def(DLOAD_0             , "dload_0"         , "b"    , LOAD);
+        def(DLOAD_1             , "dload_1"         , "b"    , LOAD);
+        def(DLOAD_2             , "dload_2"         , "b"    , LOAD);
+        def(DLOAD_3             , "dload_3"         , "b"    , LOAD);
+        def(ALOAD_0             , "aload_0"         , "b"    , LOAD);
+        def(ALOAD_1             , "aload_1"         , "b"    , LOAD);
+        def(ALOAD_2             , "aload_2"         , "b"    , LOAD);
+        def(ALOAD_3             , "aload_3"         , "b"    , LOAD);
+        def(IALOAD              , "iaload"          , "b"    , TRAP);
+        def(LALOAD              , "laload"          , "b"    , TRAP);
+        def(FALOAD              , "faload"          , "b"    , TRAP);
+        def(DALOAD              , "daload"          , "b"    , TRAP);
+        def(AALOAD              , "aaload"          , "b"    , TRAP);
+        def(BALOAD              , "baload"          , "b"    , TRAP);
+        def(CALOAD              , "caload"          , "b"    , TRAP);
+        def(SALOAD              , "saload"          , "b"    , TRAP);
+        def(ISTORE              , "istore"          , "bi"   , STORE);
+        def(LSTORE              , "lstore"          , "bi"   , STORE);
+        def(FSTORE              , "fstore"          , "bi"   , STORE);
+        def(DSTORE              , "dstore"          , "bi"   , STORE);
+        def(ASTORE              , "astore"          , "bi"   , STORE);
+        def(ISTORE_0            , "istore_0"        , "b"    , STORE);
+        def(ISTORE_1            , "istore_1"        , "b"    , STORE);
+        def(ISTORE_2            , "istore_2"        , "b"    , STORE);
+        def(ISTORE_3            , "istore_3"        , "b"    , STORE);
+        def(LSTORE_0            , "lstore_0"        , "b"    , STORE);
+        def(LSTORE_1            , "lstore_1"        , "b"    , STORE);
+        def(LSTORE_2            , "lstore_2"        , "b"    , STORE);
+        def(LSTORE_3            , "lstore_3"        , "b"    , STORE);
+        def(FSTORE_0            , "fstore_0"        , "b"    , STORE);
+        def(FSTORE_1            , "fstore_1"        , "b"    , STORE);
+        def(FSTORE_2            , "fstore_2"        , "b"    , STORE);
+        def(FSTORE_3            , "fstore_3"        , "b"    , STORE);
+        def(DSTORE_0            , "dstore_0"        , "b"    , STORE);
+        def(DSTORE_1            , "dstore_1"        , "b"    , STORE);
+        def(DSTORE_2            , "dstore_2"        , "b"    , STORE);
+        def(DSTORE_3            , "dstore_3"        , "b"    , STORE);
+        def(ASTORE_0            , "astore_0"        , "b"    , STORE);
+        def(ASTORE_1            , "astore_1"        , "b"    , STORE);
+        def(ASTORE_2            , "astore_2"        , "b"    , STORE);
+        def(ASTORE_3            , "astore_3"        , "b"    , STORE);
+        def(IASTORE             , "iastore"         , "b"    , TRAP);
+        def(LASTORE             , "lastore"         , "b"    , TRAP);
+        def(FASTORE             , "fastore"         , "b"    , TRAP);
+        def(DASTORE             , "dastore"         , "b"    , TRAP);
+        def(AASTORE             , "aastore"         , "b"    , TRAP);
+        def(BASTORE             , "bastore"         , "b"    , TRAP);
+        def(CASTORE             , "castore"         , "b"    , TRAP);
+        def(SASTORE             , "sastore"         , "b"    , TRAP);
+        def(POP                 , "pop"             , "b"    );
+        def(POP2                , "pop2"            , "b"    );
+        def(DUP                 , "dup"             , "b"    );
+        def(DUP_X1              , "dup_x1"          , "b"    );
+        def(DUP_X2              , "dup_x2"          , "b"    );
+        def(DUP2                , "dup2"            , "b"    );
+        def(DUP2_X1             , "dup2_x1"         , "b"    );
+        def(DUP2_X2             , "dup2_x2"         , "b"    );
+        def(SWAP                , "swap"            , "b"    );
+        def(IADD                , "iadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(LADD                , "ladd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(FADD                , "fadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(DADD                , "dadd"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(ISUB                , "isub"            , "b"    );
+        def(LSUB                , "lsub"            , "b"    );
+        def(FSUB                , "fsub"            , "b"    );
+        def(DSUB                , "dsub"            , "b"    );
+        def(IMUL                , "imul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(LMUL                , "lmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(FMUL                , "fmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(DMUL                , "dmul"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(IDIV                , "idiv"            , "b"    , TRAP);
+        def(LDIV                , "ldiv"            , "b"    , TRAP);
+        def(FDIV                , "fdiv"            , "b"    );
+        def(DDIV                , "ddiv"            , "b"    );
+        def(IREM                , "irem"            , "b"    , TRAP);
+        def(LREM                , "lrem"            , "b"    , TRAP);
+        def(FREM                , "frem"            , "b"    );
+        def(DREM                , "drem"            , "b"    );
+        def(INEG                , "ineg"            , "b"    );
+        def(LNEG                , "lneg"            , "b"    );
+        def(FNEG                , "fneg"            , "b"    );
+        def(DNEG                , "dneg"            , "b"    );
+        def(ISHL                , "ishl"            , "b"    );
+        def(LSHL                , "lshl"            , "b"    );
+        def(ISHR                , "ishr"            , "b"    );
+        def(LSHR                , "lshr"            , "b"    );
+        def(IUSHR               , "iushr"           , "b"    );
+        def(LUSHR               , "lushr"           , "b"    );
+        def(IAND                , "iand"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(LAND                , "land"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(IOR                 , "ior"             , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(LOR                 , "lor"             , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(IXOR                , "ixor"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(LXOR                , "lxor"            , "b"    , COMMUTATIVE | ASSOCIATIVE);
+        def(IINC                , "iinc"            , "bic"  , LOAD | STORE);
+        def(I2L                 , "i2l"             , "b"    );
+        def(I2F                 , "i2f"             , "b"    );
+        def(I2D                 , "i2d"             , "b"    );
+        def(L2I                 , "l2i"             , "b"    );
+        def(L2F                 , "l2f"             , "b"    );
+        def(L2D                 , "l2d"             , "b"    );
+        def(F2I                 , "f2i"             , "b"    );
+        def(F2L                 , "f2l"             , "b"    );
+        def(F2D                 , "f2d"             , "b"    );
+        def(D2I                 , "d2i"             , "b"    );
+        def(D2L                 , "d2l"             , "b"    );
+        def(D2F                 , "d2f"             , "b"    );
+        def(I2B                 , "i2b"             , "b"    );
+        def(I2C                 , "i2c"             , "b"    );
+        def(I2S                 , "i2s"             , "b"    );
+        def(LCMP                , "lcmp"            , "b"    );
+        def(FCMPL               , "fcmpl"           , "b"    );
+        def(FCMPG               , "fcmpg"           , "b"    );
+        def(DCMPL               , "dcmpl"           , "b"    );
+        def(DCMPG               , "dcmpg"           , "b"    );
+        def(IFEQ                , "ifeq"            , "boo"  , FALL_THROUGH | BRANCH);
+        def(IFNE                , "ifne"            , "boo"  , FALL_THROUGH | BRANCH);
+        def(IFLT                , "iflt"            , "boo"  , FALL_THROUGH | BRANCH);
+        def(IFGE                , "ifge"            , "boo"  , FALL_THROUGH | BRANCH);
+        def(IFGT                , "ifgt"            , "boo"  , FALL_THROUGH | BRANCH);
+        def(IFLE                , "ifle"            , "boo"  , FALL_THROUGH | BRANCH);
+        def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPNE           , "if_icmpne"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPLT           , "if_icmplt"       , "boo"  , FALL_THROUGH | BRANCH);
+        def(IF_ICMPGE           , "if_icmpge"       , "boo"  , FALL_THROUGH | BRANCH);
+        def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , FALL_THROUGH | BRANCH);
+        def(IF_ICMPLE           , "if_icmple"       , "boo"  , FALL_THROUGH | BRANCH);
+        def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ACMPNE           , "if_acmpne"       , "boo"  , COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(GOTO                , "goto"            , "boo"  , STOP | BRANCH);
+        def(JSR                 , "jsr"             , "boo"  , STOP | BRANCH);
+        def(RET                 , "ret"             , "bi"   , STOP);
+        def(TABLESWITCH         , "tableswitch"     , ""     , STOP);
+        def(LOOKUPSWITCH        , "lookupswitch"    , ""     , STOP);
+        def(IRETURN             , "ireturn"         , "b"    , TRAP | STOP);
+        def(LRETURN             , "lreturn"         , "b"    , TRAP | STOP);
+        def(FRETURN             , "freturn"         , "b"    , TRAP | STOP);
+        def(DRETURN             , "dreturn"         , "b"    , TRAP | STOP);
+        def(ARETURN             , "areturn"         , "b"    , TRAP | STOP);
+        def(RETURN              , "return"          , "b"    , TRAP | STOP);
+        def(GETSTATIC           , "getstatic"       , "bjj"  , TRAP | FIELD_READ);
+        def(PUTSTATIC           , "putstatic"       , "bjj"  , TRAP | FIELD_WRITE);
+        def(GETFIELD            , "getfield"        , "bjj"  , TRAP | FIELD_READ);
+        def(PUTFIELD            , "putfield"        , "bjj"  , TRAP | FIELD_WRITE);
+        def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , TRAP | INVOKE);
+        def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , TRAP | INVOKE);
+        def(INVOKESTATIC        , "invokestatic"    , "bjj"  , TRAP | INVOKE);
+        def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", TRAP | INVOKE);
+        def(XXXUNUSEDXXX        , "xxxunusedxxx"    , ""     );
+        def(NEW                 , "new"             , "bii"  , TRAP);
+        def(NEWARRAY            , "newarray"        , "bc"   , TRAP);
+        def(ANEWARRAY           , "anewarray"       , "bii"  , TRAP);
+        def(ARRAYLENGTH         , "arraylength"     , "b"    , TRAP);
+        def(ATHROW              , "athrow"          , "b"    , TRAP | STOP);
+        def(CHECKCAST           , "checkcast"       , "bii"  , TRAP);
+        def(INSTANCEOF          , "instanceof"      , "bii"  , TRAP);
+        def(MONITORENTER        , "monitorenter"    , "b"    , TRAP);
+        def(MONITOREXIT         , "monitorexit"     , "b"    , TRAP);
+        def(WIDE                , "wide"            , ""     );
+        def(MULTIANEWARRAY      , "multianewarray"  , "biic" , TRAP);
+        def(IFNULL              , "ifnull"          , "boo"  , FALL_THROUGH | BRANCH);
+        def(IFNONNULL           , "ifnonnull"       , "boo"  , FALL_THROUGH | BRANCH);
+        def(GOTO_W              , "goto_w"          , "boooo", STOP | BRANCH);
+        def(JSR_W               , "jsr_w"           , "boooo", STOP | BRANCH);
+        def(BREAKPOINT          , "breakpoint"      , "b"    , TRAP);
+    }
+    // Checkstyle: resume
+
+    /**
+     * Determines if an opcode is commutative.
+     * @param opcode the opcode to check
+     * @return {@code true} iff commutative
+     */
+    public static boolean isCommutative(int opcode) {
+        return (flagsArray[opcode & 0xff] & COMMUTATIVE) != 0;
+    }
+
+    /**
+     * Gets the length of an instruction denoted by a given opcode.
+     *
+     * @param opcode an instruction opcode
+     * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a
+     *         variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned.
+     */
+    public static int lengthOf(int opcode) {
+        return lengthArray[opcode & 0xff];
+    }
+
+    /**
+     * Gets the length of an instruction at a given position in a given bytecode array.
+     * This methods handles variable length and {@linkplain #WIDE widened} instructions.
+     *
+     * @param code an array of bytecode
+     * @param bci the position in {@code code} of an instruction's opcode
+     * @return the length of the instruction at position {@code bci} in {@code code}
+     */
+    public static int lengthOf(byte[] code, int bci) {
+        int opcode = Bytes.beU1(code, bci);
+        int length = Bytecodes.lengthArray[opcode & 0xff];
+        if (length == 0) {
+            switch (opcode) {
+                case TABLESWITCH: {
+                    return new BytecodeTableSwitch(code, bci).size();
+                }
+                case LOOKUPSWITCH: {
+                    return new BytecodeLookupSwitch(code, bci).size();
+                }
+                case WIDE: {
+                    int opc = Bytes.beU1(code, bci + 1);
+                    if (opc == RET) {
+                        return 4;
+                    } else if (opc == IINC) {
+                        return 6;
+                    } else {
+                        return 4; // a load or store bytecode
+                    }
+                }
+                default:
+                    throw new Error("unknown variable-length bytecode: " + opcode);
+            }
+        }
+        return length;
+    }
+
+    /**
+     * Gets the lower-case mnemonic for a given opcode.
+     *
+     * @param opcode an opcode
+     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode
+     */
+    public static String nameOf(int opcode) throws IllegalArgumentException {
+        String name = nameArray[opcode & 0xff];
+        if (name == null) {
+            return "<illegal opcode: " + opcode + ">";
+        }
+        return name;
+    }
+
+    /**
+     * Allocation-free version of {@linkplain #nameOf(int)}.
+     * @param opcode an opcode.
+     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode.
+     */
+    public static String baseNameOf(int opcode) {
+        String name = nameArray[opcode & 0xff];
+        if (name == null) {
+            return "<illegal opcode>";
+        }
+        return name;
+    }
+
+    /**
+     * Gets the opcode corresponding to a given mnemonic.
+     *
+     * @param name an opcode mnemonic
+     * @return the opcode corresponding to {@code mnemonic}
+     * @throws IllegalArgumentException if {@code name} does not denote a valid opcode
+     */
+    public static int valueOf(String name) {
+        for (int opcode = 0; opcode < nameArray.length; ++opcode) {
+            if (name.equalsIgnoreCase(nameArray[opcode])) {
+                return opcode;
+            }
+        }
+        throw new IllegalArgumentException("No opcode for " + name);
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that can cause an implicit exception.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise
+     */
+    public static boolean canTrap(int opcode) {
+        return (flagsArray[opcode & 0xff] & TRAP) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise
+     */
+    public static boolean isLoad(int opcode) {
+        return (flagsArray[opcode & 0xff] & LOAD) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall
+     * through to its lexical successor.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} properly ends a basic block
+     */
+    public static boolean isStop(int opcode) {
+        return (flagsArray[opcode & 0xff] & STOP) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that stores a value to a local variable
+     * after popping it from the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
+     */
+    public static boolean isInvoke(int opcode) {
+        return (flagsArray[opcode & 0xff] & INVOKE) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that stores a value to a local variable
+     * after popping it from the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
+     */
+    public static boolean isStore(int opcode) {
+        return (flagsArray[opcode & 0xff] & STORE) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is an instruction that delimits a basic block.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} delimits a basic block
+     */
+    public static boolean isBlockEnd(int opcode) {
+        return (flagsArray[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another
+     * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} is a branch instruction with a single operand
+     */
+    public static boolean isBranch(int opcode) {
+        return (flagsArray[opcode & 0xff] & BRANCH) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes a conditional branch.
+     * @param opcode
+     * @return {@code true} iff {@code opcode} is a conditional branch
+     */
+    public static boolean isConditionalBranch(int opcode) {
+        return (flagsArray[opcode & 0xff] & FALL_THROUGH) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes a standard bytecode. A standard bytecode is
+     * defined in the JVM specification.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} is a standard bytecode
+     */
+    public static boolean isStandard(int opcode) {
+        return (flagsArray[opcode & 0xff] & EXTENSION) == 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an extended bytecode.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} if {@code opcode} is an extended bytecode
+     */
+    public static boolean isExtended(int opcode) {
+        return (flagsArray[opcode & 0xff] & EXTENSION) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is a three-byte extended bytecode.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} if {@code (opcode & ~0xff) != 0}
+     */
+    public static boolean isThreeByteExtended(int opcode) {
+        return (opcode & ~0xff) != 0;
+    }
+
+    /**
+     * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an
+     * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned
+     * instead.
+     *
+     * @param op an opcode
+     * @return the arithmetic operator name
+     */
+    public static String operator(int op) {
+        // Checkstyle: stop
+        switch (op) {
+            // arithmetic ops
+            case IADD : // fall through
+            case LADD : // fall through
+            case FADD : // fall through
+            case DADD : return "+";
+            case ISUB : // fall through
+            case LSUB : // fall through
+            case FSUB : // fall through
+            case DSUB : return "-";
+            case IMUL : // fall through
+            case LMUL : // fall through
+            case FMUL : // fall through
+            case DMUL : return "*";
+            case IDIV : // fall through
+            case LDIV : // fall through
+            case FDIV : // fall through
+            case DDIV : return "/";
+            case IREM : // fall through
+            case LREM : // fall through
+            case FREM : // fall through
+            case DREM : return "%";
+            // shift ops
+            case ISHL : // fall through
+            case LSHL : return "<<";
+            case ISHR : // fall through
+            case LSHR : return ">>";
+            case IUSHR: // fall through
+            case LUSHR: return ">>>";
+            // logic ops
+            case IAND : // fall through
+            case LAND : return "&";
+            case IOR  : // fall through
+            case LOR  : return "|";
+            case IXOR : // fall through
+            case LXOR : return "^";
+        }
+        // Checkstyle: resume
+        return nameOf(op);
+    }
+
+    /**
+     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
+     *
+     * @param name instruction name (should be lower case)
+     * @param format encodes the length of the instruction
+     * @param flagsArray the set of {@link Flags} associated with the instruction
+     */
+    private static void def(int opcode, String name, String format) {
+        def(opcode, name, format, 0);
+    }
+
+    /**
+     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
+     *
+     * @param name instruction name (lower case)
+     * @param format encodes the length of the instruction
+     * @param flags the set of {@link Flags} associated with the instruction
+     */
+    private static void def(int opcode, String name, String format, int flags) {
+        assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode];
+        nameArray[opcode] = name;
+        int instructionLength = format.length();
+        lengthArray[opcode] = instructionLength;
+        Bytecodes.flagsArray[opcode] = flags;
+
+        assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch";
+    }
+
+    /**
+     * Utility for ensuring that the extended opcodes are contiguous and follow on directly
+     * from the standard JVM opcodes. If these conditions do not hold for the input source
+     * file, then it is modified 'in situ' to fix the problem.
+     *
+     * @param args {@code args[0]} is the path to this source file
+     */
+    public static void main(String[] args) throws Exception {
+        Method findWorkspaceDirectory = Class.forName("com.sun.max.ide.JavaProject").getDeclaredMethod("findWorkspaceDirectory");
+        File base = new File((File) findWorkspaceDirectory.invoke(null), "com.oracle.max.cri/src");
+        File file = new File(base, Bytecodes.class.getName().replace('.', File.separatorChar) + ".java").getAbsoluteFile();
+
+        Pattern opcodeDecl = Pattern.compile("(\\s*public static final int )(\\w+)(\\s*=\\s*)(\\d+)(;.*)");
+
+        BufferedReader br = new BufferedReader(new FileReader(file));
+        CharArrayWriter buffer = new CharArrayWriter((int) file.length());
+        PrintWriter out = new PrintWriter(buffer);
+        String line;
+        int lastExtendedOpcode = BREAKPOINT;
+        boolean modified = false;
+        int section = 0;
+        while ((line = br.readLine()) != null) {
+            if (section == 0) {
+                if (line.equals("    // Start extended bytecodes")) {
+                    section = 1;
+                }
+            } else if (section == 1) {
+                if (line.equals("    // End extended bytecodes")) {
+                    section = 2;
+                } else {
+                    Matcher matcher = opcodeDecl.matcher(line);
+                    if (matcher.matches()) {
+                        String name = matcher.group(2);
+                        String value = matcher.group(4);
+                        int opcode = Integer.parseInt(value);
+                        if (nameArray[opcode] == null || !nameArray[opcode].equalsIgnoreCase(name)) {
+                            throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + nameArray[opcode]);
+                        }
+                        if (opcode != lastExtendedOpcode + 1) {
+                            System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")");
+                            opcode = lastExtendedOpcode + 1;
+                            line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4));
+                            modified = true;
+                        }
+
+                        if (opcode >= 256) {
+                            throw new RuntimeException("Exceeded maximum opcode value with " + name);
+                        }
+
+                        lastExtendedOpcode = opcode;
+                    }
+                }
+            }
+
+            out.println(line);
+        }
+        if (section == 0) {
+            throw new RuntimeException("Did not find line starting extended bytecode declarations:\n\n    // Start extended bytecodes");
+        } else if (section == 1) {
+            throw new RuntimeException("Did not find line ending extended bytecode declarations:\n\n    // End extended bytecodes");
+        }
+
+        if (modified) {
+            out.flush();
+            FileWriter fileWriter = new FileWriter(file);
+            fileWriter.write(buffer.toCharArray());
+            fileWriter.close();
+
+            System.out.println("Modified: " + file);
+        }
+
+
+        // Uncomment to print out visitor method declarations:
+//        for (int opcode = 0; opcode < flags.length; ++opcode) {
+//            if (isExtension(opcode)) {
+//                String visitorParams = length(opcode) == 1 ? "" : "int index";
+//                System.out.println("@Override");
+//                System.out.println("protected void " + name(opcode) + "(" + visitorParams + ") {");
+//                System.out.println("}");
+//                System.out.println();
+//            }
+//        }
+
+        // Uncomment to print out visitor method declarations:
+//        for (int opcode = 0; opcode < flags.length; ++opcode) {
+//            if (isExtension(opcode)) {
+//                System.out.println("case " + name(opcode).toUpperCase() + ": {");
+//                String arg = "";
+//                int length = length(opcode);
+//                if (length == 2) {
+//                    arg = "readUnsigned1()";
+//                } else if (length == 3) {
+//                    arg = "readUnsigned2()";
+//                }
+//                System.out.println("    bytecodeVisitor." + name(opcode) + "(" + arg + ");");
+//                System.out.println("    break;");
+//                System.out.println("}");
+//            }
+//        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytes.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * 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.java;
+
+/**
+ * A collection of utility methods for dealing with bytes, particularly in byte arrays.
+ */
+public class Bytes {
+    /**
+     * Gets a signed 1-byte value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 1-byte value at index {@code bci} in array {@code data}
+     */
+    public static int beS1(byte[] data, int bci) {
+        return data[bci];
+    }
+
+    /**
+     * Gets a signed 2-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 2-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beS2(byte[] data, int bci) {
+        return (data[bci] << 8) | (data[bci + 1] & 0xff);
+    }
+
+    /**
+     * Gets an unsigned 1-byte value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the unsigned 1-byte value at index {@code bci} in array {@code data}
+     */
+    public static int beU1(byte[] data, int bci) {
+        return data[bci] & 0xff;
+    }
+
+    /**
+     * Gets an unsigned 2-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the unsigned 2-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beU2(byte[] data, int bci) {
+        return ((data[bci] & 0xff) << 8) | (data[bci + 1] & 0xff);
+    }
+
+    /**
+     * Gets a signed 4-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 4-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beS4(byte[] data, int bci) {
+        return (data[bci] << 24) | ((data[bci + 1] & 0xff) << 16) | ((data[bci + 2] & 0xff) << 8) | (data[bci + 3] & 0xff);
+    }
+
+    /**
+     * Gets either a signed 2-byte or a signed 4-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @param fourByte if true, this method will return a 4-byte value
+     * @return the signed 2 or 4-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beSVar(byte[] data, int bci, boolean fourByte) {
+        if (fourByte) {
+            return beS4(data, bci);
+        } else {
+            return beS2(data, bci);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/FrameStateBuilder.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,532 @@
+/*
+ * 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.java;
+
+import static com.oracle.max.graal.nodes.ValueUtil.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public class FrameStateBuilder implements FrameStateAccess {
+
+    private final StructuredGraph graph;
+
+    private final ValueNode[] locals;
+    private final ValueNode[] stack;
+    private final ArrayList<MonitorObject> locks;
+
+    private int stackIndex;
+    private boolean rethrowException;
+
+    private final RiResolvedMethod method;
+
+    public FrameStateBuilder(RiResolvedMethod method, int maxLocals, int maxStackSize, StructuredGraph graph) {
+        assert graph != null;
+        this.method = method;
+        this.graph = graph;
+        this.locals = new ValueNode[maxLocals];
+        // we always need at least one stack slot (for exceptions)
+        int stackSize = Math.max(1, maxStackSize);
+        this.stack = new ValueNode[stackSize];
+
+        int javaIndex = 0;
+        int index = 0;
+        if (!isStatic(method.accessFlags())) {
+            // add the receiver
+            LocalNode local = graph.unique(new LocalNode(javaIndex, StampFactory.declaredNonNull(method.holder())));
+            storeLocal(javaIndex, local);
+            javaIndex = 1;
+            index = 1;
+        }
+        RiSignature sig = method.signature();
+        int max = sig.argumentCount(false);
+        RiType accessingClass = method.holder();
+        for (int i = 0; i < max; i++) {
+            RiType type = sig.argumentTypeAt(i, accessingClass);
+            CiKind kind = type.kind(false).stackKind();
+            Stamp stamp;
+            if (kind == CiKind.Object && type instanceof RiResolvedType) {
+                RiResolvedType resolvedType = (RiResolvedType) type;
+                stamp = StampFactory.declared(resolvedType);
+            } else {
+                stamp = StampFactory.forKind(kind);
+            }
+            LocalNode local = graph.unique(new LocalNode(index, stamp));
+            storeLocal(javaIndex, local);
+            javaIndex += stackSlots(kind);
+            index++;
+        }
+        this.locks = new ArrayList<>();
+    }
+
+    @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();
+
+        this.stackIndex = other.stackSize();
+        for (int i = 0; i < other.localsSize(); i++) {
+            locals[i] = other.localAt(i);
+        }
+        for (int i = 0; i < other.stackSize(); i++) {
+            stack[i] = other.stackAt(i);
+        }
+        locks.clear();
+        for (int i = 0; i < other.locksSize(); i++) {
+            locks.add(other.lockAt(i));
+        }
+        this.rethrowException = other.rethrowException();
+    }
+
+    public FrameState create(int bci) {
+        return graph.add(new FrameState(method, bci, locals, stack, stackIndex, locks, rethrowException));
+    }
+
+    public FrameState duplicateWithException(int bci, ValueNode exceptionObject) {
+        FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[]{exceptionObject}, 1, locks, true));
+        frameState.setOuterFrameState(outerFrameState());
+        return frameState;
+    }
+
+    /**
+     * Pushes an instruction onto the stack with the expected type.
+     * @param kind the type expected for this instruction
+     * @param x the instruction to push onto the stack
+     */
+    public void push(CiKind kind, ValueNode x) {
+        assert kind != CiKind.Void;
+        xpush(assertKind(kind, x));
+        if (isTwoSlot(kind)) {
+            xpush(null);
+        }
+    }
+
+    /**
+     * Pushes a value onto the stack without checking the type.
+     * @param x the instruction to push onto the stack
+     */
+    public void xpush(ValueNode x) {
+        assert x == null || !x.isDeleted();
+        assert x == null || (x.kind() != CiKind.Void && x.kind() != CiKind.Illegal) : "unexpected value: " + x;
+        stack[stackIndex++] = x;
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is an int.
+     * @param x the instruction to push onto the stack
+     */
+    public void ipush(ValueNode x) {
+        xpush(assertInt(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a float.
+     * @param x the instruction to push onto the stack
+     */
+    public void fpush(ValueNode x) {
+        xpush(assertFloat(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is an object.
+     * @param x the instruction to push onto the stack
+     */
+    public void apush(ValueNode x) {
+        xpush(assertObject(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a JSR return address.
+     * @param x the instruction to push onto the stack
+     */
+    public void jpush(ValueNode x) {
+        xpush(assertJsr(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a long.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void lpush(ValueNode x) {
+        xpush(assertLong(x));
+        xpush(null);
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a double.
+     * @param x the instruction to push onto the stack
+     */
+    public void dpush(ValueNode x) {
+        xpush(assertDouble(x));
+        xpush(null);
+    }
+
+    public void pushReturn(CiKind kind, ValueNode x) {
+        if (kind != CiKind.Void) {
+            push(kind.stackKind(), x);
+        }
+    }
+
+    /**
+     * Pops an instruction off the stack with the expected type.
+     * @param kind the expected type
+     * @return the instruction on the top of the stack
+     */
+    public ValueNode pop(CiKind kind) {
+        assert kind != CiKind.Void;
+        if (isTwoSlot(kind)) {
+            xpop();
+        }
+        return assertKind(kind, xpop());
+    }
+
+    /**
+     * Pops a value off of the stack without checking the type.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode xpop() {
+        ValueNode result = stack[--stackIndex];
+        assert result == null || !result.isDeleted();
+        return result;
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is an int.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode ipop() {
+        return assertInt(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a float.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode fpop() {
+        return assertFloat(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is an object.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode apop() {
+        return assertObject(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a JSR return address.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode jpop() {
+        return assertJsr(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a long.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode lpop() {
+        assertHigh(xpop());
+        return assertLong(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a double.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode dpop() {
+        assertHigh(xpop());
+        return assertDouble(xpop());
+    }
+
+    /**
+     * Pop the specified number of slots off of this stack and return them as an array of instructions.
+     * @param size the number of arguments off of the stack
+     * @return an array containing the arguments off of the stack
+     */
+    public ValueNode[] popArguments(int slotSize, int argSize) {
+        int base = stackIndex - slotSize;
+        ValueNode[] r = new ValueNode[argSize];
+        int argIndex = 0;
+        int stackindex = 0;
+        while (stackindex < slotSize) {
+            ValueNode element = stack[base + stackindex];
+            assert element != null;
+            r[argIndex++] = element;
+            stackindex += stackSlots(element.kind());
+        }
+        stackIndex = base;
+        return r;
+    }
+
+    /**
+     * Peeks an element from the operand stack.
+     * @param argumentNumber The number of the argument, relative from the top of the stack (0 = top).
+     *        Long and double arguments only count as one argument, i.e., null-slots are ignored.
+     * @return The peeked argument.
+     */
+    public ValueNode peek(int argumentNumber) {
+        int idx = stackSize() - 1;
+        for (int i = 0; i < argumentNumber; i++) {
+            if (stackAt(idx) == null) {
+                idx--;
+                assert isTwoSlot(stackAt(idx).kind());
+            }
+            idx--;
+        }
+        return stackAt(idx);
+    }
+
+    /**
+     * Truncates this stack to the specified size.
+     * @param size the size to truncate to
+     */
+    public void truncateStack(int size) {
+        stackIndex = size;
+        assert stackIndex >= 0;
+    }
+
+    /**
+     * Clears all values on this stack.
+     */
+    public void clearStack() {
+        stackIndex = 0;
+    }
+
+    /**
+     * Loads the local variable at the specified index.
+     *
+     * @param i the index of the local variable to load
+     * @return the instruction that produced the specified local
+     */
+    public ValueNode loadLocal(int i) {
+        ValueNode x = locals[i];
+        if (x != null) {
+            if (x instanceof PhiNode) {
+                assert ((PhiNode) x).type() == PhiType.Value;
+                if (x.isDeleted()) {
+                    return null;
+                }
+            }
+            assert !isTwoSlot(x.kind()) || locals[i + 1] == null || locals[i + 1] instanceof PhiNode;
+        }
+        return x;
+    }
+
+    /**
+     * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word},
+     * then the next local variable index is also overwritten.
+     *
+     * @param i the index at which to store
+     * @param x the instruction which produces the value for the local
+     */
+    public void storeLocal(int i, ValueNode x) {
+        assert x == null || (x.kind() != CiKind.Void && x.kind() != CiKind.Illegal) : "unexpected value: " + x;
+        locals[i] = x;
+        if (isTwoSlot(x.kind())) {
+            // (tw) if this was a double word then kill i+1
+            locals[i + 1] = null;
+        }
+        if (i > 0) {
+            // if there was a double word at i - 1, then kill it
+            ValueNode p = locals[i - 1];
+            if (p != null && isTwoSlot(p.kind())) {
+                locals[i - 1] = null;
+            }
+        }
+    }
+
+    /**
+     * Locks a new object within the specified IRScope.
+     * @param scope the IRScope in which this locking operation occurs
+     * @param obj the object being locked
+     */
+    public void lock(MonitorObject obj) {
+        assert obj == null || (obj.kind() != CiKind.Void && obj.kind() != CiKind.Illegal) : "unexpected value: " + obj;
+        locks.add(obj);
+    }
+
+    /**
+     * Unlock the lock on the top of the stack.
+     */
+    public void unlock(MonitorObject obj) {
+        assert locks.get(locks.size() - 1) == obj;
+        locks.remove(locks.size() - 1);
+    }
+
+    /**
+     * Get the value on the stack at the specified stack index.
+     *
+     * @param i the index into the stack, with {@code 0} being the bottom of the stack
+     * @return the instruction at the specified position in the stack
+     */
+    public final ValueNode stackAt(int i) {
+        return stack[i];
+    }
+
+    /**
+     * Gets the value in the local variables at the specified index.
+     *
+     * @param i the index into the locals
+     * @return the instruction that produced the value for the specified local
+     */
+    public final ValueNode localAt(int i) {
+        return locals[i];
+    }
+
+    /**
+     * Retrieves the lock at the specified index in the lock stack.
+     * @param i the index into the lock stack
+     * @return the instruction which produced the object at the specified location in the lock stack
+     */
+    public final MonitorObject lockAt(int i) {
+        return locks.get(i);
+    }
+
+    /**
+     * Returns the size of the local variables.
+     *
+     * @return the size of the local variables
+     */
+    public int localsSize() {
+        return locals.length;
+    }
+
+    /**
+     * Gets number of locks held by this frame state.
+     */
+    public int locksSize() {
+        return locks.size();
+    }
+
+    /**
+     * Gets the current size (height) of the stack.
+     */
+    public int stackSize() {
+        return stackIndex;
+    }
+
+    public Iterator<ValueNode> locals() {
+        return new ValueArrayIterator(locals);
+    }
+
+    public Iterator<ValueNode> stack() {
+        return new ValueArrayIterator(locals);
+    }
+
+    public List<MonitorObject> locks() {
+        return Collections.unmodifiableList(locks);
+    }
+
+
+    private static class ValueArrayIterator implements Iterator<ValueNode> {
+        private final ValueNode[] array;
+        private int index;
+
+        public ValueArrayIterator(ValueNode[] array, int length) {
+            assert length <= array.length;
+            this.array = array;
+            this.index = 0;
+        }
+
+        public ValueArrayIterator(ValueNode[] array) {
+            this(array, array.length);
+        }
+
+        @Override
+        public boolean hasNext() {
+            return index < array.length;
+        }
+
+        @Override
+        public ValueNode next() {
+            return array[index++];
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException("cannot remove from array");
+        }
+
+    }
+
+
+    @Override
+    public FrameState duplicate(int bci) {
+        return create(bci);
+    }
+
+    @Override
+    public ValueNode valueAt(int i) {
+        if (i < locals.length) {
+            return locals[i];
+        } else if (i < locals.length + stackIndex) {
+            return stack[i - locals.length];
+        } else {
+            return locks.get(i - locals.length - stack.length);
+        }
+    }
+
+    @Override
+    public FrameState outerFrameState() {
+        return null;
+    }
+
+    public FrameState duplicateWithoutStack(int bci) {
+        FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[0], 0, locks, false));
+        frameState.setOuterFrameState(outerFrameState());
+        return frameState;
+    }
+
+    @Override
+    public boolean rethrowException() {
+        return rethrowException;
+    }
+
+    public void setRethrowException(boolean b) {
+        rethrowException = b;
+    }
+
+    public static int stackSlots(CiKind kind) {
+        return isTwoSlot(kind) ? 2 : 1;
+    }
+
+    public static boolean isTwoSlot(CiKind kind) {
+        assert kind != CiKind.Void && kind != CiKind.Illegal;
+        return kind == CiKind.Long || kind == CiKind.Double;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderConfiguration.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.java;
+
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+
+public class GraphBuilderConfiguration {
+    private final boolean useBranchPrediction;
+    private final boolean eagerResolving;
+    private final PhasePlan plan;
+
+    public GraphBuilderConfiguration(boolean useBranchPrediction, boolean eagerResolving, PhasePlan plan) {
+        this.useBranchPrediction = useBranchPrediction;
+        this.eagerResolving = eagerResolving;
+        this.plan = plan;
+    }
+
+    public boolean useBranchPrediction() {
+        return useBranchPrediction;
+    }
+
+    public boolean eagerResolving() {
+        return eagerResolving;
+    }
+
+    public PhasePlan plan() {
+        return plan;
+    }
+
+    public static GraphBuilderConfiguration getDefault() {
+        return getDefault(null);
+    }
+
+    public static GraphBuilderConfiguration getDefault(PhasePlan plan) {
+        return new GraphBuilderConfiguration(GraalOptions.UseBranchPrediction, false, plan);
+    }
+
+    public static GraphBuilderConfiguration getDeoptFreeDefault() {
+        return getDeoptFreeDefault(null);
+    }
+
+    public static GraphBuilderConfiguration getDeoptFreeDefault(PhasePlan plan) {
+        return new GraphBuilderConfiguration(false, true, plan);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,1748 @@
+/*
+ * 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.java;
+
+import static com.oracle.max.graal.java.Bytecodes.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.java.BlockMap.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.java.BlockMap.Block;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
+ */
+public final class GraphBuilderPhase extends Phase {
+
+    /**
+     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
+     * the bytecode instructions as they are parsed.
+     */
+    public static final int TRACELEVEL_INSTRUCTIONS = 1;
+
+    /**
+     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
+     * the frame state before each bytecode instruction as it is parsed.
+     */
+    public static final int TRACELEVEL_STATE = 2;
+
+    private StructuredGraph currentGraph;
+
+    private final CiStatistics stats;
+    private final RiRuntime runtime;
+    private RiConstantPool constantPool;
+    private RiExceptionHandler[] exceptionHandlers;
+    private RiResolvedMethod method;
+
+    private BytecodeStream stream;           // the bytecode stream
+    private final LogStream log;
+
+    private FrameStateBuilder frameState;          // the current execution state
+    private Block currentBlock;
+
+    private int nextBlockNumber;
+
+    private ValueNode methodSynchronizedObject;
+    private ExceptionBlock unwindBlock;
+    private Block returnBlock;
+
+    // the worklist of blocks, sorted by depth first number
+    private final PriorityQueue<Block> workList = new PriorityQueue<>(10, new Comparator<Block>() {
+        public int compare(Block o1, Block o2) {
+            return o1.blockID - o2.blockID;
+        }
+    });
+
+    private FixedWithNextNode lastInstr;                 // the last instruction added
+
+    private Set<Block> blocksOnWorklist;
+    private Set<Block> blocksVisited;
+
+    private BitSet canTrapBitSet;
+
+    public static final Map<RiMethod, StructuredGraph> cachedGraphs = new WeakHashMap<>();
+
+    private final GraphBuilderConfiguration config;
+
+    public GraphBuilderPhase(RiRuntime runtime) {
+        this(runtime, null);
+    }
+
+    public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats) {
+        this(runtime, stats, GraphBuilderConfiguration.getDefault());
+    }
+
+    public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats, GraphBuilderConfiguration config) {
+        this.config = config;
+        this.runtime = runtime;
+        this.stats = stats;
+        this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        method = graph.method();
+        assert method.code() != null : "method must contain bytecodes: " + method;
+        this.stream = new BytecodeStream(method.code());
+        this.constantPool = method.getConstantPool();
+        this.blocksOnWorklist = new HashSet<>();
+        this.blocksVisited = new HashSet<>();
+        unwindBlock = null;
+        returnBlock = null;
+        methodSynchronizedObject = null;
+        exceptionHandlers = null;
+        assert graph != null;
+        this.currentGraph = graph;
+        this.frameState = new FrameStateBuilder(method, method.maxLocals(), method.maxStackSize(), graph);
+        build();
+    }
+
+    @Override
+    protected String getDetailedName() {
+        return getName() + " " + CiUtil.format("%H.%n(%p):%r", method);
+    }
+
+    private BlockMap createBlockMap() {
+        BlockMap map = new BlockMap(method, config.useBranchPrediction());
+        map.build();
+        if (stats != null) {
+            stats.bytecodeCount += method.code().length;
+        }
+
+        if (currentContext.isObserved()) {
+            String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method);
+            currentContext.observable.fireCompilationEvent(label, map);
+        }
+        return map;
+    }
+
+    private void build() {
+        if (log != null) {
+            log.println();
+            log.println("Compiling " + method);
+        }
+
+        // compute the block map, setup exception handlers and get the entrypoint(s)
+        BlockMap blockMap = createBlockMap();
+        this.canTrapBitSet = blockMap.canTrap;
+
+        exceptionHandlers = blockMap.exceptionHandlers();
+        if (stats != null) {
+            stats.blockCount += blockMap.blocks.size();
+        }
+        nextBlockNumber = blockMap.blocks.size();
+
+        lastInstr = currentGraph.start();
+        if (isSynchronized(method.accessFlags())) {
+            // add a monitor enter to the start block
+            currentGraph.start().setStateAfter(frameState.create(FrameState.BEFORE_BCI));
+            methodSynchronizedObject = synchronizedObject(frameState, method);
+            lastInstr = genMonitorEnter(methodSynchronizedObject);
+        }
+
+        // finish the start block
+        ((AbstractStateSplit) lastInstr).setStateAfter(frameState.create(0));
+        if (blockMap.startBlock.isLoopHeader) {
+            appendGoto(createTarget(blockMap.startBlock, frameState));
+        } else {
+            blockMap.startBlock.firstInstruction = lastInstr;
+        }
+        addToWorkList(blockMap.startBlock);
+
+        iterateAllBlocks();
+        connectLoopEndToBegin();
+
+        // remove Placeholders (except for loop exits)
+        for (PlaceholderNode n : currentGraph.getNodes(PlaceholderNode.class)) {
+            n.replaceAndDelete(n.next());
+        }
+
+        // remove dead FrameStates
+        for (Node n : currentGraph.getNodes(FrameState.class)) {
+            if (n.usages().size() == 0 && n.predecessor() == null) {
+                n.safeDelete();
+            }
+        }
+
+        if (GraalOptions.CacheGraphs && !currentGraph.hasNode(DeoptimizeNode.class)) {
+            cachedGraphs.put(method, currentGraph.copy());
+        }
+    }
+
+    private int nextBlockNumber() {
+        if (stats != null) {
+            stats.blockCount++;
+        }
+        return nextBlockNumber++;
+    }
+
+    private Block unwindBlock(int bci) {
+        if (unwindBlock == null) {
+            unwindBlock = new ExceptionBlock();
+            unwindBlock.startBci = -1;
+            unwindBlock.endBci = -1;
+            unwindBlock.deoptBci = bci;
+            unwindBlock.blockID = nextBlockNumber();
+            addToWorkList(unwindBlock);
+        }
+        return unwindBlock;
+    }
+
+    private Block returnBlock(int bci) {
+        if (returnBlock == null) {
+            returnBlock = new Block();
+            returnBlock.startBci = bci;
+            returnBlock.endBci = bci;
+            returnBlock.blockID = nextBlockNumber();
+            addToWorkList(returnBlock);
+        }
+        return returnBlock;
+    }
+
+    private void markOnWorkList(Block block) {
+        blocksOnWorklist.add(block);
+    }
+
+    private boolean isOnWorkList(Block block) {
+        return blocksOnWorklist.contains(block);
+    }
+
+    private void markVisited(Block block) {
+        blocksVisited.add(block);
+    }
+
+    private boolean isVisited(Block block) {
+        return blocksVisited.contains(block);
+    }
+
+    public void mergeOrClone(Block target, FrameStateAccess newState) {
+        AbstractStateSplit first = (AbstractStateSplit) target.firstInstruction;
+
+        if (target.isLoopHeader && isVisited(target)) {
+            first = (AbstractStateSplit) loopBegin(target).loopEnd().predecessor();
+        }
+
+        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
+            first.setStateAfter(newState.duplicate(bci));
+        } else {
+            if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
+                // stacks or locks do not match--bytecodes would not verify
+                TTY.println(existingState.toString());
+                TTY.println(newState.duplicate(0).toString());
+                throw new CiBailout("stack or locks do not match");
+            }
+            assert existingState.localsSize() == newState.localsSize();
+            assert existingState.stackSize() == newState.stackSize();
+
+            if (first instanceof PlaceholderNode) {
+                PlaceholderNode p = (PlaceholderNode) first;
+                if (p.predecessor() == null) {
+                    p.setStateAfter(newState.duplicate(bci));
+                    return;
+                } else {
+                    MergeNode merge = currentGraph.add(new MergeNode());
+                    FixedNode next = p.next();
+                    EndNode end = currentGraph.add(new EndNode());
+                    p.setNext(end);
+                    merge.setNext(next);
+                    merge.addEnd(end);
+                    merge.setStateAfter(existingState);
+                    p.setStateAfter(existingState.duplicate(bci));
+                    if (!(next instanceof LoopEndNode)) {
+                        target.firstInstruction = merge;
+                    }
+                    first = merge;
+                }
+            }
+
+            existingState.merge((MergeNode) first, newState);
+        }
+    }
+
+    public BytecodeStream stream() {
+        return stream;
+    }
+
+    public int bci() {
+        return stream.currentBCI();
+    }
+
+    private void loadLocal(int index, CiKind kind) {
+        frameState.push(kind, frameState.loadLocal(index));
+    }
+
+    private void storeLocal(CiKind kind, int index) {
+        frameState.storeLocal(index, frameState.pop(kind));
+    }
+
+    public static boolean covers(RiExceptionHandler handler, int bci) {
+        return handler.startBCI() <= bci && bci < handler.endBCI();
+    }
+
+    public static boolean isCatchAll(RiExceptionHandler handler) {
+        return handler.catchTypeCPI() == 0;
+    }
+
+    private BeginNode handleException(ValueNode exceptionObject, int bci) {
+        assert bci == FrameState.BEFORE_BCI || bci == bci() : "invalid bci";
+
+        if (GraalOptions.UseExceptionProbability && method.invocationCount() > GraalOptions.MatureInvocationCount) {
+            if (bci != FrameState.BEFORE_BCI && exceptionObject == null && method.exceptionProbability(bci) == 0) {
+                return null;
+            }
+        }
+
+        RiExceptionHandler firstHandler = null;
+        // join with all potential exception handlers
+        if (exceptionHandlers != null) {
+            for (RiExceptionHandler handler : exceptionHandlers) {
+                if (covers(handler, bci)) {
+                    firstHandler = handler;
+                    break;
+                }
+            }
+        }
+
+        Block dispatchBlock = null;
+        if (firstHandler == null) {
+            dispatchBlock = unwindBlock(bci);
+        } else {
+            for (int i = currentBlock.normalSuccessors; i < currentBlock.successors.size(); i++) {
+                Block block = currentBlock.successors.get(i);
+                if (block instanceof ExceptionBlock && ((ExceptionBlock) block).handler == firstHandler) {
+                    dispatchBlock = block;
+                    break;
+                }
+                if (isCatchAll(firstHandler) && block.startBci == firstHandler.handlerBCI()) {
+                    dispatchBlock = block;
+                    break;
+                }
+            }
+        }
+
+        BeginNode p = currentGraph.add(new BeginNode());
+        p.setStateAfter(frameState.duplicateWithoutStack(bci));
+
+        ValueNode currentExceptionObject;
+        ExceptionObjectNode newObj = null;
+        if (exceptionObject == null) {
+            newObj = currentGraph.add(new ExceptionObjectNode());
+            currentExceptionObject = newObj;
+        } else {
+            currentExceptionObject = exceptionObject;
+        }
+        FrameState stateWithException = frameState.duplicateWithException(bci, currentExceptionObject);
+        if (newObj != null) {
+            newObj.setStateAfter(stateWithException);
+        }
+        FixedNode target = createTarget(dispatchBlock, stateWithException);
+        if (exceptionObject == null) {
+            ExceptionObjectNode eObj = (ExceptionObjectNode) currentExceptionObject;
+            eObj.setNext(target);
+            p.setNext(eObj);
+        } else {
+            p.setNext(target);
+        }
+        return p;
+    }
+
+    private void genLoadConstant(int cpi) {
+        Object con = constantPool.lookupConstant(cpi);
+
+        if (con instanceof RiType) {
+            // this is a load of class constant which might be unresolved
+            RiType riType = (RiType) con;
+            if (riType instanceof RiResolvedType) {
+                frameState.push(CiKind.Object, append(ConstantNode.forCiConstant(((RiResolvedType) riType).getEncoding(Representation.JavaClass), runtime, currentGraph)));
+            } else {
+                append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+                frameState.push(CiKind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
+            }
+        } else if (con instanceof CiConstant) {
+            CiConstant constant = (CiConstant) con;
+            frameState.push(constant.kind.stackKind(), appendConstant(constant));
+        } else {
+            throw new Error("lookupConstant returned an object of incorrect type");
+        }
+    }
+
+    private void genLoadIndexed(CiKind kind) {
+        emitExplicitExceptions(frameState.peek(1), frameState.peek(0));
+
+        ValueNode index = frameState.ipop();
+        ValueNode array = frameState.apop();
+        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
+        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, length, kind)));
+        frameState.push(kind.stackKind(), v);
+    }
+
+    private void genStoreIndexed(CiKind kind) {
+        emitExplicitExceptions(frameState.peek(2), frameState.peek(1));
+
+        ValueNode value = frameState.pop(kind.stackKind());
+        ValueNode index = frameState.ipop();
+        ValueNode array = frameState.apop();
+        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
+        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, length, kind, value));
+        append(result);
+    }
+
+    private void stackOp(int opcode) {
+        switch (opcode) {
+            case POP: {
+                frameState.xpop();
+                break;
+            }
+            case POP2: {
+                frameState.xpop();
+                frameState.xpop();
+                break;
+            }
+            case DUP: {
+                ValueNode w = frameState.xpop();
+                frameState.xpush(w);
+                frameState.xpush(w);
+                break;
+            }
+            case DUP_X1: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                frameState.xpush(w1);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP_X2: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
+                frameState.xpush(w1);
+                frameState.xpush(w3);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP2: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP2_X1: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                frameState.xpush(w3);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP2_X2: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
+                ValueNode w4 = frameState.xpop();
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                frameState.xpush(w4);
+                frameState.xpush(w3);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case SWAP: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                frameState.xpush(w1);
+                frameState.xpush(w2);
+                break;
+            }
+            default:
+                throw Util.shouldNotReachHere();
+        }
+
+    }
+
+    private void genArithmeticOp(CiKind result, int opcode, boolean canTrap) {
+        ValueNode y = frameState.pop(result);
+        ValueNode x = frameState.pop(result);
+        boolean isStrictFP = isStrict(method.accessFlags());
+        ArithmeticNode v;
+        switch(opcode){
+            case IADD:
+            case LADD: v = new IntegerAddNode(result, x, y); break;
+            case FADD:
+            case DADD: v = new FloatAddNode(result, x, y, isStrictFP); break;
+            case ISUB:
+            case LSUB: v = new IntegerSubNode(result, x, y); break;
+            case FSUB:
+            case DSUB: v = new FloatSubNode(result, x, y, isStrictFP); break;
+            case IMUL:
+            case LMUL: v = new IntegerMulNode(result, x, y); break;
+            case FMUL:
+            case DMUL: v = new FloatMulNode(result, x, y, isStrictFP); break;
+            case IDIV:
+            case LDIV: v = new IntegerDivNode(result, x, y); break;
+            case FDIV:
+            case DDIV: v = new FloatDivNode(result, x, y, isStrictFP); break;
+            case IREM:
+            case LREM: v = new IntegerRemNode(result, x, y); break;
+            case FREM:
+            case DREM: v = new FloatRemNode(result, x, y, isStrictFP); break;
+            default:
+                throw new CiBailout("should not reach");
+        }
+        ValueNode result1 = append(currentGraph.unique(v));
+        if (canTrap) {
+            append(currentGraph.add(new ValueAnchorNode(result1)));
+        }
+        frameState.push(result, result1);
+    }
+
+    private void genNegateOp(CiKind kind) {
+        frameState.push(kind, append(currentGraph.unique(new NegateNode(frameState.pop(kind)))));
+    }
+
+    private void genShiftOp(CiKind kind, int opcode) {
+        ValueNode s = frameState.ipop();
+        ValueNode x = frameState.pop(kind);
+        ShiftNode v;
+        switch(opcode){
+            case ISHL:
+            case LSHL: v = new LeftShiftNode(kind, x, s); break;
+            case ISHR:
+            case LSHR: v = new RightShiftNode(kind, x, s); break;
+            case IUSHR:
+            case LUSHR: v = new UnsignedRightShiftNode(kind, x, s); break;
+            default:
+                throw new CiBailout("should not reach");
+        }
+        frameState.push(kind, append(currentGraph.unique(v)));
+    }
+
+    private void genLogicOp(CiKind kind, int opcode) {
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
+        LogicNode v;
+        switch(opcode){
+            case IAND:
+            case LAND: v = new AndNode(kind, x, y); break;
+            case IOR:
+            case LOR: v = new OrNode(kind, x, y); break;
+            case IXOR:
+            case LXOR: v = new XorNode(kind, x, y); break;
+            default:
+                throw new CiBailout("should not reach");
+        }
+        frameState.push(kind, append(currentGraph.unique(v)));
+    }
+
+    private void genCompareOp(CiKind kind, boolean isUnorderedLess) {
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
+        frameState.ipush(append(currentGraph.unique(new NormalizeCompareNode(x, y, isUnorderedLess))));
+    }
+
+    private void genConvert(ConvertNode.Op opcode) {
+        ValueNode input = frameState.pop(opcode.from.stackKind());
+        frameState.push(opcode.to.stackKind(), append(currentGraph.unique(new ConvertNode(opcode, input))));
+    }
+
+    private void genIncrement() {
+        int index = stream().readLocalIndex();
+        int delta = stream().readIncrement();
+        ValueNode x = frameState.localAt(index);
+        ValueNode y = append(ConstantNode.forInt(delta, currentGraph));
+        frameState.storeLocal(index, append(currentGraph.unique(new IntegerAddNode(CiKind.Int, x, y))));
+    }
+
+    private void genGoto() {
+        appendGoto(createTarget(currentBlock.successors.get(0), frameState));
+        assert currentBlock.normalSuccessors == 1;
+    }
+
+    private void ifNode(ValueNode x, Condition cond, ValueNode y) {
+        assert !x.isDeleted() && !y.isDeleted();
+        double probability = method.branchProbability(bci());
+        if (probability < 0) {
+            if (GraalOptions.TraceProbability) {
+                TTY.println("missing probability in " + method + " at bci " + bci());
+            }
+            probability = 0.5;
+        }
+
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new CompareNode(x, cond, y)), probability));
+        append(ifNode);
+        ifNode.setTrueSuccessor(BeginNode.begin(createTarget(currentBlock.successors.get(0), frameState)));
+        ifNode.setFalseSuccessor(BeginNode.begin(createTarget(currentBlock.successors.get(1), frameState)));
+
+        assert currentBlock.normalSuccessors == 2 : currentBlock.normalSuccessors;
+    }
+
+    private void genIfZero(Condition cond) {
+        ValueNode y = appendConstant(CiConstant.INT_0);
+        ValueNode x = frameState.ipop();
+        ifNode(x, cond, y);
+    }
+
+    private void genIfNull(Condition cond) {
+        ValueNode y = appendConstant(CiConstant.NULL_OBJECT);
+        ValueNode x = frameState.apop();
+        ifNode(x, cond, y);
+    }
+
+    private void genIfSame(CiKind kind, Condition cond) {
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
+        assert !x.isDeleted() && !y.isDeleted();
+        ifNode(x, cond, y);
+    }
+
+    private void genThrow(int bci) {
+        ValueNode exception = frameState.apop();
+        FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false))));
+        append(node);
+        append(handleException(exception, bci));
+    }
+
+    private RiType lookupType(int cpi, int bytecode) {
+        eagerResolving(cpi, bytecode);
+        RiType result = constantPool.lookupType(cpi, bytecode);
+        assert !config.eagerResolving() || result instanceof RiResolvedType;
+        return result;
+    }
+
+    private RiMethod lookupMethod(int cpi, int opcode) {
+        eagerResolving(cpi, opcode);
+        RiMethod result = constantPool.lookupMethod(cpi, opcode);
+        assert !config.eagerResolving() || ((result instanceof RiResolvedMethod) && ((RiResolvedMethod) result).holder().isInitialized());
+        return result;
+    }
+
+    private RiField lookupField(int cpi, int opcode) {
+        eagerResolving(cpi, opcode);
+        RiField result = constantPool.lookupField(cpi, opcode);
+        assert !config.eagerResolving() || (result instanceof RiResolvedField && ((RiResolvedField) result).holder().isInitialized());
+        return result;
+    }
+
+    private void eagerResolving(int cpi, int bytecode) {
+        if (config.eagerResolving()) {
+            constantPool.loadReferencedType(cpi, bytecode);
+        }
+    }
+
+    private void genCheckCast() {
+        int cpi = stream().readCPI();
+        RiType type = lookupType(cpi, CHECKCAST);
+        boolean initialized = type instanceof RiResolvedType;
+        if (initialized) {
+            ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, true);
+            ValueNode object = frameState.apop();
+            AnchorNode anchor = currentGraph.add(new AnchorNode());
+            append(anchor);
+            CheckCastNode checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object));
+            append(currentGraph.add(new ValueAnchorNode(checkCast)));
+            frameState.apush(checkCast);
+        } else {
+            ValueNode object = frameState.apop();
+            append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(object, Condition.EQ, ConstantNode.forObject(null, runtime, currentGraph))))));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+    }
+
+    private void genInstanceOf() {
+        int cpi = stream().readCPI();
+        RiType type = lookupType(cpi, INSTANCEOF);
+        ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, type instanceof RiResolvedType);
+        ValueNode object = frameState.apop();
+        if (typeInstruction != null) {
+            frameState.ipush(append(MaterializeNode.create(currentGraph.unique(new InstanceOfNode(typeInstruction, (RiResolvedType) type, object, false)), currentGraph)));
+        } else {
+            frameState.ipush(appendConstant(CiConstant.INT_0));
+        }
+    }
+
+    void genNewInstance(int cpi) {
+        RiType type = lookupType(cpi, NEW);
+        if (type instanceof RiResolvedType) {
+            NewInstanceNode n = currentGraph.add(new NewInstanceNode((RiResolvedType) type));
+            frameState.apush(append(n));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+    }
+
+    /**
+     * Gets the kind of array elements for the array type code that appears
+     * in a {@link Bytecodes#NEWARRAY} bytecode.
+     * @param code the array type code
+     * @return the kind from the array type code
+     */
+    public static CiKind arrayTypeCodeToKind(int code) {
+        // Checkstyle: stop
+        switch (code) {
+            case 4:  return CiKind.Boolean;
+            case 5:  return CiKind.Char;
+            case 6:  return CiKind.Float;
+            case 7:  return CiKind.Double;
+            case 8:  return CiKind.Byte;
+            case 9:  return CiKind.Short;
+            case 10: return CiKind.Int;
+            case 11: return CiKind.Long;
+            default: throw new IllegalArgumentException("unknown array type code: " + code);
+        }
+        // Checkstyle: resume
+    }
+
+    private void genNewTypeArray(int typeCode) {
+        CiKind kind = arrayTypeCodeToKind(typeCode);
+        RiResolvedType elementType = runtime.asRiType(kind);
+        NewTypeArrayNode nta = currentGraph.add(new NewTypeArrayNode(frameState.ipop(), elementType));
+        frameState.apush(append(nta));
+    }
+
+    private void genNewObjectArray(int cpi) {
+        RiType type = lookupType(cpi, ANEWARRAY);
+        ValueNode length = frameState.ipop();
+        if (type instanceof RiResolvedType) {
+            NewArrayNode n = currentGraph.add(new NewObjectArrayNode((RiResolvedType) type, length));
+            frameState.apush(append(n));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+
+    }
+
+    private void genNewMultiArray(int cpi) {
+        RiType type = lookupType(cpi, MULTIANEWARRAY);
+        int rank = stream().readUByte(bci() + 3);
+        ValueNode[] dims = new ValueNode[rank];
+        for (int i = rank - 1; i >= 0; i--) {
+            dims[i] = frameState.ipop();
+        }
+        if (type instanceof RiResolvedType) {
+            FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((RiResolvedType) type, dims));
+            frameState.apush(append(n));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+    }
+
+    private void genGetField(RiField field) {
+        emitExplicitExceptions(frameState.peek(0), null);
+
+        CiKind kind = field.kind(false);
+        ValueNode receiver = frameState.apop();
+        if ((field instanceof RiResolvedField) && ((RiResolvedField) field).holder().isInitialized()) {
+            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (RiResolvedField) field));
+            appendOptimizedLoadField(kind, load);
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+        }
+    }
+
+    public static class ExceptionInfo {
+
+        public final FixedWithNextNode exceptionEdge;
+        public final ValueNode exception;
+
+        public ExceptionInfo(FixedWithNextNode exceptionEdge, ValueNode exception) {
+            this.exceptionEdge = exceptionEdge;
+            this.exception = exception;
+        }
+    }
+
+    private ExceptionInfo emitNullCheck(ValueNode receiver) {
+        PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode());
+        PlaceholderNode falseSucc = currentGraph.add(new PlaceholderNode());
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(receiver, false)), trueSucc, falseSucc, 1));
+
+        append(ifNode);
+        lastInstr = trueSucc;
+
+        if (GraalOptions.OmitHotExceptionStacktrace) {
+            ValueNode exception = ConstantNode.forObject(new NullPointerException(), runtime, currentGraph);
+            return new ExceptionInfo(falseSucc, exception);
+        } else {
+            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateNullPointerException));
+            call.setStateAfter(frameState.duplicate(bci()));
+            falseSucc.setNext(call);
+            return new ExceptionInfo(call, call);
+        }
+    }
+
+    private ExceptionInfo emitBoundsCheck(ValueNode index, ValueNode length) {
+        PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode());
+        PlaceholderNode falseSucc = currentGraph.add(new PlaceholderNode());
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new CompareNode(index, Condition.BT, length)), trueSucc, falseSucc, 1));
+
+        append(ifNode);
+        lastInstr = trueSucc;
+
+        if (GraalOptions.OmitHotExceptionStacktrace) {
+            ValueNode exception = ConstantNode.forObject(new ArrayIndexOutOfBoundsException(), runtime, currentGraph);
+            return new ExceptionInfo(falseSucc, exception);
+        } else {
+            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateOutOfBoundsException, new ValueNode[] {index}));
+            call.setStateAfter(frameState.duplicate(bci()));
+            falseSucc.setNext(call);
+            return new ExceptionInfo(call, call);
+        }
+    }
+
+    private void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) {
+        assert receiver != null;
+
+        if (canTrapBitSet.get(bci()) && GraalOptions.AllowExplicitExceptionChecks) {
+            ArrayList<ExceptionInfo> exceptions = new ArrayList<>(2);
+            exceptions.add(emitNullCheck(receiver));
+            if (outOfBoundsIndex != null) {
+                ArrayLengthNode length = currentGraph.add(new ArrayLengthNode(receiver));
+                append(length);
+                exceptions.add(emitBoundsCheck(outOfBoundsIndex, length));
+            }
+            final ExceptionInfo exception;
+            if (exceptions.size() == 1) {
+                exception = exceptions.get(0);
+            } else {
+                assert exceptions.size() > 1;
+                MergeNode merge = currentGraph.add(new MergeNode());
+                PhiNode phi = currentGraph.unique(new PhiNode(CiKind.Object, merge, PhiType.Value));
+                for (ExceptionInfo info : exceptions) {
+                    EndNode end = currentGraph.add(new EndNode());
+                    info.exceptionEdge.setNext(end);
+                    merge.addEnd(end);
+                    phi.addInput(info.exception);
+                }
+                merge.setStateAfter(frameState.duplicate(bci()));
+                exception = new ExceptionInfo(merge, phi);
+            }
+
+            FixedNode entry = handleException(exception.exception, bci());
+            if (entry != null) {
+                exception.exceptionEdge.setNext(entry);
+            } else {
+                exception.exceptionEdge.setNext(createTarget(unwindBlock(bci()), frameState.duplicateWithException(bci(), exception.exception)));
+            }
+            if (GraalOptions.Meter) {
+                currentContext.metrics.ExplicitExceptions++;
+            }
+        }
+    }
+
+    private void genPutField(RiField field) {
+        emitExplicitExceptions(frameState.peek(1), null);
+
+        ValueNode value = frameState.pop(field.kind(false).stackKind());
+        ValueNode receiver = frameState.apop();
+        if (field instanceof RiResolvedField && ((RiResolvedField) field).holder().isInitialized()) {
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (RiResolvedField) field, value));
+            appendOptimizedStoreField(store);
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+        }
+    }
+
+    private void genGetStatic(RiField field) {
+        RiType holder = field.holder();
+        boolean isInitialized = (field instanceof RiResolvedField) && ((RiResolvedType) holder).isInitialized();
+        CiConstant constantValue = null;
+        if (isInitialized) {
+            constantValue = ((RiResolvedField) field).constantValue(null);
+        }
+        if (constantValue != null) {
+            frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue));
+        } else {
+            ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized);
+            CiKind kind = field.kind(false);
+            if (container != null) {
+                LoadFieldNode load = currentGraph.add(new LoadFieldNode(container, (RiResolvedField) field));
+                appendOptimizedLoadField(kind, load);
+            } else {
+                // deopt will be generated by genTypeOrDeopt, not needed here
+                frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+            }
+        }
+    }
+
+    private void genPutStatic(RiField field) {
+        RiType holder = field.holder();
+        ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field instanceof RiResolvedField && ((RiResolvedType) holder).isInitialized());
+        ValueNode value = frameState.pop(field.kind(false).stackKind());
+        if (container != null) {
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(container, (RiResolvedField) field, value));
+            appendOptimizedStoreField(store);
+        } else {
+            // deopt will be generated by genTypeOrDeopt, not needed here
+        }
+    }
+
+    private ConstantNode genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized) {
+        if (initialized) {
+            return appendConstant(((RiResolvedType) holder).getEncoding(representation));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            return null;
+        }
+    }
+
+    private void appendOptimizedStoreField(StoreFieldNode store) {
+        append(store);
+    }
+
+    private void appendOptimizedLoadField(CiKind kind, LoadFieldNode load) {
+        // append the load to the instruction
+        ValueNode optimized = append(load);
+        frameState.push(kind.stackKind(), optimized);
+    }
+
+    private void genInvokeStatic(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            RiResolvedMethod resolvedTarget = (RiResolvedMethod) target;
+            RiResolvedType holder = resolvedTarget.holder();
+            if (!holder.isInitialized() && GraalOptions.ResolveClassBeforeStaticInvoke) {
+                genInvokeDeopt(target, false);
+            } else {
+                ValueNode[] args = frameState.popArguments(resolvedTarget.signature().argumentSlots(false), resolvedTarget.signature().argumentCount(false));
+                appendInvoke(InvokeKind.Static, resolvedTarget, args);
+            }
+        } else {
+            genInvokeDeopt(target, false);
+        }
+    }
+
+    private void genInvokeInterface(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
+            genInvokeIndirect(InvokeKind.Interface, (RiResolvedMethod) target, args);
+        } else {
+            genInvokeDeopt(target, true);
+        }
+    }
+
+    private void genInvokeVirtual(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
+            genInvokeIndirect(InvokeKind.Virtual, (RiResolvedMethod) target, args);
+        } else {
+            genInvokeDeopt(target, true);
+        }
+
+    }
+
+    private void genInvokeSpecial(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            assert target != null;
+            assert target.signature() != null;
+            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
+            invokeDirect((RiResolvedMethod) target, args);
+        } else {
+            genInvokeDeopt(target, true);
+        }
+    }
+
+    private void genInvokeDeopt(RiMethod unresolvedTarget, boolean withReceiver) {
+        append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+        frameState.popArguments(unresolvedTarget.signature().argumentSlots(withReceiver), unresolvedTarget.signature().argumentCount(withReceiver));
+        CiKind kind = unresolvedTarget.signature().returnKind(false);
+        if (kind != CiKind.Void) {
+            frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+        }
+    }
+
+    private void genInvokeIndirect(InvokeKind invokeKind, RiResolvedMethod target, ValueNode[] args) {
+        ValueNode receiver = args[0];
+        // attempt to devirtualize the call
+        RiResolvedType klass = target.holder();
+
+        // 0. check for trivial cases
+        if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) {
+            // check for trivial cases (e.g. final methods, nonvirtual methods)
+            invokeDirect(target, args);
+            return;
+        }
+        // 1. check if the exact type of the receiver can be determined
+        RiResolvedType exact = getExactType(klass, receiver);
+        if (exact != null) {
+            // either the holder class is exact, or the receiver object has an exact type
+            invokeDirect(exact.resolveMethodImpl(target), args);
+            return;
+        }
+        // devirtualization failed, produce an actual invokevirtual
+        appendInvoke(invokeKind, target, args);
+    }
+
+    private void invokeDirect(RiResolvedMethod target, ValueNode[] args) {
+        appendInvoke(InvokeKind.Special, target, args);
+    }
+
+    private void appendInvoke(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] args) {
+        CiKind resultType = targetMethod.signature().returnKind(false);
+        if (GraalOptions.DeoptALot) {
+            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptAction.None));
+            deoptimize.setMessage("invoke " + targetMethod.name());
+            append(deoptimize);
+            frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
+        } else {
+            MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, targetMethod.signature().returnType(method.holder())));
+            BeginNode exceptionEdge = handleException(null, bci());
+            ValueNode result;
+            if (exceptionEdge != null) {
+                InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
+                result = append(invoke);
+                frameState.pushReturn(resultType, result);
+                Block nextBlock = currentBlock.successors.get(0);
+                invoke.setNext(createTarget(nextBlock, frameState));
+                invoke.setStateAfter(frameState.create(nextBlock.startBci));
+            } else {
+                result = appendWithBCI(currentGraph.add(new InvokeNode(callTarget, bci())));
+                frameState.pushReturn(resultType, result);
+            }
+        }
+    }
+
+    private RiResolvedType getExactType(RiResolvedType staticType, ValueNode receiver) {
+        RiResolvedType exact = staticType.exactType();
+        if (exact == null) {
+            exact = receiver.exactType();
+            if (exact == null) {
+                if (receiver.isConstant()) {
+                    exact = runtime.getTypeOf(receiver.asConstant());
+                }
+                if (exact == null) {
+                    RiType declared = receiver.declaredType();
+                    if (declared instanceof RiResolvedType) {
+                        exact = ((RiResolvedType) declared).exactType();
+                    }
+                }
+            }
+        }
+        return exact;
+    }
+
+    private void callRegisterFinalizer() {
+        // append a call to the finalizer registration
+        append(currentGraph.add(new RegisterFinalizerNode(frameState.loadLocal(0))));
+    }
+
+    private void genReturn(ValueNode x) {
+        frameState.clearStack();
+        if (x != null) {
+            frameState.push(x.kind(), x);
+        }
+        appendGoto(createTarget(returnBlock(bci()), frameState));
+    }
+
+    private MonitorEnterNode genMonitorEnter(ValueNode x) {
+        MonitorObject monitorObject = currentGraph.add(new MonitorObject(x));
+        MonitorEnterNode monitorEnter = currentGraph.add(new MonitorEnterNode(monitorObject));
+        frameState.lock(monitorObject);
+        appendWithBCI(monitorEnter);
+        return monitorEnter;
+    }
+
+    private MonitorExitNode genMonitorExit(ValueNode x) {
+        if (frameState.locksSize() <= 0) {
+            throw new CiBailout("monitor stack underflow");
+        }
+        MonitorObject monitorObject = frameState.lockAt(frameState.locksSize() - 1);
+
+        // We only compile methods with balanced monitors.  However, x might be a phi function
+        // that can be optimized away later on, so we have to disable the check for phi functions.
+        assert x == monitorObject.owner() || x instanceof PhiNode;
+
+        MonitorExitNode monitorExit = currentGraph.add(new MonitorExitNode(monitorObject));
+        appendWithBCI(monitorExit);
+        frameState.unlock(monitorObject);
+        return monitorExit;
+    }
+
+    private void genJsr(int dest) {
+        Block successor = currentBlock.jsrSuccessor;
+        assert successor.startBci == dest : successor.startBci + " != " + dest + " @" + bci();
+        JsrScope scope = currentBlock.jsrScope;
+        if (!successor.jsrScope.pop().equals(scope)) {
+            throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
+        }
+        if (successor.jsrScope.nextReturnAddress() != stream().nextBCI()) {
+            throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
+        }
+        frameState.push(CiKind.Jsr, ConstantNode.forJsr(stream().nextBCI(), currentGraph));
+        appendGoto(createTarget(successor, frameState));
+    }
+
+    private void genRet(int localIndex) {
+        Block successor = currentBlock.retSuccessor;
+        ValueNode local = frameState.loadLocal(localIndex);
+        JsrScope scope = currentBlock.jsrScope;
+        int retAddress = scope.nextReturnAddress();
+        append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(local, Condition.EQ, ConstantNode.forJsr(retAddress, currentGraph))))));
+        if (!successor.jsrScope.equals(scope.pop())) {
+            throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
+        }
+        appendGoto(createTarget(successor, frameState));
+    }
+
+    private void genTableswitch() {
+        int bci = bci();
+        ValueNode value = frameState.ipop();
+        BytecodeTableSwitch ts = new BytecodeTableSwitch(stream(), bci);
+
+        int nofCases = ts.numberOfCases() + 1; // including default case
+        assert currentBlock.normalSuccessors == nofCases;
+
+        TableSwitchNode tableSwitch = currentGraph.add(new TableSwitchNode(value, ts.lowKey(), switchProbability(nofCases, bci)));
+        for (int i = 0; i < nofCases; ++i) {
+            tableSwitch.setBlockSuccessor(i, BeginNode.begin(createTarget(currentBlock.successors.get(i), frameState)));
+        }
+        append(tableSwitch);
+    }
+
+    private double[] switchProbability(int numberOfCases, int bci) {
+        double[] prob = method.switchProbability(bci);
+        if (prob != null) {
+            assert prob.length == numberOfCases;
+        } else {
+            if (GraalOptions.TraceProbability) {
+                TTY.println("Missing probability (switch) in " + method + " at bci " + bci);
+            }
+            prob = new double[numberOfCases];
+            for (int i = 0; i < numberOfCases; i++) {
+                prob[i] = 1.0d / numberOfCases;
+            }
+        }
+        return prob;
+    }
+
+    private void genLookupswitch() {
+        int bci = bci();
+        ValueNode value = frameState.ipop();
+        BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci);
+
+        int nofCases = ls.numberOfCases() + 1; // including default case
+        assert currentBlock.normalSuccessors == nofCases;
+
+        int[] keys = new int[nofCases - 1];
+        for (int i = 0; i < nofCases - 1; ++i) {
+            keys[i] = ls.keyAt(i);
+        }
+        LookupSwitchNode lookupSwitch = currentGraph.add(new LookupSwitchNode(value, keys, switchProbability(nofCases, bci)));
+        for (int i = 0; i < nofCases; ++i) {
+            lookupSwitch.setBlockSuccessor(i, BeginNode.begin(createTarget(currentBlock.successors.get(i), frameState)));
+        }
+        append(lookupSwitch);
+    }
+
+    private ConstantNode appendConstant(CiConstant constant) {
+        return ConstantNode.forCiConstant(constant, runtime, currentGraph);
+    }
+
+    private ValueNode append(FixedNode fixed) {
+        lastInstr.setNext(fixed);
+        lastInstr = null;
+        return fixed;
+    }
+
+    private ValueNode append(FixedWithNextNode x) {
+        return appendWithBCI(x);
+    }
+
+    private static ValueNode append(ValueNode v) {
+        return v;
+    }
+
+    private ValueNode appendWithBCI(FixedWithNextNode x) {
+        assert x.predecessor() == null : "instruction should not have been appended yet";
+        assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
+        lastInstr.setNext(x);
+        lastInstr = x;
+        return x;
+    }
+
+    private FixedNode createTarget(Block block, FrameStateAccess stateAfter) {
+        assert block != null && stateAfter != null;
+        assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null :
+            "non-loop block must be iterated after all its predecessors. startBci=" + block.startBci + ", " + block.getClass().getSimpleName() + ", " + block.firstInstruction.next();
+
+        if (block.isExceptionEntry) {
+            assert stateAfter.stackSize() == 1;
+        }
+
+        if (block.firstInstruction == null) {
+            if (block.isLoopHeader) {
+                LoopBeginNode loopBegin = currentGraph.add(new LoopBeginNode());
+                loopBegin.addEnd(currentGraph.add(new EndNode()));
+                LoopEndNode loopEnd = currentGraph.add(new LoopEndNode());
+                loopEnd.setLoopBegin(loopBegin);
+                PlaceholderNode pBegin = currentGraph.add(new PlaceholderNode());
+                pBegin.setNext(loopBegin.forwardEdge());
+                PlaceholderNode pEnd = currentGraph.add(new PlaceholderNode());
+                pEnd.setNext(loopEnd);
+                loopBegin.setStateAfter(stateAfter.duplicate(block.startBci));
+                block.firstInstruction = pBegin;
+            } else {
+                block.firstInstruction = currentGraph.add(new PlaceholderNode());
+            }
+        }
+        mergeOrClone(block, stateAfter);
+        addToWorkList(block);
+
+        FixedNode result = null;
+        if (block.isLoopHeader && isVisited(block)) {
+            result = (FixedNode) loopBegin(block).loopEnd().predecessor();
+        } else {
+            result = block.firstInstruction;
+        }
+
+        assert result instanceof MergeNode || result instanceof PlaceholderNode : result;
+        if (result instanceof MergeNode) {
+            if (result instanceof LoopBeginNode) {
+                result = ((LoopBeginNode) result).forwardEdge();
+            } else {
+                EndNode end = currentGraph.add(new EndNode());
+                ((MergeNode) result).addEnd(end);
+                PlaceholderNode p = currentGraph.add(new PlaceholderNode());
+                int bci = block.startBci;
+                if (block instanceof ExceptionBlock) {
+                    bci = ((ExceptionBlock) block).deoptBci;
+                }
+                p.setStateAfter(stateAfter.duplicate(bci));
+                p.setNext(end);
+                result = p;
+            }
+        }
+        assert !(result instanceof LoopBeginNode || result instanceof MergeNode);
+        return result;
+    }
+
+    private ValueNode synchronizedObject(FrameStateAccess state, RiResolvedMethod target) {
+        if (isStatic(target.accessFlags())) {
+            return append(ConstantNode.forCiConstant(target.holder().getEncoding(Representation.JavaClass), runtime, currentGraph));
+        } else {
+            return state.localAt(0);
+        }
+    }
+
+    private void iterateAllBlocks() {
+        Block block;
+        while ((block = removeFromWorkList()) != null) {
+            // remove blocks that have no predecessors by the time it their bytecodes are parsed
+            if (block.firstInstruction == null) {
+                markVisited(block);
+                continue;
+            }
+
+            if (!isVisited(block)) {
+                markVisited(block);
+                // now parse the block
+                if (block.isLoopHeader) {
+                    LoopBeginNode begin = loopBegin(block);
+                    FrameState preLoopState = ((StateSplit) block.firstInstruction).stateAfter();
+                    assert preLoopState != null;
+                    FrameState duplicate = preLoopState.duplicate(preLoopState.bci);
+                    begin.setStateAfter(duplicate);
+                    duplicate.insertLoopPhis(begin);
+                    lastInstr = begin;
+                } else {
+                    lastInstr = block.firstInstruction;
+                }
+                frameState.initializeFrom(((StateSplit) lastInstr).stateAfter());
+                assert lastInstr.next() == null : "instructions already appended at block " + block.blockID;
+
+                if (block == returnBlock) {
+                    createReturn();
+                } else if (block == unwindBlock) {
+                    createUnwind();
+                } else if (block instanceof ExceptionBlock) {
+                    createExceptionDispatch((ExceptionBlock) block);
+                } else if (block instanceof DeoptBlock) {
+                    createDeopt();
+                } else {
+                    frameState.setRethrowException(false);
+                    iterateBytecodesForBlock(block);
+                }
+            }
+        }
+    }
+
+    private void connectLoopEndToBegin() {
+        for (LoopBeginNode begin : currentGraph.getNodes(LoopBeginNode.class)) {
+            LoopEndNode loopEnd = begin.loopEnd();
+            AbstractStateSplit loopEndStateSplit = (AbstractStateSplit) loopEnd.predecessor();
+            if (loopEndStateSplit.stateAfter() != null) {
+                begin.stateAfter().mergeLoop(begin, loopEndStateSplit.stateAfter());
+            } else {
+//              This can happen with degenerated loops like this one:
+//              for (;;) {
+//                  try {
+//                      break;
+//                  } catch (UnresolvedException iioe) {
+//                  }
+//              }
+                // Delete the phis (all of them must have exactly one input).
+                for (PhiNode phi : begin.phis().snapshot()) {
+                    assert phi.valueCount() == 1;
+                    begin.stateAfter().deleteRedundantPhi(phi, phi.firstValue());
+                }
+
+                // Delete the loop end.
+                loopEndStateSplit.safeDelete();
+                loopEnd.safeDelete();
+
+                // Remove the loop begin.
+                EndNode loopEntryEnd = begin.forwardEdge();
+                FixedNode beginSucc = begin.next();
+                FrameState stateAfter = begin.stateAfter();
+                stateAfter.delete();
+                begin.safeDelete();
+                loopEntryEnd.replaceAndDelete(beginSucc);
+            }
+        }
+    }
+
+    private static LoopBeginNode loopBegin(Block block) {
+        EndNode endNode = (EndNode) block.firstInstruction.next();
+        LoopBeginNode loopBegin = (LoopBeginNode) endNode.merge();
+        return loopBegin;
+    }
+
+    private void createDeopt() {
+        append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile)));
+    }
+
+    private void createUnwind() {
+        synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
+        UnwindNode unwindNode = currentGraph.add(new UnwindNode(frameState.apop()));
+        append(unwindNode);
+    }
+
+    private void createReturn() {
+        if (method.isConstructor() && method.holder().superType() == null) {
+            callRegisterFinalizer();
+        }
+        CiKind returnKind = method.signature().returnKind(false).stackKind();
+        ValueNode x = returnKind == CiKind.Void ? null : frameState.pop(returnKind);
+        assert frameState.stackSize() == 0;
+
+        // TODO (gd) remove this when FloatingRead is fixed
+        if (Modifier.isSynchronized(method.accessFlags())) {
+            append(currentGraph.add(new ValueAnchorNode(x)));
+        }
+
+        synchronizedEpilogue(FrameState.AFTER_BCI);
+        ReturnNode returnNode = currentGraph.add(new ReturnNode(x));
+        append(returnNode);
+    }
+
+    private void synchronizedEpilogue(int bci) {
+        if (Modifier.isSynchronized(method.accessFlags())) {
+            MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject);
+            monitorExit.setStateAfter(frameState.create(bci));
+        }
+    }
+
+    private void createExceptionDispatch(ExceptionBlock block) {
+        if (block.handler == null) {
+            assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize();
+            createUnwind();
+        } else {
+            assert frameState.stackSize() == 1 : frameState;
+
+            RiType catchType = block.handler.catchType();
+            ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, catchType, (catchType instanceof RiResolvedType) && ((RiResolvedType) catchType).isInitialized());
+            if (typeInstruction != null) {
+                Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
+                FixedNode catchSuccessor = createTarget(block.successors.get(0), frameState);
+                FixedNode nextDispatch = createTarget(nextBlock, frameState);
+                ValueNode exception = frameState.stackAt(0);
+                IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode(typeInstruction, (RiResolvedType) catchType, exception, false)), catchSuccessor, nextDispatch, 0.5));
+                append(ifNode);
+            }
+        }
+    }
+
+    private void appendGoto(FixedNode target) {
+        if (lastInstr != null) {
+            lastInstr.setNext(target);
+        }
+    }
+
+    private void iterateBytecodesForBlock(Block block) {
+        assert frameState != null;
+
+        currentBlock = block;
+
+        int endBCI = stream.endBCI();
+
+        stream.setBCI(block.startBci);
+        int bci = block.startBci;
+        while (bci < endBCI) {
+            // read the opcode
+            int opcode = stream.currentBC();
+            traceState();
+            traceInstruction(bci, opcode, bci == block.startBci);
+            processBytecode(bci, opcode);
+
+            if (lastInstr == null || IdentifyBlocksPhase.isBlockEnd(lastInstr) || lastInstr.next() != null) {
+                break;
+            }
+
+            stream.next();
+            bci = stream.currentBCI();
+            if (lastInstr instanceof StateSplit) {
+                StateSplit stateSplit = (StateSplit) lastInstr;
+                if (stateSplit.stateAfter() == null && stateSplit.needsStateAfter()) {
+                    stateSplit.setStateAfter(frameState.create(bci));
+                }
+            }
+            if (bci < endBCI) {
+                if (bci > block.endBci) {
+                    assert !block.successors.get(0).isExceptionEntry;
+                    assert block.normalSuccessors == 1;
+                    // we fell through to the next block, add a goto and break
+                    appendGoto(createTarget(block.successors.get(0), frameState));
+                    break;
+                }
+            }
+        }
+    }
+
+    private void traceState() {
+        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) {
+            log.println(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
+            for (int i = 0; i < frameState.localsSize(); ++i) {
+                ValueNode value = frameState.localAt(i);
+                log.println(String.format("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
+            }
+            for (int i = 0; i < frameState.stackSize(); ++i) {
+                ValueNode value = frameState.stackAt(i);
+                log.println(String.format("|   stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
+            }
+            for (int i = 0; i < frameState.locksSize(); ++i) {
+                ValueNode value = frameState.lockAt(i);
+                log.println(String.format("|   lock[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
+            }
+        }
+    }
+
+    private void processBytecode(int bci, int opcode) {
+        int cpi;
+
+        // Checkstyle: stop
+        switch (opcode) {
+            case NOP            : /* nothing to do */ break;
+            case ACONST_NULL    : frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); break;
+            case ICONST_M1      : frameState.ipush(appendConstant(CiConstant.INT_MINUS_1)); break;
+            case ICONST_0       : frameState.ipush(appendConstant(CiConstant.INT_0)); break;
+            case ICONST_1       : frameState.ipush(appendConstant(CiConstant.INT_1)); break;
+            case ICONST_2       : frameState.ipush(appendConstant(CiConstant.INT_2)); break;
+            case ICONST_3       : frameState.ipush(appendConstant(CiConstant.INT_3)); break;
+            case ICONST_4       : frameState.ipush(appendConstant(CiConstant.INT_4)); break;
+            case ICONST_5       : frameState.ipush(appendConstant(CiConstant.INT_5)); break;
+            case LCONST_0       : frameState.lpush(appendConstant(CiConstant.LONG_0)); break;
+            case LCONST_1       : frameState.lpush(appendConstant(CiConstant.LONG_1)); break;
+            case FCONST_0       : frameState.fpush(appendConstant(CiConstant.FLOAT_0)); break;
+            case FCONST_1       : frameState.fpush(appendConstant(CiConstant.FLOAT_1)); break;
+            case FCONST_2       : frameState.fpush(appendConstant(CiConstant.FLOAT_2)); break;
+            case DCONST_0       : frameState.dpush(appendConstant(CiConstant.DOUBLE_0)); break;
+            case DCONST_1       : frameState.dpush(appendConstant(CiConstant.DOUBLE_1)); break;
+            case BIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readByte()))); break;
+            case SIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readShort()))); break;
+            case LDC            : // fall through
+            case LDC_W          : // fall through
+            case LDC2_W         : genLoadConstant(stream.readCPI()); break;
+            case ILOAD          : loadLocal(stream.readLocalIndex(), CiKind.Int); break;
+            case LLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Long); break;
+            case FLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Float); break;
+            case DLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Double); break;
+            case ALOAD          : loadLocal(stream.readLocalIndex(), CiKind.Object); break;
+            case ILOAD_0        : // fall through
+            case ILOAD_1        : // fall through
+            case ILOAD_2        : // fall through
+            case ILOAD_3        : loadLocal(opcode - ILOAD_0, CiKind.Int); break;
+            case LLOAD_0        : // fall through
+            case LLOAD_1        : // fall through
+            case LLOAD_2        : // fall through
+            case LLOAD_3        : loadLocal(opcode - LLOAD_0, CiKind.Long); break;
+            case FLOAD_0        : // fall through
+            case FLOAD_1        : // fall through
+            case FLOAD_2        : // fall through
+            case FLOAD_3        : loadLocal(opcode - FLOAD_0, CiKind.Float); break;
+            case DLOAD_0        : // fall through
+            case DLOAD_1        : // fall through
+            case DLOAD_2        : // fall through
+            case DLOAD_3        : loadLocal(opcode - DLOAD_0, CiKind.Double); break;
+            case ALOAD_0        : // fall through
+            case ALOAD_1        : // fall through
+            case ALOAD_2        : // fall through
+            case ALOAD_3        : loadLocal(opcode - ALOAD_0, CiKind.Object); break;
+            case IALOAD         : genLoadIndexed(CiKind.Int   ); break;
+            case LALOAD         : genLoadIndexed(CiKind.Long  ); break;
+            case FALOAD         : genLoadIndexed(CiKind.Float ); break;
+            case DALOAD         : genLoadIndexed(CiKind.Double); break;
+            case AALOAD         : genLoadIndexed(CiKind.Object); break;
+            case BALOAD         : genLoadIndexed(CiKind.Byte  ); break;
+            case CALOAD         : genLoadIndexed(CiKind.Char  ); break;
+            case SALOAD         : genLoadIndexed(CiKind.Short ); break;
+            case ISTORE         : storeLocal(CiKind.Int, stream.readLocalIndex()); break;
+            case LSTORE         : storeLocal(CiKind.Long, stream.readLocalIndex()); break;
+            case FSTORE         : storeLocal(CiKind.Float, stream.readLocalIndex()); break;
+            case DSTORE         : storeLocal(CiKind.Double, stream.readLocalIndex()); break;
+            case ASTORE         : storeLocal(CiKind.Object, stream.readLocalIndex()); break;
+            case ISTORE_0       : // fall through
+            case ISTORE_1       : // fall through
+            case ISTORE_2       : // fall through
+            case ISTORE_3       : storeLocal(CiKind.Int, opcode - ISTORE_0); break;
+            case LSTORE_0       : // fall through
+            case LSTORE_1       : // fall through
+            case LSTORE_2       : // fall through
+            case LSTORE_3       : storeLocal(CiKind.Long, opcode - LSTORE_0); break;
+            case FSTORE_0       : // fall through
+            case FSTORE_1       : // fall through
+            case FSTORE_2       : // fall through
+            case FSTORE_3       : storeLocal(CiKind.Float, opcode - FSTORE_0); break;
+            case DSTORE_0       : // fall through
+            case DSTORE_1       : // fall through
+            case DSTORE_2       : // fall through
+            case DSTORE_3       : storeLocal(CiKind.Double, opcode - DSTORE_0); break;
+            case ASTORE_0       : // fall through
+            case ASTORE_1       : // fall through
+            case ASTORE_2       : // fall through
+            case ASTORE_3       : storeLocal(CiKind.Object, opcode - ASTORE_0); break;
+            case IASTORE        : genStoreIndexed(CiKind.Int   ); break;
+            case LASTORE        : genStoreIndexed(CiKind.Long  ); break;
+            case FASTORE        : genStoreIndexed(CiKind.Float ); break;
+            case DASTORE        : genStoreIndexed(CiKind.Double); break;
+            case AASTORE        : genStoreIndexed(CiKind.Object); break;
+            case BASTORE        : genStoreIndexed(CiKind.Byte  ); break;
+            case CASTORE        : genStoreIndexed(CiKind.Char  ); break;
+            case SASTORE        : genStoreIndexed(CiKind.Short ); break;
+            case POP            : // fall through
+            case POP2           : // fall through
+            case DUP            : // fall through
+            case DUP_X1         : // fall through
+            case DUP_X2         : // fall through
+            case DUP2           : // fall through
+            case DUP2_X1        : // fall through
+            case DUP2_X2        : // fall through
+            case SWAP           : stackOp(opcode); break;
+            case IADD           : // fall through
+            case ISUB           : // fall through
+            case IMUL           : genArithmeticOp(CiKind.Int, opcode, false); break;
+            case IDIV           : // fall through
+            case IREM           : genArithmeticOp(CiKind.Int, opcode, true); break;
+            case LADD           : // fall through
+            case LSUB           : // fall through
+            case LMUL           : genArithmeticOp(CiKind.Long, opcode, false); break;
+            case LDIV           : // fall through
+            case LREM           : genArithmeticOp(CiKind.Long, opcode, true); break;
+            case FADD           : // fall through
+            case FSUB           : // fall through
+            case FMUL           : // fall through
+            case FDIV           : // fall through
+            case FREM           : genArithmeticOp(CiKind.Float, opcode, false); break;
+            case DADD           : // fall through
+            case DSUB           : // fall through
+            case DMUL           : // fall through
+            case DDIV           : // fall through
+            case DREM           : genArithmeticOp(CiKind.Double, opcode, false); break;
+            case INEG           : genNegateOp(CiKind.Int); break;
+            case LNEG           : genNegateOp(CiKind.Long); break;
+            case FNEG           : genNegateOp(CiKind.Float); break;
+            case DNEG           : genNegateOp(CiKind.Double); break;
+            case ISHL           : // fall through
+            case ISHR           : // fall through
+            case IUSHR          : genShiftOp(CiKind.Int, opcode); break;
+            case IAND           : // fall through
+            case IOR            : // fall through
+            case IXOR           : genLogicOp(CiKind.Int, opcode); break;
+            case LSHL           : // fall through
+            case LSHR           : // fall through
+            case LUSHR          : genShiftOp(CiKind.Long, opcode); break;
+            case LAND           : // fall through
+            case LOR            : // fall through
+            case LXOR           : genLogicOp(CiKind.Long, opcode); break;
+            case IINC           : genIncrement(); break;
+            case I2L            : genConvert(ConvertNode.Op.I2L); break;
+            case I2F            : genConvert(ConvertNode.Op.I2F); break;
+            case I2D            : genConvert(ConvertNode.Op.I2D); break;
+            case L2I            : genConvert(ConvertNode.Op.L2I); break;
+            case L2F            : genConvert(ConvertNode.Op.L2F); break;
+            case L2D            : genConvert(ConvertNode.Op.L2D); break;
+            case F2I            : genConvert(ConvertNode.Op.F2I); break;
+            case F2L            : genConvert(ConvertNode.Op.F2L); break;
+            case F2D            : genConvert(ConvertNode.Op.F2D); break;
+            case D2I            : genConvert(ConvertNode.Op.D2I); break;
+            case D2L            : genConvert(ConvertNode.Op.D2L); break;
+            case D2F            : genConvert(ConvertNode.Op.D2F); break;
+            case I2B            : genConvert(ConvertNode.Op.I2B); break;
+            case I2C            : genConvert(ConvertNode.Op.I2C); break;
+            case I2S            : genConvert(ConvertNode.Op.I2S); break;
+            case LCMP           : genCompareOp(CiKind.Long, false); break;
+            case FCMPL          : genCompareOp(CiKind.Float, true); break;
+            case FCMPG          : genCompareOp(CiKind.Float, false); break;
+            case DCMPL          : genCompareOp(CiKind.Double, true); break;
+            case DCMPG          : genCompareOp(CiKind.Double, false); break;
+            case IFEQ           : genIfZero(Condition.EQ); break;
+            case IFNE           : genIfZero(Condition.NE); break;
+            case IFLT           : genIfZero(Condition.LT); break;
+            case IFGE           : genIfZero(Condition.GE); break;
+            case IFGT           : genIfZero(Condition.GT); break;
+            case IFLE           : genIfZero(Condition.LE); break;
+            case IF_ICMPEQ      : genIfSame(CiKind.Int, Condition.EQ); break;
+            case IF_ICMPNE      : genIfSame(CiKind.Int, Condition.NE); break;
+            case IF_ICMPLT      : genIfSame(CiKind.Int, Condition.LT); break;
+            case IF_ICMPGE      : genIfSame(CiKind.Int, Condition.GE); break;
+            case IF_ICMPGT      : genIfSame(CiKind.Int, Condition.GT); break;
+            case IF_ICMPLE      : genIfSame(CiKind.Int, Condition.LE); break;
+            case IF_ACMPEQ      : genIfSame(CiKind.Object, Condition.EQ); break;
+            case IF_ACMPNE      : genIfSame(CiKind.Object, Condition.NE); break;
+            case GOTO           : genGoto(); break;
+            case JSR            : genJsr(stream.readBranchDest()); break;
+            case RET            : genRet(stream.readLocalIndex()); break;
+            case TABLESWITCH    : genTableswitch(); break;
+            case LOOKUPSWITCH   : genLookupswitch(); break;
+            case IRETURN        : genReturn(frameState.ipop()); break;
+            case LRETURN        : genReturn(frameState.lpop()); break;
+            case FRETURN        : genReturn(frameState.fpop()); break;
+            case DRETURN        : genReturn(frameState.dpop()); break;
+            case ARETURN        : genReturn(frameState.apop()); break;
+            case RETURN         : genReturn(null); break;
+            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(lookupField(cpi, opcode)); break;
+            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(lookupField(cpi, opcode)); break;
+            case GETFIELD       : cpi = stream.readCPI(); genGetField(lookupField(cpi, opcode)); break;
+            case PUTFIELD       : cpi = stream.readCPI(); genPutField(lookupField(cpi, opcode)); break;
+            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(lookupMethod(cpi, opcode)); break;
+            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break;
+            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
+            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
+            case NEW            : genNewInstance(stream.readCPI()); break;
+            case NEWARRAY       : genNewTypeArray(stream.readLocalIndex()); break;
+            case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
+            case ARRAYLENGTH    : genArrayLength(); break;
+            case ATHROW         : genThrow(stream.currentBCI()); break;
+            case CHECKCAST      : genCheckCast(); break;
+            case INSTANCEOF     : genInstanceOf(); break;
+            case MONITORENTER   : genMonitorEnter(frameState.apop()); break;
+            case MONITOREXIT    : genMonitorExit(frameState.apop()); break;
+            case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break;
+            case IFNULL         : genIfNull(Condition.EQ); break;
+            case IFNONNULL      : genIfNull(Condition.NE); break;
+            case GOTO_W         : genGoto(); break;
+            case JSR_W          : genJsr(stream.readFarBranchDest()); break;
+            case BREAKPOINT:
+                throw new CiBailout("concurrent setting of breakpoint");
+            default:
+                throw new CiBailout("Unsupported opcode " + opcode + " (" + nameOf(opcode) + ") [bci=" + bci + "]");
+        }
+        // Checkstyle: resume
+    }
+
+    private void traceInstruction(int bci, int opcode, boolean blockStart) {
+        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_INSTRUCTIONS && !TTY.isSuppressed()) {
+            StringBuilder sb = new StringBuilder(40);
+            sb.append(blockStart ? '+' : '|');
+            if (bci < 10) {
+                sb.append("  ");
+            } else if (bci < 100) {
+                sb.append(' ');
+            }
+            sb.append(bci).append(": ").append(Bytecodes.nameOf(opcode));
+            for (int i = bci + 1; i < stream.nextBCI(); ++i) {
+                sb.append(' ').append(stream.readUByte(i));
+            }
+            if (!currentBlock.jsrScope.isEmpty()) {
+                sb.append(' ').append(currentBlock.jsrScope);
+            }
+            log.println(sb.toString());
+        }
+    }
+
+    private void genArrayLength() {
+        frameState.ipush(append(currentGraph.add(new ArrayLengthNode(frameState.apop()))));
+    }
+
+    /**
+     * Adds a block to the worklist, if it is not already in the worklist.
+     * This method will keep the worklist topologically stored (i.e. the lower
+     * DFNs are earlier in the list).
+     * @param block the block to add to the work list
+     */
+    private void addToWorkList(Block block) {
+        if (!isOnWorkList(block)) {
+            markOnWorkList(block);
+            sortIntoWorkList(block);
+        }
+    }
+
+    private void sortIntoWorkList(Block top) {
+        workList.offer(top);
+    }
+
+    /**
+     * Removes the next block from the worklist. The list is sorted topologically, so the
+     * block with the lowest depth first number in the list will be removed and returned.
+     * @return the next block from the worklist; {@code null} if there are no blocks
+     * in the worklist
+     */
+    private Block removeFromWorkList() {
+        return workList.poll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrNotSupportedBailout.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.java;
+
+import com.oracle.max.cri.ci.*;
+
+
+public class JsrNotSupportedBailout extends CiBailout{
+    private static final long serialVersionUID = -7476925652727154272L;
+
+    public JsrNotSupportedBailout(String reason) {
+        super(reason);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrScope.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * 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.java;
+
+public class JsrScope {
+
+    public static final JsrScope EMPTY_SCOPE = new JsrScope();
+
+    private final long scope;
+
+    private JsrScope(long scope) {
+        this.scope = scope;
+    }
+
+    public JsrScope() {
+        this.scope = 0;
+    }
+
+    public int nextReturnAddress() {
+        return (int) (scope & 0xffff);
+    }
+
+    public JsrScope push(int jsrReturnBci) {
+        if ((scope & 0xffff000000000000L) != 0) {
+            throw new JsrNotSupportedBailout("only four jsr nesting levels are supported");
+        }
+        return new JsrScope((scope << 16) | jsrReturnBci);
+    }
+
+    public boolean isEmpty() {
+        return scope == 0;
+    }
+
+    public JsrScope pop() {
+        return new JsrScope(scope >>> 16);
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) (scope ^ (scope >>> 32));
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        return obj != null && getClass() == obj.getClass() && scope == ((JsrScope) obj).scope;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        long tmp = scope;
+        sb.append(" [");
+        while (tmp != 0) {
+            sb.append(", ").append(tmp & 0xffff);
+            tmp = tmp >>> 16;
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/package-info.java	Tue Jan 03 18:22:10 2012 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.java;
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Tue Jan 03 18:22:10 2012 +0100
@@ -33,12 +33,12 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.alloc.*;
 import com.oracle.max.graal.compiler.alloc.Interval.UsePosList;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.graph.Node.*;
 import com.oracle.max.graal.graph.NodeClass.*;
+import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.calc.*;
 
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Tue Jan 03 18:22:10 2012 +0100
@@ -30,11 +30,11 @@
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.alloc.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
 
 /**
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java	Tue Jan 03 18:22:10 2012 +0100
@@ -28,7 +28,6 @@
 
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.compiler.util.LoopUtil.Loop;
@@ -36,6 +35,7 @@
 import com.oracle.max.graal.graph.Node.Verbosity;
 import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.max.graal.graph.NodeClass.Position;
+import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.loop.*;
 import com.oracle.max.graal.printer.BasicIdealGraphPrinter.*;
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java	Tue Jan 03 18:22:10 2012 +0100
@@ -27,12 +27,12 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.cri.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.extended.*;
 import com.oracle.max.graal.nodes.java.*;
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Tue Jan 03 17:53:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Tue Jan 03 18:22:10 2012 +0100
@@ -30,10 +30,10 @@
 
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.graphbuilder.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.*;
 import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.printer.*;
 
--- a/mx/projects	Tue Jan 03 17:53:26 2012 +0100
+++ b/mx/projects	Tue Jan 03 18:22:10 2012 +0100
@@ -70,10 +70,16 @@
 project@com.oracle.max.graal.compiler@dependencies=com.oracle.max.asm,com.oracle.max.graal.nodes
 project@com.oracle.max.graal.compiler@checkstyle=com.oracle.max.graal.graph
 
+# graal.java
+project@com.oracle.max.graal.java@subDir=graal
+project@com.oracle.max.graal.java@sourceDirs=src
+project@com.oracle.max.graal.java@dependencies=com.oracle.max.graal.compiler
+project@com.oracle.max.graal.java@checkstyle=com.oracle.max.graal.graph
+
 # graal.printer
 project@com.oracle.max.graal.printer@subDir=graal
 project@com.oracle.max.graal.printer@sourceDirs=src
-project@com.oracle.max.graal.printer@dependencies=com.oracle.max.graal.compiler
+project@com.oracle.max.graal.printer@dependencies=com.oracle.max.graal.java
 project@com.oracle.max.graal.printer@checkstyle=com.oracle.max.graal.graph
 
 # graal.test
--- a/src/share/vm/runtime/arguments.cpp	Tue Jan 03 17:53:26 2012 +0100
+++ b/src/share/vm/runtime/arguments.cpp	Tue Jan 03 18:22:10 2012 +0100
@@ -2101,6 +2101,8 @@
     prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.nodes");
     prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.snippets");
     prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.hotspot");
+    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.printer");
+    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.java");
     scp_compiler.expand_endorsed();
 
     Arguments::set_compilerclasspath(scp_compiler.combined_path());