changeset 13277:ce017d1e4234

Merge.
author Christian Humer <christian.humer@gmail.com>
date Mon, 09 Dec 2013 17:31:12 +0100
parents 06afa0db90b3 (current diff) 68b964b6dc8e (diff)
children 038f55aab194
files graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackend.java graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackendFactory.java graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/util/OptimizedCallTargetFieldInfo.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleBackendFactory.java
diffstat 196 files changed, 3667 insertions(+), 3032 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Mon Dec 09 17:31:12 2013 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.api.code;
 
+import java.util.*;
+
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -127,11 +129,39 @@
         return sameRegister(v1, v2) && sameRegister(v1, v3);
     }
 
-    public static boolean differentRegisters(Value v1, Value v2) {
-        return !isRegister(v1) || !isRegister(v2) || !asRegister(v1).equals(asRegister(v2));
+    /**
+     * Checks if all the provided values are different physical registers. The parameters can be
+     * either {@link Register registers}, {@link Value values} or arrays of them. All values that
+     * are not {@link RegisterValue registers} are ignored.
+     */
+    public static boolean differentRegisters(Object... values) {
+        List<Register> registers = collectRegisters(values, new ArrayList<Register>());
+        for (int i = 1; i < registers.size(); i++) {
+            Register r1 = registers.get(i);
+            for (int j = 0; j < i; j++) {
+                Register r2 = registers.get(j);
+                if (r1.equals(r2)) {
+                    return false;
+                }
+            }
+        }
+        return true;
     }
 
-    public static boolean differentRegisters(Value v1, Value v2, Value v3) {
-        return differentRegisters(v1, v2) && differentRegisters(v1, v3) && differentRegisters(v2, v3);
+    private static List<Register> collectRegisters(Object[] values, List<Register> registers) {
+        for (Object o : values) {
+            if (o instanceof Register) {
+                registers.add((Register) o);
+            } else if (o instanceof Value) {
+                if (isRegister((Value) o)) {
+                    registers.add(asRegister((Value) o));
+                }
+            } else if (o instanceof Object[]) {
+                collectRegisters((Object[]) o, registers);
+            } else {
+                throw new IllegalArgumentException("Not a Register or Value: " + o);
+            }
+        }
+        return registers;
     }
 }
--- a/graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java	Mon Dec 09 17:31:12 2013 +0100
@@ -46,7 +46,7 @@
             ResolvedJavaMethod m = e.getValue();
             assertEquals(e.getKey().isDefault(), m.isDefault());
         }
-        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
             ResolvedJavaMethod m = e.getValue();
             assertFalse(m.isDefault());
         }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java	Mon Dec 09 17:31:12 2013 +0100
@@ -33,7 +33,7 @@
 public class MethodUniverse extends TypeUniverse {
 
     public final Map<Method, ResolvedJavaMethod> methods = new HashMap<>();
-    public final Map<Constructor, ResolvedJavaMethod> constructors = new HashMap<>();
+    public final Map<Constructor<?>, ResolvedJavaMethod> constructors = new HashMap<>();
 
     public MethodUniverse() {
         for (Class c : classes) {
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Mon Dec 09 17:31:12 2013 +0100
@@ -113,7 +113,7 @@
             ResolvedJavaMethod m = e.getValue();
             assertFalse(m.isClassInitializer());
         }
-        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
             ResolvedJavaMethod m = e.getValue();
             assertFalse(m.isClassInitializer());
         }
@@ -125,7 +125,7 @@
             ResolvedJavaMethod m = e.getValue();
             assertFalse(m.isConstructor());
         }
-        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
             ResolvedJavaMethod m = e.getValue();
             assertTrue(m.isConstructor());
         }
@@ -137,7 +137,7 @@
             ResolvedJavaMethod m = e.getValue();
             assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
         }
-        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
             ResolvedJavaMethod m = e.getValue();
             assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
         }
@@ -149,7 +149,7 @@
             ResolvedJavaMethod m = e.getValue();
             assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey().getModifiers()));
         }
-        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
             ResolvedJavaMethod m = e.getValue();
             assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey().getModifiers()));
         }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java	Mon Dec 09 17:31:12 2013 +0100
@@ -85,6 +85,14 @@
     JavaType lookupType(int cpi, int opcode);
 
     /**
+     * Looks up an Utf8 string.
+     * 
+     * @param cpi the constant pool index
+     * @return the Utf8 string at index {@code cpi} in this constant pool
+     */
+    String lookupUtf8(int cpi);
+
+    /**
      * Looks up a method signature.
      * 
      * @param cpi the constant pool index
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Mon Dec 09 17:31:12 2013 +0100
@@ -180,10 +180,14 @@
     }
 
     private void emitArith(int op1, int op2, Register dst, int imm32) {
+        emitArith(op1, op2, dst, imm32, false);
+    }
+
+    private void emitArith(int op1, int op2, Register dst, int imm32, boolean force32Imm) {
         assert isUByte(op1) && isUByte(op2) : "wrong opcode";
         assert (op1 & 0x01) == 1 : "should be 32bit operation";
         assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
-        if (isByte(imm32)) {
+        if (isByte(imm32) && !force32Imm) {
             emitByte(op1 | 0x02); // set sign bit
             emitByte(op2 | encode(dst));
             emitByte(imm32 & 0xFF);
@@ -2272,8 +2276,12 @@
     }
 
     public final void subq(Register dst, int imm32) {
+        subq(dst, imm32, false);
+    }
+
+    public final void subq(Register dst, int imm32, boolean force32Imm) {
         prefixqAndEncode(dst.encoding);
-        emitArith(0x81, 0xE8, dst, imm32);
+        emitArith(0x81, 0xE8, dst, imm32, force32Imm);
     }
 
     public final void subq(Register dst, AMD64Address src) {
@@ -2516,4 +2524,53 @@
     public AMD64Address getPlaceholder() {
         return Placeholder;
     }
+
+    private void prefetchPrefix(AMD64Address src) {
+        prefix(src);
+        emitByte(0x0F);
+    }
+
+    public void prefetchnta(AMD64Address src) {
+        prefetchPrefix(src);
+        emitByte(0x18);
+        emitOperandHelper(0, src);
+    }
+
+    void prefetchr(AMD64Address src) {
+        // assert(VM_Version::supports_3dnow_prefetch(), "must support");
+        prefetchPrefix(src);
+        emitByte(0x0D);
+        emitOperandHelper(0, src);
+    }
+
+    public void prefetcht0(AMD64Address src) {
+        // NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
+        prefetchPrefix(src);
+        emitByte(0x18);
+        emitOperandHelper(1, src);
+    }
+
+    public void prefetcht1(AMD64Address src) {
+        // NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
+        prefetchPrefix(src);
+        emitByte(0x18);
+        emitOperandHelper(2, src);
+    }
+
+    public void prefetcht2(AMD64Address src) {
+        // NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
+        prefix(src);
+        emitByte(0x0f);
+        emitByte(0x18);
+        emitOperandHelper(3, src);
+    }
+
+    public void prefetchw(AMD64Address src) {
+        // assert(VM_Version::supports_3dnow_prefetch(), "must support");
+        prefix(src);
+        emitByte(0x0f);
+        emitByte(0x0D);
+        emitOperandHelper(1, src);
+    }
+
 }
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Mon Dec 09 17:31:12 2013 +0100
@@ -171,7 +171,7 @@
         movsxw(reg, reg);
     }
 
-    public final void movflt(Register dst, Register src) {
+    public void movflt(Register dst, Register src) {
         assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         if (UseXmmRegToRegMoveAll) {
             movaps(dst, src);
@@ -180,17 +180,17 @@
         }
     }
 
-    public final void movflt(Register dst, AMD64Address src) {
+    public void movflt(Register dst, AMD64Address src) {
         assert dst.getRegisterCategory() == AMD64.XMM;
         movss(dst, src);
     }
 
-    public final void movflt(AMD64Address dst, Register src) {
+    public void movflt(AMD64Address dst, Register src) {
         assert src.getRegisterCategory() == AMD64.XMM;
         movss(dst, src);
     }
 
-    public final void movdbl(Register dst, Register src) {
+    public void movdbl(Register dst, Register src) {
         assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         if (UseXmmRegToRegMoveAll) {
             movapd(dst, src);
@@ -199,7 +199,7 @@
         }
     }
 
-    public final void movdbl(Register dst, AMD64Address src) {
+    public void movdbl(Register dst, AMD64Address src) {
         assert dst.getRegisterCategory() == AMD64.XMM;
         if (UseXmmLoadAndClearUpper) {
             movsd(dst, src);
@@ -208,6 +208,11 @@
         }
     }
 
+    public void movdbl(AMD64Address dst, Register src) {
+        assert src.getRegisterCategory() == AMD64.XMM;
+        movsd(dst, src);
+    }
+
     /**
      * Non-atomic write of a 64-bit constant to memory. Do not use if the address might be a
      * volatile field!
@@ -257,7 +262,7 @@
         assert value.getRegisterCategory() == AMD64.XMM;
         AMD64Address tmp = new AMD64Address(AMD64.rsp);
         subq(AMD64.rsp, target.arch.getSizeInBytes(Kind.Double));
-        movsd(tmp, value);
+        movdbl(tmp, value);
         fldd(tmp);
         return tmp;
     }
@@ -265,7 +270,7 @@
     private void trigEpilogue(Register dest, AMD64Address tmp) {
         assert dest.getRegisterCategory() == AMD64.XMM;
         fstpd(tmp);
-        movsd(dest, tmp);
+        movdbl(dest, tmp);
         addq(AMD64.rsp, target.arch.getSizeInBytes(Kind.Double));
     }
 
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java	Mon Dec 09 17:31:12 2013 +0100
@@ -115,7 +115,7 @@
     }
 
     /**
-     * This is used by the TargetMethodAssembler to convert a {@link StackSlot} to an
+     * This is used by the CompilationResultBuilder to convert a {@link StackSlot} to an
      * {@link AbstractAddress}.
      */
     public abstract AbstractAddress makeAddress(Register base, int displacement);
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -142,6 +142,7 @@
 
     @Override
     public AMD64AddressValue emitAddress(Value base, long displacement, Value index, int scale) {
+        assert (scale >= 1 && scale <= 8) || index.equals(Value.ILLEGAL) : "invalid scale";
         AllocatableValue baseRegister;
         long finalDisp = displacement;
         if (isConstant(base)) {
@@ -223,18 +224,18 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) {
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         switch (left.getKind().getStackKind()) {
             case Int:
             case Long:
             case Object:
-                append(new BranchOp(finalCondition, label));
+                append(new BranchOp(finalCondition, trueLabel, falseLabel));
                 break;
             case Float:
             case Double:
-                append(new FloatBranchOp(finalCondition, unorderedIsTrue, label));
+                append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere("" + left.getKind());
@@ -249,14 +250,22 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef destination, boolean negated) {
-        append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, destination));
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
+        if (negated) {
+            append(new BranchOp(ConditionFlag.NoOverflow, noOverflow, overflow));
+        } else {
+            append(new BranchOp(ConditionFlag.Overflow, overflow, noOverflow));
+        }
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) {
+    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
         emitIntegerTest(left, right);
-        append(new BranchOp(negated ? Condition.NE : Condition.EQ, label));
+        if (negated) {
+            append(new BranchOp(Condition.NE, falseDestination, trueDestination));
+        } else {
+            append(new BranchOp(Condition.EQ, trueDestination, falseDestination));
+        }
     }
 
     @Override
@@ -298,6 +307,28 @@
         }
     }
 
+    protected void emitCompareOp(Variable left, Value right) {
+        switch (left.getKind().getStackKind()) {
+            case Int:
+                append(new CompareOp(ICMP, left, right));
+                break;
+            case Long:
+                append(new CompareOp(LCMP, left, right));
+                break;
+            case Object:
+                append(new CompareOp(ACMP, left, right));
+                break;
+            case Float:
+                append(new CompareOp(FCMP, left, right));
+                break;
+            case Double:
+                append(new CompareOp(DCMP, left, right));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     /**
      * This method emits the compare instruction, and may reorder the operands. It returns true if
      * it did so.
@@ -319,25 +350,7 @@
             right = loadNonConst(b);
             mirrored = false;
         }
-        switch (left.getKind().getStackKind()) {
-            case Int:
-                append(new CompareOp(ICMP, left, right));
-                break;
-            case Long:
-                append(new CompareOp(LCMP, left, right));
-                break;
-            case Object:
-                append(new CompareOp(ACMP, left, right));
-                break;
-            case Float:
-                append(new CompareOp(FCMP, left, right));
-                break;
-            case Double:
-                append(new CompareOp(DCMP, left, right));
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
+        emitCompareOp(left, right);
         return mirrored;
     }
 
@@ -885,7 +898,7 @@
     protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
         long maxOffset = linkage.getMaxCallTargetOffset();
         if (maxOffset != (int) maxOffset) {
-            append(new AMD64Call.DirectFarForeignCallOp(this, linkage, result, arguments, temps, info));
+            append(new AMD64Call.DirectFarForeignCallOp(linkage, result, arguments, temps, info));
         } else {
             append(new AMD64Call.DirectNearForeignCallOp(linkage, result, arguments, temps, info));
         }
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -44,7 +44,6 @@
 import com.oracle.graal.lir.hsail.HSAILArithmetic.ShiftOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.CompareBranchOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp;
-import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.SwitchOp;
@@ -191,8 +190,8 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) {
-        // We don't have top worry about mirroring the condition on HSAIL.
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
+        // We don't have to worry about mirroring the condition on HSAIL.
         Condition finalCondition = cond;
         Variable result = newVariable(left.getKind());
         Kind kind = left.getKind().getStackKind();
@@ -200,11 +199,11 @@
             case Int:
             case Long:
             case Object:
-                append(new CompareBranchOp(mapKindToCompareOp(kind), finalCondition, left, right, result, result, label));
+                append(new CompareBranchOp(mapKindToCompareOp(kind), finalCondition, left, right, result, result, trueDestination, falseDestination, false));
                 break;
             case Float:
             case Double:
-                append(new FloatCompareBranchOp(mapKindToCompareOp(kind), finalCondition, left, right, result, result, label, unorderedIsTrue));
+                append(new CompareBranchOp(mapKindToCompareOp(kind), finalCondition, left, right, result, result, trueDestination, falseDestination, unorderedIsTrue));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere("" + left.getKind());
@@ -212,12 +211,12 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef label, boolean negated) {
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
         throw GraalInternalError.unimplemented();
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) {
+    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
         throw GraalInternalError.unimplemented();
     }
 
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,20 +23,23 @@
 package com.oracle.graal.compiler.ptx.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.ptx.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.ptx.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.ptx.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -57,6 +60,12 @@
         super(PTX.class);
     }
 
+    private static CompilerToGPU toGPU = HotSpotGraalRuntime.runtime().getCompilerToGPU();
+
+    private static boolean validDevice = toGPU.deviceInit();
+
+    private static final int totalProcessors = (validDevice ? toGPU.availableProcessors() : 0);
+
     protected CompilationResult compile(String test) {
         if (getBackend() instanceof PTXHotSpotBackend) {
             StructuredGraph graph = parse(test);
@@ -80,8 +89,20 @@
              * GPU fallback to CPU in cases of ECC failure on kernel invocation.
              */
             Suites suites = Suites.createDefaultSuites();
-            CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(),
-                            suites, new ExternalCompilationResult());
+            ExternalCompilationResult result = compileGraph(graph, cc, graph.method(), getProviders(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE, getProfilingInfo(graph),
+                            new SpeculationLog(), suites, true, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
+
+            ResolvedJavaMethod method = graph.method();
+
+            try {
+                if ((validDevice) && (result.getTargetCode() != null)) {
+                    long kernel = toGPU.generateKernel(result.getTargetCode(), method.getName());
+                    result.setEntryPoint(kernel);
+                }
+            } catch (Throwable th) {
+                th.printStackTrace();
+            }
+
             return result;
         } else {
             return null;
@@ -143,7 +164,7 @@
                  * for now assert that the warp array block is no larger than the number of physical
                  * gpu cores.
                  */
-                assert dimensionX * dimensionY * dimensionZ < PTXTargetMethodAssembler.getAvailableProcessors();
+                assert dimensionX * dimensionY * dimensionZ < totalProcessors;
 
                 r = ((HotSpotNmethod) installedCode).executeParallel(dimensionX, dimensionY, dimensionZ, executeArgs);
             } else {
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -89,7 +89,7 @@
     public PTXLIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
         super(graph, providers, frameMap, cc, lir);
         lir.spillMoveFactory = new PTXSpillMoveFactory();
-        int callVariables = cc.getArgumentCount() + (cc.getReturn() == Value.ILLEGAL ? 0 : 1);
+        int callVariables = cc.getArgumentCount() + (cc.getReturn().equals(Value.ILLEGAL) ? 0 : 1);
         lir.setFirstVariableNumber(callVariables);
         nextPredRegNum = 0;
     }
@@ -139,7 +139,7 @@
         AllocatableValue[] params = incomingArguments.getArguments();
         int argCount = incomingArguments.getArgumentCount();
 
-        if (returnObject == Value.ILLEGAL) {
+        if (returnObject.equals(Value.ILLEGAL)) {
             params = incomingArguments.getArguments();
             append(new PTXParameterOp(params, false));
         } else {
@@ -294,27 +294,27 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) {
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
         switch (left.getKind().getStackKind()) {
             case Int:
                 append(new CompareOp(ICMP, cond, left, right, nextPredRegNum));
-                append(new BranchOp(cond, label, nextPredRegNum++));
+                append(new BranchOp(cond, trueDestination, falseDestination, nextPredRegNum++));
                 break;
             case Long:
                 append(new CompareOp(LCMP, cond, left, right, nextPredRegNum));
-                append(new BranchOp(cond, label, nextPredRegNum++));
+                append(new BranchOp(cond, trueDestination, falseDestination, nextPredRegNum++));
                 break;
             case Float:
                 append(new CompareOp(FCMP, cond, left, right, nextPredRegNum));
-                append(new BranchOp(cond, label, nextPredRegNum++));
+                append(new BranchOp(cond, trueDestination, falseDestination, nextPredRegNum++));
                 break;
             case Double:
                 append(new CompareOp(DCMP, cond, left, right, nextPredRegNum));
-                append(new BranchOp(cond, label, nextPredRegNum++));
+                append(new BranchOp(cond, trueDestination, falseDestination, nextPredRegNum++));
                 break;
             case Object:
                 append(new CompareOp(ACMP, cond, left, right, nextPredRegNum));
-                append(new BranchOp(cond, label, nextPredRegNum++));
+                append(new BranchOp(cond, trueDestination, falseDestination, nextPredRegNum++));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere("" + left.getKind());
@@ -322,12 +322,12 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef label, boolean negated) {
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
         throw GraalInternalError.unimplemented("PTXLIRGenerator.emitOverflowCheckBranch()");
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) {
+    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
         // / emitIntegerTest(left, right);
         // append(new BranchOp(negated ? Condition.NE : Condition.EQ, label));
         throw GraalInternalError.unimplemented("emitIntegerTestBranch()");
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java	Mon Dec 09 17:30:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2013, 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.graal.compiler.ptx;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.*;
-
-public class PTXTargetMethodAssembler extends TargetMethodAssembler {
-
-    private static CompilerToGPU toGPU = HotSpotGraalRuntime.runtime().getCompilerToGPU();
-
-    private static boolean validDevice = toGPU.deviceInit();
-
-    private static final int totalProcessors = (validDevice ? toGPU.availableProcessors() : 0);
-
-    public static int getAvailableProcessors() {
-        return totalProcessors;
-    }
-
-    // detach ??
-
-    public PTXTargetMethodAssembler(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
-                    CompilationResult compilationResult) {
-        super(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
-    }
-
-    @Override
-    public CompilationResult finishTargetMethod(StructuredGraph graph) {
-        ResolvedJavaMethod method = graph.method();
-        assert method != null : graph + " is not associated wth a method";
-
-        ExternalCompilationResult graalCompile = (ExternalCompilationResult) super.finishTargetMethod(graph);
-
-        try {
-            if ((validDevice) && (graalCompile.getTargetCode() != null)) {
-                long kernel = toGPU.generateKernel(graalCompile.getTargetCode(), method.getName());
-                graalCompile.setEntryPoint(kernel);
-            }
-        } catch (Throwable th) {
-            th.printStackTrace();
-        }
-
-        return graalCompile;
-    }
-}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -231,7 +231,7 @@
     }
 
     @Override
-    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) {
+    public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
         boolean mirrored = emitCompare(left, right);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         Kind kind = left.getKind().getStackKind();
@@ -239,7 +239,7 @@
             case Int:
             case Long:
             case Object:
-                append(new BranchOp(finalCondition, label, kind));
+                append(new BranchOp(finalCondition, trueDestination, falseDestination, kind));
                 break;
             // case Float:
             // append(new CompareOp(FCMP, x, y));
@@ -255,15 +255,15 @@
     }
 
     @Override
-    public void emitOverflowCheckBranch(LabelRef label, boolean negated) {
+    public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated) {
         // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label));
         throw GraalInternalError.unimplemented();
     }
 
     @Override
-    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) {
+    public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination) {
         emitIntegerTest(left, right);
-        append(new BranchOp(negated ? Condition.NE : Condition.EQ, label, left.getKind().getStackKind()));
+        append(new BranchOp(negated ? Condition.NE : Condition.EQ, trueDestination, falseDestination, left.getKind().getStackKind()));
     }
 
     private void emitIntegerTest(Value a, Value b) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.nodes.ConstantNode.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 
@@ -38,13 +39,13 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.spi.*;
@@ -554,31 +555,17 @@
             GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
             CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-            final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
-                            new SpeculationLog(), getSuites(), new CompilationResult());
+            final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
+                            getProfilingInfo(graph), new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
             if (printCompilation) {
                 TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
             }
 
             try (Scope s = Debug.scope("CodeInstall", getCodeCache(), method)) {
-                InstalledCode code = addMethod(method, compResult);
-                if (code == null) {
+                installedCode = addMethod(method, compResult);
+                if (installedCode == null) {
                     throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", method));
                 }
-                if (Debug.isDumpEnabled()) {
-                    Debug.dump(new Object[]{compResult, code}, "After code installation");
-                }
-                if (Debug.isLogEnabled()) {
-                    DisassemblerProvider dis = backend.getDisassembler();
-                    if (dis != null) {
-                        String text = dis.disassemble(code);
-                        if (text != null) {
-                            Debug.log("Code installed for %s%n%s", method, text);
-                        }
-                    }
-                }
-
-                installedCode = code;
             } catch (Throwable e) {
                 throw Debug.handle(e);
             }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static org.junit.Assert.*;
 
 import java.lang.reflect.*;
@@ -33,7 +34,7 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.code.CompilationResult.Call;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
-import com.oracle.graal.compiler.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.test.*;
@@ -59,8 +60,8 @@
         final Method method = getMethod("testMethod");
         final StructuredGraph graph = parse(method);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultPhasePlan(),
-                        OptimisticOptimizations.ALL, new SpeculationLog(), getSuites(), new CompilationResult());
+        final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL,
+                        getProfilingInfo(graph), new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
             if (sp instanceof Call) {
@@ -81,8 +82,8 @@
         }
         assertTrue(graphLineSPs > 0);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultPhasePlan(true),
-                        OptimisticOptimizations.ALL, new SpeculationLog(), getSuites(), new CompilationResult());
+        final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultPhasePlan(true), OptimisticOptimizations.ALL,
+                        getProfilingInfo(graph), new SpeculationLog(), getSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
         int lineSPs = 0;
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -605,7 +605,7 @@
                 new FloatingReadPhase().apply(graph);
                 new RemoveValueProxyPhase().apply(graph);
 
-                MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+                MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo());
                 new GuardLoweringPhase().apply(graph, midContext);
                 new LoweringPhase(canonicalizer).apply(graph, midContext);
                 new LoweringPhase(canonicalizer).apply(graph, midContext);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -112,7 +112,8 @@
 
         LIR lir = null;
         try (Scope s = Debug.scope("FrontEnd")) {
-            lir = GraalCompiler.emitHIR(getProviders(), getBackend().getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), getSuites());
+            lir = GraalCompiler.emitHIR(getProviders(), getBackend().getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, graph.method().getProfilingInfo(),
+                            new SpeculationLog(), getSuites());
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Dec 09 17:31:12 2013 +0100
@@ -30,7 +30,9 @@
 
 import com.oracle.graal.alloc.*;
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.ProfilingInfo.*;
 import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -130,49 +132,48 @@
      * @param installedCodeOwner the method the compiled code will be
      *            {@linkplain InstalledCode#getMethod() associated} with once installed. This
      *            argument can be null.
+     * @param withScope specifies if a {@link DebugScope} with the name {@code "GraalCompiler"}
+     *            should be used for the compilation
      * @return the result of the compilation
      */
     public static <T extends CompilationResult> T compileGraph(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
-                    TargetDescription target, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog, Suites suites, T compilationResult) {
-        try (Scope s = Debug.scope("GraalCompiler", graph, providers.getCodeCache())) {
-            compileGraphNoScope(graph, cc, installedCodeOwner, providers, backend, target, cache, plan, optimisticOpts, speculationLog, suites, compilationResult);
+                    TargetDescription target, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites,
+                    boolean withScope, T compilationResult, CompilationResultBuilderFactory factory) {
+        try (Scope s0 = withScope ? Debug.scope("GraalCompiler", graph, providers.getCodeCache()) : null) {
+            Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
+            LIR lir = null;
+            try (Scope s = Debug.scope("FrontEnd"); TimerCloseable a = FrontEnd.start()) {
+                lir = emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, profilingInfo, speculationLog, suites);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
+            try (TimerCloseable a = BackEnd.start()) {
+                LIRGenerator lirGen = null;
+                try (Scope s = Debug.scope("BackEnd", lir)) {
+                    lirGen = emitLIR(backend, target, lir, graph, cc);
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
+                try (Scope s = Debug.scope("CodeGen", lirGen)) {
+                    emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner, factory);
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
         return compilationResult;
     }
 
-    /**
-     * Same as {@link #compileGraph} but without entering a
-     * {@linkplain Debug#scope(String, Object...) debug scope}.
-     */
-    public static <T extends CompilationResult> T compileGraphNoScope(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
-                    TargetDescription target, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog, Suites suites, T compilationResult) {
-        Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
-
-        LIR lir = null;
-        try (Scope s = Debug.scope("FrontEnd"); TimerCloseable a = FrontEnd.start()) {
-            lir = emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
-        } catch (Throwable e) {
-            throw Debug.handle(e);
+    public static ProfilingInfo getProfilingInfo(StructuredGraph graph) {
+        if (graph.method() != null) {
+            return graph.method().getProfilingInfo();
+        } else {
+            return DefaultProfilingInfo.get(TriState.UNKNOWN);
         }
-        try (TimerCloseable a = BackEnd.start()) {
-            LIRGenerator lirGen = null;
-            try (Scope s = Debug.scope("BackEnd", lir)) {
-                lirGen = emitLIR(backend, target, lir, graph, cc);
-            } catch (Throwable e) {
-                throw Debug.handle(e);
-            }
-            try (Scope s = Debug.scope("CodeGen", lirGen)) {
-                emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner);
-            } catch (Throwable e) {
-                throw Debug.handle(e);
-            }
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
-
-        return compilationResult;
     }
 
     private static long[] getLeafGraphIdArray(StructuredGraph graph) {
@@ -189,7 +190,7 @@
      * Builds the graph, optimizes it.
      */
     public static LIR emitHIR(Providers providers, TargetDescription target, StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts,
-                    SpeculationLog speculationLog, Suites suites) {
+                    ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) {
 
         if (speculationLog != null) {
             speculationLog.snapshot();
@@ -206,7 +207,7 @@
         suites.getHighTier().apply(graph, highTierContext);
         graph.maybeCompress();
 
-        MidTierContext midTierContext = new MidTierContext(providers, assumptions, target, optimisticOpts);
+        MidTierContext midTierContext = new MidTierContext(providers, assumptions, target, optimisticOpts, profilingInfo);
         suites.getMidTier().apply(graph, midTierContext);
         graph.maybeCompress();
 
@@ -279,19 +280,43 @@
         return lirGen;
     }
 
-    public static void emitCode(Backend backend, long[] leafGraphIds, Assumptions assumptions, LIRGenerator lirGen, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner) {
-        TargetMethodAssembler tasm = backend.newAssembler(lirGen, compilationResult);
-        backend.emitCode(tasm, lirGen, installedCodeOwner);
-        CompilationResult result = tasm.finishTargetMethod(lirGen.getGraph());
+    public static void emitCode(Backend backend, long[] leafGraphIds, Assumptions assumptions, LIRGenerator lirGen, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner,
+                    CompilationResultBuilderFactory factory) {
+        CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGen, compilationResult, factory);
+        backend.emitCode(crb, lirGen, installedCodeOwner);
+        crb.finish();
         if (!assumptions.isEmpty()) {
-            result.setAssumptions(assumptions);
+            compilationResult.setAssumptions(assumptions);
         }
-        result.setLeafGraphIds(leafGraphIds);
+        compilationResult.setLeafGraphIds(leafGraphIds);
+
+        if (Debug.isMeterEnabled()) {
+            List<DataPatch> ldp = compilationResult.getDataReferences();
+            DebugMetric[] dms = new DebugMetric[Kind.values().length];
+            for (int i = 0; i < dms.length; i++) {
+                dms[i] = Debug.metric("DataPatches-" + Kind.values()[i].toString());
+            }
+            DebugMetric dmRaw = Debug.metric("DataPatches-raw");
+
+            for (DataPatch dp : ldp) {
+                if (dp.constant != null) {
+                    dms[dp.constant.getKind().ordinal()].add(1);
+                } else {
+                    dmRaw.add(1);
+                }
+            }
+
+            Debug.metric("CompilationResults").increment();
+            Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize());
+            Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size());
+            Debug.metric("DataPatches").add(ldp.size());
+            Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size());
+        }
 
         if (Debug.isLogEnabled()) {
-            Debug.log("%s", backend.getProviders().getCodeCache().disassemble(result, null));
+            Debug.log("%s", backend.getProviders().getCodeCache().disassemble(compilationResult, null));
         }
 
-        Debug.dump(result, "After code generation");
+        Debug.dump(compilationResult, "After code generation");
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -25,6 +25,7 @@
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.api.meta.Value.*;
+import static com.oracle.graal.lir.LIR.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
 import static com.oracle.graal.nodes.ConstantNode.*;
 import static com.oracle.graal.phases.GraalOptions.*;
@@ -39,7 +40,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.FallThroughOp;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.StandardOp.LabelOp;
 import com.oracle.graal.nodes.*;
@@ -395,13 +396,14 @@
                 }
             }
         }
-        if (block.getSuccessorCount() >= 1 && !endsWithJump(block)) {
+        if (block.getSuccessorCount() >= 1 && !hasBlockEnd(block)) {
             NodeClassIterable successors = block.getEndNode().successors();
             assert successors.isNotEmpty() : "should have at least one successor : " + block.getEndNode();
-
             emitJump(getLIRBlock((FixedNode) successors.first()));
         }
 
+        assert verifyBlock(lir, block);
+
         if (traceLevel >= 1) {
             TTY.println("END Generating LIR for block B" + block.getId());
         }
@@ -421,18 +423,12 @@
 
     protected abstract boolean peephole(ValueNode valueNode);
 
-    private boolean endsWithJump(Block block) {
-        List<LIRInstruction> instructions = lir.lir(block);
-        if (instructions.size() == 0) {
+    private boolean hasBlockEnd(Block block) {
+        List<LIRInstruction> ops = lir.lir(block);
+        if (ops.size() == 0) {
             return false;
         }
-        LIRInstruction lirInstruction = instructions.get(instructions.size() - 1);
-        if (lirInstruction instanceof StandardOp.JumpOp) {
-            return true;
-        } else if (lirInstruction instanceof FallThroughOp) {
-            return ((FallThroughOp) lirInstruction).fallThroughTarget() != null;
-        }
-        return false;
+        return ops.get(ops.size() - 1) instanceof BlockEndOp;
     }
 
     private void doRoot(ValueNode instr) {
@@ -569,23 +565,19 @@
     }
 
     private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor) {
-        emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.NE, false, falseSuccessor);
-        emitJump(trueSuccessor);
+        emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, falseSuccessor);
     }
 
-    public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) {
-        emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock);
-        emitJump(trueSuccessorBlock);
+    public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+        emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor);
     }
 
     public void emitOverflowCheckBranch(LabelRef noOverflowBlock, LabelRef overflowBlock) {
-        emitOverflowCheckBranch(overflowBlock, false);
-        emitJump(noOverflowBlock);
+        emitOverflowCheckBranch(overflowBlock, noOverflowBlock, false);
     }
 
-    public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) {
-        emitIntegerTestBranch(operand(test.x()), operand(test.y()), true, falseSuccessorBlock);
-        emitJump(trueSuccessorBlock);
+    public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+        emitIntegerTestBranch(operand(test.x()), operand(test.y()), false, trueSuccessor, falseSuccessor);
     }
 
     public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) {
@@ -619,11 +611,11 @@
 
     public abstract void emitJump(LabelRef label);
 
-    public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label);
+    public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination);
 
-    public abstract void emitOverflowCheckBranch(LabelRef label, boolean negated);
+    public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, boolean negated);
 
-    public abstract void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label);
+    public abstract void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef trueDestination, LabelRef falseDestination);
 
     public abstract Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Mon Dec 09 17:31:12 2013 +0100
@@ -67,9 +67,15 @@
 
     public abstract LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir);
 
+    /**
+     * Creates the assembler used to emit the machine code.
+     */
     protected abstract AbstractAssembler createAssembler(FrameMap frameMap);
 
-    public abstract TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult);
+    /**
+     * Creates the object used to fill in the details of a given compilation result.
+     */
+    public abstract CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory);
 
     public abstract boolean shouldAllocateRegisters();
 
@@ -80,5 +86,5 @@
      *            {@linkplain InstalledCode#getMethod() associated} with once installed. This
      *            argument can be null.
      */
-    public abstract void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner);
+    public abstract void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner);
 }
--- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -54,6 +54,7 @@
 
             @Override
             public void generateCode(AMD64Assembler asm) {
+                asm.nop(5); // padding for mt-safe patching
                 asm.ret(0);
             }
         });
@@ -70,6 +71,7 @@
             @Override
             public void generateCode(AMD64Assembler asm) {
                 Register arg = getArgumentRegister(0, Kind.Int);
+                asm.nop(5); // padding for mt-safe patching
                 asm.addl(arg, 5);
                 asm.movl(rax, arg);
                 asm.ret(0);
@@ -88,6 +90,7 @@
             @Override
             public void generateCode(AMD64Assembler asm) {
                 Register arg = getArgumentRegister(0, Kind.Long);
+                asm.nop(5); // padding for mt-safe patching
                 asm.addq(arg, 1);
                 asm.movq(rax, arg);
                 asm.ret(0);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -26,11 +26,12 @@
 
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
 @Opcode("DEOPT")
-final class AMD64DeoptimizeOp extends AMD64LIRInstruction {
+final class AMD64DeoptimizeOp extends AMD64LIRInstruction implements BlockEndOp {
 
     @State private LIRFrameState info;
 
@@ -39,7 +40,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        AMD64Call.directCall(tasm, masm, tasm.foreignCalls.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        AMD64Call.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Mon Dec 09 17:31:12 2013 +0100
@@ -80,73 +80,108 @@
      * 
      * @param afterFrameInit specifies if the stack pointer has already been adjusted to allocate
      *            the current frame
+     * @param isVerifiedEntryPoint specifies if the code buffer is currently at the verified entry
+     *            point
      */
-    protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, boolean afterFrameInit) {
-        if (StackShadowPages.getValue() > 0) {
+    protected static void emitStackOverflowCheck(CompilationResultBuilder crb, int stackShadowPages, boolean afterFrameInit, boolean isVerifiedEntryPoint) {
+        if (stackShadowPages > 0) {
 
-            AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
-            int frameSize = tasm.frameMap.frameSize();
+            AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm;
+            int frameSize = crb.frameMap.frameSize();
             if (frameSize > 0) {
                 int lastFramePage = frameSize / unsafe.pageSize();
                 // emit multiple stack bangs for methods with frames larger than a page
                 for (int i = 0; i <= lastFramePage; i++) {
-                    int disp = (i + StackShadowPages.getValue()) * unsafe.pageSize();
+                    int disp = (i + stackShadowPages) * unsafe.pageSize();
                     if (afterFrameInit) {
                         disp -= frameSize;
                     }
-                    tasm.blockComment("[stack overflow check]");
+                    crb.blockComment("[stack overflow check]");
+                    int pos = asm.codeBuffer.position();
                     asm.movq(new AMD64Address(rsp, -disp), AMD64.rax);
+                    assert i > 0 || !isVerifiedEntryPoint || asm.codeBuffer.position() - pos >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
                 }
             }
         }
     }
 
+    /**
+     * The size of the instruction used to patch the verified entry point of an nmethod when the
+     * nmethod is made non-entrant or a zombie (e.g. during deopt or class unloading). The first
+     * instruction emitted at an nmethod's verified entry point must be at least this length to
+     * ensure mt-safe patching.
+     */
+    public static final int PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE = 5;
+
+    /**
+     * Emits code at the verified entry point and return point(s) of a method.
+     */
     class HotSpotFrameContext implements FrameContext {
 
         final boolean isStub;
+        final boolean omitFrame;
 
-        HotSpotFrameContext(boolean isStub) {
+        HotSpotFrameContext(boolean isStub, boolean omitFrame) {
             this.isStub = isStub;
+            this.omitFrame = omitFrame;
+        }
+
+        public boolean hasFrame() {
+            return !omitFrame;
         }
 
         @Override
-        public void enter(TargetMethodAssembler tasm) {
-            FrameMap frameMap = tasm.frameMap;
+        public void enter(CompilationResultBuilder crb) {
+            FrameMap frameMap = crb.frameMap;
             int frameSize = frameMap.frameSize();
-
-            AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
-            if (!isStub) {
-                emitStackOverflowCheck(tasm, false);
-            }
-            asm.decrementq(rsp, frameSize);
-            if (ZapStackOnMethodEntry.getValue()) {
-                final int intSize = 4;
-                for (int i = 0; i < frameSize / intSize; ++i) {
-                    asm.movl(new AMD64Address(rsp, i * intSize), 0xC1C1C1C1);
+            AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm;
+            if (omitFrame) {
+                if (!isStub) {
+                    asm.nop(PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE);
+                }
+            } else {
+                int verifiedEntryPointOffset = asm.codeBuffer.position();
+                if (!isStub && stackShadowPages > 0) {
+                    emitStackOverflowCheck(crb, stackShadowPages, false, true);
+                    assert asm.codeBuffer.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
                 }
-            }
-            CalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout();
-            if (csl != null && csl.size != 0) {
-                int frameToCSA = frameMap.offsetToCalleeSaveArea();
-                assert frameToCSA >= 0;
-                asm.save(csl, frameToCSA);
+                if (!isStub && asm.codeBuffer.position() == verifiedEntryPointOffset) {
+                    asm.subq(rsp, frameSize, true);
+                    assert asm.codeBuffer.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE;
+                } else {
+                    asm.decrementq(rsp, frameSize);
+                }
+                if (ZapStackOnMethodEntry.getValue()) {
+                    final int intSize = 4;
+                    for (int i = 0; i < frameSize / intSize; ++i) {
+                        asm.movl(new AMD64Address(rsp, i * intSize), 0xC1C1C1C1);
+                    }
+                }
+                CalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout();
+                if (csl != null && csl.size != 0) {
+                    int frameToCSA = frameMap.offsetToCalleeSaveArea();
+                    assert frameToCSA >= 0;
+                    asm.save(csl, frameToCSA);
+                }
             }
         }
 
         @Override
-        public void leave(TargetMethodAssembler tasm) {
-            int frameSize = tasm.frameMap.frameSize();
-            AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
-            CalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
+        public void leave(CompilationResultBuilder crb) {
+            if (!omitFrame) {
+                AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm;
+                CalleeSaveLayout csl = crb.frameMap.registerConfig.getCalleeSaveLayout();
 
-            if (csl != null && csl.size != 0) {
-                tasm.compilationResult.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position());
-                // saved all registers, restore all registers
-                int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
-                asm.restore(csl, frameToCSA);
+                if (csl != null && csl.size != 0) {
+                    crb.compilationResult.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position());
+                    // saved all registers, restore all registers
+                    int frameToCSA = crb.frameMap.offsetToCalleeSaveArea();
+                    asm.restore(csl, frameToCSA);
+                }
+
+                int frameSize = crb.frameMap.frameSize();
+                asm.incrementq(rsp, frameSize);
             }
-
-            asm.incrementq(rsp, frameSize);
         }
     }
 
@@ -156,7 +191,7 @@
     }
 
     @Override
-    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
+    public CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
         // Omit the frame if the method:
         // - has no spill slots or other slots allocated during register allocation
         // - has no callee-saved registers
@@ -171,12 +206,12 @@
 
         Stub stub = gen.getStub();
         AbstractAssembler masm = createAssembler(frameMap);
-        HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext(stub != null);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
-        tasm.setFrameSize(frameMap.frameSize());
+        HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null, omitFrame);
+        CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        crb.setFrameSize(frameMap.frameSize());
         StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot;
         if (deoptimizationRescueSlot != null && stub == null) {
-            tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot));
+            crb.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot));
         }
 
         if (stub != null) {
@@ -184,34 +219,36 @@
             updateStub(stub, definedRegisters, gen.calleeSaveInfo, frameMap);
         }
 
-        return tasm;
+        return crb;
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) {
-        AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
-        FrameMap frameMap = tasm.frameMap;
+    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) {
+        AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm;
+        FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
         HotSpotVMConfig config = getRuntime().getConfig();
-        Label verifiedStub = new Label();
+        Label verifiedEntry = new Label();
 
         // Emit the prefix
-        emitCodePrefix(installedCodeOwner, tasm, asm, regConfig, config, verifiedStub);
+        emitCodePrefix(installedCodeOwner, crb, asm, regConfig, config, verifiedEntry);
 
         // Emit code for the LIR
-        emitCodeBody(installedCodeOwner, tasm, lirGen);
+        emitCodeBody(installedCodeOwner, crb, lirGen);
 
         // Emit the suffix
-        emitCodeSuffix(installedCodeOwner, tasm, lirGen, asm, frameMap);
+        emitCodeSuffix(installedCodeOwner, crb, lirGen, asm, frameMap);
     }
 
     /**
+     * Emits the code prior to the verified entry point.
+     * 
      * @param installedCodeOwner see {@link Backend#emitCode}
      */
-    public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, AMD64MacroAssembler asm, RegisterConfig regConfig, HotSpotVMConfig config, Label verifiedStub) {
+    public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, AMD64MacroAssembler asm, RegisterConfig regConfig, HotSpotVMConfig config, Label verifiedEntry) {
         HotSpotProviders providers = getProviders();
         if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) {
-            tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
+            crb.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
             CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{providers.getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false);
             Register inlineCacheKlass = rax; // see definition of IC_Klass in
                                              // c1_LIRAssembler_x86.cpp
@@ -226,34 +263,36 @@
             } else {
                 asm.cmpq(inlineCacheKlass, src);
             }
-            AMD64Call.directConditionalJmp(tasm, asm, getForeignCalls().lookupForeignCall(IC_MISS_HANDLER), ConditionFlag.NotEqual);
+            AMD64Call.directConditionalJmp(crb, asm, getForeignCalls().lookupForeignCall(IC_MISS_HANDLER), ConditionFlag.NotEqual);
         }
 
         asm.align(config.codeEntryAlignment);
-        tasm.recordMark(Marks.MARK_OSR_ENTRY);
-        asm.bind(verifiedStub);
-        tasm.recordMark(Marks.MARK_VERIFIED_ENTRY);
+        crb.recordMark(Marks.MARK_OSR_ENTRY);
+        asm.bind(verifiedEntry);
+        crb.recordMark(Marks.MARK_VERIFIED_ENTRY);
+    }
+
+    /**
+     * Emits the code which starts at the verified entry point.
+     * 
+     * @param installedCodeOwner see {@link Backend#emitCode}
+     */
+    public void emitCodeBody(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, LIRGenerator lirGen) {
+        lirGen.lir.emitCode(crb);
     }
 
     /**
      * @param installedCodeOwner see {@link Backend#emitCode}
      */
-    public void emitCodeBody(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, LIRGenerator lirGen) {
-        lirGen.lir.emitCode(tasm);
-    }
-
-    /**
-     * @param installedCodeOwner see {@link Backend#emitCode}
-     */
-    public void emitCodeSuffix(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, LIRGenerator lirGen, AMD64MacroAssembler asm, FrameMap frameMap) {
+    public void emitCodeSuffix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, LIRGenerator lirGen, AMD64MacroAssembler asm, FrameMap frameMap) {
         HotSpotProviders providers = getProviders();
-        HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
-        if (frameContext != null && !frameContext.isStub) {
+        HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext;
+        if (!frameContext.isStub) {
             HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls();
-            tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
-            tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null);
+            crb.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
+            AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            crb.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
+            AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null);
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -42,7 +42,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         // reset last Java frame:
         masm.movslq(new AMD64Address(thread, threadLastJavaSpOffset), 0);
         masm.movslq(new AMD64Address(thread, threadLastJavaFpOffset), 0);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -42,7 +42,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         // save last Java frame
         masm.movq(new AMD64Address(thread, threadLastJavaSpOffset), rsp);
     }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -36,8 +36,8 @@
 final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp {
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        leaveFrameAndRestoreRbp(tasm, masm);
-        AMD64Call.directJmp(tasm, masm, tasm.foreignCalls.lookupForeignCall(UNCOMMON_TRAP));
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        leaveFrameAndRestoreRbp(crb, masm);
+        AMD64Call.directJmp(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP));
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -30,13 +30,14 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
  * Superclass for operations that use the value of RBP saved in a method's prologue.
  */
-abstract class AMD64HotSpotEpilogueOp extends AMD64LIRInstruction {
+abstract class AMD64HotSpotEpilogueOp extends AMD64LIRInstruction implements BlockEndOp {
 
     /**
      * The type of location (i.e., stack or register) in which RBP is saved is not known until
@@ -47,18 +48,16 @@
 
     @Use({REG, STACK}) protected AllocatableValue savedRbp = PLACEHOLDER;
 
-    protected void leaveFrameAndRestoreRbp(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         if (isStackSlot(savedRbp)) {
             // Restoring RBP from the stack must be done before the frame is removed
-            masm.movq(rbp, (AMD64Address) tasm.asAddress(savedRbp));
+            masm.movq(rbp, (AMD64Address) crb.asAddress(savedRbp));
         } else {
             Register framePointer = asRegister(savedRbp);
             if (!framePointer.equals(rbp)) {
                 masm.movq(rbp, framePointer);
             }
         }
-        if (tasm.frameContext != null) {
-            tasm.frameContext.leave(tasm);
-        }
+        crb.frameContext.leave(crb);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -55,8 +55,8 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        leaveFrameAndRestoreRbp(tasm, masm);
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        leaveFrameAndRestoreRbp(crb, masm);
 
         // Discard the return address, thus completing restoration of caller frame
         masm.incrementq(rsp, 8);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -574,4 +574,9 @@
             super.visitInfopointNode(i);
         }
     }
+
+    public void emitPrefetchAllocate(ValueNode address, ValueNode distance) {
+        AMD64AddressValue addr = emitAddress(operand(address), 0, loadNonConst(operand(distance)), 1);
+        append(new AMD64PrefetchOp(addr, config.allocatePrefetchInstr));
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Dec 09 17:31:12 2013 +0100
@@ -126,7 +126,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             masm.movq(asRegister(scratch), asRegister(input));
             if (kind == Kind.Object) {
                 encodePointer(masm, asRegister(scratch), heapBaseReg, heapBase, shift, alignment);
@@ -134,7 +134,7 @@
                 encodeKlassPointer(masm, asRegister(scratch), heapBaseReg, klassBase, heapBase, shift, alignment);
             }
             if (state != null) {
-                tasm.recordImplicitException(masm.codeBuffer.position(), state);
+                crb.recordImplicitException(masm.codeBuffer.position(), state);
             }
             masm.movl(address.toAddress(), asRegister(scratch));
         }
@@ -169,12 +169,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            compareAndSwapCompressed(tasm, masm, result, address, cmpValue, newValue, scratch, base, shift, alignment, heapBaseReg);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            compareAndSwapCompressed(crb, masm, result, address, cmpValue, newValue, scratch, base, shift, alignment, heapBaseReg);
         }
     }
 
-    protected static void compareAndSwapCompressed(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue,
+    protected static void compareAndSwapCompressed(CompilationResultBuilder crb, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue,
                     AllocatableValue newValue, AllocatableValue scratch, long base, int shift, int alignment, Register heapBaseReg) {
         assert AMD64.rax.equals(asRegister(cmpValue)) && AMD64.rax.equals(asRegister(result));
         final Register scratchRegister = asRegister(scratch);
@@ -184,7 +184,7 @@
         encodePointer(masm, cmpRegister, heapBase, base, shift, alignment);
         masm.movq(scratchRegister, newRegister);
         encodePointer(masm, scratchRegister, heapBase, base, shift, alignment);
-        if (tasm.target.isMP) {
+        if (crb.target.isMP) {
             masm.lock();
         }
         masm.cmpxchgl(scratchRegister, address.toAddress());
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotPatchReturnAddressOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -45,8 +45,8 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        int frameSize = tasm.frameMap.frameSize();
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        int frameSize = crb.frameMap.frameSize();
         masm.movq(new AMD64Address(rsp, frameSize), asRegister(address));
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -49,10 +49,10 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        leaveFrameAndRestoreRbp(tasm, masm);
-        if (!isStub && (tasm.frameContext != null || !OptEliminateSafepoints.getValue())) {
-            AMD64HotSpotSafepointOp.emitCode(tasm, masm, runtime().getConfig(), true, null, scratchForSafepointOnReturn);
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        leaveFrameAndRestoreRbp(crb, masm);
+        if (!isStub && (crb.frameContext.hasFrame() || !OptEliminateSafepoints.getValue())) {
+            AMD64HotSpotSafepointOp.emitCode(crb, masm, runtime().getConfig(), true, null, scratchForSafepointOnReturn);
         }
         masm.ret(0);
     }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -53,9 +53,9 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
         RegisterValue scratch = (RegisterValue) temp;
-        emitCode(tasm, asm, config, false, state, scratch.getRegister());
+        emitCode(crb, asm, config, false, state, scratch.getRegister());
     }
 
     /**
@@ -68,19 +68,19 @@
         return !NumUtil.isInt(pollingPageAddress - config.codeCacheLowBoundary()) || !NumUtil.isInt(pollingPageAddress - config.codeCacheHighBoundary());
     }
 
-    public static void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
+    public static void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
         final int pos = asm.codeBuffer.position();
         if (isPollingPageFar(config)) {
             asm.movq(scratch, config.safepointPollingAddress);
-            tasm.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR);
+            crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR);
             if (state != null) {
-                tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+                crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
             }
             asm.movq(scratch, new AMD64Address(scratch));
         } else {
-            tasm.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
+            crb.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
             if (state != null) {
-                tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+                crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
             }
             // The C++ code transforms the polling page offset into an RIP displacement
             // to the real address at that offset in the polling page.
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -47,10 +47,10 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        leaveFrameAndRestoreRbp(tasm, masm);
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        leaveFrameAndRestoreRbp(crb, masm);
 
-        ForeignCallLinkage linkage = tasm.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
+        ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
         CallingConvention cc = linkage.getOutgoingCallingConvention();
         assert cc.getArgumentCount() == 2;
         assert exception.equals(cc.getArgument(0));
@@ -59,6 +59,6 @@
         Register returnAddress = asRegister(cc.getArgument(1));
         masm.movq(returnAddress, new AMD64Address(rsp, 0));
 
-        AMD64Call.directJmp(tasm, masm, linkage);
+        AMD64Call.directJmp(crb, masm, linkage);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -51,12 +51,12 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         // The mark for an invocation that uses an inline cache must be placed at the
         // instruction that loads the Klass from the inline cache.
-        AMD64Move.move(tasm, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod);
-        tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
-        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.runtime().getConfig().nonOopBits));
-        super.emitCode(tasm, masm);
+        AMD64Move.move(crb, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod);
+        crb.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
+        AMD64Move.move(crb, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.runtime().getConfig().nonOopBits));
+        super.emitCode(crb, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -51,11 +51,11 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         // The mark for an invocation that uses an inline cache must be placed at the
         // instruction that loads the Klass from the inline cache.
-        tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
-        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.runtime().getConfig().nonOopBits));
-        super.emitCode(tasm, masm);
+        crb.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
+        AMD64Move.move(crb, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.runtime().getConfig().nonOopBits));
+        super.emitCode(crb, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -57,11 +57,11 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        tasm.recordMark(Marks.MARK_INLINE_INVOKE);
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        crb.recordMark(Marks.MARK_INLINE_INVOKE);
         Register callReg = asRegister(targetAddress);
         assert !callReg.equals(METHOD);
-        AMD64Call.indirectCall(tasm, masm, callReg, callTarget, state);
+        AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64PrefetchOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, 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.graal.hotspot.amd64;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+
+public class AMD64PrefetchOp extends AMD64LIRInstruction {
+
+    private final int instr;  // AllocatePrefecthInstr
+    @Alive({COMPOSITE}) protected AMD64AddressValue address;
+
+    public AMD64PrefetchOp(AMD64AddressValue address, int instr) {
+        this.address = address;
+        this.instr = instr;
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        switch (instr) {
+            case 0:
+                masm.prefetchnta(address.toAddress());
+                break;
+            case 1:
+                masm.prefetcht0(address.toAddress());
+                break;
+            case 2:
+                masm.prefetcht2(address.toAddress());
+                break;
+            case 3:
+                masm.prefetchw(address.toAddress());
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("unspported prefetch op " + instr);
+
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -47,7 +47,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         // destroy the current frame (now the return address is the top of stack)
         masm.leave();
 
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,24 +23,26 @@
 
 package com.oracle.graal.hotspot.hsail;
 
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.lang.reflect.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.bridge.CompilerToGPU;
+import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hsail.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
@@ -174,8 +176,8 @@
         CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false);
         SuitesProvider suitesProvider = backend.getSuites();
         try {
-            HSAILCompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(),
-                            suitesProvider.getDefaultSuites(), new HSAILCompilationResult());
+            HSAILCompilationResult compResult = compileGraph(graph, cc, graph.method(), providers, backend, target, null, phasePlan, OptimisticOptimizations.NONE, getProfilingInfo(graph),
+                            new SpeculationLog(), suitesProvider.getDefaultSuites(), true, new HSAILCompilationResult(), CompilationResultBuilderFactory.Default);
             if ((validDevice) && (compResult.getTargetCode() != null)) {
                 long kernel = toGPU.generateKernel(compResult.getTargetCode(), graph.method().getName());
 
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Mon Dec 09 17:31:12 2013 +0100
@@ -94,13 +94,17 @@
 
     class HotSpotFrameContext implements FrameContext {
 
+        public boolean hasFrame() {
+            return true;
+        }
+
         @Override
-        public void enter(TargetMethodAssembler tasm) {
+        public void enter(CompilationResultBuilder crb) {
             Debug.log("Nothing to do here");
         }
 
         @Override
-        public void leave(TargetMethodAssembler tasm) {
+        public void leave(CompilationResultBuilder crb) {
             Debug.log("Nothing to do here");
         }
     }
@@ -111,20 +115,20 @@
     }
 
     @Override
-    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
+    public CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
         FrameMap frameMap = lirGen.frameMap;
         AbstractAssembler masm = createAssembler(frameMap);
         HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        TargetMethodAssembler tasm = new TargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
-        tasm.setFrameSize(frameMap.frameSize());
-        return tasm;
+        CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        crb.setFrameSize(frameMap.frameSize());
+        return crb;
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod method) {
+    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod method) {
         assert method != null : lirGen.getGraph() + " is not associated with a method";
         // Emit the prologue.
-        codeBuffer = tasm.asm.codeBuffer;
+        codeBuffer = crb.asm.codeBuffer;
         codeBuffer.emitString0("version 0:95: $full : $large;");
         codeBuffer.emitString("");
 
@@ -176,7 +180,7 @@
         codeBuffer.emitString0("kernel &run (");
         codeBuffer.emitString("");
 
-        FrameMap frameMap = tasm.frameMap;
+        FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
         // Build list of param types which does include the gid (for cc register mapping query).
         JavaType[] ccParamTypes = new JavaType[nonConstantParamCount + 1];
@@ -280,9 +284,9 @@
             }
         }
         // Prologue done, Emit code for the LIR.
-        lirGen.lir.emitCode(tasm);
+        lirGen.lir.emitCode(crb);
         // Now that code is emitted go back and figure out what the upper Bound stack size was.
-        long maxStackSize = ((HSAILAssembler) tasm.asm).upperBoundStackSize();
+        long maxStackSize = ((HSAILAssembler) crb.asm).upperBoundStackSize();
         String spillsegStringFinal;
         if (maxStackSize == 0) {
             // If no spilling, get rid of spillseg declaration.
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Mon Dec 09 17:31:12 2013 +0100
@@ -157,17 +157,21 @@
     class PTXFrameContext implements FrameContext {
 
         @Override
-        public void enter(TargetMethodAssembler tasm) {
+        public void enter(CompilationResultBuilder crb) {
             // codeBuffer.emitString(".address_size 32"); // PTX ISA version 2.3
         }
 
         @Override
-        public void leave(TargetMethodAssembler tasm) {
+        public void leave(CompilationResultBuilder crb) {
+        }
+
+        public boolean hasFrame() {
+            return true;
         }
     }
 
     @Override
-    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
+    public CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
         // Omit the frame of the method:
         // - has no spill slots or other slots allocated during register allocation
         // - has no callee-saved registers
@@ -176,9 +180,9 @@
         FrameMap frameMap = lirGen.frameMap;
         AbstractAssembler masm = createAssembler(frameMap);
         PTXFrameContext frameContext = new PTXFrameContext();
-        TargetMethodAssembler tasm = new PTXTargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
-        tasm.setFrameSize(0);
-        return tasm;
+        CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        crb.setFrameSize(0);
+        return crb;
     }
 
     @Override
@@ -191,14 +195,14 @@
         return new PTXLIRGenerator(graph, getProviders(), frameMap, cc, lir);
     }
 
-    private static void emitKernelEntry(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
+    private static void emitKernelEntry(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
         // Emit PTX kernel entry text based on PTXParameterOp
         // instructions in the start block. Remove the instructions
         // once kernel entry text and directives are emitted to
         // facilitate seemless PTX code generation subsequently.
         assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method";
         final String name = codeCacheOwner.getName();
-        Buffer codeBuffer = tasm.asm.codeBuffer;
+        Buffer codeBuffer = crb.asm.codeBuffer;
 
         // Emit initial boiler-plate directives.
         codeBuffer.emitString(".version 3.0");
@@ -216,7 +220,7 @@
         // instruction.
         for (LIRInstruction op : lirGen.lir.lir(startBlock)) {
             if (op instanceof PTXParameterOp) {
-                op.emitCode(tasm);
+                op.emitCode(crb);
                 deleteOps.add(op);
             }
         }
@@ -232,11 +236,11 @@
     }
 
     // Emit .reg space declarations
-    private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
+    private static void emitRegisterDecl(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
 
         assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method";
 
-        Buffer codeBuffer = tasm.asm.codeBuffer;
+        Buffer codeBuffer = crb.asm.codeBuffer;
         RegisterAnalysis registerAnalysis = new RegisterAnalysis();
 
         for (Block b : lirGen.lir.codeEmittingOrder()) {
@@ -261,15 +265,15 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
+    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
         assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method";
-        Buffer codeBuffer = tasm.asm.codeBuffer;
+        Buffer codeBuffer = crb.asm.codeBuffer;
         // Emit the prologue
-        emitKernelEntry(tasm, lirGen, codeCacheOwner);
+        emitKernelEntry(crb, lirGen, codeCacheOwner);
 
         // Emit register declarations
         try {
-            emitRegisterDecl(tasm, lirGen, codeCacheOwner);
+            emitRegisterDecl(crb, lirGen, codeCacheOwner);
         } catch (GraalInternalError e) {
             e.printStackTrace();
             // TODO : Better error handling needs to be done once
@@ -280,7 +284,7 @@
         }
         // Emit code for the LIR
         try {
-            lirGen.lir.emitCode(tasm);
+            lirGen.lir.emitCode(crb);
         } catch (GraalInternalError e) {
             e.printStackTrace();
             // TODO : Better error handling needs to be done once
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -39,7 +39,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // TODO the patched call address looks odd (and is invalid) compared to other runtime calls:
         // 0xffffffff749bb5fc: call 0xffffffff415a720c ; {runtime_call}
         // [Exception Handler]
@@ -48,6 +48,6 @@
         // [Deopt Handler Code]
         // 0xffffffff749bb60c: call 0xffffffff748da540 ; {runtime_call}
         // 0xffffffff749bb610: nop
-        SPARCCall.directCall(tasm, masm, tasm.foreignCalls.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
+        SPARCCall.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Dec 09 17:31:12 2013 +0100
@@ -81,19 +81,19 @@
      * @param afterFrameInit specifies if the stack pointer has already been adjusted to allocate
      *            the current frame
      */
-    protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, boolean afterFrameInit) {
-        if (StackShadowPages.getValue() > 0) {
-            SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm;
-            final int frameSize = tasm.frameMap.totalFrameSize();
+    protected static void emitStackOverflowCheck(CompilationResultBuilder crb, int stackShadowPages, boolean afterFrameInit) {
+        if (stackShadowPages > 0) {
+            SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
+            final int frameSize = crb.frameMap.totalFrameSize();
             if (frameSize > 0) {
                 int lastFramePage = frameSize / unsafe.pageSize();
                 // emit multiple stack bangs for methods with frames larger than a page
                 for (int i = 0; i <= lastFramePage; i++) {
-                    int disp = (i + StackShadowPages.getValue()) * unsafe.pageSize();
+                    int disp = (i + stackShadowPages) * unsafe.pageSize();
                     if (afterFrameInit) {
                         disp -= frameSize;
                     }
-                    tasm.blockComment("[stack overflow check]");
+                    crb.blockComment("[stack overflow check]");
                     // Use SPARCAddress to get the final displacement including the stack bias.
                     SPARCAddress address = new SPARCAddress(sp, -disp);
                     if (SPARCAssembler.isSimm13(address.getDisplacement())) {
@@ -115,13 +115,17 @@
             this.isStub = isStub;
         }
 
-        @Override
-        public void enter(TargetMethodAssembler tasm) {
-            final int frameSize = tasm.frameMap.totalFrameSize();
+        public boolean hasFrame() {
+            return true;
+        }
 
-            SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm;
-            if (!isStub) {
-                emitStackOverflowCheck(tasm, false);
+        @Override
+        public void enter(CompilationResultBuilder crb) {
+            final int frameSize = crb.frameMap.totalFrameSize();
+
+            SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
+            if (!isStub && stackShadowPages > 0) {
+                emitStackOverflowCheck(crb, stackShadowPages, false);
             }
             new Save(sp, -frameSize, sp).emit(masm);
 
@@ -135,8 +139,8 @@
         }
 
         @Override
-        public void leave(TargetMethodAssembler tasm) {
-            SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm;
+        public void leave(CompilationResultBuilder crb) {
+            SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
             new RestoreWindow().emit(masm);
         }
     }
@@ -147,7 +151,7 @@
     }
 
     @Override
-    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
+    public CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
         SPARCHotSpotLIRGenerator gen = (SPARCHotSpotLIRGenerator) lirGen;
         FrameMap frameMap = gen.frameMap;
         assert gen.deoptimizationRescueSlot == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame";
@@ -156,11 +160,11 @@
         AbstractAssembler masm = createAssembler(frameMap);
         // On SPARC we always use stack frames.
         HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(getProviders().getCodeCache(), getProviders().getForeignCalls(), frameMap, masm, frameContext, compilationResult);
-        tasm.setFrameSize(frameMap.frameSize());
+        CompilationResultBuilder crb = factory.createBuilder(getProviders().getCodeCache(), getProviders().getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        crb.setFrameSize(frameMap.frameSize());
         StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot;
         if (deoptimizationRescueSlot != null && stub == null) {
-            tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot));
+            crb.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot));
         }
 
         if (stub != null) {
@@ -170,13 +174,13 @@
             updateStub(stub, destroyedRegisters, calleeSaveInfo, frameMap);
         }
 
-        return tasm;
+        return crb;
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) {
-        SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm;
-        FrameMap frameMap = tasm.frameMap;
+    public void emitCode(CompilationResultBuilder crb, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) {
+        SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
+        FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
         HotSpotVMConfig config = getRuntime().getConfig();
         Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label();
@@ -184,7 +188,7 @@
         // Emit the prefix
 
         if (unverifiedStub != null) {
-            tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
+            crb.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
             // We need to use JavaCall here because we haven't entered the frame yet.
             CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getProviders().getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false);
             Register inlineCacheKlass = g5; // see MacroAssembler::ic_call
@@ -199,19 +203,19 @@
         }
 
         masm.align(config.codeEntryAlignment);
-        tasm.recordMark(Marks.MARK_OSR_ENTRY);
-        tasm.recordMark(Marks.MARK_VERIFIED_ENTRY);
+        crb.recordMark(Marks.MARK_OSR_ENTRY);
+        crb.recordMark(Marks.MARK_VERIFIED_ENTRY);
 
         // Emit code for the LIR
-        lirGen.lir.emitCode(tasm);
+        lirGen.lir.emitCode(crb);
 
-        HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
+        HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext;
         HotSpotForeignCallsProvider foreignCalls = getProviders().getForeignCalls();
-        if (frameContext != null && !frameContext.isStub) {
-            tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
-            tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null);
+        if (!frameContext.isStub) {
+            crb.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
+            SPARCCall.directCall(crb, masm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            crb.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
+            SPARCCall.directCall(crb, masm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null);
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
@@ -221,7 +225,7 @@
         if (unverifiedStub != null) {
             masm.bind(unverifiedStub);
             Register scratch = g3;
-            SPARCCall.indirectJmp(tasm, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
+            SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Dec 09 17:31:12 2013 +0100
@@ -25,7 +25,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
@@ -71,7 +70,12 @@
 
     @SuppressWarnings("unused")
     private static Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) {
-        throw GraalInternalError.unimplemented();
+        CalleeSaveLayout csl = regConfig.getCalleeSaveLayout();
+        Value[] nativeABICallerSaveRegisters = new Value[csl.registers.length];
+        for (int i = 0; i < csl.registers.length; i++) {
+            nativeABICallerSaveRegisters[i] = csl.registers[i].asValue();
+        }
+        return nativeABICallerSaveRegisters;
     }
 
     public String getArchitecture() {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -49,7 +49,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 
         // Restore the thread register when coming back from the runtime.
         new Mov(l7, thread).emit(masm);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -47,7 +47,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 
         // Save last Java frame.
         new Add(stackPointer, new SPARCAddress(stackPointer, 0).getDisplacement(), g4).emit(masm);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot.sparc;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 
@@ -35,7 +34,6 @@
 
     @Override
     protected RegisterConfig createRegisterConfig() {
-        throw GraalInternalError.unimplemented();
+        return new SPARCHotSpotRegisterConfig(getTarget().arch, runtime.getConfig());
     }
-
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -38,17 +38,17 @@
 final class SPARCHotSpotDeoptimizeCallerOp extends SPARCHotSpotEpilogueOp {
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        leaveFrame(tasm);
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        leaveFrame(crb);
 
         // SPARCHotSpotBackend backend = (SPARCHotSpotBackend)
         // HotSpotGraalRuntime.runtime().getBackend();
         // final boolean isStub = true;
         // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub);
-        // frameContext.enter(tasm);
+        // frameContext.enter(crb);
         Register scratch = g3;
-        SPARCCall.indirectJmp(tasm, masm, scratch, tasm.foreignCalls.lookupForeignCall(UNCOMMON_TRAP));
+        SPARCCall.indirectJmp(crb, masm, scratch, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP));
 
-        // frameContext.leave(tasm);
+        // frameContext.leave(crb);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -30,9 +30,7 @@
  */
 abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction {
 
-    protected void leaveFrame(TargetMethodAssembler tasm) {
-        if (tasm.frameContext != null) {
-            tasm.frameContext.leave(tasm);
-        }
+    protected void leaveFrame(CompilationResultBuilder crb) {
+        crb.frameContext.leave(crb);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -60,8 +60,8 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        leaveFrame(tasm);
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        leaveFrame(crb);
 
         // Restore SP from L7 if the exception PC is a method handle call site.
         SPARCAddress dst = new SPARCAddress(thread, isMethodHandleReturnOffset);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -311,4 +311,9 @@
         GraalInternalError.shouldNotReachHere("binary negation not implemented");
         return null;
     }
+
+    public void emitPrefetchAllocate(ValueNode address, ValueNode distance) {
+        SPARCAddressValue addr = emitAddress(operand(address), 0, loadNonConst(operand(distance)), 1);
+        append(new SPARCPrefetchOp(addr, config.allocatePrefetchInstr));
+    }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -45,10 +45,10 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // FIXME This is non-trivial. On SPARC we need to flush all register windows first before we
         // can patch the return address (see: frame::patch_pc).
-        // int frameSize = tasm.frameMap.frameSize();
+        // int frameSize = crb.frameMap.frameSize();
         // new Stx(asRegister(address), new SPARCAddress(sp, frameSize));
         new Ldx(new SPARCAddress(g0, 0x123), g0).emit(masm);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -48,12 +48,12 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        if (!isStub && (tasm.frameContext != null || !OptEliminateSafepoints.getValue())) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        if (!isStub && (crb.frameContext.hasFrame() || !OptEliminateSafepoints.getValue())) {
             // Using the same scratch register as LIR_Assembler::return_op
             // in c1_LIRAssembler_sparc.cpp
-            SPARCHotSpotSafepointOp.emitCode(tasm, masm, runtime().getConfig(), true, null, SPARC.l0);
+            SPARCHotSpotSafepointOp.emitCode(crb, masm, runtime().getConfig(), true, null, SPARC.l0);
         }
-        ReturnOp.emitCodeHelper(tasm, masm);
+        ReturnOp.emitCodeHelper(crb, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -53,17 +53,17 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         Register scratch = ((RegisterValue) temp).getRegister();
-        emitCode(tasm, masm, config, false, state, scratch);
+        emitCode(crb, masm, config, false, state, scratch);
     }
 
-    public static void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
+    public static void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
         final int pos = masm.codeBuffer.position();
         new Setx(config.safepointPollingAddress, scratch).emit(masm);
-        tasm.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
+        crb.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR);
         if (state != null) {
-            tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
+            crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
         }
         new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -48,10 +48,10 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        leaveFrame(tasm);
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        leaveFrame(crb);
 
-        ForeignCallLinkage linkage = tasm.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
+        ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
         CallingConvention cc = linkage.getOutgoingCallingConvention();
         assert cc.getArgumentCount() == 2;
         assert exception.equals(cc.getArgument(0));
@@ -61,6 +61,6 @@
         new Mov(o7, returnAddress).emit(masm);
 
         Register scratch = g5;
-        SPARCCall.indirectJmp(tasm, masm, scratch, linkage);
+        SPARCCall.indirectJmp(crb, masm, scratch, linkage);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -54,13 +54,13 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // The mark for an invocation that uses an inline cache must be placed at the
         // instruction that loads the Klass from the inline cache.
-        SPARCMove.move(tasm, masm, g5.asValue(Kind.Long), metaspaceMethod);
-        tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
-        // SPARCMove.move(tasm, masm, g3.asValue(Kind.Long), Constant.LONG_0);
+        SPARCMove.move(crb, masm, g5.asValue(Kind.Long), metaspaceMethod);
+        crb.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
+        // SPARCMove.move(crb, masm, g3.asValue(Kind.Long), Constant.LONG_0);
         new Setx(nonOopBits, g3, true).emit(masm);
-        super.emitCode(tasm, masm);
+        super.emitCode(crb, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -51,11 +51,11 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // The mark for an invocation that uses an inline cache must be placed at the
         // instruction that loads the Klass from the inline cache.
-        tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
+        crb.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
         new Setx(HotSpotGraalRuntime.runtime().getConfig().nonOopBits, g3, true).emit(masm);
-        super.emitCode(tasm, masm);
+        super.emitCode(crb, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -57,11 +57,11 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        tasm.recordMark(Marks.MARK_INLINE_INVOKE);
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        crb.recordMark(Marks.MARK_INLINE_INVOKE);
         Register callReg = asRegister(targetAddress);
         assert !callReg.equals(METHOD);
-        SPARCCall.indirectCall(tasm, masm, callReg, callTarget, state);
+        SPARCCall.indirectCall(crb, masm, callReg, callTarget, state);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, 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.graal.hotspot.sparc;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.sparc.*;
+
+public class SPARCPrefetchOp extends SPARCLIRInstruction {
+
+    private final int instr;  // AllocatePrefecthInstr
+    @Alive({COMPOSITE}) protected SPARCAddressValue address;
+
+    public SPARCPrefetchOp(SPARCAddressValue address, int instr) {
+        this.address = address;
+        this.instr = instr;
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        assert instr == 0 : "only supported value is 0";
+        // masm.prefetch(address.toAddress(), 2);
+        throw GraalInternalError.unimplemented("prefetch instruction");
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.nodes.ConstantNode.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 
@@ -32,11 +33,11 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.options.*;
@@ -207,8 +208,8 @@
             CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
             // create suites everytime, as we modify options for the compiler
             final Suites suitesLocal = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites().createSuites();
-            final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
-                            new SpeculationLog(), suitesLocal, new CompilationResult());
+            final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
+                            getProfilingInfo(graph), new SpeculationLog(), suitesLocal, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
             addMethod(method, compResult);
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 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.graal.hotspot.test;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.hotspot.meta.*;
+
+/**
+ * Tests {@link HotSpotResolvedObjectType} functionality.
+ */
+public class HotSpotResolvedObjectTypeTest extends GraalCompilerTest {
+
+    @Test
+    public void testGetSourceFileName() throws Throwable {
+        Assert.assertEquals("Object.java", HotSpotResolvedObjectType.fromClass(Object.class).getSourceFileName());
+        Assert.assertEquals("HotSpotResolvedObjectTypeTest.java", HotSpotResolvedObjectType.fromClass(this.getClass()).getSourceFileName());
+    }
+}
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -247,7 +247,7 @@
         try (Scope s = Debug.scope("WriteBarrierAdditionTest", new DebugDumpScope(snippet))) {
             StructuredGraph graph = parse(snippet);
             HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-            MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+            MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo());
             new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext);
             new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext);
             new GuardLoweringPhase().apply(graph, midContext);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Mon Dec 09 17:31:12 2013 +0100
@@ -615,7 +615,7 @@
             HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
 
-            MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+            MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo());
 
             new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
             new GuardLoweringPhase().apply(graph, midTierContext);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.phases.common.InliningUtil.*;
@@ -35,12 +36,12 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
@@ -63,6 +64,7 @@
     private final HotSpotBackend backend;
     private final PhasePlan plan;
     private final OptimisticOptimizations optimisticOpts;
+    private final ProfilingInfo profilingInfo;
     private final HotSpotResolvedJavaMethod method;
     private final int entryBCI;
     private final int id;
@@ -70,16 +72,18 @@
 
     private StructuredGraph graph;
 
-    public static CompilationTask create(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
-        return new CompilationTask(backend, plan, optimisticOpts, method, entryBCI, id);
+    public static CompilationTask create(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, HotSpotResolvedJavaMethod method, int entryBCI,
+                    int id) {
+        return new CompilationTask(backend, plan, optimisticOpts, profilingInfo, method, entryBCI, id);
     }
 
-    private CompilationTask(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
+    private CompilationTask(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
         assert id >= 0;
         this.backend = backend;
         this.plan = plan;
         this.method = method;
         this.optimisticOpts = optimisticOpts;
+        this.profilingInfo = profilingInfo;
         this.entryBCI = entryBCI;
         this.id = id;
         this.status = new AtomicReference<>(CompilationStatus.Queued);
@@ -161,8 +165,8 @@
                 InlinedBytecodes.add(method.getCodeSize());
                 CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
                 Suites suites = providers.getSuites().getDefaultSuites();
-                result = GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, method.getSpeculationLog(), suites,
-                                new CompilationResult());
+                result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, profilingInfo, method.getSpeculationLog(), suites, true,
+                                new CompilationResult(), CompilationResultBuilderFactory.Default);
 
             } catch (Throwable e) {
                 throw Debug.handle(e);
@@ -232,12 +236,6 @@
         HotSpotInstalledCode installedCode = null;
         try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) {
             installedCode = codeCache.installMethod(method, entryBCI, compResult);
-            if (Debug.isDumpEnabled()) {
-                Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
-            }
-            if (Debug.isLogEnabled()) {
-                Debug.log("%s", backend.getProviders().getDisassembler().disassemble(installedCode));
-            }
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Dec 09 17:31:12 2013 +0100
@@ -42,6 +42,8 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.runtime.*;
 
+//JaCoCo Exclude
+
 /**
  * Singleton class holding the instance of the {@link GraalRuntime}.
  */
@@ -187,6 +189,16 @@
     protected final HotSpotVMConfig config;
     private final HotSpotBackend hostBackend;
 
+    public final HotSpotResolvedPrimitiveType typeBoolean;
+    public final HotSpotResolvedPrimitiveType typeByte;
+    public final HotSpotResolvedPrimitiveType typeChar;
+    public final HotSpotResolvedPrimitiveType typeShort;
+    public final HotSpotResolvedPrimitiveType typeInt;
+    public final HotSpotResolvedPrimitiveType typeLong;
+    public final HotSpotResolvedPrimitiveType typeFloat;
+    public final HotSpotResolvedPrimitiveType typeDouble;
+    public final HotSpotResolvedPrimitiveType typeVoid;
+
     private final Map<Class<? extends Architecture>, HotSpotBackend> backends = new HashMap<>();
 
     private HotSpotGraalRuntime() {
@@ -199,6 +211,26 @@
         vmToCompiler = toCompiler;
         config = new HotSpotVMConfig(compilerToVm);
 
+        typeBoolean = new HotSpotResolvedPrimitiveType(Kind.Boolean);
+        typeByte = new HotSpotResolvedPrimitiveType(Kind.Byte);
+        typeChar = new HotSpotResolvedPrimitiveType(Kind.Char);
+        typeShort = new HotSpotResolvedPrimitiveType(Kind.Short);
+        typeInt = new HotSpotResolvedPrimitiveType(Kind.Int);
+        typeLong = new HotSpotResolvedPrimitiveType(Kind.Long);
+        typeFloat = new HotSpotResolvedPrimitiveType(Kind.Float);
+        typeDouble = new HotSpotResolvedPrimitiveType(Kind.Double);
+        typeVoid = new HotSpotResolvedPrimitiveType(Kind.Void);
+
+        initMirror(typeBoolean);
+        initMirror(typeByte);
+        initMirror(typeChar);
+        initMirror(typeShort);
+        initMirror(typeInt);
+        initMirror(typeLong);
+        initMirror(typeFloat);
+        initMirror(typeDouble);
+        initMirror(typeVoid);
+
         // Set some global options:
         if (config.compileTheWorld) {
             GraalOptions.CompileTheWorld.setValue(CompileTheWorld.SUN_BOOT_CLASS_PATH);
@@ -235,12 +267,18 @@
             registerBackend(factory.createBackend(this, hostBackend));
         }
 
-        GraalOptions.StackShadowPages.setValue(config.stackShadowPages);
         if (GraalOptions.CacheGraphs.getValue()) {
             cache = new HotSpotGraphCache(compilerToVm);
         }
     }
 
+    private void initMirror(HotSpotResolvedPrimitiveType type) {
+        Class<?> mirror = type.mirror();
+        final long offset = config.graalMirrorInClassOffset;
+        unsafe.putObject(mirror, offset, type);
+        assert unsafe.getObject(mirror, offset) == type;
+    }
+
     private HotSpotBackend registerBackend(HotSpotBackend backend) {
         Class<? extends Architecture> arch = backend.getTarget().arch.getClass();
         HotSpotBackend oldValue = backends.put(arch, backend);
@@ -256,9 +294,11 @@
         String arch = System.getProperty("os.arch");
         switch (arch) {
             case "x86_64":
-                // This is what Mac OS X reports;
                 arch = "amd64";
                 break;
+            case "sparcv9":
+                arch = "sparc";
+                break;
         }
         return arch;
     }
@@ -321,32 +361,31 @@
     }
 
     public JavaType lookupType(String name, HotSpotResolvedObjectType accessingClass, boolean eagerResolve) {
-        if (name.length() == 1 && vmToCompiler instanceof VMToCompilerImpl) {
-            VMToCompilerImpl impl = (VMToCompilerImpl) vmToCompiler;
+        if (name.length() == 1) {
             Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
             switch (kind) {
                 case Boolean:
-                    return impl.typeBoolean;
+                    return typeBoolean;
                 case Byte:
-                    return impl.typeByte;
+                    return typeByte;
                 case Char:
-                    return impl.typeChar;
+                    return typeChar;
+                case Short:
+                    return typeShort;
+                case Int:
+                    return typeInt;
+                case Long:
+                    return typeLong;
+                case Float:
+                    return typeFloat;
                 case Double:
-                    return impl.typeDouble;
-                case Float:
-                    return impl.typeFloat;
+                    return typeDouble;
+                case Void:
+                    return typeVoid;
+                case Object:
+                    break;
                 case Illegal:
                     break;
-                case Int:
-                    return impl.typeInt;
-                case Long:
-                    return impl.typeLong;
-                case Object:
-                    break;
-                case Short:
-                    return impl.typeShort;
-                case Void:
-                    return impl.typeVoid;
             }
         }
         return compilerToVm.lookupType(name, accessingClass, eagerResolve);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Mon Dec 09 17:31:12 2013 +0100
@@ -37,8 +37,14 @@
  */
 public abstract class HotSpotHostBackend extends HotSpotBackend {
 
+    /**
+     * This will be 0 if stack banging is disabled.
+     */
+    protected final int stackShadowPages;
+
     public HotSpotHostBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
         super(runtime, providers);
+        this.stackShadowPages = runtime.getConfig().useStackBanging ? runtime.getConfig().stackShadowPages : 0;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -50,6 +50,8 @@
 
     void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc);
 
+    void emitPrefetchAllocate(ValueNode address, ValueNode distance);
+
     void visitDirectCompareAndSwap(DirectCompareAndSwapNode x);
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013, 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.graal.hotspot;
+
+import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import java.io.*;
+
+import com.oracle.graal.graph.*;
+
+/**
+ * Represents a metaspace {@code Symbol}.
+ */
+public class HotSpotSymbol {
+
+    private final long metaspaceSymbol;
+
+    public HotSpotSymbol(long metaspaceSymbol) {
+        assert metaspaceSymbol != 0;
+        this.metaspaceSymbol = metaspaceSymbol;
+    }
+
+    /**
+     * Decodes this {@code Symbol} and returns the symbol string as {@link java.lang.String}.
+     */
+    public String asString() {
+        return readModifiedUTF8(asByteArray());
+    }
+
+    private static String readModifiedUTF8(byte[] buf) {
+        try {
+            final int length = buf.length;
+            byte[] tmp = new byte[length + 2];
+            // write modified UTF-8 length as short in big endian
+            tmp[0] = (byte) ((length >>> 8) & 0xFF);
+            tmp[1] = (byte) ((length >>> 0) & 0xFF);
+            // copy the data
+            System.arraycopy(buf, 0, tmp, 2, length);
+            DataInputStream dis = new DataInputStream(new ByteArrayInputStream(tmp));
+            return dis.readUTF();
+        } catch (IOException e) {
+            // This should never happen so let's fail hard here.
+            throw GraalInternalError.shouldNotReachHere("error reading symbol: " + e);
+        }
+    }
+
+    private byte[] asByteArray() {
+        final int length = getLength();
+        byte[] result = new byte[length];
+        for (int index = 0; index < length; index++) {
+            result[index] = getByteAt(index);
+        }
+        return result;
+    }
+
+    private int getLength() {
+        return unsafe.getShort(metaspaceSymbol + runtime().getConfig().symbolLengthOffset);
+    }
+
+    private byte getByteAt(int index) {
+        return unsafe.getByte(metaspaceSymbol + runtime().getConfig().symbolBodyOffset + index);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Dec 09 17:31:12 2013 +0100
@@ -73,6 +73,7 @@
             if (f.isAnnotationPresent(HotSpotVMField.class)) {
                 HotSpotVMField annotation = f.getAnnotation(HotSpotVMField.class);
                 String name = annotation.name();
+                String type = annotation.type();
                 VMFields.Field entry = vmFields.get(name);
                 if (entry == null) {
                     if (annotation.optional()) {
@@ -81,6 +82,14 @@
                         throw new IllegalArgumentException("field not found: " + name);
                     }
                 }
+
+                // Make sure the native type is still the type we expect.
+                if (!type.equals("")) {
+                    if (!type.equals(entry.getTypeString())) {
+                        throw new IllegalArgumentException("compiler expects type " + type + " but field " + name + " is of type " + entry.getTypeString());
+                    }
+                }
+
                 switch (annotation.get()) {
                     case OFFSET:
                         setField(f, entry.getOffset());
@@ -664,8 +673,15 @@
     @HotSpotVMFlag(name = "UseCRC32Intrinsics") @Stable public boolean useCRC32Intrinsics;
     @HotSpotVMFlag(name = "UseG1GC") @Stable public boolean useG1GC;
 
-    @HotSpotVMField(name = "Universe::_collectedHeap", get = HotSpotVMField.Type.VALUE) @Stable private long universeCollectedHeap;
-    @HotSpotVMField(name = "CollectedHeap::_total_collections", get = HotSpotVMField.Type.OFFSET) @Stable private int collectedHeapTotalCollectionsOffset;
+    @HotSpotVMFlag(name = "AllocatePrefetchStyle") @Stable public int allocatePrefetchStyle;
+    @HotSpotVMFlag(name = "AllocatePrefetchInstr") @Stable public int allocatePrefetchInstr;
+    @HotSpotVMFlag(name = "AllocatePrefetchLines") @Stable public int allocatePrefetchLines;
+    @HotSpotVMFlag(name = "AllocateInstancePrefetchLines") @Stable public int allocateInstancePrefetchLines;
+    @HotSpotVMFlag(name = "AllocatePrefetchStepSize") @Stable public int allocatePrefetchStepSize;
+    @HotSpotVMFlag(name = "AllocatePrefetchDistance") @Stable public int allocatePrefetchDistance;
+
+    @HotSpotVMField(name = "Universe::_collectedHeap", type = "CollectedHeap*", get = HotSpotVMField.Type.VALUE) @Stable private long universeCollectedHeap;
+    @HotSpotVMField(name = "CollectedHeap::_total_collections", type = "unsigned int", get = HotSpotVMField.Type.OFFSET) @Stable private int collectedHeapTotalCollectionsOffset;
 
     public long gcTotalCollectionsAddress() {
         return universeCollectedHeap + collectedHeapTotalCollectionsOffset;
@@ -678,16 +694,16 @@
     @HotSpotVMFlag(name = "UseCompressedOops") @Stable public boolean useCompressedOops;
     @HotSpotVMFlag(name = "UseCompressedClassPointers") @Stable public boolean useCompressedClassPointers;
 
-    @HotSpotVMField(name = "Universe::_narrow_oop._base", get = HotSpotVMField.Type.VALUE) @Stable public long narrowOopBase;
-    @HotSpotVMField(name = "Universe::_narrow_oop._shift", get = HotSpotVMField.Type.VALUE) @Stable public int narrowOopShift;
+    @HotSpotVMField(name = "Universe::_narrow_oop._base", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long narrowOopBase;
+    @HotSpotVMField(name = "Universe::_narrow_oop._shift", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int narrowOopShift;
     @HotSpotVMFlag(name = "ObjectAlignmentInBytes") @Stable public int objectAlignment;
 
     public int logMinObjAlignment() {
         return (int) (Math.log(objectAlignment) / Math.log(2));
     }
 
-    @HotSpotVMField(name = "Universe::_narrow_klass._base", get = HotSpotVMField.Type.VALUE) @Stable public long narrowKlassBase;
-    @HotSpotVMField(name = "Universe::_narrow_klass._shift", get = HotSpotVMField.Type.VALUE) @Stable public int narrowKlassShift;
+    @HotSpotVMField(name = "Universe::_narrow_klass._base", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long narrowKlassBase;
+    @HotSpotVMField(name = "Universe::_narrow_klass._shift", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int narrowKlassShift;
     @HotSpotVMConstant(name = "LogKlassAlignmentInBytes") @Stable public int logKlassAlignment;
 
     // CPU capabilities
@@ -696,19 +712,20 @@
 
     // offsets, ...
     @HotSpotVMFlag(name = "StackShadowPages") @Stable public int stackShadowPages;
+    @HotSpotVMFlag(name = "UseStackBanging") @Stable public boolean useStackBanging;
 
-    @HotSpotVMField(name = "oopDesc::_mark", get = HotSpotVMField.Type.OFFSET) @Stable public int markOffset;
-    @HotSpotVMField(name = "oopDesc::_metadata._klass", get = HotSpotVMField.Type.OFFSET) @Stable public int hubOffset;
+    @HotSpotVMField(name = "oopDesc::_mark", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int markOffset;
+    @HotSpotVMField(name = "oopDesc::_metadata._klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int hubOffset;
 
-    @HotSpotVMField(name = "Klass::_prototype_header", get = HotSpotVMField.Type.OFFSET) @Stable public int prototypeMarkWordOffset;
-    @HotSpotVMField(name = "Klass::_subklass", get = HotSpotVMField.Type.OFFSET) @Stable public int subklassOffset;
-    @HotSpotVMField(name = "Klass::_next_sibling", get = HotSpotVMField.Type.OFFSET) @Stable public int nextSiblingOffset;
-    @HotSpotVMField(name = "Klass::_super_check_offset", get = HotSpotVMField.Type.OFFSET) @Stable public int superCheckOffsetOffset;
-    @HotSpotVMField(name = "Klass::_secondary_super_cache", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySuperCacheOffset;
-    @HotSpotVMField(name = "Klass::_secondary_supers", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySupersOffset;
+    @HotSpotVMField(name = "Klass::_prototype_header", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int prototypeMarkWordOffset;
+    @HotSpotVMField(name = "Klass::_subklass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int subklassOffset;
+    @HotSpotVMField(name = "Klass::_next_sibling", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int nextSiblingOffset;
+    @HotSpotVMField(name = "Klass::_super_check_offset", type = "juint", get = HotSpotVMField.Type.OFFSET) @Stable public int superCheckOffsetOffset;
+    @HotSpotVMField(name = "Klass::_secondary_super_cache", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySuperCacheOffset;
+    @HotSpotVMField(name = "Klass::_secondary_supers", type = "Array<Klass*>*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySupersOffset;
 
     @HotSpotVMType(name = "vtableEntry", get = HotSpotVMType.Type.SIZE) @Stable public int vtableEntrySize;
-    @HotSpotVMField(name = "vtableEntry::_method", get = HotSpotVMField.Type.OFFSET) @Stable public int vtableEntryMethodOffset;
+    @HotSpotVMField(name = "vtableEntry::_method", type = "Method*", get = HotSpotVMField.Type.OFFSET) @Stable public int vtableEntryMethodOffset;
     @Stable public int instanceKlassVtableStartOffset;
 
     /**
@@ -716,25 +733,29 @@
      */
     @Stable public int arrayLengthOffset;
 
-    @HotSpotVMField(name = "Array<Klass*>::_length", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset;
-    @HotSpotVMField(name = "Array<Klass*>::_data", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayBaseOffset;
+    @HotSpotVMField(name = "Array<int>::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1LengthOffset;
+    @HotSpotVMField(name = "Array<u1>::_data", type = "", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1DataOffset;
+    @HotSpotVMField(name = "Array<Klass*>::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset;
+    @HotSpotVMField(name = "Array<Klass*>::_data[0]", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayBaseOffset;
 
-    @HotSpotVMField(name = "InstanceKlass::_init_state", get = HotSpotVMField.Type.OFFSET) @Stable public int klassStateOffset;
+    @HotSpotVMField(name = "InstanceKlass::_source_file_name_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSourceFileNameIndexOffset;
+    @HotSpotVMField(name = "InstanceKlass::_init_state", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int klassStateOffset;
+    @HotSpotVMConstant(name = "InstanceKlass::linked") @Stable public int klassStateLinked;
     @HotSpotVMConstant(name = "InstanceKlass::fully_initialized") @Stable public int klassStateFullyInitialized;
-    @HotSpotVMField(name = "InstanceKlass::_constants", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset;
-
-    @HotSpotVMField(name = "ObjArrayKlass::_element_klass", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayClassElementOffset;
+    @HotSpotVMField(name = "InstanceKlass::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset;
 
-    @HotSpotVMField(name = "Thread::_tlab", get = HotSpotVMField.Type.OFFSET) @Stable public int threadTlabOffset;
+    @HotSpotVMField(name = "ObjArrayKlass::_element_klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayClassElementOffset;
+
+    @HotSpotVMField(name = "Thread::_tlab", type = "ThreadLocalAllocBuffer", get = HotSpotVMField.Type.OFFSET) @Stable public int threadTlabOffset;
 
-    @HotSpotVMField(name = "JavaThread::_anchor", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadAnchorOffset;
-    @HotSpotVMField(name = "JavaThread::_threadObj", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectOffset;
-    @HotSpotVMField(name = "JavaThread::_osthread", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadOffset;
-    @HotSpotVMField(name = "JavaThread::_dirty_card_queue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadDirtyCardQueueOffset;
-    @HotSpotVMField(name = "JavaThread::_is_method_handle_return", get = HotSpotVMField.Type.OFFSET) @Stable public int threadIsMethodHandleReturnOffset;
-    @HotSpotVMField(name = "JavaThread::_satb_mark_queue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadSatbMarkQueueOffset;
-    @HotSpotVMField(name = "JavaThread::_vm_result", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
-    @HotSpotVMField(name = "JavaThread::_graal_counters[0]", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable public int graalCountersThreadOffset;
+    @HotSpotVMField(name = "JavaThread::_anchor", type = "JavaFrameAnchor", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadAnchorOffset;
+    @HotSpotVMField(name = "JavaThread::_threadObj", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectOffset;
+    @HotSpotVMField(name = "JavaThread::_osthread", type = "OSThread*", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadOffset;
+    @HotSpotVMField(name = "JavaThread::_dirty_card_queue", type = "DirtyCardQueue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadDirtyCardQueueOffset;
+    @HotSpotVMField(name = "JavaThread::_is_method_handle_return", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int threadIsMethodHandleReturnOffset;
+    @HotSpotVMField(name = "JavaThread::_satb_mark_queue", type = "ObjPtrQueue", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadSatbMarkQueueOffset;
+    @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
+    @HotSpotVMField(name = "JavaThread::_graal_counters[0]", type = "jlong", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable public int graalCountersThreadOffset;
 
     @HotSpotVMConstant(name = "GRAAL_COUNTERS_SIZE", optional = true) @Stable public int graalCountersSize;
 
@@ -744,13 +765,13 @@
      * <p>
      * <b>NOTE: This is not the same as {@link #pendingExceptionOffset}.</b>
      */
-    @HotSpotVMField(name = "JavaThread::_exception_oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadExceptionOopOffset;
-    @HotSpotVMField(name = "JavaThread::_exception_pc", get = HotSpotVMField.Type.OFFSET) @Stable public int threadExceptionPcOffset;
+    @HotSpotVMField(name = "JavaThread::_exception_oop", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadExceptionOopOffset;
+    @HotSpotVMField(name = "JavaThread::_exception_pc", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int threadExceptionPcOffset;
 
-    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_sp", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaSpOffset;
-    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_pc", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaPcOffset;
-    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_fp", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable private int javaFrameAnchorLastJavaFpOffset;
-    @HotSpotVMField(name = "JavaFrameAnchor::_flags", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable private int javaFrameAnchorFlagsOffset;
+    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_sp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaSpOffset;
+    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_pc", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaPcOffset;
+    @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_fp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable private int javaFrameAnchorLastJavaFpOffset;
+    @HotSpotVMField(name = "JavaFrameAnchor::_flags", type = "int", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable private int javaFrameAnchorFlagsOffset;
 
     public int threadLastJavaSpOffset() {
         return javaThreadAnchorOffset + javaFrameAnchorLastJavaSpOffset;
@@ -776,11 +797,11 @@
         return javaThreadAnchorOffset + javaFrameAnchorFlagsOffset;
     }
 
-    @HotSpotVMField(name = "PtrQueue::_active", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueActiveOffset;
-    @HotSpotVMField(name = "PtrQueue::_buf", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueBufferOffset;
-    @HotSpotVMField(name = "PtrQueue::_index", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueIndexOffset;
+    @HotSpotVMField(name = "PtrQueue::_active", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueActiveOffset;
+    @HotSpotVMField(name = "PtrQueue::_buf", type = "void**", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueBufferOffset;
+    @HotSpotVMField(name = "PtrQueue::_index", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueIndexOffset;
 
-    @HotSpotVMField(name = "OSThread::_interrupted", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadInterruptedOffset;
+    @HotSpotVMField(name = "OSThread::_interrupted", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadInterruptedOffset;
 
     @HotSpotVMConstant(name = "markOopDesc::unlocked_value") @Stable public int unlockedMask;
     @HotSpotVMConstant(name = "markOopDesc::biased_lock_mask_in_place") @Stable public int biasedLockMaskInPlace;
@@ -817,8 +838,8 @@
      * <p>
      * <b>NOTE: This is not the same as {@link #threadExceptionOopOffset}.</b>
      */
-    @HotSpotVMField(name = "ThreadShadow::_pending_exception", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingExceptionOffset;
-    @HotSpotVMField(name = "ThreadShadow::_pending_deoptimization", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingDeoptimizationOffset;
+    @HotSpotVMField(name = "ThreadShadow::_pending_exception", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingExceptionOffset;
+    @HotSpotVMField(name = "ThreadShadow::_pending_deoptimization", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingDeoptimizationOffset;
 
     /**
      * Mark word right shift to get identity hash code.
@@ -835,22 +856,48 @@
      */
     @HotSpotVMConstant(name = "JVM_ACC_QUEUED") @Stable public int methodQueuedForCompilationBit;
 
-    @HotSpotVMField(name = "Method::_access_flags", get = HotSpotVMField.Type.OFFSET) @Stable public int methodAccessFlagsOffset;
-    @HotSpotVMField(name = "Method::_constMethod", get = HotSpotVMField.Type.OFFSET) @Stable public int methodConstMethodOffset;
-    @HotSpotVMField(name = "Method::_intrinsic_id", get = HotSpotVMField.Type.OFFSET) @Stable public int methodIntrinsicIdOffset;
-    @HotSpotVMField(name = "Method::_vtable_index", get = HotSpotVMField.Type.OFFSET) @Stable public int methodVtableIndexOffset;
+    @HotSpotVMField(name = "Method::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int methodAccessFlagsOffset;
+    @HotSpotVMField(name = "Method::_constMethod", type = "ConstMethod*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodConstMethodOffset;
+    @HotSpotVMField(name = "Method::_intrinsic_id", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodIntrinsicIdOffset;
+    @HotSpotVMField(name = "Method::_vtable_index", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodVtableIndexOffset;
 
     /**
      * Value of Method::extra_stack_entries().
      */
     @Stable public int extraStackEntries;
 
-    @HotSpotVMField(name = "ConstMethod::_max_stack", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodMaxStackOffset;
-    @HotSpotVMField(name = "ConstMethod::_max_locals", get = HotSpotVMField.Type.OFFSET) @Stable public int methodMaxLocalsOffset;
-    @HotSpotVMField(name = "ConstMethod::_constants", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodConstantsOffset;
+    @HotSpotVMField(name = "ConstMethod::_code_size", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodCodeSizeOffset;
+    @HotSpotVMField(name = "ConstMethod::_name_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodNameIndexOffset;
+    @HotSpotVMField(name = "ConstMethod::_signature_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodSignatureIndexOffset;
+    @HotSpotVMField(name = "ConstMethod::_max_stack", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodMaxStackOffset;
+    @HotSpotVMField(name = "ConstMethod::_max_locals", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int methodMaxLocalsOffset;
+    @HotSpotVMField(name = "ConstMethod::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int constMethodConstantsOffset;
+
+    @HotSpotVMType(name = "ConstantPool", get = HotSpotVMType.Type.SIZE) @Stable public int constantPoolSize;
+    @HotSpotVMField(name = "ConstantPool::_tags", type = "Array<u1>*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolTagsOffset;
+    @HotSpotVMField(name = "ConstantPool::_pool_holder", type = "InstanceKlass*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolHolderOffset;
+    @HotSpotVMField(name = "ConstantPool::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolLengthOffset;
 
-    @HotSpotVMField(name = "ConstantPool::_pool_holder", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolHolderOffset;
-    @HotSpotVMField(name = "ConstantPool::_length", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolLengthOffset;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Utf8") @Stable public int jvmConstantUtf8;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Integer") @Stable public int jvmConstantInteger;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Long") @Stable public int jvmConstantLong;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Float") @Stable public int jvmConstantFloat;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Double") @Stable public int jvmConstantDouble;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Class") @Stable public int jvmConstantClass;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_UnresolvedClass") @Stable public int jvmConstantUnresolvedClass;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_UnresolvedClassInError") @Stable public int jvmConstantUnresolvedClassInError;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_String") @Stable public int jvmConstantString;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Fieldref") @Stable public int jvmConstantFieldref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Methodref") @Stable public int jvmConstantMethodref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_InterfaceMethodref") @Stable public int jvmConstantInterfaceMethodref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_NameAndType") @Stable public int jvmConstantNameAndType;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodHandle") @Stable public int jvmConstantMethodHandle;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodHandleInError") @Stable public int jvmConstantMethodHandleInError;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodType") @Stable public int jvmConstantMethodType;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_MethodTypeInError") @Stable public int jvmConstantMethodTypeInError;
+
+    @HotSpotVMField(name = "Symbol::_length", type = "unsigned short", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolLengthOffset;
+    @HotSpotVMField(name = "Symbol::_body[0]", type = "jbyte", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolBodyOffset;
 
     @HotSpotVMConstant(name = "JVM_ACC_HAS_FINALIZER") @Stable public int klassHasFinalizerFlag;
 
@@ -858,17 +905,17 @@
      * Bit pattern that represents a non-oop. Neither the high bits nor the low bits of this value
      * are allowed to look like (respectively) the high or low bits of a real oop.
      */
-    @HotSpotVMField(name = "Universe::_non_oop_bits", get = HotSpotVMField.Type.VALUE) @Stable public long nonOopBits;
+    @HotSpotVMField(name = "Universe::_non_oop_bits", type = "intptr_t", get = HotSpotVMField.Type.VALUE) @Stable public long nonOopBits;
 
-    @HotSpotVMField(name = "StubRoutines::_verify_oop_count", get = HotSpotVMField.Type.ADDRESS) @Stable public long verifyOopCounterAddress;
+    @HotSpotVMField(name = "StubRoutines::_verify_oop_count", type = "jint", get = HotSpotVMField.Type.ADDRESS) @Stable public long verifyOopCounterAddress;
     @Stable public long verifyOopMask;
     @Stable public long verifyOopBits;
 
-    @HotSpotVMField(name = "CollectedHeap::_barrier_set", get = HotSpotVMField.Type.OFFSET) @Stable public int collectedHeapBarrierSetOffset;
+    @HotSpotVMField(name = "CollectedHeap::_barrier_set", type = "BarrierSet*", get = HotSpotVMField.Type.OFFSET) @Stable public int collectedHeapBarrierSetOffset;
 
-    @HotSpotVMField(name = "HeapRegion::LogOfHRGrainBytes", get = HotSpotVMField.Type.VALUE) @Stable public int logOfHRGrainBytes;
+    @HotSpotVMField(name = "HeapRegion::LogOfHRGrainBytes", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int logOfHRGrainBytes;
 
-    @HotSpotVMField(name = "BarrierSet::_kind", get = HotSpotVMField.Type.OFFSET) @Stable public int barrierSetKindOffset;
+    @HotSpotVMField(name = "BarrierSet::_kind", type = "BarrierSet::Name", get = HotSpotVMField.Type.OFFSET) @Stable private int barrierSetKindOffset;
     @HotSpotVMConstant(name = "BarrierSet::CardTableModRef") @Stable public int barrierSetCardTableModRef;
     @HotSpotVMConstant(name = "BarrierSet::CardTableExtension") @Stable public int barrierSetCardTableExtension;
     @HotSpotVMConstant(name = "BarrierSet::G1SATBCT") @Stable public int barrierSetG1SATBCT;
@@ -876,7 +923,7 @@
     @HotSpotVMConstant(name = "BarrierSet::ModRef") @Stable public int barrierSetModRef;
     @HotSpotVMConstant(name = "BarrierSet::Other") @Stable public int barrierSetOther;
 
-    @HotSpotVMField(name = "CardTableModRefBS::byte_map_base", get = HotSpotVMField.Type.OFFSET) @Stable public int cardTableModRefBSByteMapBaseOffset;
+    @HotSpotVMField(name = "CardTableModRefBS::byte_map_base", type = "jbyte*", get = HotSpotVMField.Type.OFFSET) @Stable private int cardTableModRefBSByteMapBaseOffset;
     @HotSpotVMConstant(name = "CardTableModRefBS::card_shift") @Stable public int cardTableModRefBSCardShift;
 
     public long cardtableStartAddress() {
@@ -907,7 +954,7 @@
         throw GraalInternalError.shouldNotReachHere("kind: " + kind);
     }
 
-    @HotSpotVMField(name = "os::_polling_page", get = HotSpotVMField.Type.VALUE) @Stable public long safepointPollingAddress;
+    @HotSpotVMField(name = "os::_polling_page", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long safepointPollingAddress;
 
     // G1 Collector Related Values.
 
@@ -934,51 +981,75 @@
     /**
      * The offset of the _java_mirror field (of type {@link Class}) in a Klass.
      */
-    @HotSpotVMField(name = "Klass::_java_mirror", get = HotSpotVMField.Type.OFFSET) @Stable public int classMirrorOffset;
+    @HotSpotVMField(name = "Klass::_java_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int classMirrorOffset;
 
     @HotSpotVMConstant(name = "frame::arg_reg_save_area_bytes", optional = true) @Stable public int runtimeCallStackSize;
 
-    @HotSpotVMField(name = "Klass::_super", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSuperKlassOffset;
-    @HotSpotVMField(name = "Klass::_modifier_flags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset;
-    @HotSpotVMField(name = "Klass::_access_flags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset;
-    @HotSpotVMField(name = "Klass::_layout_helper", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset;
-    @HotSpotVMField(name = "Klass::_layout_helper", get = HotSpotVMField.Type.OFFSET) @Stable public int klassInstanceSizeOffset;
+    @HotSpotVMField(name = "Klass::_super", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSuperKlassOffset;
+    @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset;
+    @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset;
+    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset;
+    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassInstanceSizeOffset;
+
+    @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue;
+    @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue;
+
+    /**
+     * This filters out the bit that differentiates a type array from an object array.
+     */
+    public int layoutHelperElementTypePrimitiveInPlace() {
+        return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift;
+    }
 
     /**
      * Bit pattern in the klass layout helper that can be used to identify arrays.
      */
     public final int arrayKlassLayoutHelperIdentifier = 0x80000000;
 
-    @HotSpotVMField(name = "ArrayKlass::_component_mirror", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayKlassComponentMirrorOffset;
+    @HotSpotVMField(name = "ArrayKlass::_component_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayKlassComponentMirrorOffset;
+
+    @HotSpotVMField(name = "java_lang_Class::_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassOffset;
+    @HotSpotVMField(name = "java_lang_Class::_array_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int arrayKlassOffset;
+    @HotSpotVMField(name = "java_lang_Class::_graal_mirror_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int graalMirrorInClassOffset;
 
-    @HotSpotVMField(name = "java_lang_Class::_klass_offset", get = HotSpotVMField.Type.VALUE) @Stable public int klassOffset;
-    @HotSpotVMField(name = "java_lang_Class::_array_klass_offset", get = HotSpotVMField.Type.VALUE) @Stable public int arrayKlassOffset;
-    @HotSpotVMField(name = "java_lang_Class::_graal_mirror_offset", get = HotSpotVMField.Type.VALUE) @Stable public int graalMirrorInClassOffset;
+    @HotSpotVMField(name = "Method::_method_data", type = "MethodData*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOffset;
+    @HotSpotVMField(name = "Method::_from_compiled_entry", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCompiledEntryOffset;
 
-    @HotSpotVMField(name = "Method::_method_data", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOffset;
-    @HotSpotVMField(name = "Method::_from_compiled_entry", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCompiledEntryOffset;
+    @HotSpotVMField(name = "MethodData::_size", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataSize;
+    @HotSpotVMField(name = "MethodData::_data_size", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataDataSize;
+    @HotSpotVMField(name = "MethodData::_data[0]", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopDataOffset;
+    @HotSpotVMField(name = "MethodData::_trap_hist._array[0]", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopTrapHistoryOffset;
 
-    @HotSpotVMField(name = "nmethod::_verified_entry_point", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodEntryOffset;
+    @HotSpotVMField(name = "nmethod::_verified_entry_point", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodEntryOffset;
 
     @HotSpotVMType(name = "BasicLock", get = HotSpotVMType.Type.SIZE) @Stable public int basicLockSize;
-    @HotSpotVMField(name = "BasicLock::_displaced_header", get = HotSpotVMField.Type.OFFSET) @Stable public int basicLockDisplacedHeaderOffset;
+    @HotSpotVMField(name = "BasicLock::_displaced_header", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int basicLockDisplacedHeaderOffset;
 
     @Stable public long heapEndAddress;
     @Stable public long heapTopAddress;
 
-    @HotSpotVMField(name = "Thread::_allocated_bytes", get = HotSpotVMField.Type.OFFSET) @Stable public int threadAllocatedBytesOffset;
+    @HotSpotVMField(name = "Thread::_allocated_bytes", type = "jlong", get = HotSpotVMField.Type.OFFSET) @Stable public int threadAllocatedBytesOffset;
 
     @HotSpotVMFlag(name = "TLABWasteIncrement") @Stable public int tlabRefillWasteIncrement;
     @Stable public int tlabAlignmentReserve;
 
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_start", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferStartOffset;
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_end", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferEndOffset;
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_top", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferTopOffset;
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_slow_allocations", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferSlowAllocationsOffset;
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_fast_refill_waste", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferFastRefillWasteOffset;
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_number_of_refills", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferNumberOfRefillsOffset;
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_refill_waste_limit", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferRefillWasteLimitOffset;
-    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_desired_size", get = HotSpotVMField.Type.OFFSET) @Stable public int threadLocalAllocBufferDesiredSizeOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_start", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferStartOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_end", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferEndOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_top", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferTopOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_slow_allocations", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferSlowAllocationsOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_fast_refill_waste", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferFastRefillWasteOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_number_of_refills", type = "unsigned", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferNumberOfRefillsOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_refill_waste_limit", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferRefillWasteLimitOffset;
+    @HotSpotVMField(name = "ThreadLocalAllocBuffer::_desired_size", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferDesiredSizeOffset;
 
     public int tlabSlowAllocationsOffset() {
         return threadTlabOffset + threadLocalAllocBufferSlowAllocationsOffset;
@@ -1015,35 +1086,14 @@
     @HotSpotVMFlag(name = "TLABStats") @Stable public boolean tlabStats;
     @Stable public boolean inlineContiguousAllocationSupported;
 
-    @HotSpotVMField(name = "Klass::_layout_helper", get = HotSpotVMField.Type.OFFSET) @Stable public int layoutHelperOffset;
-    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue;
-
-    /**
-     * This filters out the bit that differentiates a type array from an object array.
-     */
-    public int layoutHelperElementTypePrimitiveInPlace() {
-        return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift;
-    }
-
-    @HotSpotVMField(name = "MethodData::_data[0]", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopDataOffset;
-    @HotSpotVMField(name = "MethodData::_trap_hist._array[0]", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopTrapHistoryOffset;
-
     /**
      * The DataLayout header size is the same as the cell size.
      */
     @HotSpotVMConstant(name = "DataLayout::cell_size") @Stable public int dataLayoutHeaderSize;
-    @HotSpotVMField(name = "DataLayout::_header._struct._tag", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutTagOffset;
-    @HotSpotVMField(name = "DataLayout::_header._struct._flags", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutFlagsOffset;
-    @HotSpotVMField(name = "DataLayout::_header._struct._bci", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutBCIOffset;
-    @HotSpotVMField(name = "DataLayout::_cells[0]", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutCellsOffset;
+    @HotSpotVMField(name = "DataLayout::_header._struct._tag", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutTagOffset;
+    @HotSpotVMField(name = "DataLayout::_header._struct._flags", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutFlagsOffset;
+    @HotSpotVMField(name = "DataLayout::_header._struct._bci", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutBCIOffset;
+    @HotSpotVMField(name = "DataLayout::_cells[0]", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutCellsOffset;
     @HotSpotVMConstant(name = "DataLayout::cell_size") @Stable public int dataLayoutCellSize;
 
     @HotSpotVMConstant(name = "DataLayout::no_tag") @Stable public int dataLayoutNoTag;
@@ -1064,17 +1114,17 @@
     @HotSpotVMFlag(name = "TypeProfileWidth") @Stable public int typeProfileWidth;
     @HotSpotVMFlag(name = "MethodProfileWidth") @Stable public int methodProfileWidth;
 
-    @HotSpotVMField(name = "CodeBlob::_code_offset", get = HotSpotVMField.Type.OFFSET) @Stable private int codeBlobCodeOffsetOffset;
-    @HotSpotVMField(name = "SharedRuntime::_ic_miss_blob", get = HotSpotVMField.Type.VALUE) @Stable private long inlineCacheMissBlob;
+    @HotSpotVMField(name = "CodeBlob::_code_offset", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable private int codeBlobCodeOffsetOffset;
+    @HotSpotVMField(name = "SharedRuntime::_ic_miss_blob", type = "RuntimeStub*", get = HotSpotVMField.Type.VALUE) @Stable private long inlineCacheMissBlob;
 
     public long inlineCacheMissStub() {
         return inlineCacheMissBlob + unsafe.getInt(inlineCacheMissBlob + codeBlobCodeOffsetOffset);
     }
 
-    @HotSpotVMField(name = "CodeCache::_heap", get = HotSpotVMField.Type.VALUE) @Stable private long codeCacheHeap;
-    @HotSpotVMField(name = "CodeHeap::_memory", get = HotSpotVMField.Type.OFFSET) @Stable private int codeHeapMemoryOffset;
-    @HotSpotVMField(name = "VirtualSpace::_low_boundary", get = HotSpotVMField.Type.OFFSET) @Stable private int virtualSpaceLowBoundaryOffset;
-    @HotSpotVMField(name = "VirtualSpace::_high_boundary", get = HotSpotVMField.Type.OFFSET) @Stable private int virtualSpaceHighBoundaryOffset;
+    @HotSpotVMField(name = "CodeCache::_heap", type = "CodeHeap*", get = HotSpotVMField.Type.VALUE) @Stable private long codeCacheHeap;
+    @HotSpotVMField(name = "CodeHeap::_memory", type = "VirtualSpace", get = HotSpotVMField.Type.OFFSET) @Stable private int codeHeapMemoryOffset;
+    @HotSpotVMField(name = "VirtualSpace::_low_boundary", type = "char*", get = HotSpotVMField.Type.OFFSET) @Stable private int virtualSpaceLowBoundaryOffset;
+    @HotSpotVMField(name = "VirtualSpace::_high_boundary", type = "char*", get = HotSpotVMField.Type.OFFSET) @Stable private int virtualSpaceHighBoundaryOffset;
 
     /**
      * @return CodeCache::_heap->_memory._low_boundary
@@ -1093,12 +1143,12 @@
     @Stable public long handleDeoptStub;
     @Stable public long uncommonTrapStub;
 
-    @HotSpotVMField(name = "StubRoutines::_aescrypt_encryptBlock", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptEncryptBlockStub;
-    @HotSpotVMField(name = "StubRoutines::_aescrypt_decryptBlock", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptDecryptBlockStub;
-    @HotSpotVMField(name = "StubRoutines::_cipherBlockChaining_encryptAESCrypt", get = HotSpotVMField.Type.VALUE) @Stable public long cipherBlockChainingEncryptAESCryptStub;
-    @HotSpotVMField(name = "StubRoutines::_cipherBlockChaining_decryptAESCrypt", get = HotSpotVMField.Type.VALUE) @Stable public long cipherBlockChainingDecryptAESCryptStub;
-    @HotSpotVMField(name = "StubRoutines::_updateBytesCRC32", get = HotSpotVMField.Type.VALUE) @Stable public long updateBytesCRC32Stub;
-    @HotSpotVMField(name = "StubRoutines::_crc_table_adr", get = HotSpotVMField.Type.VALUE) @Stable public long crcTableAddress;
+    @HotSpotVMField(name = "StubRoutines::_aescrypt_encryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptEncryptBlockStub;
+    @HotSpotVMField(name = "StubRoutines::_aescrypt_decryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptDecryptBlockStub;
+    @HotSpotVMField(name = "StubRoutines::_cipherBlockChaining_encryptAESCrypt", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long cipherBlockChainingEncryptAESCryptStub;
+    @HotSpotVMField(name = "StubRoutines::_cipherBlockChaining_decryptAESCrypt", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long cipherBlockChainingDecryptAESCryptStub;
+    @HotSpotVMField(name = "StubRoutines::_updateBytesCRC32", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long updateBytesCRC32Stub;
+    @HotSpotVMField(name = "StubRoutines::_crc_table_adr", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long crcTableAddress;
 
     @Stable public long newInstanceAddress;
     @Stable public long newArrayAddress;
@@ -1144,6 +1194,7 @@
     @HotSpotVMConstant(name = "Deoptimization::Reason_constraint") @Stable public int deoptReasonConstraint;
     @HotSpotVMConstant(name = "Deoptimization::Reason_loop_limit_check") @Stable public int deoptReasonLoopLimitCheck;
     @HotSpotVMConstant(name = "Deoptimization::Reason_aliasing") @Stable public int deoptReasonAliasing;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_LIMIT") @Stable public int deoptReasonOSROffset;
 
     @HotSpotVMConstant(name = "Deoptimization::Action_none") @Stable public int deoptActionNone;
     @HotSpotVMConstant(name = "Deoptimization::Action_maybe_recompile") @Stable public int deoptActionMaybeRecompile;
@@ -1151,6 +1202,13 @@
     @HotSpotVMConstant(name = "Deoptimization::Action_make_not_entrant") @Stable public int deoptActionMakeNotEntrant;
     @HotSpotVMConstant(name = "Deoptimization::Action_make_not_compilable") @Stable public int deoptActionMakeNotCompilable;
 
+    @HotSpotVMConstant(name = "Deoptimization::_action_bits") @Stable public int deoptimizationActionBits;
+    @HotSpotVMConstant(name = "Deoptimization::_reason_bits") @Stable public int deoptimizationReasonBits;
+    @HotSpotVMConstant(name = "Deoptimization::_speculation_id_bits") @Stable public int deoptimizationSpeculationIdBits;
+    @HotSpotVMConstant(name = "Deoptimization::_action_shift") @Stable public int deoptimizationActionShift;
+    @HotSpotVMConstant(name = "Deoptimization::_reason_shift") @Stable public int deoptimizationReasonShift;
+    @HotSpotVMConstant(name = "Deoptimization::_speculation_id_shift") @Stable public int deoptimizationSpeculationIdShift;
+
     @HotSpotVMConstant(name = "vmIntrinsics::_invokeBasic") @Stable public int vmIntrinsicInvokeBasic;
     @HotSpotVMConstant(name = "vmIntrinsics::_linkToVirtual") @Stable public int vmIntrinsicLinkToVirtual;
     @HotSpotVMConstant(name = "vmIntrinsics::_linkToStatic") @Stable public int vmIntrinsicLinkToStatic;
@@ -1171,8 +1229,6 @@
         }
 
         assert codeEntryAlignment > 0 : codeEntryAlignment;
-        assert stackShadowPages > 0 : stackShadowPages;
-
         assert (layoutHelperArrayTagObjectValue & layoutHelperArrayTagTypeValue & arrayKlassLayoutHelperIdentifier) != 0 : "object array and type array must have first bit set";
 
         return true;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMField.java	Mon Dec 09 17:31:12 2013 +0100
@@ -34,6 +34,8 @@
 
     String name();
 
+    String type();
+
     Type get();
 
     boolean optional() default false;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,8 +23,6 @@
 
 package com.oracle.graal.hotspot.bridge;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
@@ -45,8 +43,6 @@
      */
     byte[] initializeBytecode(long metaspaceMethod, byte[] code);
 
-    String getSignature(long metaspaceMethod);
-
     ExceptionHandler[] initializeExceptionHandlers(long metaspaceMethod, ExceptionHandler[] handlers);
 
     /**
@@ -101,14 +97,6 @@
     void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method);
 
     /**
-     * Initializes a {@link HotSpotMethodData} object from a metaspace MethodData object.
-     * 
-     * @param metaspaceMethodData the metaspace MethodData object
-     * @param methodData the object to initialize from the metaspace object
-     */
-    void initializeMethodData(long metaspaceMethodData, HotSpotMethodData methodData);
-
-    /**
      * Converts a name to a Java type.
      * 
      * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
@@ -121,17 +109,17 @@
      */
     JavaType lookupType(String name, HotSpotResolvedObjectType accessingClass, boolean eagerResolve);
 
-    Object lookupConstantInPool(HotSpotResolvedObjectType pool, int cpi);
+    Object lookupConstantInPool(long metaspaceConstantPool, int cpi);
 
-    JavaMethod lookupMethodInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
+    JavaMethod lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
-    JavaType lookupTypeInPool(HotSpotResolvedObjectType pool, int cpi);
+    JavaType lookupTypeInPool(long metaspaceConstantPool, int cpi);
 
-    JavaField lookupFieldInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
+    JavaField lookupFieldInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
-    void lookupReferencedTypeInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
+    void lookupReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
-    Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
+    Object lookupAppendixInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
     public enum CodeInstallResult {
         OK("ok"), DEPENDENCIES_FAILED("dependencies failed"), CACHE_FULL("code cache is full"), CODE_TOO_LARGE("code is too large");
@@ -207,12 +195,6 @@
 
     JavaMethod resolveMethod(HotSpotResolvedObjectType klass, String name, String signature);
 
-    boolean isTypeInitialized(HotSpotResolvedObjectType klass);
-
-    void initializeType(HotSpotResolvedObjectType klass);
-
-    ResolvedJavaType getResolvedType(Class<?> javaClass);
-
     HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
 
     HotSpotResolvedJavaMethod[] getMethods(HotSpotResolvedObjectType klass);
@@ -228,17 +210,14 @@
     int getCompiledCodeSize(long metaspaceMethod);
 
     /**
-     * Gets the metaspace Method object corresponding to a given reflection {@link Method} object.
+     * Gets the metaspace Method object corresponding to a given {@link Class} object and slot
+     * number.
      * 
-     * @param reflectionMethod
-     * @param resultHolder the holder of the result is put in element 0 of this array
-     * @return the metaspace Method result for {@code reflectionMethod}
+     * @param holder method holder
+     * @param slot slot number of the method
+     * @return the metaspace Method
      */
-    long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedObjectType[] resultHolder);
-
-    long getMetaspaceConstructor(Constructor reflectionConstructor, HotSpotResolvedObjectType[] resultHolder);
-
-    HotSpotResolvedJavaField getJavaField(Field reflectionField);
+    long getMetaspaceMethod(Class<?> holder, int slot);
 
     long getMaxCallTargetOffset(long address);
 
@@ -273,8 +252,6 @@
 
     void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode);
 
-    boolean isTypeLinked(HotSpotResolvedObjectType hotSpotResolvedObjectType);
-
     /**
      * Collects the current values of all Graal benchmark counters, summed up over all threads.
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,8 +23,6 @@
 
 package com.oracle.graal.hotspot.bridge;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
@@ -43,21 +41,12 @@
     }
 
     @Override
-    public native long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedObjectType[] resultHolder);
-
-    @Override
-    public native long getMetaspaceConstructor(Constructor reflectionConstructor, HotSpotResolvedObjectType[] resultHolder);
-
-    @Override
-    public native HotSpotResolvedJavaField getJavaField(Field reflectionMethod);
+    public native long getMetaspaceMethod(Class<?> holder, int slot);
 
     @Override
     public native byte[] initializeBytecode(long metaspaceMethod, byte[] code);
 
     @Override
-    public native String getSignature(long metaspaceMethod);
-
-    @Override
     public native ExceptionHandler[] initializeExceptionHandlers(long metaspaceMethod, ExceptionHandler[] handlers);
 
     @Override
@@ -76,19 +65,22 @@
     public native JavaType lookupType(String name, HotSpotResolvedObjectType accessingClass, boolean eagerResolve);
 
     @Override
-    public native Object lookupConstantInPool(HotSpotResolvedObjectType pool, int cpi);
+    public native Object lookupConstantInPool(long metaspaceConstantPool, int cpi);
 
     @Override
-    public native JavaMethod lookupMethodInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
+    public native JavaMethod lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
     @Override
-    public native JavaType lookupTypeInPool(HotSpotResolvedObjectType pool, int cpi);
+    public native JavaType lookupTypeInPool(long metaspaceConstantPool, int cpi);
 
     @Override
-    public native void lookupReferencedTypeInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
+    public native JavaField lookupFieldInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
     @Override
-    public native JavaField lookupFieldInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
+    public native void lookupReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode);
+
+    @Override
+    public native Object lookupAppendixInPool(long metaspaceConstantPool, int cpi, byte opcode);
 
     @Override
     public native void initializeConfiguration(HotSpotVMConfig config);
@@ -97,26 +89,12 @@
     public native JavaMethod resolveMethod(HotSpotResolvedObjectType klass, String name, String signature);
 
     @Override
-    public native boolean isTypeInitialized(HotSpotResolvedObjectType klass);
-
-    public native boolean isTypeLinked(HotSpotResolvedObjectType hotSpotResolvedObjectType);
-
-    @Override
     public native boolean hasFinalizableSubclass(HotSpotResolvedObjectType klass);
 
     @Override
-    public native void initializeType(HotSpotResolvedObjectType klass);
-
-    @Override
     public native void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method);
 
     @Override
-    public native void initializeMethodData(long metaspaceMethodData, HotSpotMethodData methodData);
-
-    @Override
-    public native ResolvedJavaType getResolvedType(Class<?> javaClass);
-
-    @Override
     public native HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
 
     @Override
@@ -154,9 +132,6 @@
     public native void reprofile(long metaspaceMethod);
 
     @Override
-    public native Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode);
-
-    @Override
     public native void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode);
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Mon Dec 09 17:31:12 2013 +0100
@@ -38,7 +38,7 @@
      * Compiles a method to machine code. This method is called from the VM
      * (VMToCompiler::compileMethod).
      */
-    void compileMethod(long metaspaceMethod, HotSpotResolvedObjectType holder, int entryBCI, boolean blocking);
+    void compileMethod(long metaspaceMethod, int entryBCI, boolean blocking);
 
     void shutdownCompiler() throws Exception;
 
@@ -67,22 +67,11 @@
      * @param name the {@linkplain JavaType#getName() name} of the type
      * @param simpleName a simple, unqualified name for the type
      * @param javaMirror the {@link Class} mirror
-     * @param sizeOrSpecies the size of an instance of the type, or
-     *            {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} or
-     *            {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE}
      * @return the resolved type associated with {@code javaMirror} which may not be the type
      *         instantiated by this call in the case of another thread racing to create the same
      *         type
      */
     ResolvedJavaType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies);
 
-    Constant createConstant(Kind kind, long value);
-
-    Constant createConstantFloat(float value);
-
-    Constant createConstantDouble(double value);
-
-    Constant createConstantObject(Object object);
-
     LocalImpl createLocalImpl(String name, String type, HotSpotResolvedObjectType holder, int bciStart, int bciEnd, int slot);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Mon Dec 09 17:31:12 2013 +0100
@@ -81,16 +81,6 @@
 
     private final HotSpotGraalRuntime runtime;
 
-    public final HotSpotResolvedPrimitiveType typeBoolean;
-    public final HotSpotResolvedPrimitiveType typeChar;
-    public final HotSpotResolvedPrimitiveType typeFloat;
-    public final HotSpotResolvedPrimitiveType typeDouble;
-    public final HotSpotResolvedPrimitiveType typeByte;
-    public final HotSpotResolvedPrimitiveType typeShort;
-    public final HotSpotResolvedPrimitiveType typeInt;
-    public final HotSpotResolvedPrimitiveType typeLong;
-    public final HotSpotResolvedPrimitiveType typeVoid;
-
     private ThreadPoolExecutor compileQueue;
     private AtomicInteger compileTaskIds = new AtomicInteger();
 
@@ -102,22 +92,6 @@
 
     public VMToCompilerImpl(HotSpotGraalRuntime runtime) {
         this.runtime = runtime;
-
-        typeBoolean = new HotSpotResolvedPrimitiveType(Kind.Boolean);
-        typeChar = new HotSpotResolvedPrimitiveType(Kind.Char);
-        typeFloat = new HotSpotResolvedPrimitiveType(Kind.Float);
-        typeDouble = new HotSpotResolvedPrimitiveType(Kind.Double);
-        typeByte = new HotSpotResolvedPrimitiveType(Kind.Byte);
-        typeShort = new HotSpotResolvedPrimitiveType(Kind.Short);
-        typeInt = new HotSpotResolvedPrimitiveType(Kind.Int);
-        typeLong = new HotSpotResolvedPrimitiveType(Kind.Long);
-        typeVoid = new HotSpotResolvedPrimitiveType(Kind.Void);
-    }
-
-    private static void initMirror(HotSpotResolvedPrimitiveType type, long offset) {
-        Class<?> mirror = type.mirror();
-        unsafe.putObject(mirror, offset, type);
-        assert unsafe.getObject(mirror, offset) == type;
     }
 
     public void startCompiler(boolean bootstrapEnabled) throws Throwable {
@@ -126,18 +100,6 @@
 
         bootstrapRunning = bootstrapEnabled;
 
-        final HotSpotVMConfig config = runtime.getConfig();
-        long offset = config.graalMirrorInClassOffset;
-        initMirror(typeBoolean, offset);
-        initMirror(typeChar, offset);
-        initMirror(typeFloat, offset);
-        initMirror(typeDouble, offset);
-        initMirror(typeByte, offset);
-        initMirror(typeShort, offset);
-        initMirror(typeInt, offset);
-        initMirror(typeLong, offset);
-        initMirror(typeVoid, offset);
-
         if (LogFile.getValue() != null) {
             try {
                 final boolean enableAutoflush = true;
@@ -540,7 +502,12 @@
     }
 
     @Override
-    public void compileMethod(long metaspaceMethod, final HotSpotResolvedObjectType holder, final int entryBCI, final boolean blocking) {
+    public void compileMethod(long metaspaceMethod, final int entryBCI, final boolean blocking) {
+        HotSpotVMConfig config = runtime().getConfig();
+        final long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
+        final long metaspaceConstantPool = unsafe.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
+        final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + config.constantPoolHolderOffset);
+        final HotSpotResolvedObjectType holder = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
         final HotSpotResolvedJavaMethod method = holder.createMethod(metaspaceMethod);
         // We have to use a privileged action here because compilations are enqueued from user code
         // which very likely contains unprivileged frames.
@@ -576,10 +543,11 @@
             if (method.tryToQueueForCompilation()) {
                 assert method.isQueuedForCompilation();
 
-                final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method);
+                final ProfilingInfo profilingInfo = method.getCompilationProfilingInfo(osrCompilation);
+                final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(profilingInfo);
                 int id = compileTaskIds.incrementAndGet();
                 HotSpotBackend backend = runtime.getHostBackend();
-                CompilationTask task = CompilationTask.create(backend, createPhasePlan(backend.getProviders(), optimisticOpts, osrCompilation), optimisticOpts, method, entryBCI, id);
+                CompilationTask task = CompilationTask.create(backend, createPhasePlan(backend.getProviders(), optimisticOpts, osrCompilation), optimisticOpts, profilingInfo, method, entryBCI, id);
 
                 if (blocking) {
                     task.runCompilation();
@@ -621,23 +589,23 @@
     public ResolvedJavaType createPrimitiveJavaType(int basicType) {
         switch (basicType) {
             case 4:
-                return typeBoolean;
+                return runtime.typeBoolean;
             case 5:
-                return typeChar;
+                return runtime.typeChar;
             case 6:
-                return typeFloat;
+                return runtime.typeFloat;
             case 7:
-                return typeDouble;
+                return runtime.typeDouble;
             case 8:
-                return typeByte;
+                return runtime.typeByte;
             case 9:
-                return typeShort;
+                return runtime.typeShort;
             case 10:
-                return typeInt;
+                return runtime.typeInt;
             case 11:
-                return typeLong;
+                return runtime.typeLong;
             case 14:
-                return typeVoid;
+                return runtime.typeVoid;
             default:
                 throw new IllegalArgumentException("Unknown basic type: " + basicType);
         }
@@ -674,40 +642,6 @@
     }
 
     @Override
-    public Constant createConstant(Kind kind, long value) {
-        if (kind == Kind.Long) {
-            return Constant.forLong(value);
-        } else if (kind == Kind.Int) {
-            return Constant.forInt((int) value);
-        } else if (kind == Kind.Short) {
-            return Constant.forShort((short) value);
-        } else if (kind == Kind.Char) {
-            return Constant.forChar((char) value);
-        } else if (kind == Kind.Byte) {
-            return Constant.forByte((byte) value);
-        } else if (kind == Kind.Boolean) {
-            return (value == 0) ? Constant.FALSE : Constant.TRUE;
-        } else {
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public Constant createConstantFloat(float value) {
-        return Constant.forFloat(value);
-    }
-
-    @Override
-    public Constant createConstantDouble(double value) {
-        return Constant.forDouble(value);
-    }
-
-    @Override
-    public Constant createConstantObject(Object object) {
-        return Constant.forObject(object);
-    }
-
-    @Override
     public LocalImpl createLocalImpl(String name, String type, HotSpotResolvedObjectType holder, int bciStart, int bciEnd, int slot) {
         return new LocalImpl(name, type, holder, bciStart, bciEnd, slot);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Dec 09 17:31:12 2013 +0100
@@ -32,6 +32,7 @@
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
@@ -157,10 +158,20 @@
         return runtime.getConfig().runtimeCallStackSize;
     }
 
+    public HotSpotInstalledCode logOrDump(HotSpotInstalledCode installedCode, CompilationResult compResult) {
+        if (Debug.isDumpEnabled()) {
+            Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
+        }
+        if (Debug.isLogEnabled()) {
+            Debug.log("%s", disassemble(installedCode));
+        }
+        return installedCode;
+    }
+
     public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
         HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), true);
         runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, entryBCI, compResult), installedCode, method.getSpeculationLog());
-        return installedCode;
+        return logOrDump(installedCode, compResult);
     }
 
     @Override
@@ -171,7 +182,7 @@
         if (result != CodeInstallResult.OK) {
             return null;
         }
-        return code;
+        return logOrDump(code, compResult);
     }
 
     public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) {
@@ -180,7 +191,6 @@
     }
 
     public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
-
         HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
         HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, compResult.getName(), false, true);
         HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, -1, compResult);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Mon Dec 09 17:31:12 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -27,6 +27,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.bytecode.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 
 /**
@@ -36,54 +37,243 @@
 
     private static final long serialVersionUID = -5443206401485234850L;
 
-    private final HotSpotResolvedObjectType type;
+    /**
+     * Reference to the C++ ConstantPool object.
+     */
+    private final long metaspaceConstantPool;
+
+    public HotSpotConstantPool(long metaspaceConstantPool) {
+        this.metaspaceConstantPool = metaspaceConstantPool;
+    }
+
+    /**
+     * Returns the constant pool tag at index {@code index}.
+     * 
+     * @param index constant pool index
+     * @return constant pool tag at index
+     */
+    private int getTagAt(int index) {
+        assertBounds(index);
+        HotSpotVMConfig config = runtime().getConfig();
+        long tags = unsafe.getAddress(metaspaceConstantPool + config.constantPoolTagsOffset);
+        return unsafe.getByteVolatile(null, tags + config.arrayU1DataOffset + index);
+    }
+
+    /**
+     * Returns the constant pool entry at index {@code index}.
+     * 
+     * @param index constant pool index
+     * @return constant pool entry at index
+     */
+    private long getEntryAt(int index) {
+        assertBounds(index);
+        HotSpotVMConfig config = runtime().getConfig();
+        return unsafe.getAddress(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize);
+    }
+
+    /**
+     * Returns the integer constant pool entry at index {@code index}.
+     * 
+     * @param index constant pool index
+     * @return integer constant pool entry at index
+     */
+    private int getIntAt(int index) {
+        HotSpotVMConfig config = runtime().getConfig();
+        assertTag(index, config.jvmConstantInteger);
+        return unsafe.getInt(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize);
+    }
+
+    /**
+     * Returns the long constant pool entry at index {@code index}.
+     * 
+     * @param index constant pool index
+     * @return long constant pool entry at index
+     */
+    private long getLongAt(int index) {
+        HotSpotVMConfig config = runtime().getConfig();
+        assertTag(index, config.jvmConstantLong);
+        return unsafe.getLong(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize);
+    }
+
+    /**
+     * Returns the float constant pool entry at index {@code index}.
+     * 
+     * @param index constant pool index
+     * @return float constant pool entry at index
+     */
+    private float getFloatAt(int index) {
+        HotSpotVMConfig config = runtime().getConfig();
+        assertTag(index, config.jvmConstantFloat);
+        return unsafe.getFloat(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize);
+    }
 
-    public HotSpotConstantPool(HotSpotResolvedObjectType type) {
-        this.type = type;
+    /**
+     * Returns the double constant pool entry at index {@code index}.
+     * 
+     * @param index constant pool index
+     * @return float constant pool entry at index
+     */
+    private double getDoubleAt(int index) {
+        HotSpotVMConfig config = runtime().getConfig();
+        assertTag(index, config.jvmConstantDouble);
+        return unsafe.getDouble(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize);
+    }
+
+    /**
+     * Asserts that the constant pool index {@code index} is in the bounds of the constant pool.
+     * 
+     * @param index constant pool index
+     */
+    private void assertBounds(int index) {
+        assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
+    }
+
+    /**
+     * Asserts that the constant pool tag at index {@code index} is equal to {@code tag}.
+     * 
+     * @param index constant pool index
+     * @param tag expected tag
+     */
+    private void assertTag(int index, int tag) {
+        assert getTagAt(index) == tag : "constant pool tag at index " + index + " is " + getNameForTag(getTagAt(index)) + " but expected " + getNameForTag(tag);
+    }
+
+    private static String getNameForTag(int tag) {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (tag == config.jvmConstantUtf8) {
+            return "JVM_CONSTANT_Utf8";
+        }
+        if (tag == config.jvmConstantInteger) {
+            return "JVM_CONSTANT_Integer";
+        }
+        if (tag == config.jvmConstantLong) {
+            return "JVM_CONSTANT_Long";
+        }
+        if (tag == config.jvmConstantFloat) {
+            return "JVM_CONSTANT_Float";
+        }
+        if (tag == config.jvmConstantDouble) {
+            return "JVM_CONSTANT_Double";
+        }
+        if (tag == config.jvmConstantClass) {
+            return "JVM_CONSTANT_Class";
+        }
+        if (tag == config.jvmConstantUnresolvedClass) {
+            return "JVM_CONSTANT_UnresolvedClass";
+        }
+        if (tag == config.jvmConstantUnresolvedClassInError) {
+            return "JVM_CONSTANT_UnresolvedClassInError";
+        }
+        if (tag == config.jvmConstantString) {
+            return "JVM_CONSTANT_String";
+        }
+        if (tag == config.jvmConstantFieldref) {
+            return "JVM_CONSTANT_Fieldref";
+        }
+        if (tag == config.jvmConstantMethodref) {
+            return "JVM_CONSTANT_Methodref";
+        }
+        if (tag == config.jvmConstantInterfaceMethodref) {
+            return "JVM_CONSTANT_InterfaceMethodref";
+        }
+        if (tag == config.jvmConstantNameAndType) {
+            return "JVM_CONSTANT_NameAndType";
+        }
+        if (tag == config.jvmConstantMethodHandle) {
+            return "JVM_CONSTANT_MethodHandle";
+        }
+        if (tag == config.jvmConstantMethodHandleInError) {
+            return "JVM_CONSTANT_MethodHandleInError";
+        }
+        if (tag == config.jvmConstantMethodType) {
+            return "JVM_CONSTANT_MethodType";
+        }
+        if (tag == config.jvmConstantMethodTypeInError) {
+            return "JVM_CONSTANT_MethodTypeInError";
+        }
+        return "unknown constant tag " + tag;
     }
 
     @Override
     public int length() {
         HotSpotVMConfig config = runtime().getConfig();
-        long constantPoolAddress = unsafe.getAddress(type.metaspaceKlass() + config.instanceKlassConstantsOffset);
-        return unsafe.getInt(constantPoolAddress + config.constantPoolLengthOffset);
+        return unsafe.getInt(metaspaceConstantPool + config.constantPoolLengthOffset);
     }
 
     @Override
     public Object lookupConstant(int cpi) {
         assert cpi != 0;
-        Object constant = runtime().getCompilerToVM().lookupConstantInPool(type, cpi);
-        return constant;
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final int tag = getTagAt(cpi);
+
+        // Handle primitive constant pool entries directly.
+        if (tag == config.jvmConstantInteger) {
+            return Constant.forInt(getIntAt(cpi));
+        }
+        if (tag == config.jvmConstantLong) {
+            return Constant.forLong(getLongAt(cpi));
+        }
+        if (tag == config.jvmConstantFloat) {
+            return Constant.forFloat(getFloatAt(cpi));
+        }
+        if (tag == config.jvmConstantDouble) {
+            return Constant.forDouble(getDoubleAt(cpi));
+        }
+
+        // All the other constant pool entries need special attention so we call down into the VM.
+        if (tag == config.jvmConstantClass || tag == config.jvmConstantUnresolvedClass || tag == config.jvmConstantUnresolvedClassInError) {
+            final int opcode = -1;  // opcode is not used
+            return lookupType(cpi, opcode);
+        }
+        if (tag == config.jvmConstantString) {
+            Object string = runtime().getCompilerToVM().lookupConstantInPool(metaspaceConstantPool, cpi);
+            return Constant.forObject(string);
+        }
+        if (tag == config.jvmConstantMethodHandle || tag == config.jvmConstantMethodHandleInError || tag == config.jvmConstantMethodType || tag == config.jvmConstantMethodTypeInError) {
+            Object obj = runtime().getCompilerToVM().lookupConstantInPool(metaspaceConstantPool, cpi);
+            return Constant.forObject(obj);
+        }
+
+        throw GraalInternalError.shouldNotReachHere("unknown constant pool tag " + tag);
+    }
+
+    @Override
+    public String lookupUtf8(int cpi) {
+        assertTag(cpi, runtime().getConfig().jvmConstantUtf8);
+        long signature = getEntryAt(cpi);
+        HotSpotSymbol symbol = new HotSpotSymbol(signature);
+        return symbol.asString();
     }
 
     @Override
     public Signature lookupSignature(int cpi) {
-        throw new UnsupportedOperationException();
+        return new HotSpotSignature(lookupUtf8(cpi));
     }
 
     @Override
     public Object lookupAppendix(int cpi, int opcode) {
         assert Bytecodes.isInvoke(opcode);
-        return runtime().getCompilerToVM().lookupAppendixInPool(type, cpi, (byte) opcode);
+        return runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, cpi, (byte) opcode);
     }
 
     @Override
     public JavaMethod lookupMethod(int cpi, int opcode) {
-        return runtime().getCompilerToVM().lookupMethodInPool(type, cpi, (byte) opcode);
+        return runtime().getCompilerToVM().lookupMethodInPool(metaspaceConstantPool, cpi, (byte) opcode);
     }
 
     @Override
     public JavaType lookupType(int cpi, int opcode) {
-        return runtime().getCompilerToVM().lookupTypeInPool(type, cpi);
+        return runtime().getCompilerToVM().lookupTypeInPool(metaspaceConstantPool, cpi);
     }
 
     @Override
     public JavaField lookupField(int cpi, int opcode) {
-        return runtime().getCompilerToVM().lookupFieldInPool(type, cpi, (byte) opcode);
+        return runtime().getCompilerToVM().lookupFieldInPool(metaspaceConstantPool, cpi, (byte) opcode);
     }
 
     @Override
     public void loadReferencedType(int cpi, int opcode) {
-        runtime().getCompilerToVM().lookupReferencedTypeInPool(type, cpi, (byte) opcode);
+        runtime().getCompilerToVM().lookupReferencedTypeInPool(metaspaceConstantPool, cpi, (byte) opcode);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Dec 09 17:31:12 2013 +0100
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.graph.UnsafeAccess.*;
+
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.bridge.*;
 
 /**
  * HotSpot implementation of {@link MetaAccessProvider}.
@@ -59,39 +60,69 @@
         return new HotSpotSignature(signature);
     }
 
+    /**
+     * {@link Field} object of {@link Method#slot}.
+     */
+    @SuppressWarnings("javadoc") private Field reflectionMethodSlot = getReflectionSlotField(Method.class);
+
+    /**
+     * {@link Field} object of {@link Constructor#slot}.
+     */
+    @SuppressWarnings("javadoc") private Field reflectionConstructorSlot = getReflectionSlotField(Constructor.class);
+
+    private static Field getReflectionSlotField(Class<?> reflectionClass) {
+        try {
+            Field field = reflectionClass.getDeclaredField("slot");
+            field.setAccessible(true);
+            return field;
+        } catch (NoSuchFieldException | SecurityException e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
     public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) {
-        CompilerToVM c2vm = runtime.getCompilerToVM();
-        HotSpotResolvedObjectType[] resultHolder = {null};
-        long metaspaceMethod = c2vm.getMetaspaceMethod(reflectionMethod, resultHolder);
-        assert metaspaceMethod != 0L;
-        return resultHolder[0].createMethod(metaspaceMethod);
+        try {
+            Class<?> holder = reflectionMethod.getDeclaringClass();
+            final int slot = reflectionMethodSlot.getInt(reflectionMethod);
+            final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot);
+            return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod);
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new GraalInternalError(e);
+        }
     }
 
     public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) {
-        CompilerToVM c2vm = runtime.getCompilerToVM();
-        HotSpotResolvedObjectType[] resultHolder = {null};
-        long metaspaceMethod = c2vm.getMetaspaceConstructor(reflectionConstructor, resultHolder);
-        assert metaspaceMethod != 0L;
-        return resultHolder[0].createMethod(metaspaceMethod);
+        try {
+            Class<?> holder = reflectionConstructor.getDeclaringClass();
+            final int slot = reflectionConstructorSlot.getInt(reflectionConstructor);
+            final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot);
+            return HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod);
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new GraalInternalError(e);
+        }
     }
 
     public ResolvedJavaField lookupJavaField(Field reflectionField) {
-        return runtime.getCompilerToVM().getJavaField(reflectionField);
-    }
-
-    // These are synchronized with values in deoptimization.hpp:105
-    private static final int ACTION_BITS = 3;
-    private static final int REASON_BITS = 5;
-    private static final int SPECULATION_BITS = 23;
+        String name = reflectionField.getName();
+        Class<?> fieldHolder = reflectionField.getDeclaringClass();
+        Class<?> fieldType = reflectionField.getType();
+        // java.lang.reflect.Field's modifiers should be enough here since VM internal modifier bits
+        // are not used (yet).
+        final int modifiers = reflectionField.getModifiers();
+        final long offset = Modifier.isStatic(modifiers) ? unsafe.staticFieldOffset(reflectionField) : unsafe.objectFieldOffset(reflectionField);
+        final boolean internal = false;
 
-    private static final int ACTION_SHIFT = 0;
-    private static final int ACTION_MASK = intMaskRight(ACTION_BITS);
+        ResolvedJavaType holder = HotSpotResolvedObjectType.fromClass(fieldHolder);
+        ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(fieldType);
 
-    private static final int REASON_SHIFT = ACTION_SHIFT + ACTION_BITS;
-    private static final int REASON_MASK = intMaskRight(REASON_BITS);
-
-    private static final int SPECULATION_SHIFT = REASON_SHIFT + REASON_BITS;
-    private static final int SPECULATION_MASK = intMaskRight(SPECULATION_BITS);
+        if (offset != -1) {
+            HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) holder;
+            return resolved.createField(name, type, offset, modifiers, internal);
+        } else {
+            // TODO this cast will not succeed
+            return (ResolvedJavaField) new HotSpotUnresolvedField(holder, name, type);
+        }
+    }
 
     private static int intMaskRight(int n) {
         assert n <= 32;
@@ -100,133 +131,157 @@
 
     @Override
     public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int speculationId) {
+        HotSpotVMConfig config = runtime.getConfig();
         int actionValue = convertDeoptAction(action);
         int reasonValue = convertDeoptReason(reason);
-        int speculationValue = speculationId & SPECULATION_MASK;
-        Constant c = Constant.forInt(~((speculationValue << SPECULATION_SHIFT) | (reasonValue << REASON_SHIFT) | (actionValue << ACTION_SHIFT)));
+        int speculationValue = speculationId & intMaskRight(config.deoptimizationSpeculationIdBits);
+        Constant c = Constant.forInt(~((speculationValue << config.deoptimizationSpeculationIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift)));
         assert c.asInt() < 0;
         return c;
     }
 
     public DeoptimizationReason decodeDeoptReason(Constant constant) {
-        int reasonValue = ((~constant.asInt()) >> REASON_SHIFT) & REASON_MASK;
+        HotSpotVMConfig config = runtime.getConfig();
+        int reasonValue = ((~constant.asInt()) >> config.deoptimizationReasonShift) & intMaskRight(config.deoptimizationReasonBits);
         DeoptimizationReason reason = convertDeoptReason(reasonValue);
         return reason;
     }
 
     public DeoptimizationAction decodeDeoptAction(Constant constant) {
-        int actionValue = ((~constant.asInt()) >> ACTION_SHIFT) & ACTION_MASK;
+        HotSpotVMConfig config = runtime.getConfig();
+        int actionValue = ((~constant.asInt()) >> config.deoptimizationActionShift) & intMaskRight(config.deoptimizationActionBits);
         DeoptimizationAction action = convertDeoptAction(actionValue);
         return action;
     }
 
     public short decodeSpeculationId(Constant constant) {
-        return (short) (((~constant.asInt()) >> SPECULATION_SHIFT) & SPECULATION_MASK);
+        HotSpotVMConfig config = runtime.getConfig();
+        return (short) (((~constant.asInt()) >> config.deoptimizationSpeculationIdShift) & intMaskRight(config.deoptimizationSpeculationIdBits));
     }
 
     public int convertDeoptAction(DeoptimizationAction action) {
+        HotSpotVMConfig config = runtime.getConfig();
         switch (action) {
             case None:
-                return runtime.getConfig().deoptActionNone;
+                return config.deoptActionNone;
             case RecompileIfTooManyDeopts:
-                return runtime.getConfig().deoptActionMaybeRecompile;
+                return config.deoptActionMaybeRecompile;
             case InvalidateReprofile:
-                return runtime.getConfig().deoptActionReinterpret;
+                return config.deoptActionReinterpret;
             case InvalidateRecompile:
-                return runtime.getConfig().deoptActionMakeNotEntrant;
+                return config.deoptActionMakeNotEntrant;
             case InvalidateStopCompiling:
-                return runtime.getConfig().deoptActionMakeNotCompilable;
+                return config.deoptActionMakeNotCompilable;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     public DeoptimizationAction convertDeoptAction(int action) {
-        if (action == runtime.getConfig().deoptActionNone) {
+        HotSpotVMConfig config = runtime.getConfig();
+        if (action == config.deoptActionNone) {
             return DeoptimizationAction.None;
-        } else if (action == runtime.getConfig().deoptActionMaybeRecompile) {
+        }
+        if (action == config.deoptActionMaybeRecompile) {
             return DeoptimizationAction.RecompileIfTooManyDeopts;
-        } else if (action == runtime.getConfig().deoptActionReinterpret) {
+        }
+        if (action == config.deoptActionReinterpret) {
             return DeoptimizationAction.InvalidateReprofile;
-        } else if (action == runtime.getConfig().deoptActionMakeNotEntrant) {
+        }
+        if (action == config.deoptActionMakeNotEntrant) {
             return DeoptimizationAction.InvalidateRecompile;
-        } else if (action == runtime.getConfig().deoptActionMakeNotCompilable) {
+        }
+        if (action == config.deoptActionMakeNotCompilable) {
             return DeoptimizationAction.InvalidateStopCompiling;
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
         }
+        throw GraalInternalError.shouldNotReachHere();
     }
 
     public int convertDeoptReason(DeoptimizationReason reason) {
+        HotSpotVMConfig config = runtime.getConfig();
         switch (reason) {
             case None:
-                return runtime.getConfig().deoptReasonNone;
+                return config.deoptReasonNone;
             case NullCheckException:
-                return runtime.getConfig().deoptReasonNullCheck;
+                return config.deoptReasonNullCheck;
             case BoundsCheckException:
-                return runtime.getConfig().deoptReasonRangeCheck;
+                return config.deoptReasonRangeCheck;
             case ClassCastException:
-                return runtime.getConfig().deoptReasonClassCheck;
+                return config.deoptReasonClassCheck;
             case ArrayStoreException:
-                return runtime.getConfig().deoptReasonArrayCheck;
+                return config.deoptReasonArrayCheck;
             case UnreachedCode:
-                return runtime.getConfig().deoptReasonUnreached0;
+                return config.deoptReasonUnreached0;
             case TypeCheckedInliningViolated:
-                return runtime.getConfig().deoptReasonTypeCheckInlining;
+                return config.deoptReasonTypeCheckInlining;
             case OptimizedTypeCheckViolated:
-                return runtime.getConfig().deoptReasonOptimizedTypeCheck;
+                return config.deoptReasonOptimizedTypeCheck;
             case NotCompiledExceptionHandler:
-                return runtime.getConfig().deoptReasonNotCompiledExceptionHandler;
+                return config.deoptReasonNotCompiledExceptionHandler;
             case Unresolved:
-                return runtime.getConfig().deoptReasonUnresolved;
+                return config.deoptReasonUnresolved;
             case JavaSubroutineMismatch:
-                return runtime.getConfig().deoptReasonJsrMismatch;
+                return config.deoptReasonJsrMismatch;
             case ArithmeticException:
-                return runtime.getConfig().deoptReasonDiv0Check;
+                return config.deoptReasonDiv0Check;
             case RuntimeConstraint:
-                return runtime.getConfig().deoptReasonConstraint;
+                return config.deoptReasonConstraint;
             case LoopLimitCheck:
-                return runtime.getConfig().deoptReasonLoopLimitCheck;
+                return config.deoptReasonLoopLimitCheck;
             case Aliasing:
-                return runtime.getConfig().deoptReasonAliasing;
+                return config.deoptReasonAliasing;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     public DeoptimizationReason convertDeoptReason(int reason) {
-        if (reason == runtime.getConfig().deoptReasonNone) {
+        HotSpotVMConfig config = runtime.getConfig();
+        if (reason == config.deoptReasonNone) {
             return DeoptimizationReason.None;
-        } else if (reason == runtime.getConfig().deoptReasonNullCheck) {
+        }
+        if (reason == config.deoptReasonNullCheck) {
             return DeoptimizationReason.NullCheckException;
-        } else if (reason == runtime.getConfig().deoptReasonRangeCheck) {
+        }
+        if (reason == config.deoptReasonRangeCheck) {
             return DeoptimizationReason.BoundsCheckException;
-        } else if (reason == runtime.getConfig().deoptReasonClassCheck) {
+        }
+        if (reason == config.deoptReasonClassCheck) {
             return DeoptimizationReason.ClassCastException;
-        } else if (reason == runtime.getConfig().deoptReasonArrayCheck) {
+        }
+        if (reason == config.deoptReasonArrayCheck) {
             return DeoptimizationReason.ArrayStoreException;
-        } else if (reason == runtime.getConfig().deoptReasonUnreached0) {
+        }
+        if (reason == config.deoptReasonUnreached0) {
             return DeoptimizationReason.UnreachedCode;
-        } else if (reason == runtime.getConfig().deoptReasonTypeCheckInlining) {
+        }
+        if (reason == config.deoptReasonTypeCheckInlining) {
             return DeoptimizationReason.TypeCheckedInliningViolated;
-        } else if (reason == runtime.getConfig().deoptReasonOptimizedTypeCheck) {
+        }
+        if (reason == config.deoptReasonOptimizedTypeCheck) {
             return DeoptimizationReason.OptimizedTypeCheckViolated;
-        } else if (reason == runtime.getConfig().deoptReasonNotCompiledExceptionHandler) {
+        }
+        if (reason == config.deoptReasonNotCompiledExceptionHandler) {
             return DeoptimizationReason.NotCompiledExceptionHandler;
-        } else if (reason == runtime.getConfig().deoptReasonUnresolved) {
+        }
+        if (reason == config.deoptReasonUnresolved) {
             return DeoptimizationReason.Unresolved;
-        } else if (reason == runtime.getConfig().deoptReasonJsrMismatch) {
+        }
+        if (reason == config.deoptReasonJsrMismatch) {
             return DeoptimizationReason.JavaSubroutineMismatch;
-        } else if (reason == runtime.getConfig().deoptReasonDiv0Check) {
+        }
+        if (reason == config.deoptReasonDiv0Check) {
             return DeoptimizationReason.ArithmeticException;
-        } else if (reason == runtime.getConfig().deoptReasonConstraint) {
+        }
+        if (reason == config.deoptReasonConstraint) {
             return DeoptimizationReason.RuntimeConstraint;
-        } else if (reason == runtime.getConfig().deoptReasonLoopLimitCheck) {
+        }
+        if (reason == config.deoptReasonLoopLimitCheck) {
             return DeoptimizationReason.LoopLimitCheck;
-        } else if (reason == runtime.getConfig().deoptReasonAliasing) {
+        }
+        if (reason == config.deoptReasonAliasing) {
             return DeoptimizationReason.Aliasing;
-        } else {
-            throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason));
         }
+        throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason));
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java	Mon Dec 09 17:31:12 2013 +0100
@@ -38,6 +38,10 @@
      */
     public static final boolean FULLY_QUALIFIED_METHOD_NAME = false;
 
+    protected HotSpotMethod(String name) {
+        this.name = name;
+    }
+
     @Override
     public final String getName() {
         return name;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Dec 09 17:31:12 2013 +0100
@@ -66,28 +66,43 @@
      */
     private final long metaspaceMethodData;
 
-    private int normalDataSize;
-    private int extraDataSize;
-
     HotSpotMethodData(long metaspaceMethodData) {
         this.metaspaceMethodData = metaspaceMethodData;
-        runtime().getCompilerToVM().initializeMethodData(metaspaceMethodData, this);
+    }
+
+    /**
+     * @return value of the MethodData::_data_size field
+     */
+    private int normalDataSize() {
+        return unsafe.getInt(metaspaceMethodData + config.methodDataDataSize);
+    }
+
+    /**
+     * Returns the size of the extra data records. This method does the same calculation as
+     * MethodData::extra_data_size().
+     * 
+     * @return size of extra data records
+     */
+    private int extraDataSize() {
+        final int extraDataBase = config.methodDataOopDataOffset + normalDataSize();
+        final int extraDataLimit = unsafe.getInt(metaspaceMethodData + config.methodDataSize);
+        return extraDataLimit - extraDataBase;
     }
 
     public boolean hasNormalData() {
-        return normalDataSize > 0;
+        return normalDataSize() > 0;
     }
 
     public boolean hasExtraData() {
-        return extraDataSize > 0;
+        return extraDataSize() > 0;
     }
 
     public int getExtraDataBeginOffset() {
-        return normalDataSize;
+        return normalDataSize();
     }
 
     public boolean isWithin(int position) {
-        return position >= 0 && position < normalDataSize + extraDataSize;
+        return position >= 0 && position < normalDataSize() + extraDataSize();
     }
 
     public int getDeoptimizationCount(DeoptimizationReason reason) {
@@ -95,8 +110,13 @@
         return unsafe.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF;
     }
 
+    public int getOSRDeoptimizationCount(DeoptimizationReason reason) {
+        int reasonIndex = runtime().getHostProviders().getMetaAccess().convertDeoptReason(reason);
+        return unsafe.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + config.deoptReasonOSROffset + reasonIndex) & 0xFF;
+    }
+
     public HotSpotMethodDataAccessor getNormalData(int position) {
-        if (position >= normalDataSize) {
+        if (position >= normalDataSize()) {
             return null;
         }
 
@@ -106,7 +126,7 @@
     }
 
     public HotSpotMethodDataAccessor getExtraData(int position) {
-        if (position >= normalDataSize + extraDataSize) {
+        if (position >= normalDataSize() + extraDataSize()) {
             return null;
         }
         HotSpotMethodDataAccessor data = getData(position);
@@ -127,7 +147,7 @@
     private HotSpotMethodDataAccessor getData(int position) {
         assert position >= 0 : "out of bounds";
         int tag = AbstractMethodData.readTag(this, position);
-        assert tag >= 0 && tag < PROFILE_DATA_ACCESSORS.length : "illegal tag";
+        assert tag >= 0 && tag < PROFILE_DATA_ACCESSORS.length : "illegal tag " + tag;
         return PROFILE_DATA_ACCESSORS[tag];
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java	Mon Dec 09 17:31:12 2013 +0100
@@ -34,7 +34,7 @@
     protected JavaType holder;
 
     public HotSpotMethodUnresolved(String name, String signature, JavaType holder) {
-        this.name = name;
+        super(name);
         this.holder = holder;
         this.signature = new HotSpotSignature(signature);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Dec 09 17:31:12 2013 +0100
@@ -39,9 +39,14 @@
     private int hintBCI;
     private HotSpotMethodDataAccessor dataAccessor;
 
-    public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method) {
+    private boolean includeNormal;
+    private boolean includeOSR;
+
+    public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) {
         this.methodData = methodData;
         this.method = method;
+        this.includeNormal = includeNormal;
+        this.includeOSR = includeOSR;
         hintPosition = 0;
         hintBCI = -1;
     }
@@ -95,7 +100,14 @@
 
     @Override
     public int getDeoptimizationCount(DeoptimizationReason reason) {
-        return methodData.getDeoptimizationCount(reason);
+        int count = 0;
+        if (includeNormal) {
+            count += methodData.getDeoptimizationCount(reason);
+        }
+        if (includeOSR) {
+            count += methodData.getOSRDeoptimizationCount(reason);
+        }
+        return count;
     }
 
     private void findBCI(int targetBCI, boolean searchExtraData) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Dec 09 17:31:12 2013 +0100
@@ -52,31 +52,32 @@
     private final String name;
     private final JavaType type;
     private final int offset;
-    private final int flags;
+    private final int modifiers;
     private Constant constant;
 
-    public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, int offset, int flags, boolean internal) {
-        assert (flags & FIELD_INTERNAL_FLAG) == 0;
+    public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, long offset, int modifiers, boolean internal) {
+        assert (modifiers & FIELD_INTERNAL_FLAG) == 0;
         this.holder = holder;
         this.name = name;
         this.type = type;
         assert offset != -1;
-        this.offset = offset;
+        assert offset == (int) offset : "offset larger than int";
+        this.offset = (int) offset;
         if (internal) {
-            this.flags = flags | FIELD_INTERNAL_FLAG;
+            this.modifiers = modifiers | FIELD_INTERNAL_FLAG;
         } else {
-            this.flags = flags;
+            this.modifiers = modifiers;
         }
     }
 
     @Override
     public int getModifiers() {
-        return flags & Modifier.fieldModifiers();
+        return modifiers & Modifier.fieldModifiers();
     }
 
     @Override
     public boolean isInternal() {
-        return (flags & FIELD_INTERNAL_FLAG) != 0;
+        return (modifiers & FIELD_INTERNAL_FLAG) != 0;
     }
 
     /**
@@ -178,7 +179,7 @@
         assert !AOTCompilation.getValue() || isCalledForSnippets() : receiver;
 
         if (receiver == null) {
-            assert Modifier.isStatic(flags);
+            assert Modifier.isStatic(modifiers);
             if (constant == null) {
                 if (holder.isInitialized() && !holder.getName().equals(SystemClassName) && isEmbeddable()) {
                     if (Modifier.isFinal(getModifiers())) {
@@ -192,7 +193,7 @@
              * for non-static final fields, we must assume that they are only initialized if they
              * have a non-default value.
              */
-            assert !Modifier.isStatic(flags);
+            assert !Modifier.isStatic(modifiers);
             Object object = receiver.asObject();
 
             // Canonicalization may attempt to process an unsafe read before
@@ -232,13 +233,13 @@
     @Override
     public Constant readValue(Constant receiver) {
         if (receiver == null) {
-            assert Modifier.isStatic(flags);
+            assert Modifier.isStatic(modifiers);
             if (holder.isInitialized()) {
                 return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object);
             }
             return null;
         } else {
-            assert !Modifier.isStatic(flags);
+            assert !Modifier.isStatic(modifiers);
             Object object = receiver.asObject();
             assert object != null && isInObject(object);
             return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), object, offset, getKind() == Kind.Object);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Dec 09 17:31:12 2013 +0100
@@ -49,16 +49,17 @@
     /**
      * Reference to metaspace Method object.
      */
-    final long metaspaceMethod;
+    private final long metaspaceMethod;
 
     private final HotSpotResolvedObjectType holder;
-    private/* final */int codeSize;
+    private final HotSpotConstantPool constantPool;
+    private final HotSpotSignature signature;
+    private final int codeSize;
     private/* final */int exceptionHandlerCount;
     private boolean callerSensitive;
     private boolean forceInline;
     private boolean dontInline;
     private boolean ignoredBySecurityStackWalk;
-    private HotSpotSignature signature;
     private Boolean hasBalancedMonitors;
     private Map<Object, Object> compilerStorage;
     private HotSpotMethodData methodData;
@@ -75,13 +76,10 @@
      */
     public static HotSpotResolvedObjectType getHolder(long metaspaceMethod) {
         HotSpotVMConfig config = runtime().getConfig();
-        long constMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
-        assert constMethod != 0;
-        long constantPool = unsafe.getAddress(constMethod + config.constMethodConstantsOffset);
-        assert constantPool != 0;
-        long holder = unsafe.getAddress(constantPool + config.constantPoolHolderOffset);
-        assert holder != 0;
-        return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(holder);
+        final long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
+        final long metaspaceConstantPool = unsafe.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
+        final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + config.constantPoolHolderOffset);
+        return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
     }
 
     /**
@@ -96,20 +94,48 @@
     }
 
     HotSpotResolvedJavaMethod(HotSpotResolvedObjectType holder, long metaspaceMethod) {
+        // It would be too much work to get the method name here so we fill it in later.
+        super(null);
         this.metaspaceMethod = metaspaceMethod;
         this.holder = holder;
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final long constMethod = getConstMethod();
+
+        /*
+         * Get the constant pool from the metaspace method. Some methods (e.g. intrinsics for
+         * signature-polymorphic method handle methods) have their own constant pool instead of the
+         * one from their holder.
+         */
+        final long metaspaceConstantPool = unsafe.getAddress(constMethod + config.constMethodConstantsOffset);
+        this.constantPool = new HotSpotConstantPool(metaspaceConstantPool);
+
+        final int nameIndex = unsafe.getChar(constMethod + config.constMethodNameIndexOffset);
+        this.name = constantPool.lookupUtf8(nameIndex);
+
+        final int signatureIndex = unsafe.getChar(constMethod + config.constMethodSignatureIndexOffset);
+        this.signature = (HotSpotSignature) constantPool.lookupSignature(signatureIndex);
+        this.codeSize = unsafe.getChar(constMethod + config.constMethodCodeSizeOffset);
+
         runtime().getCompilerToVM().initializeMethod(metaspaceMethod, this);
     }
 
+    /**
+     * Returns a pointer to this method's constant method data structure (
+     * {@code Method::_constMethod}).
+     * 
+     * @return pointer to this method's ConstMethod
+     */
+    private long getConstMethod() {
+        assert metaspaceMethod != 0;
+        return unsafe.getAddress(metaspaceMethod + runtime().getConfig().methodConstMethodOffset);
+    }
+
     @Override
     public ResolvedJavaType getDeclaringClass() {
         return holder;
     }
 
-    public long getMetaspaceMethod() {
-        return metaspaceMethod;
-    }
-
     /**
      * Gets the address of the C++ Method object for this method.
      */
@@ -139,7 +165,7 @@
         if (codeSize == 0) {
             return null;
         }
-        if (code == null && runtime().getCompilerToVM().isTypeLinked(holder)) {
+        if (code == null && holder.isLinked()) {
             code = runtime().getCompilerToVM().initializeBytecode(metaspaceMethod, new byte[codeSize]);
             assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length;
         }
@@ -232,8 +258,7 @@
             return 0;
         }
         HotSpotVMConfig config = runtime().getConfig();
-        long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
-        return unsafe.getShort(metaspaceConstMethod + config.methodMaxLocalsOffset) & 0xFFFF;
+        return unsafe.getChar(getConstMethod() + config.methodMaxLocalsOffset);
     }
 
     @Override
@@ -243,8 +268,7 @@
             return 0;
         }
         HotSpotVMConfig config = runtime().getConfig();
-        long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
-        return config.extraStackEntries + (unsafe.getShort(metaspaceConstMethod + config.constMethodMaxStackOffset) & 0xFFFF);
+        return config.extraStackEntries + unsafe.getChar(getConstMethod() + config.constMethodMaxStackOffset);
     }
 
     @Override
@@ -269,9 +293,6 @@
 
     @Override
     public HotSpotSignature getSignature() {
-        if (signature == null) {
-            signature = new HotSpotSignature(runtime().getCompilerToVM().getSignature(metaspaceMethod));
-        }
         return signature;
     }
 
@@ -287,6 +308,14 @@
 
     @Override
     public ProfilingInfo getProfilingInfo() {
+        return getProfilingInfo(true, true);
+    }
+
+    public ProfilingInfo getCompilationProfilingInfo(boolean isOSR) {
+        return getProfilingInfo(!isOSR, isOSR);
+    }
+
+    private ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
         ProfilingInfo info;
 
         if (UseProfilingInformation.getValue() && methodData == null) {
@@ -305,7 +334,7 @@
             // case of a deoptimization.
             info = DefaultProfilingInfo.get(TriState.FALSE);
         } else {
-            info = new HotSpotProfilingInfo(methodData, this);
+            info = new HotSpotProfilingInfo(methodData, this, includeNormal, includeOSR);
         }
         return info;
     }
@@ -325,7 +354,7 @@
 
     @Override
     public ConstantPool getConstantPool() {
-        return ((HotSpotResolvedObjectType) getDeclaringClass()).constantPool();
+        return constantPool;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Mon Dec 09 17:31:12 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.hotspot.meta;
 
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-
 import com.oracle.graal.api.meta.*;
 
 public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {
@@ -35,9 +33,4 @@
     }
 
     public abstract Class<?> mirror();
-
-    @Override
-    public String getSourceFileName() {
-        return runtime().getCompilerToVM().getFileName(this);
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Dec 09 17:31:12 2013 +0100
@@ -44,46 +44,20 @@
     private static final long serialVersionUID = 3481514353553840471L;
 
     /**
-     * Value for the {@code sizeOrSpecies} parameter in
-     * {@link HotSpotResolvedObjectType#HotSpotResolvedObjectType} denoting that the new type
-     * represents an interface class.
+     * The Java class this type represents.
      */
-    public static final int INTERFACE_SPECIES_VALUE = Integer.MIN_VALUE;
-
-    /**
-     * Value for the {@code sizeOrSpecies} parameter in
-     * {@link HotSpotResolvedObjectType#HotSpotResolvedObjectType} denoting that the new type
-     * represents an array class.
-     */
-    public static final int ARRAY_SPECIES_VALUE = Integer.MAX_VALUE;
-
-    /**
-     * Reference to the metaspace Klass object.
-     */
-    private final long metaspaceKlass;
-
-    private final Class<?> javaMirror; // this could be read directly from 'metaspaceKlass'...
-    private final String simpleName;
+    private final Class<?> javaClass;
 
     /**
      * Used for implemented a lazy binding from a {@link Node} type to a {@link NodeClass} value.
      */
     private NodeClass nodeClass;
 
-    /**
-     * The instance size (in bytes) for an instance type,
-     * {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} denoting an interface type or
-     * {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE} denoting an array type.
-     */
-    private final int sizeOrSpecies;
-
     private HashMap<Long, ResolvedJavaField> fieldCache;
     private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
     private HotSpotResolvedJavaField[] instanceFields;
     private ResolvedJavaType[] interfaces;
     private ConstantPool constantPool;
-    private boolean isInitialized;
-    private boolean isLinked;
     private ResolvedJavaType arrayOfType;
 
     /**
@@ -117,51 +91,84 @@
      */
     public static ResolvedJavaType fromClass(Class javaClass) {
         assert javaClass != null;
-        ResolvedJavaType type = (ResolvedJavaType) unsafe.getObject(javaClass, (long) runtime().getConfig().graalMirrorInClassOffset);
+        HotSpotGraalRuntime runtime = runtime();
+        ResolvedJavaType type = (ResolvedJavaType) unsafe.getObject(javaClass, (long) runtime.getConfig().graalMirrorInClassOffset);
         if (type == null) {
-            type = runtime().getCompilerToVM().getResolvedType(javaClass);
+            assert !javaClass.isPrimitive() : "primitive type " + javaClass + " should have its mirror initialized";
+            type = new HotSpotResolvedObjectType(javaClass);
+
+            // Install the Graal mirror in the Class object.
+            final long offset = runtime().getConfig().graalMirrorInClassOffset;
+            if (!unsafe.compareAndSwapObject(javaClass, offset, null, type)) {
+                // lost the race - return the existing value instead
+                type = (HotSpotResolvedObjectType) unsafe.getObject(javaClass, offset);
+            }
+
             assert type != null;
         }
         return type;
     }
 
-    /**
-     * @param sizeOrSpecies the size of an instance of the type, or
-     *            {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} or
-     *            {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE}
-     */
     public HotSpotResolvedObjectType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies) {
         super(name);
-        this.metaspaceKlass = metaspaceKlass;
-        this.javaMirror = javaMirror;
-        this.simpleName = simpleName;
-        this.sizeOrSpecies = sizeOrSpecies;
-        assert name.charAt(0) != '[' || sizeOrSpecies == ARRAY_SPECIES_VALUE : name + " " + Long.toHexString(sizeOrSpecies);
-        assert javaMirror.isArray() == isArray();
-        assert javaMirror.isInterface() == isInterface();
+        assert HotSpotGraalRuntime.unsafeReadWord(javaMirror, runtime().getConfig().klassOffset) == metaspaceKlass;
+        this.javaClass = javaMirror;
+        assert name.charAt(0) != '[' || isArray() : name + " " + simpleName + " " + Long.toHexString(sizeOrSpecies);
+    }
+
+    /**
+     * Creates the Graal mirror for a {@link Class} object.
+     * 
+     * <p>
+     * <b>NOTE</b>: Creating a Graal mirror does not install the mirror in the {@link Class} object.
+     * </p>
+     * 
+     * @param javaClass the Class to create the mirror for
+     */
+    public HotSpotResolvedObjectType(Class<?> javaClass) {
+        super(getSignatureName(javaClass));
+        this.javaClass = javaClass;
+        assert getName().charAt(0) != '[' || isArray() : getName();
+    }
+
+    /**
+     * Returns the name of this type as it would appear in a signature.
+     */
+    private static String getSignatureName(Class<?> javaClass) {
+        if (javaClass.isArray()) {
+            return javaClass.getName().replace('.', '/');
+        }
+        return "L" + javaClass.getName().replace('.', '/') + ";";
+    }
+
+    /**
+     * Gets the address of the C++ Klass object for this type.
+     */
+    private long metaspaceKlass() {
+        return HotSpotGraalRuntime.unsafeReadWord(javaClass, runtime().getConfig().klassOffset);
     }
 
     @Override
     public int getModifiers() {
-        return javaMirror.getModifiers();
+        return javaClass.getModifiers();
     }
 
     public int getAccessFlags() {
         HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(metaspaceKlass + config.klassAccessFlagsOffset);
+        return unsafe.getInt(metaspaceKlass() + config.klassAccessFlagsOffset);
     }
 
     @Override
     public ResolvedJavaType getArrayClass() {
         if (arrayOfType == null) {
-            arrayOfType = fromClass(Array.newInstance(javaMirror, 0).getClass());
+            arrayOfType = fromClass(Array.newInstance(javaClass, 0).getClass());
         }
         return arrayOfType;
     }
 
     @Override
     public ResolvedJavaType getComponentType() {
-        Class javaComponentType = javaMirror.getComponentType();
+        Class javaComponentType = javaClass.getComponentType();
         return javaComponentType == null ? null : fromClass(javaComponentType);
     }
 
@@ -175,13 +182,13 @@
         } else {
             HotSpotResolvedObjectType type = this;
             while (isAbstract(type.getModifiers())) {
-                long subklass = unsafeReadWord(type.metaspaceKlass + config.subklassOffset);
+                long subklass = unsafeReadWord(type.metaspaceKlass() + config.subklassOffset);
                 if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) {
                     return null;
                 }
                 type = (HotSpotResolvedObjectType) fromMetaspaceKlass(subklass);
             }
-            if (isAbstract(type.getModifiers()) || type.isInterface() || unsafeReadWord(type.metaspaceKlass + config.subklassOffset) != 0) {
+            if (isAbstract(type.getModifiers()) || type.isInterface() || unsafeReadWord(type.metaspaceKlass() + config.subklassOffset) != 0) {
                 return null;
             }
             return type;
@@ -190,14 +197,14 @@
 
     @Override
     public HotSpotResolvedObjectType getSuperclass() {
-        Class javaSuperclass = javaMirror.getSuperclass();
+        Class javaSuperclass = javaClass.getSuperclass();
         return javaSuperclass == null ? null : (HotSpotResolvedObjectType) fromClass(javaSuperclass);
     }
 
     @Override
     public ResolvedJavaType[] getInterfaces() {
         if (interfaces == null) {
-            Class[] javaInterfaces = javaMirror.getInterfaces();
+            Class[] javaInterfaces = javaClass.getInterfaces();
             ResolvedJavaType[] result = new ResolvedJavaType[javaInterfaces.length];
             for (int i = 0; i < javaInterfaces.length; i++) {
                 result[i] = fromClass(javaInterfaces[i]);
@@ -210,7 +217,7 @@
     public HotSpotResolvedObjectType getSupertype() {
         if (isArray()) {
             ResolvedJavaType componentType = getComponentType();
-            if (javaMirror == Object[].class || componentType.isPrimitive()) {
+            if (javaClass == Object[].class || componentType.isPrimitive()) {
                 return (HotSpotResolvedObjectType) fromClass(Object.class);
             }
             return (HotSpotResolvedObjectType) ((HotSpotResolvedObjectType) componentType).getSupertype().getArrayClass();
@@ -253,12 +260,11 @@
     public Constant getEncoding(Representation r) {
         switch (r) {
             case JavaClass:
-                return Constant.forObject(javaMirror);
+                return Constant.forObject(javaClass);
             case ObjectHub:
                 return klass();
             default:
-                assert false : "Should not reach here.";
-                return null;
+                throw GraalInternalError.shouldNotReachHere("unexpected representation " + r);
         }
     }
 
@@ -281,38 +287,43 @@
 
     @Override
     public boolean isArray() {
-        return sizeOrSpecies == ARRAY_SPECIES_VALUE;
+        return javaClass.isArray();
     }
 
     @Override
     public boolean isInitialized() {
-        if (!isInitialized) {
-            isInitialized = runtime().getCompilerToVM().isTypeInitialized(this);
-        }
-        return isInitialized;
+        final int state = getState();
+        return state == runtime().getConfig().klassStateFullyInitialized;
     }
 
     @Override
     public boolean isLinked() {
-        if (!isLinked) {
-            isLinked = runtime().getCompilerToVM().isTypeLinked(this);
-        }
-        return isLinked;
+        final int state = getState();
+        return state >= runtime().getConfig().klassStateLinked;
+    }
+
+    /**
+     * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace
+     * klass.
+     * 
+     * @return state field value of this type
+     */
+    private int getState() {
+        return unsafe.getByte(metaspaceKlass() + runtime().getConfig().klassStateOffset) & 0xFF;
     }
 
     @Override
     public void initialize() {
-        if (!isInitialized) {
-            runtime().getCompilerToVM().initializeType(this);
-            assert runtime().getCompilerToVM().isTypeInitialized(this);
+        if (!isInitialized()) {
+            unsafe.ensureClassInitialized(javaClass);
+            assert isInitialized();
         }
-        isInitialized = true;
     }
 
     @Override
     public boolean isInstance(Constant obj) {
         if (obj.getKind() == Kind.Object && !obj.isNull()) {
-            return javaMirror.isInstance(obj.asObject());
+            return javaClass.isInstance(obj.asObject());
         }
         return false;
     }
@@ -324,7 +335,7 @@
 
     @Override
     public boolean isInterface() {
-        return sizeOrSpecies == INTERFACE_SPECIES_VALUE;
+        return javaClass.isInterface();
     }
 
     @Override
@@ -332,7 +343,7 @@
         assert other != null;
         if (other instanceof HotSpotResolvedObjectType) {
             HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other;
-            return javaMirror.isAssignableFrom(otherType.javaMirror);
+            return javaClass.isAssignableFrom(otherType.javaClass);
         }
         return false;
     }
@@ -354,12 +365,19 @@
 
     @Override
     public String toString() {
+        String simpleName;
+        if (isArray() || isInterface()) {
+            simpleName = getName();
+        } else {
+            simpleName = getName().substring(1, getName().length() - 1);
+        }
         return "HotSpotType<" + simpleName + ", resolved>";
     }
 
     public ConstantPool constantPool() {
         if (constantPool == null) {
-            constantPool = new HotSpotConstantPool(this);
+            final long metaspaceConstantPool = unsafe.getAddress(metaspaceKlass() + runtime().getConfig().instanceKlassConstantsOffset);
+            constantPool = new HotSpotConstantPool(metaspaceConstantPool);
         }
         return constantPool;
     }
@@ -372,7 +390,18 @@
     public int instanceSize() {
         assert !isArray();
         assert !isInterface();
-        return sizeOrSpecies;
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final int layoutHelper = unsafe.getInt(metaspaceKlass() + config.klassLayoutHelperOffset);
+        assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance";
+
+        // See: Klass::layout_helper_size_in_bytes
+        int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit;
+
+        // See: Klass::layout_helper_needs_slow_path
+        boolean needsSlowPath = (layoutHelper & config.klassLayoutHelperInstanceSlowPathBit) != 0;
+
+        return needsSlowPath ? -size : size;
     }
 
     public synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
@@ -389,7 +418,7 @@
         return method;
     }
 
-    public synchronized ResolvedJavaField createField(String fieldName, JavaType type, int offset, int flags, boolean internal) {
+    public synchronized ResolvedJavaField createField(String fieldName, JavaType type, long offset, int flags, boolean internal) {
         ResolvedJavaField result = null;
 
         long id = offset + ((long) flags << 32);
@@ -434,7 +463,7 @@
             } else {
                 HotSpotResolvedJavaField[] myFields = runtime().getCompilerToVM().getInstanceFields(this);
                 Arrays.sort(myFields, new OffsetComparator());
-                if (javaMirror != Object.class) {
+                if (javaClass != Object.class) {
                     HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true);
                     HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length);
                     System.arraycopy(myFields, 0, fields, superFields.length, myFields.length);
@@ -463,17 +492,22 @@
 
     @Override
     public Class<?> mirror() {
-        return javaMirror;
+        return javaClass;
     }
 
     @Override
     public String getSourceFileName() {
-        return runtime().getCompilerToVM().getFileName(this);
+        HotSpotVMConfig config = runtime().getConfig();
+        final int sourceFileNameIndex = unsafe.getChar(metaspaceKlass() + config.klassSourceFileNameIndexOffset);
+        if (sourceFileNameIndex == 0) {
+            return null;
+        }
+        return constantPool().lookupUtf8(sourceFileNameIndex);
     }
 
     @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        return javaMirror.getAnnotation(annotationClass);
+        return javaClass.getAnnotation(annotationClass);
     }
 
     @Override
@@ -485,14 +519,7 @@
      * Gets the address of the C++ Klass object for this type.
      */
     public Constant klass() {
-        return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass, this);
-    }
-
-    /**
-     * Gets the address of the C++ Klass object for this type.
-     */
-    public long metaspaceKlass() {
-        return metaspaceKlass;
+        return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass(), this);
     }
 
     public boolean isPrimaryType() {
@@ -501,7 +528,7 @@
 
     public int superCheckOffset() {
         HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(metaspaceKlass + config.superCheckOffsetOffset);
+        return unsafe.getInt(metaspaceKlass() + config.superCheckOffsetOffset);
     }
 
     public long prototypeMarkWord() {
@@ -509,7 +536,7 @@
         if (isArray()) {
             return config.arrayPrototypeMarkWord();
         } else {
-            return unsafeReadWord(metaspaceKlass + config.prototypeMarkWordOffset);
+            return unsafeReadWord(metaspaceKlass() + config.prototypeMarkWordOffset);
         }
     }
 
@@ -548,7 +575,7 @@
 
     @Override
     public ResolvedJavaMethod[] getDeclaredConstructors() {
-        Constructor[] constructors = javaMirror.getDeclaredConstructors();
+        Constructor[] constructors = javaClass.getDeclaredConstructors();
         ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
         for (int i = 0; i < constructors.length; i++) {
             result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]);
@@ -559,7 +586,7 @@
 
     @Override
     public ResolvedJavaMethod[] getDeclaredMethods() {
-        Method[] methods = javaMirror.getDeclaredMethods();
+        Method[] methods = javaClass.getDeclaredMethods();
         ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length];
         for (int i = 0; i < methods.length; i++) {
             result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(methods[i]);
@@ -580,7 +607,7 @@
 
     @Override
     public Constant newArray(int length) {
-        return Constant.forObject(Array.newInstance(javaMirror, length));
+        return Constant.forObject(Array.newInstance(javaClass, length));
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.graal.hotspot.nodes;
+
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.word.*;
+
+public class PrefetchAllocateNode extends FixedWithNextNode implements LIRGenLowerable {
+
+    @Input private ValueNode distance;
+    @Input private ValueNode address;
+
+    public PrefetchAllocateNode(ValueNode address, ValueNode distance) {
+        super(StampFactory.forVoid());
+        this.address = address;
+        this.distance = distance;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        ((HotSpotLIRGenerator) gen).emitPrefetchAllocate(address, distance);
+    }
+
+    @NodeIntrinsic
+    public static native void prefetch(Word address, Word distance);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Mon Dec 09 17:31:12 2013 +0100
@@ -98,7 +98,9 @@
             }
         } else if (barrierType == BarrierType.IMPRECISE) {
             if (useG1GC()) {
-                addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph);
+                if (!node.isInitialization()) {
+                    addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph);
+                }
                 addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph);
             } else {
                 addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Mon Dec 09 17:31:12 2013 +0100
@@ -229,7 +229,7 @@
     }
 
     @Fold
-    private static int klassLayoutHelperOffset() {
+    public static int klassLayoutHelperOffset() {
         return config().klassLayoutHelperOffset;
     }
 
@@ -613,11 +613,6 @@
     }
 
     @Fold
-    public static int layoutHelperOffset() {
-        return config().layoutHelperOffset;
-    }
-
-    @Fold
     public static int layoutHelperHeaderSizeShift() {
         return config().layoutHelperHeaderSizeShift;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Dec 09 17:31:12 2013 +0100
@@ -112,6 +112,21 @@
         }
     }
 
+    private static void emitPrefetchAllocate(Word address, boolean isArray) {
+        if (config().allocatePrefetchStyle > 0) {
+            // Insert a prefetch for each allocation only on the fast-path
+            // Generate several prefetch instructions.
+            int lines = isArray ? config().allocatePrefetchLines : config().allocateInstancePrefetchLines;
+            int stepSize = config().allocatePrefetchStepSize;
+            int distance = config().allocatePrefetchDistance;
+            ExplodeLoopNode.explodeLoop();
+            for (int i = 0; i < lines; i++) {
+                PrefetchAllocateNode.prefetch(address, Word.signed(distance));
+                distance += stepSize;
+            }
+        }
+    }
+
     @Snippet
     public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
                     @ConstantParameter String typeContext) {
@@ -122,6 +137,7 @@
         Word newTop = top.add(size);
         if (useTLAB() && probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) {
             writeTlabTop(thread, newTop);
+            emitPrefetchAllocate(newTop, false);
             result = formatObject(hub, size, top, prototypeMarkWord, fillContents);
         } else {
             new_stub.inc();
@@ -157,6 +173,7 @@
         Word newTop = top.add(allocationSize);
         if (useTLAB() && probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) {
             writeTlabTop(thread, newTop);
+            emitPrefetchAllocate(newTop, true);
             newarray_loopInit.inc();
             result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents);
         } else {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Mon Dec 09 17:31:12 2013 +0100
@@ -89,7 +89,7 @@
      */
     @Snippet
     private static Object newArray(Word hub, int length, @ConstantParameter Word intArrayHub, @ConstantParameter Register threadRegister) {
-        int layoutHelper = hub.readInt(layoutHelperOffset(), LocationIdentity.FINAL_LOCATION);
+        int layoutHelper = hub.readInt(klassLayoutHelperOffset(), LocationIdentity.FINAL_LOCATION);
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
         int elementKind = (layoutHelper >> layoutHelperElementTypeShift()) & layoutHelperElementTypeMask();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Dec 09 17:31:12 2013 +0100
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -39,6 +39,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
@@ -151,24 +152,20 @@
                 phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                 // The stub itself needs the incoming calling convention.
                 CallingConvention incomingCc = linkage.getIncomingCallingConvention();
-                final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null, phasePlan,
-                                OptimisticOptimizations.ALL, new SpeculationLog(), providers.getSuites().getDefaultSuites(), new CompilationResult());
+                final CompilationResult compResult = compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
+                                getProfilingInfo(graph), new SpeculationLog(), providers.getSuites().getDefaultSuites(), true, new CompilationResult(), CompilationResultBuilderFactory.Default);
 
                 assert destroyedRegisters != null;
                 try (Scope s = Debug.scope("CodeInstall")) {
                     Stub stub = Stub.this;
                     HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub);
                     HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult);
+
                     CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
                     if (result != CodeInstallResult.OK) {
                         throw new GraalInternalError("Error installing stub %s: %s", Stub.this, result);
                     }
-                    if (Debug.isDumpEnabled()) {
-                        Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
-                    }
-                    if (Debug.isLogEnabled()) {
-                        Debug.log("%s", providers.getDisassembler().disassemble(installedCode));
-                    }
+                    ((HotSpotCodeCacheProvider) codeCache).logOrDump(installedCode, compResult);
                     code = installedCode;
                 } catch (Throwable e) {
                     throw Debug.handle(e);
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,14 +23,15 @@
 package com.oracle.graal.java.decompiler.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
@@ -53,7 +54,7 @@
         GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
-        GraalCompiler.compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites,
-                        new CompilationResult());
+        compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(), suites,
+                        true, new CompilationResult(), CompilationResultBuilderFactory.Default);
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Dec 09 17:31:12 2013 +0100
@@ -1218,14 +1218,14 @@
             frameState.pushReturn(resultType, append(invoke));
             return invoke;
         } else {
+            assert bci() == currentBlock.endBci;
+            frameState.clearNonLiveLocals(currentBlock.localsLiveOut);
+
             DispatchBeginNode exceptionEdge = handleException(null, bci());
             InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
             frameState.pushReturn(resultType, invoke);
             Block nextBlock = currentBlock.successors.get(0);
 
-            assert bci() == currentBlock.endBci;
-            frameState.clearNonLiveLocals(currentBlock.localsLiveOut);
-
             invoke.setNext(createTarget(nextBlock, frameState));
             invoke.setStateAfter(frameState.create(nextBlock.startBci));
             return invoke;
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Math_pow.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Math_pow.java	Mon Dec 09 17:31:12 2013 +0100
@@ -29,18 +29,57 @@
  */
 public class Math_pow extends JTTTest {
 
-    public static double test(double pow) {
-        return Math.pow(2.0d, pow);
+    public static double test(double x, double y) {
+        return Math.pow(x, y);
     }
 
     @Test
     public void run0() throws Throwable {
-        runTest("test", 2d);
+        runTest("test", 2d, 0d);
     }
 
     @Test
     public void run1() throws Throwable {
-        runTest("test", 3.1d);
+        runTest("test", 2d, 0.5d);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", -2d, 0.5d);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 2d, 1d);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", 2d, -1d);
     }
 
+    @Test
+    public void run5() throws Throwable {
+        runTest("test", 2d, 2d);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        runTest("test", 2d, 3.1d);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        runTest("test", 2d, Double.NaN);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        runTest("test", Double.NaN, 0d);
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        runTest("test", Double.NaN, 23d);
+    }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Mon Dec 09 17:31:12 2013 +0100
@@ -74,8 +74,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, null);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, null);
         }
     }
 
@@ -95,9 +95,9 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            AMD64Move.move(tasm, masm, result, x);
-            emit(tasm, masm, opcode, result);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            emit(crb, masm, opcode, result);
         }
     }
 
@@ -120,9 +120,9 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            AMD64Move.move(tasm, masm, result, x);
-            emit(tasm, masm, opcode, result, y, null);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            emit(crb, masm, opcode, result, y, null);
         }
 
         @Override
@@ -152,9 +152,9 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            AMD64Move.move(tasm, masm, result, x);
-            emit(tasm, masm, opcode, result, y, null);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            emit(crb, masm, opcode, result, y, null);
         }
 
         @Override
@@ -183,9 +183,9 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            AMD64Move.move(tasm, masm, result, x);
-            emit(tasm, masm, opcode, result, y, null);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            emit(crb, masm, opcode, result, y, null);
         }
 
         @Override
@@ -214,12 +214,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (sameRegister(result, y)) {
-                emit(tasm, masm, opcode, result, x, null);
+                emit(crb, masm, opcode, result, x, null);
             } else {
-                AMD64Move.move(tasm, masm, result, x);
-                emit(tasm, masm, opcode, result, y, null);
+                AMD64Move.move(crb, masm, result, x);
+                emit(crb, masm, opcode, result, y, null);
             }
         }
 
@@ -248,9 +248,9 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            AMD64Move.move(tasm, masm, result, x);
-            emit(tasm, masm, opcode, result, y, null);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move(crb, masm, result, x);
+            emit(crb, masm, opcode, result, y, null);
         }
 
         @Override
@@ -279,8 +279,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            emit(tasm, masm, opcode, null, y, state);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            emit(crb, masm, opcode, null, y, state);
         }
 
         @Override
@@ -312,7 +312,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             AMD64Address tmp = new AMD64Address(AMD64.rsp);
             masm.subq(AMD64.rsp, 8);
             if (opcode == FREM) {
@@ -322,9 +322,9 @@
                 masm.flds(tmp);
             } else {
                 assert opcode == DREM;
-                masm.movsd(tmp, asRegister(y));
+                masm.movdbl(tmp, asRegister(y));
                 masm.fldd(tmp);
-                masm.movsd(tmp, asRegister(x));
+                masm.movdbl(tmp, asRegister(x));
                 masm.fldd(tmp);
             }
 
@@ -343,7 +343,7 @@
                 masm.movflt(asRegister(result), tmp);
             } else {
                 masm.fstpd(tmp);
-                masm.movsd(asRegister(result), tmp);
+                masm.movdbl(asRegister(result), tmp);
             }
             masm.addq(AMD64.rsp, 8);
         }
@@ -356,7 +356,7 @@
     }
 
     @SuppressWarnings("unused")
-    protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, AllocatableValue result) {
+    protected static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, AMD64Arithmetic opcode, AllocatableValue result) {
         switch (opcode) {
             case INEG:
                 masm.negl(asIntReg(result));
@@ -381,7 +381,7 @@
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, Value dst, Value src, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, AMD64Arithmetic opcode, Value dst, Value src, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isRegister(src)) {
             switch (opcode) {
@@ -584,103 +584,103 @@
         } else if (isConstant(src)) {
             switch (opcode) {
                 case IADD:
-                    masm.incrementl(asIntReg(dst), tasm.asIntConst(src));
+                    masm.incrementl(asIntReg(dst), crb.asIntConst(src));
                     break;
                 case ISUB:
-                    masm.decrementl(asIntReg(dst), tasm.asIntConst(src));
+                    masm.decrementl(asIntReg(dst), crb.asIntConst(src));
                     break;
                 case IMUL:
-                    masm.imull(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src));
+                    masm.imull(asIntReg(dst), asIntReg(dst), crb.asIntConst(src));
                     break;
                 case IAND:
-                    masm.andl(asIntReg(dst), tasm.asIntConst(src));
+                    masm.andl(asIntReg(dst), crb.asIntConst(src));
                     break;
                 case IOR:
-                    masm.orl(asIntReg(dst), tasm.asIntConst(src));
+                    masm.orl(asIntReg(dst), crb.asIntConst(src));
                     break;
                 case IXOR:
-                    masm.xorl(asIntReg(dst), tasm.asIntConst(src));
+                    masm.xorl(asIntReg(dst), crb.asIntConst(src));
                     break;
                 case ISHL:
-                    masm.shll(asIntReg(dst), tasm.asIntConst(src) & 31);
+                    masm.shll(asIntReg(dst), crb.asIntConst(src) & 31);
                     break;
                 case ISHR:
-                    masm.sarl(asIntReg(dst), tasm.asIntConst(src) & 31);
+                    masm.sarl(asIntReg(dst), crb.asIntConst(src) & 31);
                     break;
                 case IUSHR:
-                    masm.shrl(asIntReg(dst), tasm.asIntConst(src) & 31);
+                    masm.shrl(asIntReg(dst), crb.asIntConst(src) & 31);
                     break;
 
                 case LADD:
-                    masm.addq(asLongReg(dst), tasm.asIntConst(src));
+                    masm.addq(asLongReg(dst), crb.asIntConst(src));
                     break;
                 case LSUB:
-                    masm.subq(asLongReg(dst), tasm.asIntConst(src));
+                    masm.subq(asLongReg(dst), crb.asIntConst(src));
                     break;
                 case LMUL:
-                    masm.imulq(asLongReg(dst), asLongReg(dst), tasm.asIntConst(src));
+                    masm.imulq(asLongReg(dst), asLongReg(dst), crb.asIntConst(src));
                     break;
                 case LAND:
-                    masm.andq(asLongReg(dst), tasm.asIntConst(src));
+                    masm.andq(asLongReg(dst), crb.asIntConst(src));
                     break;
                 case LOR:
-                    masm.orq(asLongReg(dst), tasm.asIntConst(src));
+                    masm.orq(asLongReg(dst), crb.asIntConst(src));
                     break;
                 case LXOR:
-                    masm.xorq(asLongReg(dst), tasm.asIntConst(src));
+                    masm.xorq(asLongReg(dst), crb.asIntConst(src));
                     break;
                 case LSHL:
-                    masm.shlq(asLongReg(dst), tasm.asIntConst(src) & 63);
+                    masm.shlq(asLongReg(dst), crb.asIntConst(src) & 63);
                     break;
                 case LSHR:
-                    masm.sarq(asLongReg(dst), tasm.asIntConst(src) & 63);
+                    masm.sarq(asLongReg(dst), crb.asIntConst(src) & 63);
                     break;
                 case LUSHR:
-                    masm.shrq(asLongReg(dst), tasm.asIntConst(src) & 63);
+                    masm.shrq(asLongReg(dst), crb.asIntConst(src) & 63);
                     break;
 
                 case FADD:
-                    masm.addss(asFloatReg(dst), (AMD64Address) tasm.asFloatConstRef(src));
+                    masm.addss(asFloatReg(dst), (AMD64Address) crb.asFloatConstRef(src));
                     break;
                 case FSUB:
-                    masm.subss(asFloatReg(dst), (AMD64Address) tasm.asFloatConstRef(src));
+                    masm.subss(asFloatReg(dst), (AMD64Address) crb.asFloatConstRef(src));
                     break;
                 case FMUL:
-                    masm.mulss(asFloatReg(dst), (AMD64Address) tasm.asFloatConstRef(src));
+                    masm.mulss(asFloatReg(dst), (AMD64Address) crb.asFloatConstRef(src));
                     break;
                 case FAND:
-                    masm.andps(asFloatReg(dst), (AMD64Address) tasm.asFloatConstRef(src, 16));
+                    masm.andps(asFloatReg(dst), (AMD64Address) crb.asFloatConstRef(src, 16));
                     break;
                 case FOR:
-                    masm.orps(asFloatReg(dst), (AMD64Address) tasm.asFloatConstRef(src, 16));
+                    masm.orps(asFloatReg(dst), (AMD64Address) crb.asFloatConstRef(src, 16));
                     break;
                 case FXOR:
-                    masm.xorps(asFloatReg(dst), (AMD64Address) tasm.asFloatConstRef(src, 16));
+                    masm.xorps(asFloatReg(dst), (AMD64Address) crb.asFloatConstRef(src, 16));
                     break;
                 case FDIV:
-                    masm.divss(asFloatReg(dst), (AMD64Address) tasm.asFloatConstRef(src));
+                    masm.divss(asFloatReg(dst), (AMD64Address) crb.asFloatConstRef(src));
                     break;
 
                 case DADD:
-                    masm.addsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleConstRef(src));
+                    masm.addsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleConstRef(src));
                     break;
                 case DSUB:
-                    masm.subsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleConstRef(src));
+                    masm.subsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleConstRef(src));
                     break;
                 case DMUL:
-                    masm.mulsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleConstRef(src));
+                    masm.mulsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleConstRef(src));
                     break;
                 case DDIV:
-                    masm.divsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleConstRef(src));
+                    masm.divsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleConstRef(src));
                     break;
                 case DAND:
-                    masm.andpd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleConstRef(src, 16));
+                    masm.andpd(asDoubleReg(dst), (AMD64Address) crb.asDoubleConstRef(src, 16));
                     break;
                 case DOR:
-                    masm.orpd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleConstRef(src, 16));
+                    masm.orpd(asDoubleReg(dst), (AMD64Address) crb.asDoubleConstRef(src, 16));
                     break;
                 case DXOR:
-                    masm.xorpd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleConstRef(src, 16));
+                    masm.xorpd(asDoubleReg(dst), (AMD64Address) crb.asDoubleConstRef(src, 16));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -688,123 +688,123 @@
         } else {
             switch (opcode) {
                 case IADD:
-                    masm.addl(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.addl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case ISUB:
-                    masm.subl(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.subl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case IAND:
-                    masm.andl(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.andl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case IMUL:
-                    masm.imull(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.imull(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case IOR:
-                    masm.orl(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.orl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case IXOR:
-                    masm.xorl(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.xorl(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
 
                 case LADD:
-                    masm.addq(asLongReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.addq(asLongReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case LSUB:
-                    masm.subq(asLongReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.subq(asLongReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case LMUL:
-                    masm.imulq(asLongReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.imulq(asLongReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case LAND:
-                    masm.andq(asLongReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.andq(asLongReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case LOR:
-                    masm.orq(asLongReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.orq(asLongReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case LXOR:
-                    masm.xorq(asLongReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.xorq(asLongReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
 
                 case FADD:
-                    masm.addss(asFloatReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.addss(asFloatReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
                 case FSUB:
-                    masm.subss(asFloatReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.subss(asFloatReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
                 case FMUL:
-                    masm.mulss(asFloatReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.mulss(asFloatReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
                 case FDIV:
-                    masm.divss(asFloatReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.divss(asFloatReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
 
                 case DADD:
-                    masm.addsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.addsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
                 case DSUB:
-                    masm.subsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.subsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
                 case DMUL:
-                    masm.mulsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.mulsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
                 case DDIV:
-                    masm.divsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.divsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
 
                 case SQRT:
-                    masm.sqrtsd(asDoubleReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.sqrtsd(asDoubleReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
 
                 case I2B:
-                    masm.movsxb(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.movsxb(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case I2S:
-                    masm.movsxw(asIntReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.movsxw(asIntReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case I2L:
-                    masm.movslq(asLongReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.movslq(asLongReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case F2D:
-                    masm.cvtss2sd(asDoubleReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.cvtss2sd(asDoubleReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
                 case D2F:
-                    masm.cvtsd2ss(asFloatReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.cvtsd2ss(asFloatReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
                 case I2F:
-                    masm.cvtsi2ssl(asFloatReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.cvtsi2ssl(asFloatReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case I2D:
-                    masm.cvtsi2sdl(asDoubleReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.cvtsi2sdl(asDoubleReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case L2F:
-                    masm.cvtsi2ssq(asFloatReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.cvtsi2ssq(asFloatReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case L2D:
-                    masm.cvtsi2sdq(asDoubleReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.cvtsi2sdq(asDoubleReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case F2I:
-                    masm.cvttss2sil(asIntReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.cvttss2sil(asIntReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
                 case D2I:
-                    masm.cvttsd2sil(asIntReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.cvttsd2sil(asIntReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
                 case F2L:
-                    masm.cvttss2siq(asLongReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.cvttss2siq(asLongReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
                 case D2L:
-                    masm.cvttsd2siq(asLongReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.cvttsd2siq(asLongReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
                 case MOV_I2F:
-                    masm.movss(asFloatReg(dst), (AMD64Address) tasm.asIntAddr(src));
+                    masm.movss(asFloatReg(dst), (AMD64Address) crb.asIntAddr(src));
                     break;
                 case MOV_L2D:
-                    masm.movsd(asDoubleReg(dst), (AMD64Address) tasm.asLongAddr(src));
+                    masm.movsd(asDoubleReg(dst), (AMD64Address) crb.asLongAddr(src));
                     break;
                 case MOV_F2I:
-                    masm.movl(asIntReg(dst), (AMD64Address) tasm.asFloatAddr(src));
+                    masm.movl(asIntReg(dst), (AMD64Address) crb.asFloatAddr(src));
                     break;
                 case MOV_D2L:
-                    masm.movq(asLongReg(dst), (AMD64Address) tasm.asDoubleAddr(src));
+                    masm.movq(asLongReg(dst), (AMD64Address) crb.asDoubleAddr(src));
                     break;
 
                 default:
@@ -814,7 +814,7 @@
 
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -45,7 +45,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         Register dst = ValueUtil.asIntReg(result);
         if (ValueUtil.isRegister(input)) {
             Register src = ValueUtil.asRegister(input);
@@ -67,7 +67,7 @@
                     break;
             }
         } else {
-            AMD64Address src = (AMD64Address) tasm.asAddress(input);
+            AMD64Address src = (AMD64Address) crb.asAddress(input);
             switch (opcode) {
                 case IPOPCNT:
                     masm.popcntl(dst, src);
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BreakpointOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -45,7 +45,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
         asm.int3();
     }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ByteSwapOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -40,8 +40,8 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        AMD64Move.move(tasm, masm, result, input);
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        AMD64Move.move(crb, masm, result, input);
         switch (input.getKind()) {
             case Int:
                 masm.bswapl(ValueUtil.asIntReg(result));
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Mon Dec 09 17:31:12 2013 +0100
@@ -25,13 +25,13 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
+import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.spi.*;
 
 public class AMD64Call {
 
@@ -75,8 +75,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            directCall(tasm, masm, callTarget, null, true, state);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            directCall(crb, masm, callTarget, null, true, state);
         }
     }
 
@@ -91,8 +91,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            indirectCall(tasm, masm, asRegister(targetAddress), callTarget, state);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            indirectCall(crb, masm, asRegister(targetAddress), callTarget, state);
         }
 
         @Override
@@ -125,8 +125,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            directCall(tasm, masm, callTarget, null, false, state);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            directCall(crb, masm, callTarget, null, false, state);
         }
     }
 
@@ -135,20 +135,25 @@
 
         @Temp({REG}) protected AllocatableValue callTemp;
 
-        public DirectFarForeignCallOp(LIRGeneratorTool gen, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+        public DirectFarForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
             super(callTarget, result, parameters, temps, state);
-            callTemp = gen.newVariable(Kind.Long);
+            /*
+             * The register allocator does not support virtual registers that are used at the call
+             * site, so use a fixed register.
+             */
+            callTemp = AMD64.rax.asValue(Kind.Long);
+            assert ValueUtil.differentRegisters(parameters, callTemp);
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            directCall(tasm, masm, callTarget, ((RegisterValue) callTemp).getRegister(), false, state);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            directCall(crb, masm, callTarget, ((RegisterValue) callTemp).getRegister(), false, state);
         }
     }
 
-    public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) {
+    public static void directCall(CompilationResultBuilder crb, AMD64MacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) {
         if (align) {
-            emitAlignmentForDirectCall(tasm, masm);
+            emitAlignmentForDirectCall(crb, masm);
         }
         int before = masm.codeBuffer.position();
         if (scratch != null) {
@@ -160,43 +165,43 @@
             masm.call();
         }
         int after = masm.codeBuffer.position();
-        tasm.recordDirectCall(before, after, callTarget, info);
-        tasm.recordExceptionHandlers(after, info);
+        crb.recordDirectCall(before, after, callTarget, info);
+        crb.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
     }
 
-    protected static void emitAlignmentForDirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    protected static void emitAlignmentForDirectCall(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         // make sure that the displacement word of the call ends up word aligned
         int offset = masm.codeBuffer.position();
-        offset += tasm.target.arch.getMachineCodeCallDisplacementOffset();
-        int modulus = tasm.target.wordSize;
+        offset += crb.target.arch.getMachineCodeCallDisplacementOffset();
+        int modulus = crb.target.wordSize;
         if (offset % modulus != 0) {
             masm.nop(modulus - offset % modulus);
         }
     }
 
-    public static void directJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, InvokeTarget target) {
+    public static void directJmp(CompilationResultBuilder crb, AMD64MacroAssembler masm, InvokeTarget target) {
         int before = masm.codeBuffer.position();
         masm.jmp(0, true);
         int after = masm.codeBuffer.position();
-        tasm.recordDirectCall(before, after, target, null);
+        crb.recordDirectCall(before, after, target, null);
         masm.ensureUniquePC();
     }
 
-    public static void directConditionalJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, InvokeTarget target, ConditionFlag cond) {
+    public static void directConditionalJmp(CompilationResultBuilder crb, AMD64MacroAssembler masm, InvokeTarget target, ConditionFlag cond) {
         int before = masm.codeBuffer.position();
         masm.jcc(cond, 0, true);
         int after = masm.codeBuffer.position();
-        tasm.recordDirectCall(before, after, target, null);
+        crb.recordDirectCall(before, after, target, null);
         masm.ensureUniquePC();
     }
 
-    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
+    public static void indirectCall(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
         int before = masm.codeBuffer.position();
         masm.call(dst);
         int after = masm.codeBuffer.position();
-        tasm.recordIndirectCall(before, after, callTarget, info);
-        tasm.recordExceptionHandlers(after, info);
+        crb.recordIndirectCall(before, after, callTarget, info);
+        crb.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
     }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Mon Dec 09 17:31:12 2013 +0100
@@ -47,8 +47,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            emit(tasm, masm, opcode, x, y);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            emit(crb, masm, opcode, x, y);
         }
 
         @Override
@@ -62,7 +62,7 @@
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Compare opcode, Value x, Value y) {
+    public static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, AMD64Compare opcode, Value x, Value y) {
         if (isRegister(y)) {
             switch (opcode) {
                 case ICMP: masm.cmpl(asIntReg(x), asIntReg(y)); break;
@@ -74,25 +74,25 @@
             }
         } else if (isConstant(y)) {
             switch (opcode) {
-                case ICMP: masm.cmpl(asIntReg(x), tasm.asIntConst(y)); break;
-                case LCMP: masm.cmpq(asLongReg(x), tasm.asIntConst(y)); break;
+                case ICMP: masm.cmpl(asIntReg(x), crb.asIntConst(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), crb.asIntConst(y)); break;
                 case ACMP:
                     if (((Constant) y).isNull()) {
                         masm.cmpq(asObjectReg(x), 0); break;
                     } else {
                         throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
                     }
-                case FCMP: masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatConstRef(y)); break;
-                case DCMP: masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleConstRef(y)); break;
+                case FCMP: masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatConstRef(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleConstRef(y)); break;
                 default:   throw GraalInternalError.shouldNotReachHere();
             }
         } else {
             switch (opcode) {
-                case ICMP: masm.cmpl(asIntReg(x), (AMD64Address) tasm.asIntAddr(y)); break;
-                case LCMP: masm.cmpq(asLongReg(x), (AMD64Address) tasm.asLongAddr(y)); break;
-                case ACMP: masm.cmpptr(asObjectReg(x), (AMD64Address) tasm.asObjectAddr(y)); break;
-                case FCMP: masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatAddr(y)); break;
-                case DCMP: masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleAddr(y)); break;
+                case ICMP: masm.cmpl(asIntReg(x), (AMD64Address) crb.asIntAddr(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), (AMD64Address) crb.asLongAddr(y)); break;
+                case ACMP: masm.cmpptr(asObjectReg(x), (AMD64Address) crb.asObjectAddr(y)); break;
+                case FCMP: masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatAddr(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleAddr(y)); break;
                 default:  throw GraalInternalError.shouldNotReachHere();
             }
         }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Mon Dec 09 17:31:12 2013 +0100
@@ -35,11 +35,10 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.FallThroughOp;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
 
-// @formatter:off
 public class AMD64ControlFlow {
 
     public static class ReturnOp extends AMD64LIRInstruction {
@@ -50,68 +49,60 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            if (tasm.frameContext != null) {
-                tasm.frameContext.leave(tasm);
-            }
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            crb.frameContext.leave(crb);
             masm.ret(0);
         }
     }
 
+    public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp {
+        protected final ConditionFlag condition;
+        protected final LabelRef trueDestination;
+        protected final LabelRef falseDestination;
 
-    public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp {
-        protected ConditionFlag condition;
-        protected LabelRef destination;
-
-        public BranchOp(Condition condition, LabelRef destination) {
-            this(intCond(condition), destination);
+        public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination) {
+            this(intCond(condition), trueDestination, falseDestination);
         }
 
-        public BranchOp(ConditionFlag condition, LabelRef destination) {
+        public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination) {
             this.condition = condition;
-            this.destination = destination;
+            this.trueDestination = trueDestination;
+            this.falseDestination = falseDestination;
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            masm.jcc(condition, destination.label());
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            int sourceIndex = crb.getCurrentBlockIndex();
+            if (trueDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex)) {
+                jcc(masm, true, falseDestination);
+            } else {
+                jcc(masm, false, trueDestination);
+                if (!falseDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex)) {
+                    masm.jmp(falseDestination.label());
+                }
+            }
         }
 
-        @Override
-        public LabelRef destination() {
-            return destination;
-        }
-
-        @Override
-        public void negate(LabelRef newDestination) {
-            destination = newDestination;
-            condition = condition.negate();
+        protected void jcc(AMD64MacroAssembler masm, boolean negate, LabelRef target) {
+            masm.jcc(negate ? condition.negate() : condition, target.label());
         }
     }
 
-
     public static class FloatBranchOp extends BranchOp {
         protected boolean unorderedIsTrue;
 
-        public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef destination) {
-            super(floatCond(condition), destination);
+        public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination) {
+            super(floatCond(condition), trueDestination, falseDestination);
             this.unorderedIsTrue = unorderedIsTrue;
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            floatJcc(masm, condition, unorderedIsTrue, destination.label());
-        }
-
-        @Override
-        public void negate(LabelRef newDestination) {
-            super.negate(newDestination);
-            unorderedIsTrue = !unorderedIsTrue;
+        protected void jcc(AMD64MacroAssembler masm, boolean negate, LabelRef target) {
+            floatJcc(masm, negate ? condition.negate() : condition, negate ? !unorderedIsTrue : unorderedIsTrue, target.label());
         }
     }
 
-
-    public static class TableSwitchOp extends AMD64LIRInstruction {
+    public static class TableSwitchOp extends AMD64LIRInstruction implements BlockEndOp {
         private final int lowKey;
         private final LabelRef defaultTarget;
         private final LabelRef[] targets;
@@ -127,12 +118,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch));
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            tableswitch(crb, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch));
         }
     }
 
-    public static class SequentialSwitchOp extends AMD64LIRInstruction implements FallThroughOp {
+    public static class SequentialSwitchOp extends AMD64LIRInstruction implements BlockEndOp {
         @Use({CONST}) protected Constant[] keyConstants;
         private final LabelRef[] keyTargets;
         private LabelRef defaultTarget;
@@ -149,12 +140,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (key.getKind() == Kind.Int) {
                 Register intKey = asIntReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    if (tasm.codeCache.needsDataPatch(keyConstants[i])) {
-                        tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
+                    if (crb.codeCache.needsDataPatch(keyConstants[i])) {
+                        crb.recordDataReferenceInCode(keyConstants[i], 0, true);
                     }
                     long lc = keyConstants[i].asLong();
                     assert NumUtil.isInt(lc);
@@ -164,39 +155,27 @@
             } else if (key.getKind() == Kind.Long) {
                 Register longKey = asLongReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    masm.cmpq(longKey, (AMD64Address) tasm.asLongConstRef(keyConstants[i]));
+                    masm.cmpq(longKey, (AMD64Address) crb.asLongConstRef(keyConstants[i]));
                     masm.jcc(ConditionFlag.Equal, keyTargets[i].label());
                 }
             } else if (key.getKind() == Kind.Object) {
                 Register objectKey = asObjectReg(key);
                 Register temp = asObjectReg(scratch);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    AMD64Move.move(tasm, masm, temp.asValue(Kind.Object), keyConstants[i]);
+                    AMD64Move.move(crb, masm, temp.asValue(Kind.Object), keyConstants[i]);
                     masm.cmpptr(objectKey, temp);
                     masm.jcc(ConditionFlag.Equal, keyTargets[i].label());
                 }
             } else {
                 throw new GraalInternalError("sequential switch only supported for int, long and object");
             }
-            if (defaultTarget != null) {
+            if (!defaultTarget.isCodeEmittingOrderSuccessorEdge(crb.getCurrentBlockIndex())) {
                 masm.jmp(defaultTarget.label());
-            } else {
-                masm.hlt();
             }
         }
-
-        @Override
-        public LabelRef fallThroughTarget() {
-            return defaultTarget;
-        }
-
-        @Override
-        public void setFallThroughTarget(LabelRef target) {
-            defaultTarget = target;
-        }
     }
 
-    public static class SwitchRangesOp extends AMD64LIRInstruction implements FallThroughOp {
+    public static class SwitchRangesOp extends AMD64LIRInstruction implements BlockEndOp {
         private final LabelRef[] keyTargets;
         private LabelRef defaultTarget;
         private final int[] lowKeys;
@@ -212,7 +191,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             assert isSorted(lowKeys) && isSorted(highKeys);
 
             Label actualDefaultTarget = defaultTarget == null ? new Label() : defaultTarget.label();
@@ -236,8 +215,11 @@
                 }
                 prevHighKey = highKey;
             }
+
             if (defaultTarget != null) {
-                masm.jmp(defaultTarget.label());
+                if (!defaultTarget.isCodeEmittingOrderSuccessorEdge(crb.getCurrentBlockIndex())) {
+                    masm.jmp(defaultTarget.label());
+                }
             } else {
                 masm.bind(actualDefaultTarget);
                 masm.hlt();
@@ -252,16 +234,6 @@
             assert key.getKind() == Kind.Int;
         }
 
-        @Override
-        public LabelRef fallThroughTarget() {
-            return defaultTarget;
-        }
-
-        @Override
-        public void setFallThroughTarget(LabelRef target) {
-            defaultTarget = target;
-        }
-
         private static boolean isSorted(int[] values) {
             for (int i = 1; i < values.length; i++) {
                 if (values[i - 1] >= values[i]) {
@@ -272,7 +244,6 @@
         }
     }
 
-
     @Opcode("CMOVE")
     public static class CondMoveOp extends AMD64LIRInstruction {
         @Def({REG, HINT}) protected Value result;
@@ -288,12 +259,11 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            cmove(tasm, masm, result, false, condition, false, trueValue, falseValue);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            cmove(crb, masm, result, false, condition, false, trueValue, falseValue);
         }
     }
 
-
     @Opcode("CMOVE")
     public static class FloatCondMoveOp extends AMD64LIRInstruction {
         @Def({REG}) protected Value result;
@@ -311,12 +281,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            cmove(crb, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue);
         }
     }
 
-    private static void tableswitch(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) {
+    private static void tableswitch(CompilationResultBuilder crb, AMD64MacroAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) {
         Buffer buf = masm.codeBuffer;
         // Compare index against jump table bounds
         int highKey = lowKey + targets.length - 1;
@@ -371,7 +341,7 @@
         }
 
         JumpTable jt = new JumpTable(jumpTablePos, lowKey, highKey, 4);
-        tasm.compilationResult.addAnnotation(jt);
+        crb.compilationResult.addAnnotation(jt);
     }
 
     private static void floatJcc(AMD64MacroAssembler masm, ConditionFlag condition, boolean unorderedIsTrue, Label label) {
@@ -385,70 +355,98 @@
         masm.bind(endLabel);
     }
 
-    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    private static void cmove(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         // check that we don't overwrite an input operand before it is used.
         assert !result.equals(trueValue);
 
-        AMD64Move.move(tasm, masm, result, falseValue);
-        cmove(tasm, masm, result, condition, trueValue);
+        AMD64Move.move(crb, masm, result, falseValue);
+        cmove(crb, masm, result, condition, trueValue);
 
         if (isFloat) {
             if (unorderedIsTrue && !trueOnUnordered(condition)) {
-                cmove(tasm, masm, result, ConditionFlag.Parity, trueValue);
+                cmove(crb, masm, result, ConditionFlag.Parity, trueValue);
             } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
-                cmove(tasm, masm, result, ConditionFlag.Parity, falseValue);
+                cmove(crb, masm, result, ConditionFlag.Parity, falseValue);
             }
         }
     }
 
-    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, ConditionFlag cond, Value other) {
+    private static void cmove(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, ConditionFlag cond, Value other) {
         if (isRegister(other)) {
             assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move";
             switch (other.getKind()) {
-                case Int:  masm.cmovl(cond, asRegister(result), asRegister(other)); break;
-                case Long: masm.cmovq(cond, asRegister(result), asRegister(other)); break;
-                default:   throw GraalInternalError.shouldNotReachHere();
+                case Int:
+                    masm.cmovl(cond, asRegister(result), asRegister(other));
+                    break;
+                case Long:
+                    masm.cmovq(cond, asRegister(result), asRegister(other));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
             }
         } else {
-            AMD64Address addr = (AMD64Address) tasm.asAddress(other);
+            AMD64Address addr = (AMD64Address) crb.asAddress(other);
             switch (other.getKind()) {
-                case Int:  masm.cmovl(cond, asRegister(result), addr); break;
-                case Long: masm.cmovq(cond, asRegister(result), addr); break;
-                default:   throw GraalInternalError.shouldNotReachHere();
+                case Int:
+                    masm.cmovl(cond, asRegister(result), addr);
+                    break;
+                case Long:
+                    masm.cmovq(cond, asRegister(result), addr);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
             }
         }
     }
 
     private static ConditionFlag intCond(Condition cond) {
         switch (cond) {
-            case EQ: return ConditionFlag.Equal;
-            case NE: return ConditionFlag.NotEqual;
-            case LT: return ConditionFlag.Less;
-            case LE: return ConditionFlag.LessEqual;
-            case GE: return ConditionFlag.GreaterEqual;
-            case GT: return ConditionFlag.Greater;
-            case BE: return ConditionFlag.BelowEqual;
-            case AE: return ConditionFlag.AboveEqual;
-            case AT: return ConditionFlag.Above;
-            case BT: return ConditionFlag.Below;
-            default: throw GraalInternalError.shouldNotReachHere();
+            case EQ:
+                return ConditionFlag.Equal;
+            case NE:
+                return ConditionFlag.NotEqual;
+            case LT:
+                return ConditionFlag.Less;
+            case LE:
+                return ConditionFlag.LessEqual;
+            case GE:
+                return ConditionFlag.GreaterEqual;
+            case GT:
+                return ConditionFlag.Greater;
+            case BE:
+                return ConditionFlag.BelowEqual;
+            case AE:
+                return ConditionFlag.AboveEqual;
+            case AT:
+                return ConditionFlag.Above;
+            case BT:
+                return ConditionFlag.Below;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     private static ConditionFlag floatCond(Condition cond) {
         switch (cond) {
-            case EQ: return ConditionFlag.Equal;
-            case NE: return ConditionFlag.NotEqual;
-            case LT: return ConditionFlag.Below;
-            case LE: return ConditionFlag.BelowEqual;
-            case GE: return ConditionFlag.AboveEqual;
-            case GT: return ConditionFlag.Above;
-            default: throw GraalInternalError.shouldNotReachHere();
+            case EQ:
+                return ConditionFlag.Equal;
+            case NE:
+                return ConditionFlag.NotEqual;
+            case LT:
+                return ConditionFlag.Below;
+            case LE:
+                return ConditionFlag.BelowEqual;
+            case GE:
+                return ConditionFlag.AboveEqual;
+            case GT:
+                return ConditionFlag.Above;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     private static boolean trueOnUnordered(ConditionFlag condition) {
-        switch(condition) {
+        switch (condition) {
             case AboveEqual:
             case NotEqual:
             case Above:
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64LIRInstruction.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64LIRInstruction.java	Mon Dec 09 17:31:12 2013 +0100
@@ -32,9 +32,9 @@
 public abstract class AMD64LIRInstruction extends LIRInstruction {
 
     @Override
-    public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
+    public final void emitCode(CompilationResultBuilder crb) {
+        emitCode(crb, (AMD64MacroAssembler) crb.asm);
     }
 
-    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
+    public abstract void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm);
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64MathIntrinsicOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -48,7 +48,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         switch (opcode) {
             case LOG:   masm.flog(asDoubleReg(result), asDoubleReg(input), false); break;
             case LOG10: masm.flog(asDoubleReg(result), asDoubleReg(input), true); break;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Mon Dec 09 17:31:12 2013 +0100
@@ -53,8 +53,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -80,8 +80,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -110,9 +110,9 @@
         protected abstract void emitMemAccess(AMD64MacroAssembler masm);
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (state != null) {
-                tasm.recordImplicitException(masm.codeBuffer.position(), state);
+                crb.recordImplicitException(masm.codeBuffer.position(), state);
             }
             emitMemAccess(masm);
         }
@@ -270,7 +270,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             masm.leaq(asLongReg(result), address.toAddress());
         }
     }
@@ -286,8 +286,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            masm.leaq(asLongReg(result), (AMD64Address) tasm.asAddress(slot));
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            masm.leaq(asLongReg(result), (AMD64Address) crb.asAddress(slot));
         }
     }
 
@@ -300,7 +300,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             masm.membar(barriers);
         }
     }
@@ -316,8 +316,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            tasm.recordImplicitException(masm.codeBuffer.position(), state);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            crb.recordImplicitException(masm.codeBuffer.position(), state);
             masm.nullCheck(asRegister(input));
         }
 
@@ -346,31 +346,31 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            compareAndSwap(tasm, masm, result, address, cmpValue, newValue);
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            compareAndSwap(crb, masm, result, address, cmpValue, newValue);
         }
     }
 
-    public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
+    public static void move(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
                 reg2reg(masm, result, input);
             } else if (isStackSlot(result)) {
-                reg2stack(tasm, masm, result, input);
+                reg2stack(crb, masm, result, input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isStackSlot(input)) {
             if (isRegister(result)) {
-                stack2reg(tasm, masm, result, input);
+                stack2reg(crb, masm, result, input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isConstant(input)) {
             if (isRegister(result)) {
-                const2reg(tasm, masm, result, (Constant) input);
+                const2reg(crb, masm, result, (Constant) input);
             } else if (isStackSlot(result)) {
-                const2stack(tasm, masm, result, (Constant) input);
+                const2stack(crb, masm, result, (Constant) input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
@@ -404,8 +404,8 @@
         }
     }
 
-    private static void reg2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
-        AMD64Address dest = (AMD64Address) tasm.asAddress(result);
+    private static void reg2stack(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, Value input) {
+        AMD64Address dest = (AMD64Address) crb.asAddress(result);
         switch (input.getKind()) {
             case Int:
                 masm.movl(dest, asRegister(input));
@@ -427,8 +427,8 @@
         }
     }
 
-    private static void stack2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
-        AMD64Address src = (AMD64Address) tasm.asAddress(input);
+    private static void stack2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, Value input) {
+        AMD64Address src = (AMD64Address) crb.asAddress(input);
         switch (input.getKind()) {
             case Int:
                 masm.movl(asRegister(result), src);
@@ -450,7 +450,7 @@
         }
     }
 
-    private static void const2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
+    private static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, Constant input) {
         /*
          * Note: we use the kind of the input operand (and not the kind of the result operand)
          * because they don't match in all cases. For example, an object constant can be loaded to a
@@ -459,8 +459,8 @@
          */
         switch (input.getKind().getStackKind()) {
             case Int:
-                if (tasm.codeCache.needsDataPatch(input)) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                if (crb.codeCache.needsDataPatch(input)) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                 }
                 // Do not optimize with an XOR as this instruction may be between
                 // a CMP and a Jcc in which case the XOR will modify the condition
@@ -469,8 +469,8 @@
 
                 break;
             case Long:
-                if (tasm.codeCache.needsDataPatch(input)) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                if (crb.codeCache.needsDataPatch(input)) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                 }
                 // Do not optimize with an XOR as this instruction may be between
                 // a CMP and a Jcc in which case the XOR will modify the condition
@@ -480,19 +480,19 @@
             case Float:
                 // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f
                 if (Float.floatToRawIntBits(input.asFloat()) == Float.floatToRawIntBits(0.0f)) {
-                    assert !tasm.codeCache.needsDataPatch(input);
+                    assert !crb.codeCache.needsDataPatch(input);
                     masm.xorps(asFloatReg(result), asFloatReg(result));
                 } else {
-                    masm.movflt(asFloatReg(result), (AMD64Address) tasm.asFloatConstRef(input));
+                    masm.movflt(asFloatReg(result), (AMD64Address) crb.asFloatConstRef(input));
                 }
                 break;
             case Double:
                 // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d
                 if (Double.doubleToRawLongBits(input.asDouble()) == Double.doubleToRawLongBits(0.0d)) {
-                    assert !tasm.codeCache.needsDataPatch(input);
+                    assert !crb.codeCache.needsDataPatch(input);
                     masm.xorpd(asDoubleReg(result), asDoubleReg(result));
                 } else {
-                    masm.movdbl(asDoubleReg(result), (AMD64Address) tasm.asDoubleConstRef(input));
+                    masm.movdbl(asDoubleReg(result), (AMD64Address) crb.asDoubleConstRef(input));
                 }
                 break;
             case Object:
@@ -501,11 +501,11 @@
                 // flags and interfere with the Jcc.
                 if (input.isNull()) {
                     masm.movq(asRegister(result), 0x0L);
-                } else if (tasm.target.inlineObjects) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                } else if (crb.target.inlineObjects) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                     masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
                 } else {
-                    masm.movq(asRegister(result), (AMD64Address) tasm.recordDataReferenceInCode(input, 0, false));
+                    masm.movq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(input, 0, false));
                 }
                 break;
             default:
@@ -513,9 +513,9 @@
         }
     }
 
-    private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
-        assert !tasm.codeCache.needsDataPatch(input);
-        AMD64Address dest = (AMD64Address) tasm.asAddress(result);
+    private static void const2stack(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, Constant input) {
+        assert !crb.codeCache.needsDataPatch(input);
+        AMD64Address dest = (AMD64Address) crb.asAddress(result);
         switch (input.getKind().getStackKind()) {
             case Int:
                 masm.movl(dest, input.asInt());
@@ -541,10 +541,11 @@
         }
     }
 
-    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
+    protected static void compareAndSwap(CompilationResultBuilder crb, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue,
+                    AllocatableValue newValue) {
         assert asRegister(cmpValue).equals(AMD64.rax) && asRegister(result).equals(AMD64.rax);
 
-        if (tasm.target.isMP) {
+        if (crb.target.isMP) {
             masm.lock();
         }
         switch (cmpValue.getKind()) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -54,17 +54,17 @@
         return save.savedRegisters;
     }
 
-    protected void restoreRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register register, StackSlot input) {
+    protected void restoreRegister(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, StackSlot input) {
         RegisterValue result = register.asValue(input.getKind());
-        AMD64Move.move(tasm, masm, result, input);
+        AMD64Move.move(crb, masm, result, input);
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         Register[] savedRegisters = getSavedRegisters();
         for (int i = 0; i < savedRegisters.length; i++) {
             if (savedRegisters[i] != null) {
-                restoreRegister(tasm, masm, savedRegisters[i], slots[i]);
+                restoreRegister(crb, masm, savedRegisters[i], slots[i]);
             }
         }
     }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -66,16 +66,16 @@
         this.supportsRemove = supportsRemove;
     }
 
-    protected void saveRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, StackSlot result, Register register) {
+    protected void saveRegister(CompilationResultBuilder crb, AMD64MacroAssembler masm, StackSlot result, Register register) {
         RegisterValue input = register.asValue(result.getKind());
-        AMD64Move.move(tasm, masm, result, input);
+        AMD64Move.move(crb, masm, result, input);
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         for (int i = 0; i < savedRegisters.length; i++) {
             if (savedRegisters[i] != null) {
-                saveRegister(tasm, masm, slots[i], savedRegisters[i]);
+                saveRegister(crb, masm, slots[i], savedRegisters[i]);
             }
         }
     }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -41,8 +41,8 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        emit(tasm, masm, x, y);
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        emit(crb, masm, x, y);
     }
 
     @Override
@@ -51,7 +51,7 @@
         assert (x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (x.getKind() == Kind.Long && y.getKind() == Kind.Long) : x + " " + y;
     }
 
-    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value x, Value y) {
+    public static void emit(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value x, Value y) {
         if (isRegister(y)) {
             switch (x.getKind()) {
                 case Int:
@@ -66,10 +66,10 @@
         } else if (isConstant(y)) {
             switch (x.getKind()) {
                 case Int:
-                    masm.testl(asIntReg(x), tasm.asIntConst(y));
+                    masm.testl(asIntReg(x), crb.asIntConst(y));
                     break;
                 case Long:
-                    masm.testq(asLongReg(x), tasm.asIntConst(y));
+                    masm.testq(asLongReg(x), crb.asIntConst(y));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -77,10 +77,10 @@
         } else {
             switch (x.getKind()) {
                 case Int:
-                    masm.testl(asIntReg(x), (AMD64Address) tasm.asIntAddr(y));
+                    masm.testl(asIntReg(x), (AMD64Address) crb.asIntAddr(y));
                     break;
                 case Long:
-                    masm.testq(asLongReg(x), (AMD64Address) tasm.asLongAddr(y));
+                    masm.testq(asLongReg(x), (AMD64Address) crb.asLongAddr(y));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -56,11 +56,11 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         for (int i = 0; i < zappedRegisters.length; i++) {
             if (zappedRegisters[i] != null) {
                 RegisterValue registerValue = zappedRegisters[i].asValue(zapValues[i].getPlatformKind());
-                AMD64Move.move(tasm, masm, registerValue, zapValues[i]);
+                AMD64Move.move(crb, masm, registerValue, zapValues[i]);
             }
         }
     }
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java	Mon Dec 09 17:31:12 2013 +0100
@@ -114,7 +114,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             masm.emitConvert(result, x, to, from);
         }
     }
@@ -131,8 +131,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            emit(tasm, masm, opcode, result, x, null);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            emit(crb, masm, opcode, result, x, null);
         }
     }
 
@@ -150,8 +150,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -173,8 +173,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            emit(tasm, masm, opcode, result, x, null);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            emit(crb, masm, opcode, result, x, null);
         }
     }
 
@@ -192,8 +192,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -217,7 +217,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             throw GraalInternalError.shouldNotReachHere();
         }
 
@@ -242,8 +242,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -270,8 +270,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            emit(tasm, masm, opcode, result, y, state);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            emit(crb, masm, opcode, result, y, state);
         }
 
         @Override
@@ -282,14 +282,14 @@
     }
 
     @SuppressWarnings("unused")
-    protected static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, HSAILArithmetic opcode, Value result) {
+    protected static void emit(CompilationResultBuilder crb, HSAILAssembler masm, HSAILArithmetic opcode, Value result) {
         switch (opcode) {
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, HSAILArithmetic opcode, Value dst, Value src, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, HSAILAssembler masm, HSAILArithmetic opcode, Value dst, Value src, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isRegister(src)) {
             switch (opcode) {
@@ -322,11 +322,11 @@
         }
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, HSAILArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, HSAILAssembler masm, HSAILArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
         /**
          * First check if one of src1 or src2 is an AddressValue. If it is, convert the address to a
          * register using an lda instruction. We can just reuse the eventual dst register for this.
@@ -334,12 +334,12 @@
         if (src1 instanceof HSAILAddressValue) {
             assert (!(src2 instanceof HSAILAddressValue));
             masm.emitLda(dst, ((HSAILAddressValue) src1).toAddress());
-            emit(tasm, masm, opcode, dst, dst, src2, info);
+            emit(crb, masm, opcode, dst, dst, src2, info);
             return;
         } else if (src2 instanceof HSAILAddressValue) {
             assert (!(src1 instanceof HSAILAddressValue));
             masm.emitLda(dst, ((HSAILAddressValue) src2).toAddress());
-            emit(tasm, masm, opcode, dst, src1, dst, info);
+            emit(crb, masm, opcode, dst, src1, dst, info);
             return;
         }
         int exceptionOffset = -1;
@@ -411,7 +411,7 @@
         }
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILBitManipulationOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILBitManipulationOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -48,7 +48,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
         switch (opcode) {
             case IPOPCNT:
                 throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java	Mon Dec 09 17:31:12 2013 +0100
@@ -54,8 +54,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            emit(tasm, masm, condition, x, y, z, unordered);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            emit(crb, masm, condition, x, y, z, unordered);
         }
 
         @Override
@@ -67,7 +67,7 @@
     }
 
     @SuppressWarnings("unused")
-    public static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, Condition condition, Value x, Value y, Value z, boolean unorderedIsTrue) {
+    public static void emit(CompilationResultBuilder crb, HSAILAssembler masm, Condition condition, Value x, Value y, Value z, boolean unorderedIsTrue) {
         emitCompare(masm, condition, x, y, unorderedIsTrue);
     }
 
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Mon Dec 09 17:31:12 2013 +0100
@@ -28,7 +28,7 @@
 import com.oracle.graal.asm.hsail.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.FallThroughOp;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
 
@@ -46,7 +46,7 @@
      * performing HSAIL code. Thus the execution path for both the TABLESWITCH and LOOKUPSWITCH
      * bytecodes go through this op.
      */
-    public static class SwitchOp extends HSAILLIRInstruction implements FallThroughOp {
+    public static class SwitchOp extends HSAILLIRInstruction implements BlockEndOp {
         /**
          * The array of key constants used for the cases of this switch statement.
          */
@@ -78,25 +78,6 @@
         }
 
         /**
-         * Get the default target for this switch op.
-         */
-        @Override
-        public LabelRef fallThroughTarget() {
-            return defaultTarget;
-        }
-
-        /**
-         * Set the default target.
-         * 
-         * @param target the default target
-         */
-        @Override
-        public void setFallThroughTarget(LabelRef target) {
-            defaultTarget = target;
-
-        }
-
-        /**
          * Generates the code for this switch op.
          * 
          * The keys for switch statements in Java bytecode for of type int. However, Graal also
@@ -104,11 +85,11 @@
          * routines with keys of type Long or Object. Currently we only support the
          * IntegerSwitchNode so we throw an exception if the key isn't of type int.
          * 
-         * @param tasm the TargetMethodAssembler
+         * @param crb the CompilationResultBuilder
          * @param masm the HSAIL assembler
          */
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             if (key.getKind() == Kind.Int) {
                 for (int i = 0; i < keyConstants.length; i++) {
                     // Generate cascading compare and branches for each case.
@@ -116,7 +97,7 @@
                     masm.cbr(masm.nameOf(keyTargets[i].label()));
                 }
                 // Generate a jump for the default target if there is one.
-                if (defaultTarget != null) {
+                if (defaultTarget != null && !defaultTarget.isCodeEmittingOrderSuccessorEdge(crb.getCurrentBlockIndex())) {
                     masm.jmp(defaultTarget.label());
                 }
 
@@ -127,7 +108,7 @@
         }
     }
 
-    public static class ReturnOp extends HSAILLIRInstruction {
+    public static class ReturnOp extends HSAILLIRInstruction implements BlockEndOp {
 
         @Use({REG, ILLEGAL}) protected Value x;
 
@@ -136,10 +117,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            if (tasm.frameContext != null) {
-                tasm.frameContext.leave(tasm);
-            }
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            crb.frameContext.leave(crb);
             masm.exit();
         }
     }
@@ -155,7 +134,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             masm.emitComment("//ForeignCall to " + callName + " would have gone here");
         }
     }
@@ -186,119 +165,37 @@
         @Use({REG, CONST}) protected Value x;
         @Use({REG, CONST}) protected Value y;
         @Def({REG}) protected Value z;
-        protected Condition condition;
-        protected LabelRef destination;
-        protected boolean unordered = false;
+        protected final Condition condition;
+        protected final LabelRef trueDestination;
+        protected final LabelRef falseDestination;
         @Def({REG}) protected Value result;
+        protected final boolean unordered;
 
-        public CompareBranchOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z, Value result, LabelRef destination) {
+        public CompareBranchOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z, Value result, LabelRef trueDestination, LabelRef falseDestination, boolean unordered) {
             this.condition = condition;
             this.opcode = opcode;
             this.x = x;
             this.y = y;
             this.z = z;
             this.result = result;
-            this.destination = destination;
-        }
-
-        @Override
-        public LabelRef destination() {
-            return destination;
-        }
-
-        @Override
-        public void negate(LabelRef newDestination) {
-            destination = newDestination;
-            condition = condition.negate();
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            HSAILCompare.emit(tasm, masm, condition, x, y, z, unordered);
-            masm.cbr(masm.nameOf(destination.label()));
-        }
-    }
-
-    public static class FloatCompareBranchOp extends CompareBranchOp {
-
-        public FloatCompareBranchOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z, Value result, LabelRef destination, boolean unordered) {
-            super(opcode, condition, x, y, z, result, destination);
-            this.unordered = unordered;
-        }
-
-        @Override
-        public void negate(LabelRef newDestination) {
-            destination = newDestination;
-            condition = condition.negate();
-            unordered = !unordered;
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            HSAILCompare.emit(tasm, masm, condition, x, y, z, unordered);
-            masm.cbr(masm.nameOf(destination.label()));
-        }
-    }
-
-    public static class DoubleCompareBranchOp extends CompareBranchOp {
-
-        public DoubleCompareBranchOp(HSAILCompare opcode, Condition condition, Value x, Value y, Value z, Value result, LabelRef destination, boolean unordered) {
-            super(opcode, condition, x, y, z, result, destination);
+            this.trueDestination = trueDestination;
+            this.falseDestination = falseDestination;
             this.unordered = unordered;
         }
 
         @Override
-        public void negate(LabelRef newDestination) {
-            destination = newDestination;
-            condition = condition.negate();
-            unordered = !unordered;
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            HSAILCompare.emit(tasm, masm, condition, x, y, z, unordered);
-            masm.cbr(masm.nameOf(destination.label()));
-        }
-    }
-
-    public static class BranchOp extends HSAILLIRInstruction implements StandardOp.BranchOp {
-
-        protected Condition condition;
-        protected LabelRef destination;
-        @Def({REG}) protected Value result;
-
-        public BranchOp(Condition condition, Value result, LabelRef destination) {
-            this.condition = condition;
-            this.destination = destination;
-            this.result = result;
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            masm.cbr(masm.nameOf(destination.label()));
-        }
-
-        @Override
-        public LabelRef destination() {
-            return destination;
-        }
-
-        @Override
-        public void negate(LabelRef newDestination) {
-            destination = newDestination;
-            condition = condition.negate();
-        }
-    }
-
-    public static class FloatBranchOp extends BranchOp {
-
-        public FloatBranchOp(Condition condition, Value result, LabelRef destination) {
-            super(condition, result, destination);
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            masm.cbr(masm.nameOf(destination.label()));
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            int sourceIndex = crb.getCurrentBlockIndex();
+            if (trueDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex)) {
+                HSAILCompare.emit(crb, masm, condition.negate(), x, y, z, !unordered);
+                masm.cbr(masm.nameOf(falseDestination.label()));
+            } else {
+                HSAILCompare.emit(crb, masm, condition, x, y, z, unordered);
+                masm.cbr(masm.nameOf(trueDestination.label()));
+                if (!falseDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex)) {
+                    masm.jmp(falseDestination.label());
+                }
+            }
         }
     }
 
@@ -323,9 +220,9 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            HSAILCompare.emit(tasm, masm, condition, left, right, right, false);
-            cmove(tasm, masm, result, false, trueValue, falseValue);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            HSAILCompare.emit(crb, masm, condition, left, right, right, false);
+            cmove(crb, masm, result, false, trueValue, falseValue);
         }
     }
 
@@ -339,14 +236,14 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            HSAILCompare.emit(tasm, masm, condition, left, right, right, unorderedIsTrue);
-            cmove(tasm, masm, result, false, trueValue, falseValue);
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            HSAILCompare.emit(crb, masm, condition, left, right, right, unorderedIsTrue);
+            cmove(crb, masm, result, false, trueValue, falseValue);
         }
     }
 
     @SuppressWarnings("unused")
-    private static void cmove(TargetMethodAssembler tasm, HSAILAssembler masm, Value result, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    private static void cmove(CompilationResultBuilder crb, HSAILAssembler masm, Value result, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         // Check that we don't overwrite an input operand before it is used.
         assert (result.getKind() == trueValue.getKind() && result.getKind() == falseValue.getKind());
         int width;
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILLIRInstruction.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILLIRInstruction.java	Mon Dec 09 17:31:12 2013 +0100
@@ -32,9 +32,9 @@
 public abstract class HSAILLIRInstruction extends LIRInstruction {
 
     @Override
-    public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (HSAILAssembler) tasm.asm);
+    public final void emitCode(CompilationResultBuilder crb) {
+        emitCode(crb, (HSAILAssembler) crb.asm);
     }
 
-    public abstract void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm);
+    public abstract void emitCode(CompilationResultBuilder crb, HSAILAssembler masm);
 }
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Mon Dec 09 17:31:12 2013 +0100
@@ -60,8 +60,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -87,8 +87,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -114,8 +114,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -144,9 +144,9 @@
         protected abstract void emitMemAccess(HSAILAssembler masm);
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             if (state != null) {
-                // tasm.recordImplicitException(masm.codeBuffer.position(), state);
+                // crb.recordImplicitException(masm.codeBuffer.position(), state);
                 throw new InternalError("NYI");
             }
             emitMemAccess(masm);
@@ -162,7 +162,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             masm.emitMembar(barriers);
         }
     }
@@ -249,13 +249,13 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             masm.emitMov(scratch, input);
             boolean testForNull = (kind == Kind.Object);
             encodePointer(masm, scratch, base, shift, alignment, testForNull);
             if (state != null) {
                 throw new InternalError("NYI");
-                // tasm.recordImplicitException(masm.codeBuffer.position(), state);
+                // crb.recordImplicitException(masm.codeBuffer.position(), state);
             }
             masm.emitStore(scratch, address.toAddress(), "u32");
         }
@@ -292,7 +292,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             throw new InternalError("NYI");
         }
     }
@@ -308,7 +308,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             throw new InternalError("NYI");
         }
     }
@@ -329,7 +329,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             masm.emitAtomicCas(result, address.toAddress(), cmpValue, newValue);
         }
     }
@@ -361,7 +361,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             // assume any encoded or decoded value could be null
             boolean testForNull = true;
             // set up scratch registers to be encoded versions
@@ -392,13 +392,13 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             Debug.log("NullCheckOp unimplemented");
         }
     }
 
     @SuppressWarnings("unused")
-    public static void move(TargetMethodAssembler tasm, HSAILAssembler masm, Value result, Value input) {
+    public static void move(CompilationResultBuilder crb, HSAILAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
                 masm.emitMov(result, input);
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXAddressValue.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXAddressValue.java	Mon Dec 09 17:31:12 2013 +0100
@@ -68,7 +68,7 @@
     }
 
     public PTXAddress toAddress() {
-        // Register baseReg = base == Value.ILLEGAL ? Register.None : asRegister(base);
+        // Register baseReg = base.equals( == Value.ILLEGAL) ? Register.None : asRegister(base);
         return new PTXAddress((Variable) base, displacement);
     }
 
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Mon Dec 09 17:31:12 2013 +0100
@@ -56,7 +56,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             Variable dst = (Variable) result;
             Variable src = (Variable) x;
             if (from == Kind.Long && to == Kind.Int) {
@@ -81,8 +81,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, null);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, null);
         }
     }
 
@@ -100,8 +100,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -125,8 +125,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -150,12 +150,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             if (sameRegister(result, y)) {
-                emit(tasm, masm, opcode, result, x, null);
+                emit(crb, masm, opcode, result, x, null);
             } else {
-                PTXMove.move(tasm, masm, result, x);
-                emit(tasm, masm, opcode, result, y, null);
+                PTXMove.move(crb, masm, result, x);
+                emit(crb, masm, opcode, result, y, null);
             }
         }
 
@@ -180,8 +180,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -208,8 +208,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, y, state);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            emit(crb, masm, opcode, result, y, state);
         }
 
         @Override
@@ -219,7 +219,7 @@
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, PTXMacroAssembler masm, PTXArithmetic opcode, Value dst, Value src, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, PTXMacroAssembler masm, PTXArithmetic opcode, Value dst, Value src, LIRFrameState info) {
         int exceptionOffset = -1;
         Variable dest = (Variable) dst;
 
@@ -267,11 +267,11 @@
 
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, PTXMacroAssembler masm, PTXArithmetic opcode,
+    public static void emit(CompilationResultBuilder crb, PTXMacroAssembler masm, PTXArithmetic opcode,
                             Value dst, Value src1, Value src2, LIRFrameState info) {
         int exceptionOffset = -1;
         Variable dest = (Variable) dst;
@@ -337,7 +337,7 @@
 
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXBitManipulationOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -46,7 +46,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
         Register dst = ValueUtil.asIntReg(result);
         Register src = ValueUtil.asRegister(input);
         switch (opcode) {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java	Mon Dec 09 17:31:12 2013 +0100
@@ -54,7 +54,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             emit(masm, opcode, condition, x, y, predRegNum);
         }
 
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Mon Dec 09 17:31:12 2013 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.lir.ptx;
 
-import static com.oracle.graal.asm.ptx.PTXAssembler.*;
-import static com.oracle.graal.asm.ptx.PTXMacroAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
 import static com.oracle.graal.nodes.calc.Condition.*;
@@ -32,9 +30,12 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.ptx.*;
+import com.oracle.graal.asm.ptx.PTXAssembler.Global;
+import com.oracle.graal.asm.ptx.PTXAssembler.Setp;
+import com.oracle.graal.asm.ptx.PTXMacroAssembler.Mov;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.FallThroughOp;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
 
@@ -49,10 +50,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            if (tasm.frameContext != null) {
-                tasm.frameContext.leave(tasm);
-            }
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            crb.frameContext.leave(crb);
             masm.exit();
         }
     }
@@ -63,40 +62,37 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            if (tasm.frameContext != null) {
-                tasm.frameContext.leave(tasm);
-            }
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            crb.frameContext.leave(crb);
             masm.ret();
         }
     }
 
     public static class BranchOp extends PTXLIRInstruction implements StandardOp.BranchOp {
 
-        protected Condition condition;
-        protected LabelRef destination;
+        protected final Condition condition;
+        protected final LabelRef trueDestination;
+        protected final LabelRef falseDestination;
         protected int predRegNum;
 
-        public BranchOp(Condition condition, LabelRef destination, int predReg) {
+        public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, int predReg) {
             this.condition = condition;
-            this.destination = destination;
+            this.trueDestination = trueDestination;
+            this.falseDestination = falseDestination;
             this.predRegNum = predReg;
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            masm.bra(masm.nameOf(destination.label()), predRegNum);
-        }
-
-        @Override
-        public LabelRef destination() {
-            return destination;
-        }
-
-        @Override
-        public void negate(LabelRef newDestination) {
-            destination = newDestination;
-            condition = condition.negate();
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            int sourceIndex = crb.getCurrentBlockIndex();
+            if (trueDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex)) {
+                masm.bra(masm.nameOf(falseDestination.label()), predRegNum);
+            } else {
+                masm.bra(masm.nameOf(trueDestination.label()));
+                if (!falseDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex)) {
+                    masm.jmp(falseDestination.label());
+                }
+            }
         }
     }
 
@@ -117,8 +113,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            cmove(tasm, masm, result, false, condition, false, trueValue, falseValue, predicate);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            cmove(crb, masm, result, false, condition, false, trueValue, falseValue, predicate);
         }
     }
 
@@ -141,25 +137,25 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue, predicate);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            cmove(crb, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue, predicate);
         }
     }
 
-    private static void cmove(TargetMethodAssembler tasm, PTXMacroAssembler asm, Value result, boolean isFloat, Condition condition, boolean unorderedIsTrue, Value trueValue, Value falseValue,
+    private static void cmove(CompilationResultBuilder crb, PTXMacroAssembler asm, Value result, boolean isFloat, Condition condition, boolean unorderedIsTrue, Value trueValue, Value falseValue,
                     int predicateRegister) {
         // check that we don't overwrite an input operand before it is used.
         assert !result.equals(trueValue);
 
-        PTXMove.move(tasm, asm, result, falseValue);
+        PTXMove.move(crb, asm, result, falseValue);
         cmove(asm, result, trueValue, predicateRegister);
 
         if (isFloat) {
             if (unorderedIsTrue && !trueOnUnordered(condition)) {
-                // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue);
+                // cmove(crb, masm, result, ConditionFlag.Parity, trueValue);
                 throw GraalInternalError.unimplemented();
             } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
-                // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue);
+                // cmove(crb, masm, result, ConditionFlag.Parity, falseValue);
                 throw GraalInternalError.unimplemented();
             }
         }
@@ -197,7 +193,7 @@
         }
     }
 
-    public static class SequentialSwitchOp extends PTXLIRInstruction implements FallThroughOp {
+    public static class SequentialSwitchOp extends PTXLIRInstruction implements BlockEndOp {
 
         @Use({CONST}) protected Constant[] keyConstants;
         private final LabelRef[] keyTargets;
@@ -218,20 +214,20 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             Kind keyKind = key.getKind();
 
             if (keyKind == Kind.Int || keyKind == Kind.Long) {
                 for (int i = 0; i < keyConstants.length; i++) {
-                    if (tasm.codeCache.needsDataPatch(keyConstants[i])) {
-                        tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
+                    if (crb.codeCache.needsDataPatch(keyConstants[i])) {
+                        crb.recordDataReferenceInCode(keyConstants[i], 0, true);
                     }
                     new Setp(EQ, keyConstants[i], key, predRegNum).emit(masm);
                     masm.bra(masm.nameOf(keyTargets[i].label()), predRegNum);
                 }
             } else if (keyKind == Kind.Object) {
                 for (int i = 0; i < keyConstants.length; i++) {
-                    PTXMove.move(tasm, masm, scratch, keyConstants[i]);
+                    PTXMove.move(crb, masm, scratch, keyConstants[i]);
                     new Setp(EQ, keyConstants[i], scratch, predRegNum).emit(masm);
                     masm.bra(keyTargets[i].label().toString(), predRegNum);
                 }
@@ -239,24 +235,16 @@
                 throw new GraalInternalError("sequential switch only supported for int, long and object");
             }
             if (defaultTarget != null) {
-                masm.jmp(defaultTarget.label());
+                if (!defaultTarget.isCodeEmittingOrderSuccessorEdge(crb.getCurrentBlockIndex())) {
+                    masm.jmp(defaultTarget.label());
+                }
             } else {
                 // masm.hlt();
             }
         }
-
-        @Override
-        public LabelRef fallThroughTarget() {
-            return defaultTarget;
-        }
-
-        @Override
-        public void setFallThroughTarget(LabelRef target) {
-            defaultTarget = target;
-        }
     }
 
-    public static class TableSwitchOp extends PTXLIRInstruction {
+    public static class TableSwitchOp extends PTXLIRInstruction implements BlockEndOp {
 
         private final int lowKey;
         private final LabelRef defaultTarget;
@@ -276,13 +264,13 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            tableswitch(tasm, masm, lowKey, defaultTarget, targets, index, scratch, predRegNum);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            tableswitch(crb, masm, lowKey, defaultTarget, targets, index, scratch, predRegNum);
         }
     }
 
     @SuppressWarnings("unused")
-    private static void tableswitch(TargetMethodAssembler tasm, PTXAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value value, Value scratch, int predNum) {
+    private static void tableswitch(CompilationResultBuilder crb, PTXAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value value, Value scratch, int predNum) {
         Buffer buf = masm.codeBuffer;
 
         // Compare index against jump table bounds
@@ -311,7 +299,7 @@
 
         // bra(Value, name);
 
-        tasm.compilationResult.addAnnotation(jt);
+        crb.compilationResult.addAnnotation(jt);
 
     }
 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXLIRInstruction.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXLIRInstruction.java	Mon Dec 09 17:31:12 2013 +0100
@@ -32,9 +32,9 @@
 public abstract class PTXLIRInstruction extends LIRInstruction {
 
     @Override
-    public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (PTXMacroAssembler) tasm.asm);
+    public final void emitCode(CompilationResultBuilder crb) {
+        emitCode(crb, (PTXMacroAssembler) crb.asm);
     }
 
-    public abstract void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm);
+    public abstract void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm);
 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -51,7 +51,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             PTXAddress addr = address.toAddress();
             switch (kind) {
                 case Byte:
@@ -87,7 +87,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             PTXAddress addr = address.toAddress();
             switch (kind) {
                 case Byte:
@@ -122,7 +122,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             PTXAddress addr = address.toAddress();
             switch (kind) {
                 case Byte:
@@ -159,7 +159,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             PTXAddress addr = address.toAddress();
             switch (kind) {
                 case Int:
@@ -191,7 +191,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             PTXAddress addr = address.toAddress();
 
             switch (kind) {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Mon Dec 09 17:31:12 2013 +0100
@@ -49,8 +49,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -76,8 +76,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -103,8 +103,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -129,7 +129,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             throw new InternalError("NYI");
         }
     }
@@ -145,7 +145,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
             throw new InternalError("NYI");
         }
     }
@@ -166,12 +166,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
-            compareAndSwap(tasm, masm, result, address, cmpValue, newValue);
+        public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
+            compareAndSwap(crb, masm, result, address, cmpValue, newValue);
         }
     }
 
-    public static void move(TargetMethodAssembler tasm, PTXMacroAssembler masm, Value result, Value input) {
+    public static void move(CompilationResultBuilder crb, PTXMacroAssembler masm, Value result, Value input) {
         if (isVariable(input)) {
             if (isVariable(result)) {
                 reg2reg(masm, result, input);
@@ -180,7 +180,7 @@
             }
         } else if (isConstant(input)) {
             if (isVariable(result)) {
-                const2reg(tasm, masm, result, (Constant) input);
+                const2reg(crb, masm, result, (Constant) input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
@@ -209,25 +209,25 @@
         }
     }
 
-    private static void const2reg(TargetMethodAssembler tasm, PTXMacroAssembler masm, Value result, Constant input) {
+    private static void const2reg(CompilationResultBuilder crb, PTXMacroAssembler masm, Value result, Constant input) {
         Variable dest = (Variable) result;
 
         switch (input.getKind().getStackKind()) {
             case Int:
             case Long:
-                if (tasm.codeCache.needsDataPatch(input)) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                if (crb.codeCache.needsDataPatch(input)) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                 }
                 new Mov(dest, input).emit(masm);
                 break;
             case Object:
                 if (input.isNull()) {
                     new Mov(dest, Constant.forLong(0x0L)).emit(masm);
-                } else if (tasm.target.inlineObjects) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                } else if (crb.target.inlineObjects) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                     new Mov(dest, Constant.forLong(0xDEADDEADDEADDEADL)).emit(masm);
                 } else {
-                    // new Mov(dest, tasm.recordDataReferenceInCode(input, 0, false));
+                    // new Mov(dest, crb.recordDataReferenceInCode(input, 0, false));
                 }
                 break;
             default:
@@ -236,7 +236,7 @@
     }
 
     @SuppressWarnings("unused")
-    protected static void compareAndSwap(TargetMethodAssembler tasm, PTXAssembler masm, AllocatableValue result, PTXAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
+    protected static void compareAndSwap(CompilationResultBuilder crb, PTXAssembler masm, AllocatableValue result, PTXAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
         throw new InternalError("NYI");
     }
 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -44,8 +44,8 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm) {
-        PTXMacroAssembler masm = (PTXMacroAssembler) tasm.asm;
+    public void emitCode(CompilationResultBuilder crb) {
+        PTXMacroAssembler masm = (PTXMacroAssembler) crb.asm;
         // Emit parameter directives for arguments
         int argCount = params.length;
         for (int i = 0; i < argCount; i++) {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -44,7 +44,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, PTXMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, PTXMacroAssembler masm) {
         emit(masm, x, y, predicate);
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Dec 09 17:31:12 2013 +0100
@@ -63,8 +63,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, null);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, null);
         }
     }
 
@@ -81,8 +81,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, null);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, null);
         }
     }
 
@@ -101,8 +101,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -131,8 +131,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -160,8 +160,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -189,8 +189,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, null);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -215,9 +215,9 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             assert !(x instanceof SPARCAddressValue);
-            emit(tasm, masm, opcode, result, x, y, null);
+            emit(crb, masm, opcode, result, x, y, null);
         }
 
         @Override
@@ -249,8 +249,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, result, x, y, scratch1, scratch2, state);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, result, x, y, scratch1, scratch2, state);
         }
 
         @Override
@@ -260,18 +260,18 @@
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isConstant(src1)) {
             switch (opcode) {
                 case ISUB:
-                    assert isSimm13(tasm.asIntConst(src1));
-                    new Add(asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src1));
+                    new Add(asIntReg(src2), -(crb.asIntConst(src1)), asIntReg(dst)).emit(masm);
                     break;
                 case IAND:
                     throw GraalInternalError.unimplemented();
                 case IDIV:
-                    assert isSimm13(tasm.asIntConst(src1));
+                    assert isSimm13(crb.asIntConst(src1));
                     throw GraalInternalError.unimplemented();
                     // new Sdivx(masm, asIntReg(src1), asIntReg(src2),
                     // asIntReg(dst));
@@ -285,85 +285,85 @@
         } else if (isConstant(src2)) {
             switch (opcode) {
                 case IADD:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Add(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Add(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case ISUB:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Sub(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Sub(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IMUL:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Mulx(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Mulx(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IDIV:
-                    assert isSimm13(tasm.asIntConst(src2));
+                    assert isSimm13(crb.asIntConst(src2));
                     new Signx(asIntReg(src1), asIntReg(src1)).emit(masm);
-                    new Sdivx(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IAND:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new And(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new And(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case ISHL:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Sll(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Sll(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case ISHR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Sra(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Sra(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IUSHR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Srl(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Srl(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IOR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Or(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Or(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IXOR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Xor(asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Xor(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case LADD:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Add(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Add(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LSUB:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Sub(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Sub(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LMUL:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Mulx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Mulx(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LDIV:
                     throw GraalInternalError.unimplemented();
                 case LUDIV:
                     throw GraalInternalError.unimplemented();
                 case LAND:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new And(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new And(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LOR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Or(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Or(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LXOR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Xor(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Xor(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LSHL:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Sllx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Sllx(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LSHR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Srax(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Srax(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LUSHR:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Srlx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Srlx(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case FADD:
                 case FMUL:
@@ -477,11 +477,11 @@
 
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isConstant(src1)) {
             switch (opcode) {
@@ -491,9 +491,9 @@
         } else if (isConstant(src2)) {
             switch (opcode) {
                 case LREM:
-                    assert isSimm13(tasm.asIntConst(src2));
-                    new Sdivx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(scratch1)).emit(masm);
-                    new Mulx(asLongReg(scratch1), tasm.asIntConst(src2), asLongReg(scratch2)).emit(masm);
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
+                    new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm);
                     new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
                     break;
                 case LUREM:
@@ -513,12 +513,12 @@
 
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
     @SuppressWarnings("unused")
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isRegister(src)) {
             switch (opcode) {
@@ -574,7 +574,7 @@
 
         if (info != null) {
             assert exceptionOffset != -1;
-            tasm.recordImplicitException(exceptionOffset, info);
+            crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -57,7 +57,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         Register dst = asIntReg(result);
         if (isRegister(input)) {
             Register src = asRegister(input);
@@ -130,20 +130,20 @@
                     throw GraalInternalError.shouldNotReachHere();
 
             }
-        } else if (isConstant(input) && isSimm13(tasm.asIntConst(input))) {
+        } else if (isConstant(input) && isSimm13(crb.asIntConst(input))) {
             switch (opcode) {
                 case IPOPCNT:
-                    new Popc(tasm.asIntConst(input), dst).emit(masm);
+                    new Popc(crb.asIntConst(input), dst).emit(masm);
                     break;
                 case LPOPCNT:
-                    new Popc(tasm.asIntConst(input), dst).emit(masm);
+                    new Popc(crb.asIntConst(input), dst).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
         } else {
             throw GraalInternalError.shouldNotReachHere();
-            // SPARCAddress src = (SPARCAddress) tasm.asAddress(input);
+            // SPARCAddress src = (SPARCAddress) crb.asAddress(input);
             // switch (opcode) {
             // case IPOPCNT:
             // new Ldsw(src, tmp).emit(masm);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -52,7 +52,7 @@
 
     @Override
     @SuppressWarnings("unused")
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         new Trap(masm, ST_RESERVED_FOR_USER_0);
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -40,8 +40,8 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        SPARCMove.move(tasm, masm, result, input);
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        SPARCMove.move(crb, masm, result, input);
         switch (input.getKind()) {
             case Int:
                 // masm.bswapl(ValueUtil.asIntReg(result));
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Mon Dec 09 17:31:12 2013 +0100
@@ -75,8 +75,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            directCall(tasm, masm, callTarget, null, true, state);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            directCall(crb, masm, callTarget, null, true, state);
         }
     }
 
@@ -91,8 +91,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            indirectCall(tasm, masm, asRegister(targetAddress), callTarget, state);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            indirectCall(crb, masm, asRegister(targetAddress), callTarget, state);
         }
 
         @Override
@@ -125,8 +125,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            directCall(tasm, masm, callTarget, null, false, state);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            directCall(crb, masm, callTarget, null, false, state);
         }
     }
 
@@ -138,12 +138,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            directCall(tasm, masm, callTarget, o7, false, state);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            directCall(crb, masm, callTarget, o7, false, state);
         }
     }
 
-    public static void directCall(TargetMethodAssembler tasm, SPARCMacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) {
+    public static void directCall(CompilationResultBuilder crb, SPARCMacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) {
         if (align) {
             // We don't need alignment on SPARC.
         }
@@ -157,28 +157,28 @@
             new Call(0).emit(masm);
         }
         int after = masm.codeBuffer.position();
-        tasm.recordDirectCall(before, after, callTarget, info);
-        tasm.recordExceptionHandlers(after, info);
+        crb.recordDirectCall(before, after, callTarget, info);
+        crb.recordExceptionHandlers(after, info);
         new Nop().emit(masm);  // delay slot
         masm.ensureUniquePC();
     }
 
-    public static void indirectJmp(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Register dst, InvokeTarget target) {
+    public static void indirectJmp(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget target) {
         int before = masm.codeBuffer.position();
         new Sethix(0L, dst, true).emit(masm);
         new Jmp(new SPARCAddress(dst, 0)).emit(masm);
         int after = masm.codeBuffer.position();
-        tasm.recordIndirectCall(before, after, target, null);
+        crb.recordIndirectCall(before, after, target, null);
         new Nop().emit(masm);  // delay slot
         masm.ensureUniquePC();
     }
 
-    public static void indirectCall(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
+    public static void indirectCall(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
         int before = masm.codeBuffer.position();
         new Jmpl(dst, 0, o7).emit(masm);
         int after = masm.codeBuffer.position();
-        tasm.recordIndirectCall(before, after, callTarget, info);
-        tasm.recordExceptionHandlers(after, info);
+        crb.recordIndirectCall(before, after, callTarget, info);
+        crb.recordExceptionHandlers(after, info);
         new Nop().emit(masm);  // delay slot
         masm.ensureUniquePC();
     }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Mon Dec 09 17:31:12 2013 +0100
@@ -49,8 +49,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emit(tasm, masm, opcode, x, y);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emit(crb, masm, opcode, x, y);
         }
 
         @Override
@@ -62,7 +62,7 @@
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, SPARCMacroAssembler masm, SPARCCompare opcode, Value x, Value y) {
+    public static void emit(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCCompare opcode, Value x, Value y) {
         if (isRegister(y)) {
             switch (opcode) {
                 case ICMP:
@@ -87,12 +87,12 @@
             assert isConstant(y);
             switch (opcode) {
                 case ICMP:
-                    assert isSimm13(tasm.asIntConst(y));
-                    new Cmp(asIntReg(x), tasm.asIntConst(y)).emit(masm);
+                    assert isSimm13(crb.asIntConst(y));
+                    new Cmp(asIntReg(x), crb.asIntConst(y)).emit(masm);
                     break;
                 case LCMP:
-                    assert isSimm13(tasm.asIntConst(y));
-                    new Cmp(asLongReg(x), tasm.asIntConst(y)).emit(masm);
+                    assert isSimm13(crb.asIntConst(y));
+                    new Cmp(asLongReg(x), crb.asIntConst(y)).emit(masm);
                     break;
                 case ACMP:
                     if (((Constant) y).isNull()) {
@@ -102,10 +102,10 @@
                         throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
                     }
                 case FCMP:
-                    // masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatConstRef(y));
+                    // masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatConstRef(y));
                     // break;
                 case DCMP:
-                    // masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleConstRef(y));
+                    // masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleConstRef(y));
                     // break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Dec 09 17:31:12 2013 +0100
@@ -33,7 +33,7 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.FallThroughOp;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
 
@@ -43,66 +43,73 @@
 
     public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
 
-        protected Condition condition;
-        protected LabelRef destination;
+        protected final Condition condition;
+        protected final LabelRef trueDestination;
+        protected final LabelRef falseDestination;
         protected final Kind kind;
 
-        public BranchOp(Condition condition, LabelRef destination, Kind kind) {
+        public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) {
             this.condition = condition;
-            this.destination = destination;
+            this.trueDestination = trueDestination;
+            this.falseDestination = falseDestination;
             this.kind = kind;
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            int sourceIndex = crb.getCurrentBlockIndex();
+            Label actualTarget;
+            Condition actualCondition;
+            boolean needJump;
+            if (trueDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex)) {
+                actualCondition = condition.negate();
+                actualTarget = falseDestination.label();
+                needJump = false;
+            } else {
+                actualCondition = condition;
+                actualTarget = trueDestination.label();
+                needJump = !falseDestination.isCodeEmittingOrderSuccessorEdge(sourceIndex);
+            }
             assert kind == Kind.Int || kind == Kind.Long || kind == Kind.Object;
             CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc;
-            switch (condition) {
+            switch (actualCondition) {
                 case EQ:
-                    new Bpe(cc, destination.label()).emit(masm);
+                    new Bpe(cc, actualTarget).emit(masm);
                     break;
                 case NE:
-                    new Bpne(cc, destination.label()).emit(masm);
+                    new Bpne(cc, actualTarget).emit(masm);
                     break;
                 case BT:
-                    new Bplu(cc, destination.label()).emit(masm);
+                    new Bplu(cc, actualTarget).emit(masm);
                     break;
                 case LT:
-                    new Bpl(cc, destination.label()).emit(masm);
+                    new Bpl(cc, actualTarget).emit(masm);
                     break;
                 case BE:
-                    new Bpleu(cc, destination.label()).emit(masm);
+                    new Bpleu(cc, actualTarget).emit(masm);
                     break;
                 case LE:
-                    new Bple(cc, destination.label()).emit(masm);
+                    new Bple(cc, actualTarget).emit(masm);
                     break;
                 case GE:
-                    new Bpge(cc, destination.label()).emit(masm);
+                    new Bpge(cc, actualTarget).emit(masm);
                     break;
                 case AE:
-                    new Bpgeu(cc, destination.label()).emit(masm);
+                    new Bpgeu(cc, actualTarget).emit(masm);
                     break;
                 case GT:
-                    new Bpg(cc, destination.label()).emit(masm);
+                    new Bpg(cc, actualTarget).emit(masm);
                     break;
                 case AT:
-                    new Bpgu(cc, destination.label()).emit(masm);
+                    new Bpgu(cc, actualTarget).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
             new Nop().emit(masm);  // delay slot
-        }
-
-        @Override
-        public LabelRef destination() {
-            return destination;
-        }
-
-        @Override
-        public void negate(LabelRef newDestination) {
-            destination = newDestination;
-            condition = condition.negate();
+            if (needJump) {
+                masm.jmp(falseDestination.label());
+            }
         }
     }
 
@@ -123,8 +130,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            cmove(tasm, masm, result, false, condition, false, trueValue, falseValue);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            cmove(crb, masm, result, false, condition, false, trueValue, falseValue);
         }
     }
 
@@ -146,32 +153,32 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            cmove(crb, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue);
         }
     }
 
-    private static void cmove(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    private static void cmove(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         // check that we don't overwrite an input operand before it is used.
         assert !result.equals(trueValue);
 
-        SPARCMove.move(tasm, masm, result, falseValue);
-        cmove(tasm, masm, result, condition, trueValue);
+        SPARCMove.move(crb, masm, result, falseValue);
+        cmove(crb, masm, result, condition, trueValue);
 
         if (isFloat) {
             if (unorderedIsTrue && !trueOnUnordered(condition)) {
-                // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue);
+                // cmove(crb, masm, result, ConditionFlag.Parity, trueValue);
                 throw GraalInternalError.unimplemented();
             } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
-                // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue);
+                // cmove(crb, masm, result, ConditionFlag.Parity, falseValue);
                 throw GraalInternalError.unimplemented();
             }
         }
     }
 
-    private static void cmove(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, ConditionFlag cond, Value other) {
+    private static void cmove(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, ConditionFlag cond, Value other) {
         if (!isRegister(other)) {
-            SPARCMove.move(tasm, masm, result, other);
+            SPARCMove.move(crb, masm, result, other);
             throw new InternalError("result should be scratch");
         }
         assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move";
@@ -246,18 +253,18 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            emitCodeHelper(tasm, masm);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            emitCodeHelper(crb, masm);
         }
 
-        public static void emitCodeHelper(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public static void emitCodeHelper(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             new Ret().emit(masm);
             // On SPARC we always leave the frame (in the delay slot).
-            tasm.frameContext.leave(tasm);
+            crb.frameContext.leave(crb);
         }
     }
 
-    public static class SequentialSwitchOp extends SPARCLIRInstruction implements FallThroughOp {
+    public static class SequentialSwitchOp extends SPARCLIRInstruction implements BlockEndOp {
 
         @Use({CONST}) protected Constant[] keyConstants;
         private final LabelRef[] keyTargets;
@@ -275,12 +282,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             if (key.getKind() == Kind.Int) {
                 Register intKey = asIntReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    if (tasm.codeCache.needsDataPatch(keyConstants[i])) {
-                        tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
+                    if (crb.codeCache.needsDataPatch(keyConstants[i])) {
+                        crb.recordDataReferenceInCode(keyConstants[i], 0, true);
                     }
                     long lc = keyConstants[i].asLong();
                     assert NumUtil.isInt(lc);
@@ -292,7 +299,7 @@
                 Register longKey = asLongReg(key);
                 Register temp = asLongReg(scratch);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    SPARCMove.move(tasm, masm, temp.asValue(Kind.Long), keyConstants[i]);
+                    SPARCMove.move(crb, masm, temp.asValue(Kind.Long), keyConstants[i]);
                     new Cmp(longKey, temp).emit(masm);
                     new Bpe(CC.Xcc, keyTargets[i].label()).emit(masm);
                     new Nop().emit(masm);  // delay slot
@@ -301,7 +308,7 @@
                 Register objectKey = asObjectReg(key);
                 Register temp = asObjectReg(scratch);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    SPARCMove.move(tasm, masm, temp.asValue(Kind.Object), keyConstants[i]);
+                    SPARCMove.move(crb, masm, temp.asValue(Kind.Object), keyConstants[i]);
                     new Cmp(objectKey, temp).emit(masm);
                     new Bpe(CC.Ptrcc, keyTargets[i].label()).emit(masm);
                     new Nop().emit(masm);  // delay slot
@@ -310,24 +317,16 @@
                 throw new GraalInternalError("sequential switch only supported for int, long and object");
             }
             if (defaultTarget != null) {
-                masm.jmp(defaultTarget.label());
+                if (!defaultTarget.isCodeEmittingOrderSuccessorEdge(crb.getCurrentBlockIndex())) {
+                    masm.jmp(defaultTarget.label());
+                }
             } else {
                 new Illtrap(0).emit(masm);
             }
         }
-
-        @Override
-        public LabelRef fallThroughTarget() {
-            return defaultTarget;
-        }
-
-        @Override
-        public void setFallThroughTarget(LabelRef target) {
-            defaultTarget = target;
-        }
     }
 
-    public static class SwitchRangesOp extends SPARCLIRInstruction implements FallThroughOp {
+    public static class SwitchRangesOp extends SPARCLIRInstruction implements BlockEndOp {
 
         private final LabelRef[] keyTargets;
         private LabelRef defaultTarget;
@@ -344,7 +343,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             assert isSorted(lowKeys) && isSorted(highKeys);
 
             Label actualDefaultTarget = defaultTarget == null ? new Label() : defaultTarget.label();
@@ -368,11 +367,14 @@
                 }
                 prevHighKey = highKey;
             }
+
             if (defaultTarget != null) {
-                new Bpa(defaultTarget.label()).emit(masm);
+                if (!defaultTarget.isCodeEmittingOrderSuccessorEdge(crb.getCurrentBlockIndex())) {
+                    new Bpa(defaultTarget.label()).emit(masm);
+                }
             } else {
                 masm.bind(actualDefaultTarget);
-                // masm.hlt();
+                new Illtrap(0).emit(masm);
             }
             throw GraalInternalError.unimplemented();
         }
@@ -385,16 +387,6 @@
             assert key.getKind() == Kind.Int;
         }
 
-        @Override
-        public LabelRef fallThroughTarget() {
-            return defaultTarget;
-        }
-
-        @Override
-        public void setFallThroughTarget(LabelRef target) {
-            defaultTarget = target;
-        }
-
         private static boolean isSorted(int[] values) {
             for (int i = 1; i < values.length; i++) {
                 if (values[i - 1] >= values[i]) {
@@ -405,7 +397,7 @@
         }
     }
 
-    public static class TableSwitchOp extends SPARCLIRInstruction {
+    public static class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp {
 
         private final int lowKey;
         private final LabelRef defaultTarget;
@@ -422,12 +414,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch));
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            tableswitch(crb, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch));
         }
     }
 
-    private static void tableswitch(TargetMethodAssembler tasm, SPARCAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) {
+    private static void tableswitch(CompilationResultBuilder crb, SPARCAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) {
         Buffer buf = masm.codeBuffer;
         // Compare index against jump table bounds
         int highKey = lowKey + targets.length - 1;
@@ -455,7 +447,7 @@
         int tablePos = buf.position();
 
         JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4);
-        tasm.compilationResult.addAnnotation(jt);
+        crb.compilationResult.addAnnotation(jt);
 
         // SPARC: unimp: tableswitch extract
         throw GraalInternalError.unimplemented();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Mon Dec 09 17:31:12 2013 +0100
@@ -32,9 +32,9 @@
 public abstract class SPARCLIRInstruction extends LIRInstruction {
 
     @Override
-    public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (SPARCMacroAssembler) tasm.asm);
+    public final void emitCode(CompilationResultBuilder crb) {
+        emitCode(crb, (SPARCMacroAssembler) crb.asm);
     }
 
-    public abstract void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm);
+    public abstract void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm);
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -48,7 +48,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         switch (opcode) {
             case SQRT:
                 new Fsqrtd(asDoubleReg(input), asDoubleReg(result)).emit(masm);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Dec 09 17:31:12 2013 +0100
@@ -51,8 +51,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -78,8 +78,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            move(tasm, masm, getResult(), getInput());
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            move(crb, masm, getResult(), getInput());
         }
 
         @Override
@@ -108,15 +108,15 @@
         protected abstract void emitMemAccess(SPARCMacroAssembler masm);
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             if (state != null) {
-                tasm.recordImplicitException(masm.codeBuffer.position(), state);
+                crb.recordImplicitException(masm.codeBuffer.position(), state);
             }
             emitMemAccess(masm);
         }
 
         public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
-            if (state == null && value.equals(address.base) && address.index == Value.ILLEGAL && address.displacement >= 0 && address.displacement < implicitNullCheckLimit) {
+            if (state == null && value.equals(address.base) && address.index.equals(Value.ILLEGAL) && address.displacement >= 0 && address.displacement < implicitNullCheckLimit) {
                 state = nullCheckState;
                 return true;
             }
@@ -179,7 +179,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress addr = address.toAddress();
             if (addr.hasIndex()) {
                 new Add(addr.getBase(), addr.getIndex(), asLongReg(result)).emit(masm);
@@ -198,7 +198,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             new Membar(barriers).emit(masm);
         }
     }
@@ -214,8 +214,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            tasm.recordImplicitException(masm.codeBuffer.position(), state);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            crb.recordImplicitException(masm.codeBuffer.position(), state);
             new Ldx(new SPARCAddress(asRegister(input), 0), r0).emit(masm);
         }
 
@@ -243,7 +243,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             compareAndSwap(masm, address, cmpValue, newValue);
         }
     }
@@ -259,8 +259,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            SPARCAddress address = (SPARCAddress) tasm.asAddress(slot);
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            SPARCAddress address = (SPARCAddress) crb.asAddress(slot);
             new Add(address.getBase(), address.getDisplacement(), asLongReg(result)).emit(masm);
         }
     }
@@ -349,24 +349,24 @@
         }
     }
 
-    public static void move(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) {
+    public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
                 reg2reg(masm, result, input);
             } else if (isStackSlot(result)) {
-                reg2stack(tasm, masm, result, input);
+                reg2stack(crb, masm, result, input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isStackSlot(input)) {
             if (isRegister(result)) {
-                stack2reg(tasm, masm, result, input);
+                stack2reg(crb, masm, result, input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isConstant(input)) {
             if (isRegister(result)) {
-                const2reg(tasm, masm, result, (Constant) input);
+                const2reg(crb, masm, result, (Constant) input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
@@ -392,8 +392,8 @@
         }
     }
 
-    private static void reg2stack(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) {
-        SPARCAddress dst = (SPARCAddress) tasm.asAddress(result);
+    private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input) {
+        SPARCAddress dst = (SPARCAddress) crb.asAddress(result);
         Register src = asRegister(input);
         switch (input.getKind()) {
             case Int:
@@ -410,8 +410,8 @@
         }
     }
 
-    private static void stack2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) {
-        SPARCAddress src = (SPARCAddress) tasm.asAddress(input);
+    private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input) {
+        SPARCAddress src = (SPARCAddress) crb.asAddress(input);
         Register dst = asRegister(result);
         switch (input.getKind()) {
             case Int:
@@ -428,11 +428,11 @@
         }
     }
 
-    private static void const2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Constant input) {
+    private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input) {
         switch (input.getKind().getStackKind()) {
             case Int:
-                if (tasm.codeCache.needsDataPatch(input)) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                if (crb.codeCache.needsDataPatch(input)) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                     new Setuw(input.asInt(), asRegister(result)).emit(masm);
                 } else {
                     if (input.isDefaultForKind()) {
@@ -443,8 +443,8 @@
                 }
                 break;
             case Long: {
-                if (tasm.codeCache.needsDataPatch(input)) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                if (crb.codeCache.needsDataPatch(input)) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                     new Setx(input.asLong(), asRegister(result), true).emit(masm);
                 } else {
                     if (input.isDefaultForKind()) {
@@ -458,13 +458,13 @@
             case Object: {
                 if (input.isNull()) {
                     new Clr(asRegister(result)).emit(masm);
-                } else if (tasm.target.inlineObjects) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
+                } else if (crb.target.inlineObjects) {
+                    crb.recordDataReferenceInCode(input, 0, true);
                     new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm);
                 } else {
                     Register dst = asRegister(result);
                     new Rdpc(dst).emit(masm);
-                    tasm.asObjectConstRef(input);
+                    crb.asObjectConstRef(input);
                     new Ldx(new SPARCAddress(dst, 0), dst).emit(masm);
                     throw GraalInternalError.shouldNotReachHere("the patched offset might be too big for the load");
                 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -43,7 +43,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         if (isRegister(y)) {
             switch (x.getKind()) {
                 case Int:
@@ -58,10 +58,10 @@
         } else if (isConstant(y)) {
             switch (x.getKind()) {
                 case Int:
-                    new Cmp(asIntReg(x), tasm.asIntConst(y)).emit(masm);
+                    new Cmp(asIntReg(x), crb.asIntConst(y)).emit(masm);
                     break;
                 case Long:
-                    new Cmp(asLongReg(x), tasm.asIntConst(y)).emit(masm);
+                    new Cmp(asLongReg(x), crb.asIntConst(y)).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -69,11 +69,11 @@
         } else {
             switch (x.getKind()) {
                 case Int:
-                    new Ldsw((SPARCAddress) tasm.asIntAddr(y), asIntReg(y)).emit(masm);
+                    new Ldsw((SPARCAddress) crb.asIntAddr(y), asIntReg(y)).emit(masm);
                     new Cmp(asIntReg(x), asIntReg(y)).emit(masm);
                     break;
                 case Long:
-                    new Ldx((SPARCAddress) tasm.asLongAddr(y), asLongReg(y)).emit(masm);
+                    new Ldx((SPARCAddress) crb.asLongAddr(y), asLongReg(y)).emit(masm);
                     new Cmp(asLongReg(x), asLongReg(y)).emit(masm);
                     break;
                 default:
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Mon Dec 09 17:31:12 2013 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.lir;
 
+import static com.oracle.graal.lir.LIR.*;
+
 import java.util.*;
 
 import com.oracle.graal.debug.*;
@@ -35,10 +37,9 @@
     /**
      * Performs control flow optimizations on the given LIR graph.
      */
-    public static void optimize(LIR ir) {
-        List<Block> blocks = ir.codeEmittingOrder();
-        ControlFlowOptimizer.deleteEmptyBlocks(ir, blocks);
-        ControlFlowOptimizer.deleteUnnecessaryJumps(ir, blocks);
+    public static void optimize(LIR lir) {
+        List<Block> blocks = lir.codeEmittingOrder();
+        ControlFlowOptimizer.deleteEmptyBlocks(lir, blocks);
     }
 
     private ControlFlowOptimizer() {
@@ -51,28 +52,28 @@
      * @param block the block checked for deletion
      * @return whether the block can be deleted
      */
-    private static boolean canDeleteBlock(LIR ir, Block block) {
+    private static boolean canDeleteBlock(LIR lir, Block block) {
         if (block.getSuccessorCount() != 1 || block.getPredecessorCount() == 0 || block.getFirstSuccessor() == block) {
             return false;
         }
 
-        List<LIRInstruction> instructions = ir.lir(block);
+        List<LIRInstruction> instructions = lir.lir(block);
 
         assert instructions.size() >= 2 : "block must have label and branch";
         assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label";
         assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "last instruction must always be a branch";
-        assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == ((StandardOp.LabelOp) ir.lir(block.getFirstSuccessor()).get(0)).getLabel() : "branch target must be the successor";
+        assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == ((StandardOp.LabelOp) lir.lir(block.getFirstSuccessor()).get(0)).getLabel() : "branch target must be the successor";
 
         // Block must have exactly one successor.
         return instructions.size() == 2 && !instructions.get(instructions.size() - 1).hasState();
     }
 
-    private static void deleteEmptyBlocks(LIR ir, List<Block> blocks) {
-        assert verify(blocks);
+    private static void deleteEmptyBlocks(LIR lir, List<Block> blocks) {
+        assert verifyBlocks(lir, blocks);
         Iterator<Block> iterator = blocks.iterator();
         while (iterator.hasNext()) {
             Block block = iterator.next();
-            if (canDeleteBlock(ir, block)) {
+            if (canDeleteBlock(lir, block)) {
                 // adjust successor and predecessor lists
                 Block other = block.getFirstSuccessor();
                 for (Block pred : block.getPredecessors()) {
@@ -90,51 +91,6 @@
                 iterator.remove();
             }
         }
-        assert verify(blocks);
-    }
-
-    private static void deleteUnnecessaryJumps(LIR ir, List<Block> blocks) {
-        // skip the last block because there a branch is always necessary
-        for (int i = blocks.size() - 2; i >= 0; i--) {
-            Block block = blocks.get(i);
-            List<LIRInstruction> instructions = ir.lir(block);
-
-            LIRInstruction lastOp = instructions.get(instructions.size() - 1);
-            if (lastOp instanceof StandardOp.JumpOp) {
-                StandardOp.JumpOp lastJump = (StandardOp.JumpOp) lastOp;
-
-                if (!lastOp.hasState()) {
-                    if (lastJump.destination().label() == ((StandardOp.LabelOp) ir.lir(blocks.get(i + 1)).get(0)).getLabel()) {
-                        // delete last branch instruction
-                        instructions.remove(instructions.size() - 1);
-                    } else {
-                        LIRInstruction prevOp = instructions.get(instructions.size() - 2);
-                        if (prevOp instanceof StandardOp.BranchOp) {
-                            StandardOp.BranchOp prevBranch = (StandardOp.BranchOp) prevOp;
-
-                            if (prevBranch.destination().label() == ((StandardOp.LabelOp) ir.lir(blocks.get(i + 1)).get(0)).getLabel() && !prevOp.hasState()) {
-                                // eliminate a conditional branch to the immediate successor
-                                prevBranch.negate(lastJump.destination());
-                                instructions.remove(instructions.size() - 1);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        assert verify(blocks);
-    }
-
-    private static boolean verify(List<Block> code) {
-        for (Block block : code) {
-            for (Block sux : block.getSuccessors()) {
-                assert code.contains(sux) : "missing successor from: " + block + "to: " + sux;
-            }
-            for (Block pred : block.getPredecessors()) {
-                assert code.contains(pred) : "missing predecessor from: " + block + "to: " + pred;
-            }
-        }
-
-        return true;
+        assert verifyBlocks(lir, blocks);
     }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java	Mon Dec 09 17:31:12 2013 +0100
@@ -183,23 +183,14 @@
         assert numSux == 2 : "method should not be called otherwise";
 
         LIRInstruction lastInstruction = instructions.get(instructions.size() - 1);
-        if (lastInstruction instanceof StandardOp.FallThroughOp) {
-            assert ((StandardOp.FallThroughOp) lastInstruction).fallThroughTarget() != null : "block must end with unconditional jump";
-            // fall through ops like switches cannot be optimized anyway - they have input operands
-            return;
-        } else {
-            assert lastInstruction instanceof StandardOp.JumpOp : "block must end with unconditional jump";
-        }
-
         if (lastInstruction.hasState()) {
             // cannot optimize instructions when debug info is needed
             return;
         }
 
-        LIRInstruction branch = instructions.get(instructions.size() - 2);
+        LIRInstruction branch = lastInstruction;
         if (!(branch instanceof StandardOp.BranchOp) || branch.hasOperands()) {
-            // Only blocks that end with two branches (conditional branch followed
-            // by unconditional branch) are optimized.
+            // Only blocks that end with a conditional branch are optimized.
             // In addition, a conditional branch with operands (including state) cannot
             // be optimized. Moving a successor instruction before such a branch may
             // interfere with the operands of the branch. For example, a successive move
@@ -207,9 +198,9 @@
             return;
         }
 
-        // now it is guaranteed that the block ends with two branch instructions.
-        // the instructions are inserted at the end of the block before these two branches
-        int insertIdx = instructions.size() - 2;
+        // Now it is guaranteed that the block ends with a conditional branch.
+        // The instructions are inserted at the end of the block before the branch.
+        int insertIdx = instructions.size() - 1;
 
         // setup a list with the lir-instructions of all successors
         for (Block sux : block.getSuccessors()) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -41,7 +41,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm) {
-        tasm.recordInfopoint(tasm.asm.codeBuffer.position(), state, reason);
+    public void emitCode(CompilationResultBuilder crb) {
+        crb.recordInfopoint(crb.asm.codeBuffer.position(), state, reason);
     }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Mon Dec 09 17:31:12 2013 +0100
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
@@ -136,41 +137,43 @@
         firstVariableNumber = num;
     }
 
-    public void emitCode(TargetMethodAssembler tasm) {
-        if (tasm.frameContext != null) {
-            tasm.frameContext.enter(tasm);
-        }
+    public void emitCode(CompilationResultBuilder crb) {
+        crb.frameContext.enter(crb);
+
+        // notifyBlocksOfSuccessors();
 
-        for (Block b : codeEmittingOrder()) {
-            emitBlock(tasm, b);
+        int index = 0;
+        for (Block b : codeEmittingOrder) {
+            crb.setCurrentBlockIndex(index++);
+            emitBlock(crb, b);
         }
     }
 
-    private void emitBlock(TargetMethodAssembler tasm, Block block) {
+    private void emitBlock(CompilationResultBuilder crb, Block block) {
         if (Debug.isDumpEnabled()) {
-            tasm.blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
+            crb.blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
         }
 
         for (LIRInstruction op : lir(block)) {
             if (Debug.isDumpEnabled()) {
-                tasm.blockComment(String.format("%d %s", op.id(), op));
+                crb.blockComment(String.format("%d %s", op.id(), op));
             }
 
-            emitOp(tasm, op);
+            try {
+                emitOp(crb, op);
+            } catch (GraalInternalError e) {
+                throw e.addContext("lir instruction", block + "@" + op.id() + " " + op + "\n" + codeEmittingOrder);
+            }
         }
     }
 
-    private static void emitOp(TargetMethodAssembler tasm, LIRInstruction op) {
+    private static void emitOp(CompilationResultBuilder crb, LIRInstruction op) {
         try {
-            try {
-                op.emitCode(tasm);
-            } catch (AssertionError t) {
-                throw new GraalInternalError(t);
-            } catch (RuntimeException t) {
-                throw new GraalInternalError(t);
-            }
-        } catch (GraalInternalError e) {
-            throw e.addContext("lir instruction", op);
+            op.emitCode(crb);
+        } catch (AssertionError t) {
+            throw new GraalInternalError(t);
+        } catch (RuntimeException t) {
+            throw new GraalInternalError(t);
         }
     }
 
@@ -185,4 +188,30 @@
     public boolean hasArgInCallerFrame() {
         return hasArgInCallerFrame;
     }
+
+    public static boolean verifyBlock(LIR lir, Block block) {
+        List<LIRInstruction> ops = lir.lir(block);
+        if (ops.size() == 0) {
+            return true;
+        }
+        for (LIRInstruction op : ops.subList(0, ops.size() - 1)) {
+            assert !(op instanceof BlockEndOp) : op.getClass();
+        }
+        LIRInstruction end = ops.get(ops.size() - 1);
+        assert end instanceof BlockEndOp : end.getClass();
+        return true;
+    }
+
+    public static boolean verifyBlocks(LIR lir, List<Block> blocks) {
+        for (Block block : blocks) {
+            for (Block sux : block.getSuccessors()) {
+                assert blocks.contains(sux) : "missing successor from: " + block + "to: " + sux;
+            }
+            for (Block pred : block.getPredecessors()) {
+                assert blocks.contains(pred) : "missing predecessor from: " + block + "to: " + pred;
+            }
+            verifyBlock(lir, block);
+        }
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Mon Dec 09 17:31:12 2013 +0100
@@ -223,7 +223,7 @@
         id = -1;
     }
 
-    public abstract void emitCode(TargetMethodAssembler tasm);
+    public abstract void emitCode(CompilationResultBuilder crb);
 
     public final int id() {
         return id;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LabelRef.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LabelRef.java	Mon Dec 09 17:31:12 2013 +0100
@@ -22,20 +22,26 @@
  */
 package com.oracle.graal.lir;
 
+import java.util.*;
+
 import com.oracle.graal.asm.*;
+import com.oracle.graal.lir.StandardOp.BranchOp;
+import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.nodes.cfg.*;
 
 /**
- * LIR instructions such as JUMP and BRANCH need to reference their target {@link Block}. However,
- * direct references are not possible since the control flow graph (and therefore successors lists)
- * can be changed by optimizations - and fixing the instructions is error prone. Therefore, we only
- * reference of block B from block A only via the tuple (A, successor-index-of-B), i.e., indirectly
- * by storing the index into the successor list of A. Note that therefore it is not allowed to
- * reorder the successor list!
+ * LIR instructions such as {@link JumpOp} and {@link BranchOp} need to reference their target
+ * {@link Block}. However, direct references are not possible since the control flow graph (and
+ * therefore successors lists) can be changed by optimizations - and fixing the instructions is
+ * error prone. Therefore, we represent an edge to block B from block A via the tuple {@code (A,
+ * successor-index-of-B)}. That is, indirectly by storing the index into the successor list of A.
+ * Note therefore that the successor list cannot be re-ordered.
  */
-public abstract class LabelRef {
+public final class LabelRef {
 
-    public abstract Label label();
+    private final LIR lir;
+    private final Block block;
+    private final int suxIndex;
 
     /**
      * Returns a new reference to a successor of the given block.
@@ -45,17 +51,48 @@
      * @return The newly created label reference.
      */
     public static LabelRef forSuccessor(final LIR lir, final Block block, final int suxIndex) {
-        return new LabelRef() {
+        return new LabelRef(lir, block, suxIndex);
+    }
+
+    /**
+     * Returns a new reference to a successor of the given block.
+     * 
+     * @param block The base block that contains the successor list.
+     * @param suxIndex The index of the successor.
+     */
+    private LabelRef(final LIR lir, final Block block, final int suxIndex) {
+        this.lir = lir;
+        this.block = block;
+        this.suxIndex = suxIndex;
+    }
+
+    public Block getSourceBlock() {
+        return block;
+    }
 
-            @Override
-            public Label label() {
-                return ((StandardOp.LabelOp) lir.lir(block.getSuccessors().get(suxIndex)).get(0)).getLabel();
-            }
+    public Block getTargetBlock() {
+        return block.getSuccessors().get(suxIndex);
+    }
+
+    public Label label() {
+        return ((StandardOp.LabelOp) lir.lir(getTargetBlock()).get(0)).getLabel();
+    }
 
-            @Override
-            public String toString() {
-                return suxIndex < block.getSuccessorCount() ? block.getSuccessors().get(suxIndex).toString() : "?" + block + ":" + suxIndex + "?";
-            }
-        };
+    /**
+     * Determines if the edge represented by this object is from a block to its lexical successor in
+     * the code emitting order of blocks.
+     * 
+     * @param sourceIndex the index of this edge's {@linkplain #getSourceBlock() source} in the code
+     *            emitting order
+     */
+    public boolean isCodeEmittingOrderSuccessorEdge(int sourceIndex) {
+        List<Block> order = lir.codeEmittingOrder();
+        assert order.get(sourceIndex) == block;
+        return sourceIndex < order.size() - 1 && order.get(sourceIndex + 1) == getTargetBlock();
+    }
+
+    @Override
+    public String toString() {
+        return suxIndex < block.getSuccessorCount() ? getTargetBlock().toString() : "?" + block + ":" + suxIndex + "?";
     }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Mon Dec 09 17:31:12 2013 +0100
@@ -40,15 +40,10 @@
 public class StandardOp {
 
     /**
-     * Marker interface for LIR ops that can fall through to the next operation, like a switch
-     * statement. setFallThroughTarget(null) can be used to make the operation fall through to the
-     * next one.
+     * A block delimiter. Every well formed block must contain exactly one such operation and it
+     * must be the last operation in the block.
      */
-    public interface FallThroughOp {
-
-        LabelRef fallThroughTarget();
-
-        void setFallThroughTarget(LabelRef target);
+    public interface BlockEndOp {
     }
 
     public interface NullCheck {
@@ -62,8 +57,7 @@
     }
 
     /**
-     * LIR operation that defines the position of a label. The first operation of every block must
-     * implement this interface.
+     * LIR operation that defines the position of a label.
      */
     public static class LabelOp extends LIRInstruction {
 
@@ -94,11 +88,11 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm) {
+        public void emitCode(CompilationResultBuilder crb) {
             if (align) {
-                tasm.asm.align(tasm.target.wordSize * 2);
+                crb.asm.align(crb.target.wordSize * 2);
             }
-            tasm.asm.bind(label);
+            crb.asm.bind(label);
         }
 
         public Label getLabel() {
@@ -107,11 +101,9 @@
     }
 
     /**
-     * LIR operation that is an unconditional jump to {@link #destination()}. When the LIR is
-     * constructed, the last operation of every block must implement this interface. After register
-     * allocation, unnecessary jumps can be deleted.
+     * LIR operation that is an unconditional jump to a {@link #destination()}.
      */
-    public static class JumpOp extends LIRInstruction {
+    public static class JumpOp extends LIRInstruction implements BlockEndOp {
 
         private final LabelRef destination;
 
@@ -120,8 +112,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm) {
-            tasm.asm.jmp(destination.label());
+        public void emitCode(CompilationResultBuilder crb) {
+            crb.asm.jmp(destination.label());
         }
 
         public LabelRef destination() {
@@ -130,14 +122,9 @@
     }
 
     /**
-     * Marker interface for a LIR operation that is a conditional jump to {@link #destination()}.
-     * Conditional jumps may be negated or optimized away after register allocation.
+     * Marker interface for a LIR operation that is a conditional jump.
      */
-    public interface BranchOp {
-
-        LabelRef destination();
-
-        void negate(LabelRef newDestination);
+    public interface BranchOp extends BlockEndOp {
     }
 
     /**
@@ -209,7 +196,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm) {
+        public void emitCode(CompilationResultBuilder crb) {
             throw new GraalInternalError(this + " should have been replaced");
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2013, 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.graal.lir.asm;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+
+/**
+ * Fills in a {@link CompilationResult} as its code is being assembled.
+ * 
+ * @see CompilationResultBuilderFactory
+ */
+public class CompilationResultBuilder {
+
+    private static class ExceptionInfo {
+
+        public final int codeOffset;
+        public final LabelRef exceptionEdge;
+
+        public ExceptionInfo(int pcOffset, LabelRef exceptionEdge) {
+            this.codeOffset = pcOffset;
+            this.exceptionEdge = exceptionEdge;
+        }
+    }
+
+    public final AbstractAssembler asm;
+    public final CompilationResult compilationResult;
+    public final TargetDescription target;
+    public final CodeCacheProvider codeCache;
+    public final ForeignCallsProvider foreignCalls;
+    public final FrameMap frameMap;
+
+    /**
+     * The index of the block currently being processed in the code emitting block order.
+     */
+    private int currentBlockIndex;
+
+    /**
+     * The object that emits code for managing a method's frame.
+     */
+    public final FrameContext frameContext;
+
+    private List<ExceptionInfo> exceptionInfoList;
+
+    public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+                    CompilationResult compilationResult) {
+        this.target = codeCache.getTarget();
+        this.codeCache = codeCache;
+        this.foreignCalls = foreignCalls;
+        this.frameMap = frameMap;
+        this.asm = asm;
+        this.compilationResult = compilationResult;
+        this.frameContext = frameContext;
+        assert frameContext != null;
+    }
+
+    public void setFrameSize(int frameSize) {
+        compilationResult.setFrameSize(frameSize);
+    }
+
+    private static final CompilationResult.Mark[] NO_REFS = {};
+
+    public CompilationResult.Mark recordMark(Object id) {
+        return compilationResult.recordMark(asm.codeBuffer.position(), id, NO_REFS);
+    }
+
+    public CompilationResult.Mark recordMark(Object id, CompilationResult.Mark... references) {
+        return compilationResult.recordMark(asm.codeBuffer.position(), id, references);
+    }
+
+    public void blockComment(String s) {
+        compilationResult.addAnnotation(new CompilationResult.CodeComment(asm.codeBuffer.position(), s));
+    }
+
+    /**
+     * Sets the {@linkplain CompilationResult#setTargetCode(byte[], int) code} and
+     * {@linkplain CompilationResult#recordExceptionHandler(int, int) exception handler} fields of
+     * the compilation result.
+     */
+    public void finish() {
+        compilationResult.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
+
+        // Record exception handlers if they exist
+        if (exceptionInfoList != null) {
+            for (ExceptionInfo ei : exceptionInfoList) {
+                int codeOffset = ei.codeOffset;
+                compilationResult.recordExceptionHandler(codeOffset, ei.exceptionEdge.label().position());
+            }
+        }
+    }
+
+    public void recordExceptionHandlers(int pcOffset, LIRFrameState info) {
+        if (info != null) {
+            if (info.exceptionEdge != null) {
+                if (exceptionInfoList == null) {
+                    exceptionInfoList = new ArrayList<>(4);
+                }
+                exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge));
+            }
+        }
+    }
+
+    public void recordImplicitException(int pcOffset, LIRFrameState info) {
+        // record an implicit exception point
+        if (info != null) {
+            compilationResult.recordInfopoint(pcOffset, info.debugInfo(), InfopointReason.IMPLICIT_EXCEPTION);
+            assert info.exceptionEdge == null;
+        }
+    }
+
+    public void recordDirectCall(int posBefore, int posAfter, InvokeTarget callTarget, LIRFrameState info) {
+        DebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        compilationResult.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, true);
+    }
+
+    public void recordIndirectCall(int posBefore, int posAfter, InvokeTarget callTarget, LIRFrameState info) {
+        DebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        compilationResult.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, false);
+    }
+
+    public void recordInfopoint(int pos, LIRFrameState info, InfopointReason reason) {
+        // infopoints always need debug info
+        DebugInfo debugInfo = info.debugInfo();
+        compilationResult.recordInfopoint(pos, debugInfo, reason);
+    }
+
+    public AbstractAddress recordDataReferenceInCode(Constant data, int alignment, boolean inlined) {
+        assert data != null;
+        int pos = asm.codeBuffer.position();
+        Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
+        compilationResult.recordDataReference(pos, data, alignment, inlined);
+        return asm.getPlaceholder();
+    }
+
+    public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) {
+        assert data != null;
+        int pos = asm.codeBuffer.position();
+        Debug.log("Raw data reference in code: pos = %d, data = %s", pos, data.toString());
+        compilationResult.recordDataReference(pos, data, alignment);
+        return asm.getPlaceholder();
+    }
+
+    /**
+     * Returns the integer value of any constant that can be represented by a 32-bit integer value,
+     * including long constants that fit into the 32-bit range.
+     */
+    public int asIntConst(Value value) {
+        assert (value.getKind().isNumericInteger()) && isConstant(value);
+        Constant constant = (Constant) value;
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        long c = constant.asLong();
+        if (!NumUtil.isInt(c)) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return (int) c;
+    }
+
+    /**
+     * Returns the float value of any constant that can be represented by a 32-bit float value.
+     */
+    public float asFloatConst(Value value) {
+        assert (value.getKind().getStackKind() == Kind.Float && isConstant(value));
+        Constant constant = (Constant) value;
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        return constant.asFloat();
+    }
+
+    /**
+     * Returns the long value of any constant that can be represented by a 64-bit long value.
+     */
+    public long asLongConst(Value value) {
+        assert (value.getKind().getStackKind() == Kind.Long && isConstant(value));
+        Constant constant = (Constant) value;
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        return constant.asLong();
+    }
+
+    /**
+     * Returns the double value of any constant that can be represented by a 64-bit float value.
+     */
+    public double asDoubleConst(Value value) {
+        assert (value.getKind().getStackKind() == Kind.Double && isConstant(value));
+        Constant constant = (Constant) value;
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        return constant.asDouble();
+    }
+
+    /**
+     * Returns the address of a float constant that is embedded as a data reference into the code.
+     */
+    public AbstractAddress asFloatConstRef(Value value) {
+        return asFloatConstRef(value, 4);
+    }
+
+    public AbstractAddress asFloatConstRef(Value value, int alignment) {
+        assert value.getKind() == Kind.Float && isConstant(value);
+        return recordDataReferenceInCode((Constant) value, alignment, false);
+    }
+
+    /**
+     * Returns the address of a double constant that is embedded as a data reference into the code.
+     */
+    public AbstractAddress asDoubleConstRef(Value value) {
+        return asDoubleConstRef(value, 8);
+    }
+
+    public AbstractAddress asDoubleConstRef(Value value, int alignment) {
+        assert value.getKind() == Kind.Double && isConstant(value);
+        return recordDataReferenceInCode((Constant) value, alignment, false);
+    }
+
+    /**
+     * Returns the address of a long constant that is embedded as a data reference into the code.
+     */
+    public AbstractAddress asLongConstRef(Value value) {
+        assert value.getKind() == Kind.Long && isConstant(value);
+        return recordDataReferenceInCode((Constant) value, 8, false);
+    }
+
+    /**
+     * Returns the address of an object constant that is embedded as a data reference into the code.
+     */
+    public AbstractAddress asObjectConstRef(Value value) {
+        assert value.getKind() == Kind.Object && isConstant(value);
+        return recordDataReferenceInCode((Constant) value, 8, false);
+    }
+
+    public AbstractAddress asIntAddr(Value value) {
+        assert value.getKind() == Kind.Int;
+        return asAddress(value);
+    }
+
+    public AbstractAddress asLongAddr(Value value) {
+        assert value.getKind() == Kind.Long;
+        return asAddress(value);
+    }
+
+    public AbstractAddress asObjectAddr(Value value) {
+        assert value.getKind() == Kind.Object;
+        return asAddress(value);
+    }
+
+    public AbstractAddress asFloatAddr(Value value) {
+        assert value.getKind() == Kind.Float;
+        return asAddress(value);
+    }
+
+    public AbstractAddress asDoubleAddr(Value value) {
+        assert value.getKind() == Kind.Double;
+        return asAddress(value);
+    }
+
+    public AbstractAddress asAddress(Value value) {
+        assert isStackSlot(value);
+        StackSlot slot = asStackSlot(value);
+        return asm.makeAddress(frameMap.registerConfig.getFrameRegister(), frameMap.offsetForStackSlot(slot));
+    }
+
+    /**
+     * Gets the index of the block currently being processed in the code emitting block order.
+     */
+    public int getCurrentBlockIndex() {
+        return currentBlockIndex;
+    }
+
+    /**
+     * Sets the index of the block currently being processed in the code emitting block order.
+     */
+    public void setCurrentBlockIndex(int index) {
+        this.currentBlockIndex = index;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilderFactory.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, 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.graal.lir.asm;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.lir.*;
+
+/**
+ * Factory class for creating {@link CompilationResultBuilder}s.
+ */
+public interface CompilationResultBuilderFactory {
+
+    /**
+     * Creates a new {@link CompilationResultBuilder}.
+     */
+    CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+                    CompilationResult compilationResult);
+
+    /**
+     * The default factory creates a standard {@link CompilationResultBuilder}.
+     */
+    CompilationResultBuilderFactory Default = new CompilationResultBuilderFactory() {
+
+        public CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+                        CompilationResult compilationResult) {
+            return new CompilationResultBuilder(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
+        }
+    };
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/FrameContext.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/FrameContext.java	Mon Dec 09 17:31:12 2013 +0100
@@ -35,7 +35,7 @@
      * <li>stack overflow checking</li>
      * </ul>
      */
-    void enter(TargetMethodAssembler tasm);
+    void enter(CompilationResultBuilder crb);
 
     /**
      * Emits code to be executed just prior to returning from a method. This may include:
@@ -45,5 +45,10 @@
      * <li>destroying the stack frame</li>
      * </ul>
      */
-    void leave(TargetMethodAssembler tasm);
+    void leave(CompilationResultBuilder crb);
+
+    /**
+     * Determines if a frame is set up and torn down by this object.
+     */
+    boolean hasFrame();
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Mon Dec 09 17:30:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, 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.graal.lir.asm;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-
-public class TargetMethodAssembler {
-
-    private static class ExceptionInfo {
-
-        public final int codeOffset;
-        public final LabelRef exceptionEdge;
-
-        public ExceptionInfo(int pcOffset, LabelRef exceptionEdge) {
-            this.codeOffset = pcOffset;
-            this.exceptionEdge = exceptionEdge;
-        }
-    }
-
-    public final AbstractAssembler asm;
-    public final CompilationResult compilationResult;
-    public final TargetDescription target;
-    public final CodeCacheProvider codeCache;
-    public final ForeignCallsProvider foreignCalls;
-    public final FrameMap frameMap;
-
-    /**
-     * The object that emits code for managing a method's frame. If null, no frame is used by the
-     * method.
-     */
-    public final FrameContext frameContext;
-
-    private List<ExceptionInfo> exceptionInfoList;
-
-    public TargetMethodAssembler(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
-                    CompilationResult compilationResult) {
-        this.target = codeCache.getTarget();
-        this.codeCache = codeCache;
-        this.foreignCalls = foreignCalls;
-        this.frameMap = frameMap;
-        this.asm = asm;
-        this.compilationResult = compilationResult;
-        this.frameContext = frameContext;
-    }
-
-    public void setFrameSize(int frameSize) {
-        compilationResult.setFrameSize(frameSize);
-    }
-
-    private static final CompilationResult.Mark[] NO_REFS = {};
-
-    public CompilationResult.Mark recordMark(Object id) {
-        return compilationResult.recordMark(asm.codeBuffer.position(), id, NO_REFS);
-    }
-
-    public CompilationResult.Mark recordMark(Object id, CompilationResult.Mark... references) {
-        return compilationResult.recordMark(asm.codeBuffer.position(), id, references);
-    }
-
-    public void blockComment(String s) {
-        compilationResult.addAnnotation(new CompilationResult.CodeComment(asm.codeBuffer.position(), s));
-    }
-
-    public CompilationResult finishTargetMethod(StructuredGraph graph) {
-        // Install code, data and frame size
-        compilationResult.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
-
-        // Record exception handlers if they exist
-        if (exceptionInfoList != null) {
-            for (ExceptionInfo ei : exceptionInfoList) {
-                int codeOffset = ei.codeOffset;
-                compilationResult.recordExceptionHandler(codeOffset, ei.exceptionEdge.label().position());
-            }
-        }
-
-        if (Debug.isMeterEnabled()) {
-            List<DataPatch> ldp = compilationResult.getDataReferences();
-            DebugMetric[] dms = new DebugMetric[Kind.values().length];
-            for (int i = 0; i < dms.length; i++) {
-                dms[i] = Debug.metric("DataPatches-" + Kind.values()[i].toString());
-            }
-            DebugMetric dmRaw = Debug.metric("DataPatches-raw");
-
-            for (DataPatch dp : ldp) {
-                if (dp.constant != null) {
-                    dms[dp.constant.getKind().ordinal()].add(1);
-                } else {
-                    dmRaw.add(1);
-                }
-            }
-
-            Debug.metric("TargetMethods").increment();
-            Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize());
-            Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size());
-            Debug.metric("DataPatches").add(ldp.size());
-            Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size());
-        }
-        Debug.log("Finished compiling %s", graph);
-        return compilationResult;
-    }
-
-    public void recordExceptionHandlers(int pcOffset, LIRFrameState info) {
-        if (info != null) {
-            if (info.exceptionEdge != null) {
-                if (exceptionInfoList == null) {
-                    exceptionInfoList = new ArrayList<>(4);
-                }
-                exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge));
-            }
-        }
-    }
-
-    public void recordImplicitException(int pcOffset, LIRFrameState info) {
-        // record an implicit exception point
-        if (info != null) {
-            compilationResult.recordInfopoint(pcOffset, info.debugInfo(), InfopointReason.IMPLICIT_EXCEPTION);
-            assert info.exceptionEdge == null;
-        }
-    }
-
-    public void recordDirectCall(int posBefore, int posAfter, InvokeTarget callTarget, LIRFrameState info) {
-        DebugInfo debugInfo = info != null ? info.debugInfo() : null;
-        compilationResult.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, true);
-    }
-
-    public void recordIndirectCall(int posBefore, int posAfter, InvokeTarget callTarget, LIRFrameState info) {
-        DebugInfo debugInfo = info != null ? info.debugInfo() : null;
-        compilationResult.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, false);
-    }
-
-    public void recordInfopoint(int pos, LIRFrameState info, InfopointReason reason) {
-        // infopoints always need debug info
-        DebugInfo debugInfo = info.debugInfo();
-        compilationResult.recordInfopoint(pos, debugInfo, reason);
-    }
-
-    public AbstractAddress recordDataReferenceInCode(Constant data, int alignment, boolean inlined) {
-        assert data != null;
-        int pos = asm.codeBuffer.position();
-        Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
-        compilationResult.recordDataReference(pos, data, alignment, inlined);
-        return asm.getPlaceholder();
-    }
-
-    public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) {
-        assert data != null;
-        int pos = asm.codeBuffer.position();
-        Debug.log("Raw data reference in code: pos = %d, data = %s", pos, data.toString());
-        compilationResult.recordDataReference(pos, data, alignment);
-        return asm.getPlaceholder();
-    }
-
-    /**
-     * Returns the integer value of any constant that can be represented by a 32-bit integer value,
-     * including long constants that fit into the 32-bit range.
-     */
-    public int asIntConst(Value value) {
-        assert (value.getKind().isNumericInteger()) && isConstant(value);
-        Constant constant = (Constant) value;
-        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
-        long c = constant.asLong();
-        if (!NumUtil.isInt(c)) {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-        return (int) c;
-    }
-
-    /**
-     * Returns the float value of any constant that can be represented by a 32-bit float value.
-     */
-    public float asFloatConst(Value value) {
-        assert (value.getKind().getStackKind() == Kind.Float && isConstant(value));
-        Constant constant = (Constant) value;
-        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
-        return constant.asFloat();
-    }
-
-    /**
-     * Returns the long value of any constant that can be represented by a 64-bit long value.
-     */
-    public long asLongConst(Value value) {
-        assert (value.getKind().getStackKind() == Kind.Long && isConstant(value));
-        Constant constant = (Constant) value;
-        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
-        return constant.asLong();
-    }
-
-    /**
-     * Returns the double value of any constant that can be represented by a 64-bit float value.
-     */
-    public double asDoubleConst(Value value) {
-        assert (value.getKind().getStackKind() == Kind.Double && isConstant(value));
-        Constant constant = (Constant) value;
-        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
-        return constant.asDouble();
-    }
-
-    /**
-     * Returns the address of a float constant that is embedded as a data reference into the code.
-     */
-    public AbstractAddress asFloatConstRef(Value value) {
-        return asFloatConstRef(value, 4);
-    }
-
-    public AbstractAddress asFloatConstRef(Value value, int alignment) {
-        assert value.getKind() == Kind.Float && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, alignment, false);
-    }
-
-    /**
-     * Returns the address of a double constant that is embedded as a data reference into the code.
-     */
-    public AbstractAddress asDoubleConstRef(Value value) {
-        return asDoubleConstRef(value, 8);
-    }
-
-    public AbstractAddress asDoubleConstRef(Value value, int alignment) {
-        assert value.getKind() == Kind.Double && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, alignment, false);
-    }
-
-    /**
-     * Returns the address of a long constant that is embedded as a data reference into the code.
-     */
-    public AbstractAddress asLongConstRef(Value value) {
-        assert value.getKind() == Kind.Long && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, 8, false);
-    }
-
-    /**
-     * Returns the address of an object constant that is embedded as a data reference into the code.
-     */
-    public AbstractAddress asObjectConstRef(Value value) {
-        assert value.getKind() == Kind.Object && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, 8, false);
-    }
-
-    public AbstractAddress asIntAddr(Value value) {
-        assert value.getKind() == Kind.Int;
-        return asAddress(value);
-    }
-
-    public AbstractAddress asLongAddr(Value value) {
-        assert value.getKind() == Kind.Long;
-        return asAddress(value);
-    }
-
-    public AbstractAddress asObjectAddr(Value value) {
-        assert value.getKind() == Kind.Object;
-        return asAddress(value);
-    }
-
-    public AbstractAddress asFloatAddr(Value value) {
-        assert value.getKind() == Kind.Float;
-        return asAddress(value);
-    }
-
-    public AbstractAddress asDoubleAddr(Value value) {
-        assert value.getKind() == Kind.Double;
-        return asAddress(value);
-    }
-
-    public AbstractAddress asAddress(Value value) {
-        assert isStackSlot(value);
-        StackSlot slot = asStackSlot(value);
-        return asm.makeAddress(frameMap.registerConfig.getFrameRegister(), frameMap.offsetForStackSlot(slot));
-    }
-}
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Mon Dec 09 17:31:12 2013 +0100
@@ -38,6 +38,9 @@
 
     // TODO (gd) change when inversion is available
     public static boolean shouldPeel(LoopEx loop, NodesToDoubles probabilities) {
+        if (loop.detectCounted()) {
+            return false;
+        }
         LoopBeginNode loopBegin = loop.loopBegin();
         double entryProbability = probabilities.get(loopBegin.forwardEnd());
         return entryProbability > MinimumPeelProbability.getValue() && loop.size() + loopBegin.graph().getNodeCount() < MaximumDesiredSize.getValue();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Mon Dec 09 17:31:12 2013 +0100
@@ -61,7 +61,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS || graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+        if (graph().getGuardsStage().ordinal() >= StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) {
             tool.getLowerer().lower(this, tool);
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Mon Dec 09 17:31:12 2013 +0100
@@ -47,12 +47,13 @@
     void registerSnippet(ResolvedJavaMethod method);
 
     /**
-     * Prepares the copy of a snippet graph immediately after instantiation. This can be used to do
-     * node intrinsification for example.
+     * Notifies this object during snippet specialization once the specialized snippet's constant
+     * parameters have been replaced with constant values.
      * 
-     * @param snippetCopy The copy of the snippet graph.
+     * @param specializedSnippet the snippet in the process of being specialized. This is a copy of
+     *            the unspecialized snippet graph created during snippet preparation.
      */
-    void prepareSnippetCopyAfterInstantiation(StructuredGraph snippetCopy);
+    void notifyAfterConstantsBound(StructuredGraph specializedSnippet);
 
     /**
      * Gets the graph that is a substitution for a given method.
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Dec 09 17:31:12 2013 +0100
@@ -1268,7 +1268,7 @@
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is marked non-inlinable");
         } else if (data.countRecursiveInlining(method) > MaximumRecursiveInlining.getValue()) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it exceeds the maximum recursive inlining depth");
-        } else if (new OptimisticOptimizations(method).lessOptimisticThan(optimisticOpts)) {
+        } else if (new OptimisticOptimizations(method.getProfilingInfo()).lessOptimisticThan(optimisticOpts)) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the callee uses less optimistic optimizations than caller");
         } else {
             return true;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Mon Dec 09 17:31:12 2013 +0100
@@ -192,12 +192,22 @@
      * 
      * @param node a node that was just lowered
      * @param preLoweringMark the graph mark before {@code node} was lowered
+     * @param unscheduledUsages set of {@code node}'s usages that were unscheduled before it was
+     *            lowered
      * @throws AssertionError if the check fails
      */
-    private static boolean checkPostNodeLowering(Node node, LoweringToolImpl loweringTool, Mark preLoweringMark) {
+    private static boolean checkPostNodeLowering(Node node, LoweringToolImpl loweringTool, Mark preLoweringMark, Collection<Node> unscheduledUsages) {
         StructuredGraph graph = (StructuredGraph) node.graph();
         Mark postLoweringMark = graph.getMark();
         NodeIterable<Node> newNodesAfterLowering = graph.getNewNodes(preLoweringMark);
+        if (node instanceof FloatingNode) {
+            if (!unscheduledUsages.isEmpty()) {
+                for (Node n : newNodesAfterLowering) {
+                    assert !(n instanceof FixedNode) : node.graph() + ": cannot lower floatable node " + node + " as it introduces fixed node(s) but has the following unscheduled usages: " +
+                                    unscheduledUsages;
+                }
+            }
+        }
         for (Node n : newNodesAfterLowering) {
             if (n instanceof Lowerable) {
                 ((Lowerable) n).lower(loweringTool);
@@ -280,13 +290,14 @@
                 }
 
                 if (node instanceof Lowerable) {
-                    assert checkUsagesAreScheduled(node);
+                    Collection<Node> unscheduledUsages = null;
+                    assert (unscheduledUsages = getUnscheduledUsages(node)) != null;
                     Mark preLoweringMark = node.graph().getMark();
                     ((Lowerable) node).lower(loweringTool);
                     if (node == startAnchor && node.isDeleted()) {
                         loweringTool.guardAnchor = BeginNode.prevBegin(nextNode);
                     }
-                    assert checkPostNodeLowering(node, loweringTool, preLoweringMark);
+                    assert checkPostNodeLowering(node, loweringTool, preLoweringMark, unscheduledUsages);
                 }
 
                 if (!nextNode.isAlive()) {
@@ -313,7 +324,7 @@
         }
 
         /**
-         * Checks that all usages of a floating, lowerable node are scheduled.
+         * Gets all usages of a floating, lowerable node that are unscheduled.
          * <p>
          * Given that the lowering of such nodes may introduce fixed nodes, they must be lowered in
          * the context of a usage that dominates all other usages. The fixed nodes resulting from
@@ -322,16 +333,19 @@
          * 
          * @param node a {@link Lowerable} node
          */
-        private boolean checkUsagesAreScheduled(Node node) {
+        private Collection<Node> getUnscheduledUsages(Node node) {
+            List<Node> unscheduledUsages = new ArrayList<>();
             if (node instanceof FloatingNode) {
                 for (Node usage : node.usages()) {
                     if (usage instanceof ScheduledNode) {
                         Block usageBlock = schedule.getCFG().blockFor(usage);
-                        assert usageBlock != null : node.graph() + ": cannot lower floatable node " + node + " that has non-scheduled usage " + usage;
+                        if (usageBlock == null) {
+                            unscheduledUsages.add(usage);
+                        }
                     }
                 }
             }
-            return true;
+            return unscheduledUsages;
         }
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Mon Dec 09 17:31:12 2013 +0100
@@ -244,9 +244,6 @@
 
     // Runtime settings
     @Option(help = "")
-    public static final OptionValue<Integer> StackShadowPages = new OptionValue<>(2);
-
-    @Option(help = "")
     public static final OptionValue<Boolean> SupportJsrBytecodes = new OptionValue<>(true);
 
     @Option(help = "")
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Mon Dec 09 17:31:12 2013 +0100
@@ -39,19 +39,19 @@
 
     private final Set<Optimization> enabledOpts;
 
-    public OptimisticOptimizations(ResolvedJavaMethod method) {
+    public OptimisticOptimizations(ProfilingInfo info) {
         this.enabledOpts = EnumSet.noneOf(Optimization.class);
 
         enabledOpts.add(Optimization.UseExceptionProbabilityForOperations);
-        addOptimization(method, DeoptimizationReason.UnreachedCode, Optimization.RemoveNeverExecutedCode);
-        addOptimization(method, DeoptimizationReason.TypeCheckedInliningViolated, Optimization.UseTypeCheckedInlining);
-        addOptimization(method, DeoptimizationReason.OptimizedTypeCheckViolated, Optimization.UseTypeCheckHints);
-        addOptimization(method, DeoptimizationReason.NotCompiledExceptionHandler, Optimization.UseExceptionProbability);
-        addOptimization(method, DeoptimizationReason.LoopLimitCheck, Optimization.UseLoopLimitChecks);
+        addOptimization(info, DeoptimizationReason.UnreachedCode, Optimization.RemoveNeverExecutedCode);
+        addOptimization(info, DeoptimizationReason.TypeCheckedInliningViolated, Optimization.UseTypeCheckedInlining);
+        addOptimization(info, DeoptimizationReason.OptimizedTypeCheckViolated, Optimization.UseTypeCheckHints);
+        addOptimization(info, DeoptimizationReason.NotCompiledExceptionHandler, Optimization.UseExceptionProbability);
+        addOptimization(info, DeoptimizationReason.LoopLimitCheck, Optimization.UseLoopLimitChecks);
     }
 
-    private void addOptimization(ResolvedJavaMethod method, DeoptimizationReason deoptReason, Optimization optimization) {
-        if (checkDeoptimizations(method.getProfilingInfo(), deoptReason)) {
+    private void addOptimization(ProfilingInfo info, DeoptimizationReason deoptReason, Optimization optimization) {
+        if (checkDeoptimizations(info, deoptReason)) {
             enabledOpts.add(optimization);
         } else {
             disabledOptimisticOptsMetric.increment();
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.phases.tiers;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 
@@ -30,11 +31,13 @@
 
     private final TargetDescription target;
     private final OptimisticOptimizations optimisticOpts;
+    private final ProfilingInfo profilingInfo;
 
-    public MidTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target, OptimisticOptimizations optimisticOpts) {
+    public MidTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo) {
         super(copyFrom, assumptions);
         this.target = target;
         this.optimisticOpts = optimisticOpts;
+        this.profilingInfo = profilingInfo;
     }
 
     public TargetDescription getTarget() {
@@ -44,4 +47,8 @@
     public OptimisticOptimizations getOptimisticOptimizations() {
         return optimisticOpts;
     }
+
+    public ProfilingInfo getProfilingInfo() {
+        return profilingInfo;
+    }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Mon Dec 09 17:31:12 2013 +0100
@@ -36,7 +36,7 @@
 @ClassSubstitution(java.lang.Math.class)
 public class MathSubstitutionsX86 {
 
-    private static final double PI_4 = 0.7853981633974483;
+    private static final double PI_4 = Math.PI / 4;
 
     @MethodSubstitution
     public static double abs(double x) {
@@ -58,6 +58,49 @@
         return MathIntrinsicNode.compute(x, Operation.LOG10);
     }
 
+    /**
+     * Special cases from {@link Math#pow} and __ieee754_pow (in sharedRuntimeTrans.cpp).
+     */
+    @MethodSubstitution
+    public static double pow(double x, double y) {
+        // If the second argument is positive or negative zero, then the result is 1.0.
+        if (y == 0) {
+            return 1;
+        }
+
+        // If the second argument is 1.0, then the result is the same as the first argument.
+        if (y == 1) {
+            return x;
+        }
+
+        // If the second argument is NaN, then the result is NaN.
+        if (Double.isNaN(y)) {
+            return Double.NaN;
+        }
+
+        // If the first argument is NaN and the second argument is nonzero, then the result is NaN.
+        if (Double.isNaN(x) && y != 0) {
+            return Double.NaN;
+        }
+
+        // x**-1 = 1/x
+        if (y == -1) {
+            return 1 / x;
+        }
+
+        // x**2 = x*x
+        if (y == 2) {
+            return x * x;
+        }
+
+        // x**0.5 = sqrt(x)
+        if (y == 0.5 && x >= 0) {
+            return sqrt(x);
+        }
+
+        return pow(x, y);
+    }
+
     // NOTE on snippets below:
     // Math.sin(), .cos() and .tan() guarantee a value within 1 ULP of the
     // exact result, but x87 trigonometric FPU instructions are only that
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Dec 09 17:31:12 2013 +0100
@@ -110,13 +110,13 @@
     }
 
     @Override
-    public void prepareSnippetCopyAfterInstantiation(StructuredGraph snippetCopy) {
+    public void notifyAfterConstantsBound(StructuredGraph specializedSnippet) {
 
         // Do deferred intrinsification of node intrinsics
 
-        new NodeIntrinsificationPhase(providers).apply(snippetCopy);
-        new CanonicalizerPhase(true).apply(snippetCopy, new PhaseContext(providers, assumptions));
-        NodeIntrinsificationVerificationPhase.verify(snippetCopy);
+        new NodeIntrinsificationPhase(providers).apply(specializedSnippet);
+        new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers, assumptions));
+        NodeIntrinsificationVerificationPhase.verify(specializedSnippet);
     }
 
     @Override
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Dec 09 17:31:12 2013 +0100
@@ -511,7 +511,7 @@
 
         Debug.dump(snippetCopy, "Before specialization");
         if (!nodeReplacements.isEmpty()) {
-            providers.getReplacements().prepareSnippetCopyAfterInstantiation(snippetCopy);
+            providers.getReplacements().notifyAfterConstantsBound(snippetCopy);
         }
 
         // Gather the template parameters
--- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackend.java	Mon Dec 09 17:30:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2013, 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.graal.truffle.hotspot.amd64;
-
-import com.oracle.graal.amd64.*;
-import com.oracle.graal.api.code.CallingConvention.Type;
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.amd64.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.hotspot.amd64.util.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Backend that decorates an existing {@link AMD64HotSpotBackend}, injecting special code into
- * {@link OptimizedCallTarget#call(PackedFrame, Arguments)} for making a tail-call to the entry
- * point of the target callee.
- */
-class AMD64HotSpotTruffleBackend extends Backend {
-
-    private final AMD64HotSpotBackend original;
-
-    private HotSpotResolvedJavaMethod optimizedCallTargetCall;
-
-    public AMD64HotSpotTruffleBackend(AMD64HotSpotBackend original) {
-        super(original.getProviders());
-        this.original = original;
-    }
-
-    private ResolvedJavaMethod getInstrumentedMethod() throws GraalInternalError {
-        if (optimizedCallTargetCall == null) {
-            try {
-                optimizedCallTargetCall = (HotSpotResolvedJavaMethod) getProviders().getMetaAccess().lookupJavaMethod(
-                                OptimizedCallTarget.class.getDeclaredMethod("call", PackedFrame.class, Arguments.class));
-                optimizedCallTargetCall.setDontInline();
-            } catch (NoSuchMethodException | SecurityException e) {
-                throw new GraalInternalError(e);
-            }
-        }
-        return optimizedCallTargetCall;
-    }
-
-    @Override
-    public SuitesProvider getSuites() {
-        return original.getSuites();
-    }
-
-    @Override
-    public DisassemblerProvider getDisassembler() {
-        return original.getDisassembler();
-    }
-
-    @Override
-    public FrameMap newFrameMap() {
-        return original.newFrameMap();
-    }
-
-    @Override
-    public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return original.newLIRGenerator(graph, frameMap, cc, lir);
-    }
-
-    @Override
-    protected AbstractAssembler createAssembler(FrameMap frameMap) {
-        return null;
-    }
-
-    @Override
-    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
-        return original.newAssembler(lirGen, compilationResult);
-    }
-
-    @Override
-    public boolean shouldAllocateRegisters() {
-        return original.shouldAllocateRegisters();
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) {
-        AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
-        FrameMap frameMap = tasm.frameMap;
-        RegisterConfig regConfig = frameMap.registerConfig;
-        HotSpotVMConfig config = original.getRuntime().getConfig();
-        Label verifiedStub = new Label();
-
-        // Emit the prefix
-        original.emitCodePrefix(installedCodeOwner, tasm, asm, regConfig, config, verifiedStub);
-
-        if (getInstrumentedMethod().equals(installedCodeOwner)) {
-            // Inject code for {@link OptimizedCallTarget#call(PackedFrame, Arguments)}
-            injectCode(asm, config);
-        }
-
-        // Emit code for the LIR
-        original.emitCodeBody(installedCodeOwner, tasm, lirGen);
-
-        // Emit the suffix
-        original.emitCodeSuffix(installedCodeOwner, tasm, lirGen, asm, frameMap);
-    }
-
-    private void injectCode(AMD64MacroAssembler asm, HotSpotVMConfig config) {
-        HotSpotProviders providers = original.getRuntime().getHostProviders();
-        Register thisRegister = providers.getCodeCache().getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, Kind.Object)[0];
-        Register spillRegister = AMD64.r10; // TODO(mg): fix me
-        AMD64Address nMethodAddress = new AMD64Address(thisRegister, OptimizedCallTargetFieldInfo.getCompiledMethodFieldOffset());
-        if (config.useCompressedOops) {
-            asm.movl(spillRegister, nMethodAddress);
-            AMD64HotSpotMove.decodePointer(asm, spillRegister, providers.getRegisters().getHeapBaseRegister(), config.narrowOopBase, config.narrowOopShift, config.logMinObjAlignment());
-        } else {
-            asm.movq(spillRegister, nMethodAddress);
-        }
-        Label doProlog = new Label();
-
-        asm.cmpq(spillRegister, 0);
-        asm.jcc(ConditionFlag.Equal, doProlog);
-
-        AMD64Address codeBlobAddress = new AMD64Address(spillRegister, OptimizedCallTargetFieldInfo.getCodeBlobFieldOffset());
-        asm.movq(spillRegister, codeBlobAddress);
-        asm.cmpq(spillRegister, 0);
-        asm.jcc(ConditionFlag.Equal, doProlog);
-
-        AMD64Address verifiedEntryPointAddress = new AMD64Address(spillRegister, config.nmethodEntryOffset);
-        asm.movq(spillRegister, verifiedEntryPointAddress);
-        asm.jmp(spillRegister);
-
-        asm.bind(doProlog);
-    }
-}
--- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackendFactory.java	Mon Dec 09 17:30:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013, 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.graal.truffle.hotspot.amd64;
-
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.amd64.*;
-import com.oracle.graal.truffle.*;
-
-/**
- * Factory to create a Truffle-specialized AMD64 HotSpot backend.
- */
-@ServiceProvider(TruffleBackendFactory.class)
-public class AMD64HotSpotTruffleBackendFactory implements TruffleBackendFactory {
-
-    @Override
-    public Backend createBackend(Backend original) {
-        return new AMD64HotSpotTruffleBackend((AMD64HotSpotBackend) original);
-    }
-
-    public String getArchitecture() {
-        return "AMD64";
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013, 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.graal.truffle.hotspot.amd64;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.amd64.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.graal.truffle.hotspot.*;
+
+@ServiceProvider(OptimizedCallTargetInstrumentationFactory.class)
+public class AMD64OptimizedCallTargetInstrumentationFactory implements OptimizedCallTargetInstrumentationFactory {
+
+    public CompilationResultBuilder createBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+                    CompilationResult compilationResult) {
+        return new OptimizedCallTargetInstrumentation(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult) {
+            @Override
+            protected void injectTailCallCode(HotSpotVMConfig config, HotSpotRegistersProvider registers) {
+                @SuppressWarnings("hiding")
+                AMD64MacroAssembler asm = (AMD64MacroAssembler) this.asm;
+                Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, Kind.Object)[0];
+                Register spillRegister = AMD64.r10; // TODO(mg): fix me
+                AMD64Address nMethodAddress = new AMD64Address(thisRegister, getFieldOffset("installedCode", OptimizedCallTarget.class));
+                int verifiedEntryPoint = asm.codeBuffer.position();
+                if (config.useCompressedOops) {
+                    asm.movl(spillRegister, nMethodAddress);
+                    asm.nop(AMD64HotSpotBackend.PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE - (asm.codeBuffer.position() - verifiedEntryPoint));
+                    AMD64HotSpotMove.decodePointer(asm, spillRegister, registers.getHeapBaseRegister(), config.narrowOopBase, config.narrowOopShift, config.logMinObjAlignment());
+                } else {
+                    asm.movq(spillRegister, nMethodAddress);
+                    asm.nop(AMD64HotSpotBackend.PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE - (asm.codeBuffer.position() - verifiedEntryPoint));
+                }
+                Label doProlog = new Label();
+
+                asm.cmpq(spillRegister, 0);
+                asm.jcc(ConditionFlag.Equal, doProlog);
+
+                AMD64Address codeBlobAddress = new AMD64Address(spillRegister, getFieldOffset("codeBlob", HotSpotInstalledCode.class));
+                asm.movq(spillRegister, codeBlobAddress);
+                asm.cmpq(spillRegister, 0);
+                asm.jcc(ConditionFlag.Equal, doProlog);
+
+                AMD64Address verifiedEntryPointAddress = new AMD64Address(spillRegister, config.nmethodEntryOffset);
+                asm.movq(spillRegister, verifiedEntryPointAddress);
+                asm.jmp(spillRegister);
+
+                asm.bind(doProlog);
+            }
+        };
+    }
+
+    public void setInstrumentedMethod(ResolvedJavaMethod method) {
+        HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
+        hsMethod.setDontInline();
+    }
+
+    public String getArchitecture() {
+        return "AMD64";
+    }
+}
--- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/util/OptimizedCallTargetFieldInfo.java	Mon Dec 09 17:30:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013, 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.graal.truffle.hotspot.amd64.util;
-
-import java.lang.reflect.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.truffle.*;
-
-public class OptimizedCallTargetFieldInfo {
-
-    private static final Unsafe unsafe = UnsafeAccess.unsafe;
-    private static int compiledMethodFieldOffset = -1;
-    private static int codeBlobFieldOffset = -1;
-
-    public static int getCodeBlobFieldOffset() {
-        if (codeBlobFieldOffset == -1) {
-            codeBlobFieldOffset = getFieldOffset("codeBlob", HotSpotInstalledCode.class);
-        }
-        return codeBlobFieldOffset;
-    }
-
-    public static int getCompiledMethodFieldOffset() {
-        if (compiledMethodFieldOffset == -1) {
-            compiledMethodFieldOffset = getFieldOffset("installedCode", OptimizedCallTarget.class);
-        }
-        return compiledMethodFieldOffset;
-
-    }
-
-    private static int getFieldOffset(String name, Class container) {
-        try {
-            container.getDeclaredField(name).setAccessible(true);
-            Field field = container.getDeclaredField(name);
-            return (int) unsafe.objectFieldOffset(field);
-        } catch (NoSuchFieldException | SecurityException e) {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013, 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.graal.truffle.hotspot;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * Mechanism for injecting special code into
+ * {@link OptimizedCallTarget#call(PackedFrame, Arguments)} .
+ */
+public abstract class OptimizedCallTargetInstrumentation extends CompilationResultBuilder {
+
+    public OptimizedCallTargetInstrumentation(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+                    CompilationResult compilationResult) {
+        super(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
+    }
+
+    @Override
+    public Mark recordMark(Object id) {
+        Mark mark = super.recordMark(id);
+        if (Integer.valueOf(Marks.MARK_VERIFIED_ENTRY).equals(id)) {
+            HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
+            HotSpotRegistersProvider registers = HotSpotGraalRuntime.runtime().getHostProviders().getRegisters();
+            injectTailCallCode(config, registers);
+        }
+        return mark;
+    }
+
+    protected static int getFieldOffset(String name, Class declaringClass) {
+        try {
+            declaringClass.getDeclaredField(name).setAccessible(true);
+            Field field = declaringClass.getDeclaredField(name);
+            return (int) UnsafeAccess.unsafe.objectFieldOffset(field);
+        } catch (NoSuchFieldException | SecurityException e) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    /**
+     * Injects code into the verified entry point of that makes a tail-call to the target callee.
+     */
+    protected abstract void injectTailCallCode(HotSpotVMConfig config, HotSpotRegistersProvider registers);
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.truffle;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
 import java.lang.reflect.*;
@@ -32,10 +33,12 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
@@ -160,8 +163,12 @@
     public static void installOptimizedCallTargetCallMethod() {
         Providers providers = getGraalProviders();
         MetaAccessProvider metaAccess = providers.getMetaAccess();
+        CodeCacheProvider codeCache = providers.getCodeCache();
         ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod());
-        providers.getCodeCache().setDefaultMethod(resolvedCallMethod, compileMethod(resolvedCallMethod));
+        CompilationResult compResult = compileMethod(resolvedCallMethod);
+        try (Scope s = Debug.scope("CodeInstall", codeCache, resolvedCallMethod)) {
+            codeCache.setDefaultMethod(resolvedCallMethod, compResult);
+        }
     }
 
     private static Method getCallMethod() {
@@ -174,16 +181,15 @@
         return method;
     }
 
-    private static Backend instrumentBackend(Backend original) {
-        String arch = original.getTarget().arch.getName();
-
-        for (TruffleBackendFactory factory : ServiceLoader.loadInstalled(TruffleBackendFactory.class)) {
+    private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) {
+        for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) {
             if (factory.getArchitecture().equals(arch)) {
-                return factory.createBackend(original);
+                factory.setInstrumentedMethod(method);
+                return factory;
             }
         }
-
-        return original;
+        // No specialization of OptimizedCallTarget on this platform.
+        return CompilationResultBuilderFactory.Default;
     }
 
     private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) {
@@ -199,8 +205,9 @@
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
         Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
-        return GraalCompiler.compileGraph(graph, cc, javaMethod, providers, instrumentBackend(backend), providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
-                        new SpeculationLog(), suites, new CompilationResult());
+        CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod);
+        return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, getProfilingInfo(graph),
+                        new SpeculationLog(), suites, true, new CompilationResult(), factory);
     }
 
     private static Providers getGraalProviders() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Dec 09 17:31:12 2013 +0100
@@ -79,8 +79,9 @@
         if (installedCode != null && installedCode.isValid()) {
             TruffleRuntime runtime = Truffle.getRuntime();
             if (runtime instanceof GraalTruffleRuntime) {
-                OUT.printf("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
-                OUT.println();
+                if (TraceTruffleCompilation.getValue()) {
+                    OUT.println("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut.");
+                }
                 GraalTruffleRuntime.installOptimizedCallTargetCallMethod();
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, 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.graal.truffle;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * A service for creating a specialized {@link CompilationResultBuilder} used to inject code into
+ * {@link OptimizedCallTarget#call(PackedFrame, Arguments)}.
+ */
+public interface OptimizedCallTargetInstrumentationFactory extends CompilationResultBuilderFactory {
+
+    /**
+     * Gets the architecture supported by this factory.
+     */
+    String getArchitecture();
+
+    /**
+     * Notifies this object of the method that is being instrumented.
+     */
+    void setInstrumentedMethod(ResolvedJavaMethod method);
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Dec 09 17:31:12 2013 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.truffle;
 
-import static com.oracle.graal.compiler.GraalDebugConfig.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
@@ -88,12 +87,11 @@
         }
     }
 
-    public StructuredGraph createGraph(final OptimizedCallTarget node, final Assumptions assumptions) {
-        if (Dump.getValue() != null && Dump.getValue().contains("Truffle")) {
-            RootNode root = node.getRootNode();
-            if (root != null) {
-                new GraphPrintVisitor().beginGroup("TruffleGraph").beginGraph(node.toString()).visit(root).printToNetwork();
-            }
+    public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions) {
+        try (Scope s = Debug.scope("TruffleTree")) {
+            Debug.dump(callTarget, "truffle tree");
+        } catch (Throwable e) {
+            throw Debug.handle(e);
         }
 
         if (TraceTruffleCompilationDetails.getValue()) {
@@ -110,7 +108,7 @@
 
             // Replace thisNode with constant.
             LocalNode thisNode = graph.getLocal(0);
-            thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph));
+            thisNode.replaceAndDelete(ConstantNode.forObject(callTarget, providers.getMetaAccess(), graph));
 
             // Canonicalize / constant propagate.
             PhaseContext baseContext = new PhaseContext(providers, assumptions);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleBackendFactory.java	Mon Dec 09 17:30:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2013, 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.graal.truffle;
-
-import com.oracle.graal.compiler.target.*;
-
-public interface TruffleBackendFactory {
-
-    Backend createBackend(Backend original);
-
-    /**
-     * Gets the CPU architecture of this backend.
-     */
-    String getArchitecture();
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Mon Dec 09 17:31:12 2013 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.truffle;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
 import java.io.*;
@@ -41,6 +42,7 @@
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.java.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
@@ -85,7 +87,13 @@
         // Create compilation queue.
         CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new DebugConfigAccess() {
             public GraalDebugConfig getDebugConfig() {
-                return Debug.isEnabled() ? DebugEnvironment.initialize(TTY.out().out()) : null;
+                if (Debug.isEnabled()) {
+                    GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
+                    debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
+                    return debugConfig;
+                } else {
+                    return null;
+                }
             }
         });
         compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
@@ -215,8 +223,8 @@
             CodeCacheProvider codeCache = providers.getCodeCache();
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(graph.method().toString());
-            result = GraalCompiler.compileGraphNoScope(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), suites,
-                            compilationResult);
+            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, getProfilingInfo(graph), new SpeculationLog(), suites,
+                            false, compilationResult, CompilationResultBuilderFactory.Default);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -237,25 +245,21 @@
 
         result.setAssumptions(newAssumptions);
 
-        InstalledCode compiledMethod = null;
+        InstalledCode installedCode = null;
         try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start()) {
-            InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result);
-            if (installedCode != null) {
-                Debug.dump(new Object[]{result, installedCode}, "After code installation");
-            }
-            compiledMethod = installedCode;
+            installedCode = providers.getCodeCache().addMethod(graph.method(), result);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
 
         for (AssumptionValidAssumption a : validAssumptions) {
-            a.getAssumption().registerInstalledCode(compiledMethod);
+            a.getAssumption().registerInstalledCode(installedCode);
         }
 
         if (Debug.isLogEnabled()) {
-            Debug.log(providers.getCodeCache().disassemble(result, compiledMethod));
+            Debug.log(providers.getCodeCache().disassemble(result, installedCode));
         }
-        return compiledMethod;
+        return installedCode;
     }
 
     private PhasePlan createPhasePlan(final GraphBuilderConfiguration config) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java	Mon Dec 09 17:31:12 2013 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 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.graal.truffle;
+
+import com.oracle.graal.debug.*;
+import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.nodes.*;
+
+public class TruffleTreeDumpHandler implements DebugDumpHandler {
+
+    @Override
+    public void dump(Object object, final String message) {
+        if (object instanceof DefaultCallTarget) {
+            DefaultCallTarget callTarget = (DefaultCallTarget) object;
+            if (callTarget.getRootNode() != null) {
+                new GraphPrintVisitor().beginGroup(callTarget.toString()).beginGraph(message).visit(callTarget.getRootNode()).printToNetwork();
+            }
+        }
+    }
+
+    public void close() {
+        // nothing to do
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Mon Dec 09 17:31:12 2013 +0100
@@ -136,6 +136,10 @@
 
     @Override
     public void virtualize(VirtualizerTool tool) {
+        if (!descriptor.isConstant()) {
+            return;
+        }
+
         int frameSize = getFrameSize();
 
         ResolvedJavaType frameType = stamp().javaType(tool.getMetaAccessProvider());
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon Dec 09 17:31:12 2013 +0100
@@ -96,6 +96,7 @@
             if (n instanceof PhiNode || n instanceof ProxyNode) {
                 ValueNode node = (ValueNode) n;
                 if (node.kind() == Kind.Object) {
+                    assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
                     node.setStamp(StampFactory.illegal(node.kind()));
                 }
             }
@@ -129,9 +130,9 @@
 
     private static boolean checkNoIllegalStamp(StructuredGraph graph) {
         for (Node n : graph.getNodes()) {
-            if (n instanceof ValueNode) {
+            if (n instanceof PhiNode || n instanceof ProxyNode) {
                 ValueNode node = (ValueNode) n;
-                assert !(node.stamp() instanceof IllegalStamp);
+                assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
             }
         }
         return true;
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImplicitCast.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImplicitCast.java	Mon Dec 09 17:31:12 2013 +0100
@@ -26,10 +26,6 @@
 
 import java.lang.annotation.*;
 
-/**
- * EXPERIMENTAL Filter feature. May change or disappear without notice. This feature is not
- * functional yet.
- */
 @Retention(RetentionPolicy.CLASS)
 @Target({ElementType.METHOD})
 public @interface ImplicitCast {
--- a/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Mon Dec 09 17:30:50 2013 +0100
+++ b/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Mon Dec 09 17:31:12 2013 +0100
@@ -23,9 +23,9 @@
 org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
 org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=${javaCompliance}
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=${javaCompliance}
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -39,7 +39,7 @@
 org.eclipse.jdt.core.compiler.problem.deprecation=warning
 org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
 org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
 org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
 org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
@@ -48,7 +48,7 @@
 org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
 org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
 org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=ignore
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore
 org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
 org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
 org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
@@ -125,7 +125,7 @@
 org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
 org.eclipse.jdt.core.compiler.processAnnotations=disabled
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=${javaCompliance}
 org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
 org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
 org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
--- a/mx/mx_graal.py	Mon Dec 09 17:30:50 2013 +0100
+++ b/mx/mx_graal.py	Mon Dec 09 17:31:12 2013 +0100
@@ -981,6 +981,10 @@
 
     for vmbuild in ['fastdebug', 'product']:
         for test in sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Gate, gateBuildLevel=vmbuild):
+            if 'eclipse' in str(test) and mx.java().version >= mx.JavaVersion('1.8'):
+                # DaCapo eclipse doesn't not run under JDK8
+                continue
+
             t = Task(str(test) + ':' + vmbuild)
             if not test.test('graal'):
                 t.abort(test.name + ' Failed')
@@ -1132,11 +1136,18 @@
 
 def igv(args):
     """run the Ideal Graph Visualizer"""
+    env = os.environ.copy()
+    if mx.java().version >= mx.JavaVersion('1.8'):
+        jdk7 = mx.get_env('JAVA7_HOME', None)
+        if jdk7:
+            env['JAVA_HOME'] = jdk7
+        else:
+            mx.abort('IGV does not yet work with JDK 8. Use --java-home to specify a JDK 7 when launching the IGV')
     with open(join(_graal_home, '.ideal_graph_visualizer.log'), 'w') as fp:
         mx.logv('[Ideal Graph Visualizer log is in ' + fp.name + ']')
         if not exists(join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'nbplatform')):
             mx.logv('[This initial execution may take a while as the NetBeans platform needs to be downloaded]')
-        mx.run(['ant', '-f', join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml'), '-l', fp.name, 'run'])
+        mx.run(['ant', '-f', join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml'), '-l', fp.name, 'run'], env=env)
 
 def bench(args):
     """run benchmarks and parse their output for results
--- a/mx/projects	Mon Dec 09 17:30:50 2013 +0100
+++ b/mx/projects	Mon Dec 09 17:31:12 2013 +0100
@@ -153,7 +153,7 @@
 # graal.hotspot.ptx
 project@com.oracle.graal.hotspot.ptx@subDir=graal
 project@com.oracle.graal.hotspot.ptx@sourceDirs=src
-project@com.oracle.graal.hotspot.ptx@dependencies=com.oracle.graal.ptx,com.oracle.graal.compiler.ptx
+project@com.oracle.graal.hotspot.ptx@dependencies=com.oracle.graal.ptx,com.oracle.graal.compiler.ptx,com.oracle.graal.hotspot
 project@com.oracle.graal.hotspot.ptx@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.ptx@annotationProcessors=com.oracle.graal.service.processor
 project@com.oracle.graal.hotspot.ptx@javaCompliance=1.7
@@ -403,7 +403,7 @@
 # graal.compiler.ptx
 project@com.oracle.graal.compiler.ptx@subDir=graal
 project@com.oracle.graal.compiler.ptx@sourceDirs=src
-project@com.oracle.graal.compiler.ptx@dependencies=com.oracle.graal.lir.ptx,com.oracle.graal.hotspot
+project@com.oracle.graal.compiler.ptx@dependencies=com.oracle.graal.lir.ptx,com.oracle.graal.compiler
 project@com.oracle.graal.compiler.ptx@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler.ptx@javaCompliance=1.7
 project@com.oracle.graal.compiler.ptx@workingSets=Graal,PTX
@@ -667,10 +667,19 @@
 project@com.oracle.graal.truffle.test@javaCompliance=1.7
 project@com.oracle.graal.truffle.test@workingSets=Graal,Truffle,Test
 
+# graal.truffle.hotspot
+project@com.oracle.graal.truffle.hotspot@subDir=graal
+project@com.oracle.graal.truffle.hotspot@sourceDirs=src
+project@com.oracle.graal.truffle.hotspot@dependencies=com.oracle.graal.truffle,com.oracle.graal.hotspot
+project@com.oracle.graal.truffle.hotspot@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.truffle.hotspot@javaCompliance=1.7
+project@com.oracle.graal.truffle.hotspot@annotationProcessors=com.oracle.graal.service.processor
+project@com.oracle.graal.truffle.hotspot@workingSets=Graal,Truffle
+
 # graal.truffle.hotspot.amd64
 project@com.oracle.graal.truffle.hotspot.amd64@subDir=graal
 project@com.oracle.graal.truffle.hotspot.amd64@sourceDirs=src
-project@com.oracle.graal.truffle.hotspot.amd64@dependencies=com.oracle.graal.truffle,com.oracle.graal.hotspot.amd64
+project@com.oracle.graal.truffle.hotspot.amd64@dependencies=com.oracle.graal.truffle.hotspot,com.oracle.graal.hotspot.amd64
 project@com.oracle.graal.truffle.hotspot.amd64@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.truffle.hotspot.amd64@javaCompliance=1.7
 project@com.oracle.graal.truffle.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor
--- a/mxtool/mx.py	Mon Dec 09 17:30:50 2013 +0100
+++ b/mxtool/mx.py	Mon Dec 09 17:31:12 2013 +0100
@@ -2011,7 +2011,7 @@
                 log('Compiling Java sources for {0} with javac...'.format(p.name))
 
 
-                javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', compliance, '-classpath', cp, '-d', outputDir]
+                javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', compliance, '-target', compliance, '-classpath', cp, '-d', outputDir]
                 if java().debug_port is not None:
                     javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)]
                 javacCmd += processorArgs
@@ -2251,7 +2251,7 @@
 
     for pyfile in pyfiles:
         log('Running pylint on ' + pyfile + '...')
-        run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env, nonZeroIsFatal=False)
+        run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env)
 
 def archive(args):
     """create jar files for projects and distributions"""
@@ -2832,13 +2832,23 @@
     generate_eclipse_workingsets()
 
 def _check_ide_timestamp(suite, timestamp):
-    """return True if and only if the projects file, imports file, and mx itself are all older than timestamp"""
+    """return True if and only if the projects file, imports file, eclipse-settings files, and mx itself are all older than timestamp"""
     projectsFile = join(suite.mxDir, 'projects')
-    projectsFileOlder = not timestamp.isOlderThan(projectsFile)
-    importsFileOlder = not timestamp.isOlderThan(suite.import_timestamp())
+    if timestamp.isOlderThan(projectsFile):
+        return False
+    if timestamp.isOlderThan(suite.import_timestamp()):
+        return False
     # Assume that any mx change might imply changes to the generated IDE files
-    mxOlder = not timestamp.isOlderThan(__file__)
-    return projectsFileOlder and importsFileOlder and mxOlder
+    if timestamp.isOlderThan(__file__):
+        return False
+
+    eclipseSettingsDir = join(suite.mxDir, 'eclipse-settings')
+    if exists(eclipseSettingsDir):
+        for name in os.listdir(eclipseSettingsDir):
+            path = join(eclipseSettingsDir, name)
+            if timestamp.isOlderThan(path):
+                return False
+    return True
 
 def _eclipseinit_suite(args, suite, buildProcessorJars=True, refreshOnly=False):
     timestamp = TimeStampFile(join(suite.mxDir, 'eclipseinit.timestamp'))
@@ -2881,7 +2891,7 @@
             out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'})
 
         # Every Java program depends on the JRE
-        out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'})
+        out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)})
 
         if exists(join(p.dir, 'plugin.xml')):  # eclipse plugin project
             out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'})
--- a/src/cpu/x86/vm/nativeInst_x86.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/cpu/x86/vm/nativeInst_x86.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -472,6 +472,7 @@
 //
 // In C2 the 5+ byte sized instruction is enforced by code in MachPrologNode::emit.
 // In C1 the restriction is enforced by CodeEmitter::method_entry
+// In Graal, the restriction is enforced by HotSpotFrameContext.enter(...)
 //
 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
   // complete jump instruction (to be inserted) is in code_buffer;
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -207,6 +207,7 @@
   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
   __ restore_bcp();
   __ restore_locals();
+#ifdef GRAAL
   // Check if we need to take lock at entry of synchronized method.
   {
     Label L;
@@ -220,6 +221,7 @@
     lock_method();
     __ bind(L);
   }
+#endif
   // handle exceptions
   {
     Label L;
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java	Mon Dec 09 17:31:12 2013 +0100
@@ -73,7 +73,7 @@
         try {
             serverSocket = ServerSocketChannel.open();
             serverSocket.bind(new InetSocketAddress(curPort));
-        } catch (IOException ex) {
+        } catch (Throwable ex) {
             NotifyDescriptor message = new NotifyDescriptor.Message("Could not create server. Listening for incoming binary data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
             DialogDisplayer.getDefault().notifyLater(message);
             return;
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -355,7 +355,7 @@
   template(compileTheWorld_name,                  "compileTheWorld")                                                                  \
   template(shutdownCompiler_name,                 "shutdownCompiler")                                                                 \
   template(compileMethod_name,                    "compileMethod")                                                                    \
-  template(compileMethod_signature,               "(JLcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;IZ)V")                  \
+  template(compileMethod_signature,               "(JIZ)V")                                                                           \
   template(setOption_name,                        "setOption")                                                                        \
   template(setOption_signature,                   "(Ljava/lang/String;)Z")                                                            \
   template(finalizeOptions_name,                  "finalizeOptions")                                                                  \
@@ -375,14 +375,6 @@
   template(createPrimitiveJavaType_signature,     "(I)Lcom/oracle/graal/api/meta/JavaType;")                                          \
   template(createLocalImpl_name,                  "createLocalImpl")                                                                  \
   template(createLocalImpl_signature,             "(Ljava/lang/String;Ljava/lang/String;Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;III)Lcom/oracle/graal/hotspot/debug/LocalImpl;") \
-  template(createConstant_name,                   "createConstant")                                                                   \
-  template(createConstant_signature,              "(Lcom/oracle/graal/api/meta/Kind;J)Lcom/oracle/graal/api/meta/Constant;")          \
-  template(createConstantFloat_name,              "createConstantFloat")                                                              \
-  template(createConstantFloat_signature,         "(F)Lcom/oracle/graal/api/meta/Constant;")                                          \
-  template(createConstantDouble_name,             "createConstantDouble")                                                             \
-  template(createConstantDouble_signature,        "(D)Lcom/oracle/graal/api/meta/Constant;")                                          \
-  template(createConstantObject_name,             "createConstantObject")                                                             \
-  template(createConstantObject_signature,        "(Ljava/lang/Object;)Lcom/oracle/graal/api/meta/Constant;")                         \
   template(getVMToCompiler_name,                  "getVMToCompiler")                                                                  \
   template(getVMToCompiler_signature,             "()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;")                                 \
   template(runtime_name,                          "runtime")                                                                          \
--- a/src/share/vm/code/nmethod.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/code/nmethod.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -1523,15 +1523,15 @@
     assert(state == not_entrant, "other cases may need to be handled differently");
   }
 #ifdef GRAAL
-      if (_graal_installed_code != NULL) {
-        // Break the link between nmethod and HotSpotInstalledCode such that the nmethod can subsequently be flushed safely.
-        HotSpotInstalledCode::set_codeBlob(_graal_installed_code, 0);
-      }
+  if (_graal_installed_code != NULL) {
+    // Break the link between nmethod and HotSpotInstalledCode such that the nmethod can subsequently be flushed safely.
+    HotSpotInstalledCode::set_codeBlob(_graal_installed_code, 0);
+  }
 #endif
 
   if (TraceCreateZombies) {
     ResourceMark m;
-    tty->print_cr("nmethod <" INTPTR_FORMAT "> %s code made %s", this, this->method()->name_and_sig_as_C_string(), (state == not_entrant) ? "not entrant" : "zombie");
+    tty->print_cr("nmethod <" INTPTR_FORMAT "> %s code made %s", this, this->method() ? this->method()->name_and_sig_as_C_string() : "null", (state == not_entrant) ? "not entrant" : "zombie");
   }
 
   NMethodSweeper::report_state_change(this);
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -143,7 +143,7 @@
     jlong prim = Constant::primitive(constant);
     if (obj != NULL) {
       if (obj->is_a(HotSpotResolvedObjectType::klass())) {
-        Klass* klass = (Klass*) (address) HotSpotResolvedObjectType::metaspaceKlass(obj);
+        Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj));
         assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
         int index = oop_recorder->find_index(klass);
         TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
@@ -247,7 +247,7 @@
   } else if (value->is_a(VirtualObject::klass())) {
     oop type = VirtualObject::type(value);
     int id = VirtualObject::id(value);
-    oop javaMirror = HotSpotResolvedObjectType::javaMirror(type);
+    oop javaMirror = HotSpotResolvedObjectType::javaClass(type);
     Klass* klass = java_lang_Class::as_Klass(javaMirror);
     bool isLongArray = klass == Universe::longArrayKlassObj();
 
@@ -549,15 +549,15 @@
 
 void CodeInstaller::assumption_NoFinalizableSubclass(Handle assumption) {
   Handle receiverType_handle = Assumptions_NoFinalizableSubclass::receiverType(assumption());
-  Klass* receiverType = asKlass(HotSpotResolvedObjectType::metaspaceKlass(receiverType_handle));
+  Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(receiverType_handle));
   _dependencies->assert_has_no_finalizable_subclasses(receiverType);
 }
 
 void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) {
   Handle context_handle = Assumptions_ConcreteSubtype::context(assumption());
   Handle subtype_handle = Assumptions_ConcreteSubtype::subtype(assumption());
-  Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle));
-  Klass* subtype = asKlass(HotSpotResolvedObjectType::metaspaceKlass(subtype_handle));
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle));
+  Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(subtype_handle));
 
   _dependencies->assert_leaf_type(subtype);
   if (context != subtype) {
@@ -571,7 +571,7 @@
   Handle context_handle = Assumptions_ConcreteMethod::context(assumption());
 
   methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
-  Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle));
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle));
 
   _dependencies->assert_unique_concrete_method(context, impl());
 }
--- a/src/share/vm/graal/graalCompiler.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/graalCompiler.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -193,9 +193,7 @@
   assert(_initialized, "must already be initialized");
   ResourceMark rm;
   thread->set_is_graal_compiling(true);
-  Handle holder = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK);
-  check_pending_exception("Error while calling createHotSpotResolvedObjectType");
-  VMToCompiler::compileMethod(method(), holder, entry_bci, blocking);
+  VMToCompiler::compileMethod(method(), entry_bci, blocking);
   thread->set_is_graal_compiling(false);
 }
 
@@ -266,22 +264,6 @@
   }
 }
 
-Handle GraalCompiler::get_JavaTypeFromClass(Handle java_class, TRAPS) {
-  oop graal_mirror = java_lang_Class::graal_mirror(java_class());
-  if (graal_mirror != NULL) {
-    return graal_mirror;
-  }
-
-  if (java_lang_Class::is_primitive(java_class())) {
-    BasicType basicType = java_lang_Class::primitive_type(java_class());
-    return VMToCompiler::createPrimitiveJavaType((int) basicType, THREAD);
-  } else {
-    KlassHandle klass = java_lang_Class::as_Klass(java_class());
-    Handle name = java_lang_String::create_from_symbol(klass->name(), CHECK_NH);
-    return GraalCompiler::createHotSpotResolvedObjectType(klass, name, CHECK_NH);
-  }
-}
-
 Handle GraalCompiler::get_JavaType(KlassHandle klass, TRAPS) {
   Handle name = java_lang_String::create_from_symbol(klass->name(), THREAD);
   return createHotSpotResolvedObjectType(klass, name, CHECK_NH);
--- a/src/share/vm/graal/graalCompiler.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/graalCompiler.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -74,7 +74,6 @@
   static Handle get_JavaTypeFromSignature(Symbol* signature, KlassHandle accessor, TRAPS);
   static Handle get_JavaType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
   static Handle get_JavaType(Symbol* klass_name, TRAPS);
-  static Handle get_JavaTypeFromClass(Handle javaClassHandle, TRAPS);
   static Handle get_JavaType(KlassHandle klass, TRAPS);
   static Handle get_JavaField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, TRAPS);
 
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -133,12 +133,6 @@
   return result;
 C2V_END
 
-C2V_VMENTRY(jstring, getSignature, (JNIEnv *env, jobject, jlong metaspace_method))
-  Method* method = asMethod(metaspace_method);
-  assert(method != NULL && method->signature() != NULL, "signature required");
-  return (jstring)JNIHandles::make_local(java_lang_String::create_from_symbol(method->signature(), THREAD)());
-C2V_END
-
 C2V_VMENTRY(jobjectArray, initializeExceptionHandlers, (JNIEnv *, jobject, jlong metaspace_method, jobjectArray java_handlers))
   ResourceMark rm;
   methodHandle method = asMethod(metaspace_method);
@@ -163,7 +157,7 @@
       ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants();
       KlassHandle loading_klass = method->method_holder();
       Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL);
-      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
+      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(catch_class)) == SystemDictionary::Throwable_klass()) {
         ExceptionHandler::set_catchType(entry, NULL);
         ExceptionHandler::set_catchTypeCPI(entry, 0);
       } else {
@@ -200,44 +194,13 @@
   return true;
 C2V_END
 
-C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jobject reflection_method_handle, jobject resultHolder))
-  oop reflection_method = JNIHandles::resolve(reflection_method_handle);
-  oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
-  int slot = java_lang_reflect_Method::slot(reflection_method);
-  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
-  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
-  return (jlong) (address) method();
-}
-
-C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder))
-  oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle);
-  oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor);
-  int slot = java_lang_reflect_Constructor::slot(reflection_ctor);
-  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
+C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jclass holder_handle, jint slot))
+  oop java_class = JNIHandles::resolve(holder_handle);
+  Klass* holder = java_lang_Class::as_Klass(java_class);
   methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
   return (jlong) (address) method();
 }
 
-C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle))
-  oop reflection_field = JNIHandles::resolve(reflection_field_handle);
-  oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field);
-  int slot = java_lang_reflect_Field::slot(reflection_field);
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(reflection_holder));
-
-  int offset = holder->field_offset(slot);
-  int flags = holder->field_access_flags(slot);
-  Symbol* field_name = holder->field_name(slot);
-  Handle field_holder = GraalCompiler::get_JavaTypeFromClass(reflection_holder, CHECK_NULL);
-  Handle field_type = GraalCompiler::get_JavaTypeFromClass(java_lang_reflect_Field::type(reflection_field), CHECK_NULL);
-
-  Handle ret = GraalCompiler::get_JavaField(offset, flags, field_name, field_holder, field_type, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, ret());
-}
-
 C2V_VMENTRY(jlong, getUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method, jobject resultHolder))
   methodHandle method = asMethod(metaspace_method);
   KlassHandle holder = method->method_holder();
@@ -268,7 +231,7 @@
 C2V_END
 
 C2V_VMENTRY(jobject, getUniqueImplementor, (JNIEnv *, jobject, jobject interface_type))
-  InstanceKlass* klass = (InstanceKlass*) asKlass(HotSpotResolvedObjectType::metaspaceKlass(interface_type));
+  InstanceKlass* klass = (InstanceKlass*) java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(interface_type));
   assert(klass->is_interface(), "must be");
   if (klass->nof_implementors() == 1) {
     InstanceKlass* implementor = (InstanceKlass*) klass->implementor();
@@ -282,10 +245,7 @@
 
 C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
   methodHandle method = asMethod(metaspace_method);
-  Handle name = java_lang_String::create_from_symbol(method->name(), CHECK);
   InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK);
-  HotSpotResolvedJavaMethod::set_name(hotspot_method, name());
-  HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size());
   HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length());
   HotSpotResolvedJavaMethod::set_callerSensitive(hotspot_method, method->caller_sensitive());
   HotSpotResolvedJavaMethod::set_forceInline(hotspot_method, method->force_inline());
@@ -298,12 +258,6 @@
   return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method);
 C2V_END
 
-C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data))
-  MethodData* method_data = asMethodData(metaspace_method_data);
-  HotSpotMethodData::set_normalDataSize(hotspot_method_data, method_data->data_size());
-  HotSpotMethodData::set_extraDataSize(hotspot_method_data, method_data->extra_data_size());
-C2V_END
-  
 C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
   nmethod* code = (asMethod(metaspace_method))->code();
   return code == NULL ? 0 : code->insts_size();
@@ -315,124 +269,67 @@
   Handle name = JNIHandles::resolve(jname);
   Symbol* nameSymbol = java_lang_String::as_symbol(name, THREAD);
   assert(nameSymbol != NULL, "name to symbol creation failed");
+  assert(nameSymbol->size() > 1, "primitive types should be handled in Java code");
 
   oop result = NULL;
-  if (nameSymbol == vmSymbols::int_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD);
-  } else if (nameSymbol == vmSymbols::long_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD);
-  } else if (nameSymbol == vmSymbols::bool_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD);
-  } else if (nameSymbol == vmSymbols::char_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD);
-  } else if (nameSymbol == vmSymbols::short_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD);
-  } else if (nameSymbol == vmSymbols::byte_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD);
-  } else if (nameSymbol == vmSymbols::double_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD);
-  } else if (nameSymbol == vmSymbols::float_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD);
-  } else if (nameSymbol == vmSymbols::void_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_VOID, THREAD);
+  Klass* resolved_type = NULL;
+  Handle classloader;
+  Handle protectionDomain;
+  if (JNIHandles::resolve(accessingClass) != NULL) {
+    classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(accessingClass))->class_loader();
+    protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(accessingClass))->protection_domain();
+  }
+
+  if (eagerResolve) {
+    resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD);
   } else {
-    Klass* resolved_type = NULL;
-    Handle classloader;
-    Handle protectionDomain;
-    if (JNIHandles::resolve(accessingClass) != NULL) {
-      classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader();
-      protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain();
-    }
+    resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
+  }
 
-    if (eagerResolve) {
-      resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD);
+  if (!HAS_PENDING_EXCEPTION) {
+    if (resolved_type == NULL) {
+      assert(!eagerResolve, "failed eager resolution should have caused an exception");
+      Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD);
+      result = type();
     } else {
-      resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
-    }
-
-    if (!HAS_PENDING_EXCEPTION) {
-      if (resolved_type == NULL) {
-        assert(!eagerResolve, "failed eager resolution should have caused an exception");
-        Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD);
-        result = type();
-      } else {
-        Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL);
-        result = type();
-      }
+      Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL);
+      result = type();
     }
   }
 
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jobject type, jint index))
-
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-
+C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+  ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   oop result = NULL;
   constantTag tag = cp->tag_at(index);
-
   switch (tag.value()) {
-  case JVM_CONSTANT_Integer:
-    result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_NULL);
-    break;
-
-  case JVM_CONSTANT_Long:
-    result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_NULL);
-    break;
-
-  case JVM_CONSTANT_Float:
-    result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_NULL);
-    break;
-
-  case JVM_CONSTANT_Double:
-    result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_NULL);
-    break;
-
-  case JVM_CONSTANT_Class:
-  case JVM_CONSTANT_UnresolvedClass:
-  case JVM_CONSTANT_UnresolvedClassInError:
-    {
-      Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
-      result = type();
+  case JVM_CONSTANT_String:
+      result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
       break;
-    }
-
-  case JVM_CONSTANT_String:
-    {
-      oop result_oop = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
-      result = VMToCompiler::createConstantObject(result_oop, CHECK_NULL);
-      break;
-    }
-
   case JVM_CONSTANT_MethodHandle:
   case JVM_CONSTANT_MethodHandleInError:
   case JVM_CONSTANT_MethodType:
   case JVM_CONSTANT_MethodTypeInError:
-    {
-      oop result_oop = cp->resolve_constant_at(index, CHECK_NULL);
-      result = VMToCompiler::createConstantObject(result_oop, CHECK_NULL);
+      result = cp->resolve_constant_at(index, CHECK_NULL);
       break;
-    }
-
   default:
     fatal(err_msg_res("unknown constant pool tag %s at cpi %d in %s", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string()));
   }
-
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode))
+C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
   Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
   index = GraalCompiler::to_cp_index(index, bc);
-  constantPoolHandle cpool(InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants());
-  oop appendix_oop = ConstantPool::appendix_at_if_loaded(cpool, index);
-
+  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+  oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
   return JNIHandles::make_local(THREAD, appendix_oop);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode))
-  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
+  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
   instanceKlassHandle pool_holder(cp->pool_holder());
 
   Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
@@ -457,15 +354,14 @@
   }
 C2V_END
 
-C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jobject type, jint index))
-
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
+  ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
   return JNIHandles::make_local(THREAD, result());
 C2V_END
 
-C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op))
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte op))
+  ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
   Bytecodes::Code bc = (Bytecodes::Code) (((int) op) & 0xFF);
   if (bc != Bytecodes::_checkcast && bc != Bytecodes::_instanceof && bc != Bytecodes::_new && bc != Bytecodes::_anewarray
       && bc != Bytecodes::_multianewarray && bc != Bytecodes::_ldc && bc != Bytecodes::_ldc_w && bc != Bytecodes::_ldc2_w)
@@ -486,11 +382,11 @@
   }
 C2V_END
 
-C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte opcode))
+C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
   ResourceMark rm;
 
   int cp_index = GraalCompiler::to_cp_index_u2(index);
-  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(constantPoolHolder)))->constants();
+  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
 
   int nt_index = cp->name_and_type_ref_index_at(cp_index);
   int sig_index = cp->signature_ref_index_at(nt_index);
@@ -529,7 +425,7 @@
 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature))
 
   assert(JNIHandles::resolve(resolved_type) != NULL, "");
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type));
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(resolved_type));
   Symbol* name_symbol = java_lang_String::as_symbol(JNIHandles::resolve(name), THREAD);
   Symbol* signature_symbol = java_lang_String::as_symbol(JNIHandles::resolve(signature), THREAD);
   methodHandle method = klass->lookup_method(name_symbol, signature_symbol);
@@ -544,36 +440,16 @@
   return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
 C2V_END
 
-// TODO move to Java
-C2V_VMENTRY(jboolean, isTypeInitialized,(JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
-  assert(klass != NULL, "method must not be called for primitive types");
-  return InstanceKlass::cast(klass)->is_initialized();
-C2V_END
-
-// TODO move to Java
-C2V_VMENTRY(jboolean, isTypeLinked,(JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
-  assert(klass != NULL, "method must not be called for primitive types");
-  return InstanceKlass::cast(klass)->is_linked();
-C2V_END
-
 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(hotspot_klass));
   assert(klass != NULL, "method must not be called for primitive types");
   return Dependencies::find_finalizable_subclass(klass) != NULL;
 C2V_END
 
-C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
-  assert(klass != NULL, "method must not be called for primitive types");
-  InstanceKlass::cast(klass)->initialize(JavaThread::current());
-C2V_END
-
 C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
   ResourceMark rm;
 
-  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass));
+  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass));
   GrowableArray<Handle> fields(k->java_fields_count());
 
   for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
@@ -596,7 +472,7 @@
 C2V_VMENTRY(jobject, getMethods, (JNIEnv *, jobject, jobject klass))
   ResourceMark rm;
 
-  instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass)));
+  instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass)));
   Array<Method*>* methods = k->methods();
   int methods_length = methods->length();
 
@@ -624,13 +500,6 @@
   return -1;
 C2V_END
 
-C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass))
-  oop java_mirror = JNIHandles::resolve(javaClass);
-  assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL");
-  Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, type());
-C2V_END
-
 
 // helpers used to set fields in the HotSpotVMConfig object
 jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
@@ -870,8 +739,8 @@
   // a ResourceMark and the buffer expands within the scope of the mark,
   // the buffer becomes garbage when that scope is exited. Experience shows that
   // the disassembled code is typically about 10x the code size so a fixed buffer
-  // sized to 20x code size should be sufficient.
-  int bufferSize = cb->code_size() * 20;
+  // sized to 20x code size plus a fixed amount for header info should be sufficient.
+  int bufferSize = cb->code_size() * 20 + 1024;
   char* buffer = NEW_RESOURCE_ARRAY(char, bufferSize);
   stringStream st(buffer, bufferSize);
   if (cb->is_nmethod()) {
@@ -993,19 +862,6 @@
 C2V_END
 
 
-C2V_VMENTRY(jobject, getFileName, (JNIEnv *, jobject, jobject klass))
-  ResourceMark rm;
-  InstanceKlass* k = (InstanceKlass*) asKlass(HotSpotResolvedObjectType::metaspaceKlass(klass));
-  Symbol *s = k->source_file_name();
-  int length;
-  jchar *name = s->as_unicode(length);
-
-  Handle result = java_lang_String::create_from_unicode(name, length, CHECK_NULL);
-  return JNIHandles::make_local(result());
-
-C2V_END
-
-
 C2V_VMENTRY(void, reprofile, (JNIEnv *env, jobject, jlong metaspace_method))
   Method* method = asMethod(metaspace_method);
   MethodCounters* mcs = method->method_counters();
@@ -1076,26 +932,22 @@
 #define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
 #define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
 #define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
-#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
 #define STRING                "Ljava/lang/String;"
 #define OBJECT                "Ljava/lang/Object;"
 #define CLASS                 "Ljava/lang/Class;"
 #define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
 #define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;"
-#define HS_RESOLVED_JAVA_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaType;"
 #define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
 #define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
 #define HS_COMPILED_CODE      "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;"
 #define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
 #define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
 #define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
-#define METHOD_DATA           "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
 #define METASPACE_METHOD      "J"
-#define METASPACE_METHOD_DATA "J"
+#define METASPACE_CONSTANT_POOL "J"
 
 JNINativeMethod CompilerToVM_methods[] = {
   {CC"initializeBytecode",            CC"("METASPACE_METHOD"[B)[B",                                     FN_PTR(initializeBytecode)},
-  {CC"getSignature",                  CC"("METASPACE_METHOD")"STRING,                                   FN_PTR(getSignature)},
   {CC"initializeExceptionHandlers",   CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS,    FN_PTR(initializeExceptionHandlers)},
   {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasBalancedMonitors)},
   {CC"getUniqueConcreteMethod",       CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,      FN_PTR(getUniqueConcreteMethod)},
@@ -1103,28 +955,21 @@
   {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
   {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
   {CC"doNotInlineOrCompile",          CC"("METASPACE_METHOD")V",                                        FN_PTR(doNotInlineOrCompile)},
-  {CC"initializeMethodData",          CC"("METASPACE_METHOD_DATA METHOD_DATA")V",                       FN_PTR(initializeMethodData)},
   {CC"isMethodCompilable",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(isMethodCompilable)},
   {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
   {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
-  {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
-  {CC"lookupAppendixInPool",          CC"("HS_RESOLVED_TYPE"IB)"OBJECT,                                 FN_PTR(lookupAppendixInPool)},
-  {CC"lookupMethodInPool",            CC"("HS_RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
-  {CC"lookupTypeInPool",              CC"("HS_RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
-  {CC"lookupReferencedTypeInPool",    CC"("HS_RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
-  {CC"lookupFieldInPool",             CC"("HS_RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
+  {CC"lookupConstantInPool",          CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                           FN_PTR(lookupConstantInPool)},
+  {CC"lookupAppendixInPool",          CC"("METASPACE_CONSTANT_POOL"IB)"OBJECT,                          FN_PTR(lookupAppendixInPool)},
+  {CC"lookupMethodInPool",            CC"("METASPACE_CONSTANT_POOL"IB)"METHOD,                          FN_PTR(lookupMethodInPool)},
+  {CC"lookupTypeInPool",              CC"("METASPACE_CONSTANT_POOL"I)"TYPE,                             FN_PTR(lookupTypeInPool)},
+  {CC"lookupReferencedTypeInPool",    CC"("METASPACE_CONSTANT_POOL"IB)V",                               FN_PTR(lookupReferencedTypeInPool)},
+  {CC"lookupFieldInPool",             CC"("METASPACE_CONSTANT_POOL"IB)"FIELD,                           FN_PTR(lookupFieldInPool)},
   {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
   {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
   {CC"getMethods",                    CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_METHOD,                      FN_PTR(getMethods)},
-  {CC"isTypeInitialized",             CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
-  {CC"isTypeLinked",                  CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeLinked)},
   {CC"hasFinalizableSubclass",        CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(hasFinalizableSubclass)},
-  {CC"initializeType",                CC"("HS_RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
   {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
-  {CC"getResolvedType",               CC"("CLASS")"RESOLVED_TYPE,                                       FN_PTR(getResolvedType)},
-  {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
-  {CC"getMetaspaceConstructor",       CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD,   FN_PTR(getMetaspaceConstructor)},
-  {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
+  {CC"getMetaspaceMethod",            CC"("CLASS"I)"METASPACE_METHOD,                                   FN_PTR(getMetaspaceMethod)},
   {CC"initializeConfiguration",       CC"("HS_CONFIG")V",                                               FN_PTR(initializeConfiguration)},
   {CC"installCode0",                  CC"("HS_COMPILED_CODE HS_INSTALLED_CODE"[Z)I",                    FN_PTR(installCode0)},
   {CC"notifyCompilationStatistics",   CC"(I"HS_RESOLVED_METHOD"ZIJJ"HS_INSTALLED_CODE")V",              FN_PTR(notifyCompilationStatistics)},
@@ -1134,7 +979,6 @@
   {CC"getDeoptedLeafGraphIds",        CC"()[J",                                                         FN_PTR(getDeoptedLeafGraphIds)},
   {CC"getLineNumberTable",            CC"("HS_RESOLVED_METHOD")[J",                                     FN_PTR(getLineNumberTable)},
   {CC"getLocalVariableTable",         CC"("HS_RESOLVED_METHOD")["LOCAL,                                 FN_PTR(getLocalVariableTable)},
-  {CC"getFileName",                   CC"("HS_RESOLVED_JAVA_TYPE")"STRING,                              FN_PTR(getFileName)},
   {CC"reprofile",                     CC"("METASPACE_METHOD")V",                                        FN_PTR(reprofile)},
   {CC"invalidateInstalledCode",       CC"("HS_INSTALLED_CODE")V",                                       FN_PTR(invalidateInstalledCode)},
   {CC"readUnsafeUncompressedPointer", CC"("OBJECT"J)"OBJECT,                                            FN_PTR(readUnsafeUncompressedPointer)},
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -49,8 +49,7 @@
 
 #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field)                \
   start_class(HotSpotResolvedObjectType)                                                                                                                       \
-    long_field(HotSpotResolvedObjectType, metaspaceKlass)                                                                                                      \
-    oop_field(HotSpotResolvedObjectType, javaMirror, "Ljava/lang/Class;")                                                                                      \
+    oop_field(HotSpotResolvedObjectType, javaClass, "Ljava/lang/Class;")                                                                                      \
   end_class                                                                                                                                                    \
   start_class(HotSpotResolvedJavaMethod)                                                                                                                       \
     oop_field(HotSpotResolvedJavaMethod, name, "Ljava/lang/String;")                                                                                           \
@@ -63,18 +62,10 @@
     boolean_field(HotSpotResolvedJavaMethod, dontInline)                                                                                                       \
     boolean_field(HotSpotResolvedJavaMethod, ignoredBySecurityStackWalk)                                                                                       \
   end_class                                                                                                                                                    \
-  start_class(HotSpotMethodData)                                                                                                                               \
-    long_field(HotSpotMethodData, metaspaceMethodData)                                                                                                         \
-    int_field(HotSpotMethodData, normalDataSize)                                                                                                               \
-    int_field(HotSpotMethodData, extraDataSize)                                                                                                                \
-  end_class                                                                                                                                                    \
   start_class(HotSpotJavaType)                                                                                                                                 \
     oop_field(HotSpotJavaType, name, "Ljava/lang/String;")                                                                                                     \
   end_class                                                                                                                                                    \
   start_class(HotSpotResolvedJavaField)                                                                                                                        \
-    oop_field(HotSpotResolvedJavaField, constant, "Lcom/oracle/graal/api/meta/Constant;")                                                                      \
-    int_field(HotSpotResolvedJavaField, offset)                                                                                                                \
-    int_field(HotSpotResolvedJavaField, flags)                                                                                                                 \
   end_class                                                                                                                                                    \
   start_class(HotSpotInstalledCode)                                                                                                                            \
     long_field(HotSpotInstalledCode, codeBlob)                                                                                                                 \
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -111,15 +111,13 @@
   check_pending_exception("Error while calling finalizeOptions");
 }
 
-void VMToCompiler::compileMethod(Method* method, Handle holder, int entry_bci, jboolean blocking) {
+void VMToCompiler::compileMethod(Method* method, int entry_bci, jboolean blocking) {
   assert(method != NULL, "just checking");
-  assert(!holder.is_null(), "just checking");
   Thread* THREAD = Thread::current();
   JavaValue result(T_VOID);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_long((jlong) (address) method);
-  args.push_oop(holder());
   args.push_int(entry_bci);
   args.push_int(blocking);
   JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
@@ -257,48 +255,6 @@
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createConstant(Handle kind, jlong value, TRAPS) {
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(kind());
-  args.push_long(value);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createConstant_name(), vmSymbols::createConstant_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createConstantFloat");
-  return (oop) result.get_jobject();
-
-}
-
-oop VMToCompiler::createConstantFloat(jfloat value, TRAPS) {
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_float(value);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createConstantFloat_name(), vmSymbols::createConstantFloat_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createConstantFloat");
-  return (oop) result.get_jobject();
-
-}
-
-oop VMToCompiler::createConstantDouble(jdouble value, TRAPS) {
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_double(value);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createConstantDouble_name(), vmSymbols::createConstantDouble_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createConstantDouble");
-  return (oop) result.get_jobject();
-}
-
-oop VMToCompiler::createConstantObject(Handle object, TRAPS) {
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  KlassHandle klass = loadClass(vmSymbols::com_oracle_graal_api_meta_Constant());
-  JavaCalls::call_static(&result, klass(), vmSymbols::forObject_name(), vmSymbols::createConstantObject_signature(), object, THREAD);
-  check_pending_exception("Error while calling Constant.forObject");
-  return (oop) result.get_jobject();
-}
-
 oop VMToCompiler::createLocal(Handle name, Handle typeInfo, int bci_start, int bci_end, int slot, Handle holder, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -60,8 +60,8 @@
   // public static void HotSpotOptions.finalizeOptions(boolean ciTime);
   static void finalizeOptions(jboolean ciTime);
 
-  // public abstract boolean compileMethod(long vmId, String name, int entry_bci, boolean blocking);
-  static void compileMethod(Method* method, Handle holder, int entry_bci, jboolean blocking);
+  // public abstract boolean compileMethod(long vmId, int entry_bci, boolean blocking);
+  static void compileMethod(Method* method, int entry_bci, jboolean blocking);
 
   // public abstract void shutdownCompiler();
   static void shutdownCompiler();
--- a/src/share/vm/graal/vmStructs_graal.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/graal/vmStructs_graal.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -30,6 +30,7 @@
 
 #define VM_STRUCTS_GRAAL(nonstatic_field, static_field)                       \
   static_field(java_lang_Class, _graal_mirror_offset, int)                    \
+  nonstatic_field(ThreadShadow, _pending_deoptimization, int)                 \
 
 #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type)                   \
 
--- a/src/share/vm/oops/methodData.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/oops/methodData.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -1900,7 +1900,11 @@
 
   // Whole-method sticky bits and flags
   enum {
+#ifdef GRAAL
+    _trap_hist_limit    = 18,   // decoupled from Deoptimization::Reason_LIMIT
+#else
     _trap_hist_limit    = 17,   // decoupled from Deoptimization::Reason_LIMIT
+#endif
     _trap_hist_mask     = max_jubyte,
     _extra_data_count   = 4     // extra DataLayout headers, for trap history
   }; // Public flag values
@@ -1910,7 +1914,11 @@
   uint _nof_overflow_traps;         // trap count, excluding _trap_hist
   union {
     intptr_t _align;
+#ifdef GRAAL
+    u1 _array[2*_trap_hist_limit];
+#else
     u1 _array[_trap_hist_limit];
+#endif
   } _trap_hist;
 
   // Support for interprocedural escape analysis, from Thomas Kotzmann.
--- a/src/share/vm/runtime/deoptimization.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/runtime/deoptimization.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -1368,10 +1368,12 @@
 
     methodHandle    trap_method = trap_scope->method();
     int             trap_bci    = trap_scope->bci();
+#ifdef GRAAL
     if (trap_bci == SynchronizationEntryBCI) {
       trap_bci = 0;
       Thread::current()->set_pending_monitorenter(true);
     }
+#endif
     Bytecodes::Code trap_bc     = trap_method->java_code_at(trap_bci);
 
     if (trap_scope->rethrow_exception()) {
@@ -1618,6 +1620,9 @@
       bool maybe_prior_trap = false;
       bool maybe_prior_recompile = false;
       pdata = query_update_method_data(trap_mdo, trap_bci, reason, true,
+#ifdef GRAAL
+                                   nm->is_compiled_by_graal() && nm->is_osr_method(),
+#endif
                                    //outputs:
                                    this_trap_count,
                                    maybe_prior_trap,
@@ -1752,6 +1757,9 @@
                                          int trap_bci,
                                          Deoptimization::DeoptReason reason,
                                          bool update_total_trap_count,
+#ifdef GRAAL
+                                         bool is_osr,
+#endif
                                          //outputs:
                                          uint& ret_this_trap_count,
                                          bool& ret_maybe_prior_trap,
@@ -1760,8 +1768,14 @@
   bool maybe_prior_recompile = false;
   uint this_trap_count = 0;
   if (update_total_trap_count) {
-    uint prior_trap_count = trap_mdo->trap_count(reason);
-    this_trap_count  = trap_mdo->inc_trap_count(reason);
+    uint idx = reason;
+#ifdef GRAAL
+    if (is_osr) {
+      idx += Reason_LIMIT;
+    }
+#endif
+    uint prior_trap_count = trap_mdo->trap_count(idx);
+    this_trap_count  = trap_mdo->inc_trap_count(idx);
 
     // If the runtime cannot find a place to store trap history,
     // it is estimated based on the general condition of the method.
@@ -1826,6 +1840,9 @@
   query_update_method_data(trap_mdo, trap_bci,
                            (DeoptReason)reason,
                            update_total_counts,
+#ifdef GRAAL
+                           false,
+#endif
                            ignore_this_trap_count,
                            ignore_maybe_prior_trap,
                            ignore_maybe_prior_recompile);
--- a/src/share/vm/runtime/deoptimization.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/runtime/deoptimization.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -378,6 +378,9 @@
                                                int trap_bci,
                                                DeoptReason reason,
                                                bool update_total_trap_count,
+#ifdef GRAAL
+                                               bool is_osr,
+#endif
                                                //outputs:
                                                uint& ret_this_trap_count,
                                                bool& ret_maybe_prior_trap,
--- a/src/share/vm/runtime/vmStructs.cpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/runtime/vmStructs.cpp	Mon Dec 09 17:31:12 2013 +0100
@@ -390,9 +390,10 @@
   nonstatic_field(ObjArrayKlass,               _element_klass,                                Klass*)                                \
   nonstatic_field(ObjArrayKlass,               _bottom_klass,                                 Klass*)                                \
   volatile_nonstatic_field(Symbol,             _refcount,                                     short)                                 \
+  nonstatic_field(Symbol,                      _length,                                       unsigned short)                        \
   nonstatic_field(Symbol,                      _identity_hash,                                int)                                   \
-  nonstatic_field(Symbol,                      _length,                                       unsigned short)                        \
   unchecked_nonstatic_field(Symbol,            _body,                                         sizeof(jbyte)) /* NOTE: no type */     \
+  nonstatic_field(Symbol,                      _body[0],                                      jbyte)                                 \
   nonstatic_field(TypeArrayKlass,              _max_length,                                   int)                                   \
                                                                                                                                      \
   /***********************/                                                                                                          \
@@ -913,7 +914,6 @@
      static_field(Threads,                     _return_code,                                  int)                                   \
                                                                                                                                      \
   nonstatic_field(ThreadShadow,                _pending_exception,                            oop)                                   \
-  nonstatic_field(ThreadShadow,                _pending_deoptimization,                       int)                                   \
   nonstatic_field(ThreadShadow,                _exception_file,                               const char*)                           \
   nonstatic_field(ThreadShadow,                _exception_line,                               int)                                   \
    volatile_nonstatic_field(Thread,            _suspend_flags,                                uint32_t)                              \
@@ -2313,6 +2313,33 @@
   declare_constant(JVM_ACC_FIELD_ACCESS_WATCHED)                          \
   declare_constant(JVM_ACC_FIELD_MODIFICATION_WATCHED)                    \
                                                                           \
+  declare_constant(JVM_CONSTANT_Utf8)                                     \
+  declare_constant(JVM_CONSTANT_Unicode)                                  \
+  declare_constant(JVM_CONSTANT_Integer)                                  \
+  declare_constant(JVM_CONSTANT_Float)                                    \
+  declare_constant(JVM_CONSTANT_Long)                                     \
+  declare_constant(JVM_CONSTANT_Double)                                   \
+  declare_constant(JVM_CONSTANT_Class)                                    \
+  declare_constant(JVM_CONSTANT_String)                                   \
+  declare_constant(JVM_CONSTANT_Fieldref)                                 \
+  declare_constant(JVM_CONSTANT_Methodref)                                \
+  declare_constant(JVM_CONSTANT_InterfaceMethodref)                       \
+  declare_constant(JVM_CONSTANT_NameAndType)                              \
+  declare_constant(JVM_CONSTANT_MethodHandle)                             \
+  declare_constant(JVM_CONSTANT_MethodType)                               \
+  declare_constant(JVM_CONSTANT_InvokeDynamic)                            \
+  declare_constant(JVM_CONSTANT_ExternalMax)                              \
+                                                                          \
+  declare_constant(JVM_CONSTANT_Invalid)                                  \
+  declare_constant(JVM_CONSTANT_InternalMin)                              \
+  declare_constant(JVM_CONSTANT_UnresolvedClass)                          \
+  declare_constant(JVM_CONSTANT_ClassIndex)                               \
+  declare_constant(JVM_CONSTANT_StringIndex)                              \
+  declare_constant(JVM_CONSTANT_UnresolvedClassInError)                   \
+  declare_constant(JVM_CONSTANT_MethodHandleInError)                      \
+  declare_constant(JVM_CONSTANT_MethodTypeInError)                        \
+  declare_constant(JVM_CONSTANT_InternalMax)                              \
+                                                                          \
   /*****************************/                                         \
   /* Thread::SuspendFlags enum */                                         \
   /*****************************/                                         \
@@ -2342,6 +2369,7 @@
   /******************************/                                        \
                                                                           \
   declare_constant(Klass::_primary_super_limit)                           \
+  declare_constant(Klass::_lh_neutral_value)                              \
   declare_constant(Klass::_lh_instance_slow_path_bit)                     \
   declare_constant(Klass::_lh_log2_element_size_shift)                    \
   declare_constant(Klass::_lh_log2_element_size_mask)                     \
@@ -2533,6 +2561,13 @@
   declare_constant(Deoptimization::Unpack_uncommon_trap)                  \
   declare_constant(Deoptimization::Unpack_reexecute)                      \
                                                                           \
+  declare_constant(Deoptimization::_action_bits)                          \
+  declare_constant(Deoptimization::_reason_bits)                          \
+  declare_constant(Deoptimization::_speculation_id_bits)                  \
+  declare_constant(Deoptimization::_action_shift)                         \
+  declare_constant(Deoptimization::_reason_shift)                         \
+  declare_constant(Deoptimization::_speculation_id_shift)                 \
+                                                                          \
   /*********************/                                                 \
   /* Matcher (C2 only) */                                                 \
   /*********************/                                                 \
--- a/src/share/vm/utilities/exceptions.hpp	Mon Dec 09 17:30:50 2013 +0100
+++ b/src/share/vm/utilities/exceptions.hpp	Mon Dec 09 17:31:12 2013 +0100
@@ -61,8 +61,10 @@
   friend class VMStructs;
 
  protected:
+#ifdef GRAAL
   int _pending_deoptimization;
   bool _pending_monitorenter;
+#endif
   oop  _pending_exception;                       // Thread has gc actions.
   const char* _exception_file;                   // file information for exception (debugging only)
   int         _exception_line;                   // line information for exception (debugging only)
@@ -78,19 +80,23 @@
 
  public:
   oop  pending_exception() const                 { return _pending_exception; }
-  int  pending_deoptimization() const            { return _pending_deoptimization; }
   bool has_pending_exception() const             { return _pending_exception != NULL; }
   const char* exception_file() const             { return _exception_file; }
   int  exception_line() const                    { return _exception_line; }
+#ifdef GRAAL
+  int  pending_deoptimization() const            { return _pending_deoptimization; }
   bool has_pending_monitorenter() const          { return _pending_monitorenter; }
+#endif
 
   // Code generation support
+  static ByteSize pending_exception_offset()     { return byte_offset_of(ThreadShadow, _pending_exception); }
+#ifdef GRAAL
   static ByteSize pending_deoptimization_offset() { return byte_offset_of(ThreadShadow, _pending_deoptimization); }
-  static ByteSize pending_exception_offset()     { return byte_offset_of(ThreadShadow, _pending_exception); }
   static ByteSize pending_monitorenter_offset()  { return byte_offset_of(ThreadShadow, _pending_monitorenter); }
 
   void set_pending_monitorenter(bool b)          { _pending_monitorenter = b; }
   void set_pending_deoptimization(int reason)    { _pending_deoptimization = reason; }
+#endif
 
   // use THROW whenever possible!
   void set_pending_exception(oop exception, const char* file, int line);
@@ -99,7 +105,11 @@
   void clear_pending_exception();
 
   ThreadShadow() : _pending_exception(NULL),
-                   _exception_file(NULL), _exception_line(0), _pending_monitorenter(false), _pending_deoptimization(-1) {}
+                   _exception_file(NULL), _exception_line(0)
+#ifdef GRAAL
+                   , _pending_monitorenter(false), _pending_deoptimization(-1)
+#endif
+  {}
 };