changeset 3011:f00918f35c7f

inlining and runtime interface related changes: added codeSize() and compilerStorage() to RiMethod HotSpotMethodResolved uses reflective methods instead of vmIds and survives compilations HotSpotResolvedType.isInitialized not represented as field (can change) inlining stores graphs into method objects and reuses them
author Lukas Stadler <lukas.stadler@jku.at>
date Thu, 16 Jun 2011 20:36:17 +0200
parents 3671e31615c9
children 4d03919746d4
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethod.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExits.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCompiler.cpp src/share/vm/graal/graalCompiler.hpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/graal/graalVMEntries.cpp src/share/vm/graal/graalVMEntries.hpp src/share/vm/graal/graalVMExits.cpp src/share/vm/graal/graalVMExits.hpp src/share/vm/graal/graalVmIds.hpp src/share/vm/oops/klass.hpp src/share/vm/oops/methodKlass.cpp src/share/vm/oops/methodOop.hpp
diffstat 31 files changed, 631 insertions(+), 437 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java	Thu Jun 16 20:36:17 2011 +0200
@@ -170,7 +170,7 @@
         map.build();
         if (compiler.isObserved()) {
             String label = CiUtil.format("BlockListBuilder %f %r %H.%n(%p)", method, true);
-            compiler.fireCompilationEvent(new CompilationEvent(this, label, map, method.code().length));
+            compiler.fireCompilationEvent(new CompilationEvent(this, label, map, method.codeSize()));
         }
         stats.bytecodeCount += method.code().length;
         return map;
@@ -206,7 +206,7 @@
             targetMethod = emitCode();
 
             if (GraalOptions.Meter) {
-                GraalMetrics.BytecodesCompiled += method.code().length;
+                GraalMetrics.BytecodesCompiled += method.codeSize();
             }
         } catch (CiBailout b) {
             return new CiResult(null, b, stats);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Thu Jun 16 20:36:17 2011 +0200
@@ -29,8 +29,6 @@
  * The help message for each option is specified by a {@linkplain #helpMap help map}.
  *
  * (tw) WARNING: Fields of this class are treated as final by Graal.
- *
- * @author Ben L. Titzer
  */
 public final class GraalOptions {
 
@@ -40,6 +38,7 @@
 
     // inlining settings
     public static boolean Inline                             = true;
+    public static boolean InlineWithTypeCheck                = ____;
     public static int     MaximumInstructionCount            = 37000;
     public static float   MaximumInlineRatio                 = 0.90f;
     public static int     MaximumInlineSize                  = 35;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Thu Jun 16 20:36:17 2011 +0200
@@ -169,7 +169,7 @@
      */
     public BlockMap(RiMethod method) {
         this.method = method;
-        this.blockMap = new Block[method.code().length];
+        this.blockMap = new Block[method.codeSize()];
         if (method.exceptionHandlers().length != 0) {
             this.canTrap = new BitSet(blockMap.length);
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java	Thu Jun 16 20:36:17 2011 +0200
@@ -38,20 +38,18 @@
         this.compilation = compilation;
     }
 
-    public Return createReturn(Value result) {
+    public void setReturn(Return returnNode) {
         assert returnSingleton == null;
-        returnSingleton = new Return(result, this);
-        return returnSingleton;
+        returnSingleton = returnNode;
     }
 
     public Return getReturn() {
         return returnSingleton;
     }
 
-    public Unwind createUnwind(Value exception) {
+    public void setUnwind(Unwind unwind) {
         assert unwindSingleton == null;
-        unwindSingleton = new Unwind(exception, this);
-        return unwindSingleton;
+        unwindSingleton = unwind;
     }
 
     public Unwind getUnwind() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Thu Jun 16 20:36:17 2011 +0200
@@ -68,7 +68,16 @@
      * Builds the graph, optimizes it, and computes the linear scan block order.
      */
     public void build() {
-        new GraphBuilderPhase(compilation, compilation.method, false, false).apply(compilation.graph);
+
+//        Object stored = compilation.method.compilerStorage().get(CompilerGraph.class);
+//        if (stored != null) {
+//            Map<Node, Node> replacements = new HashMap<Node, Node>();
+//            CompilerGraph duplicate = (CompilerGraph) stored;
+//            replacements.put(duplicate.start(), compilation.graph.start());
+//            compilation.graph.addDuplicate(duplicate.getNodes(), replacements);
+//        } else {
+            new GraphBuilderPhase(compilation, compilation.method, false, false).apply(compilation.graph);
+//        }
 
         //printGraph("After GraphBuilding", compilation.graph);
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Thu Jun 16 20:36:17 2011 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import java.util.*;
+
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
@@ -115,6 +117,13 @@
     }
 
     @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("type", type);
+        return properties;
+    }
+
+    @Override
     public Node copy(Graph into) {
         return new IsType(null, type, into);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jun 16 20:36:17 2011 +0200
@@ -88,6 +88,8 @@
     private Block unwindBlock;
     private Block returnBlock;
 
+    private boolean storeResultGraph;
+
     // the worklist of blocks, sorted by depth first number
     private final PriorityQueue<Block> workList = new PriorityQueue<Block>(10, new Comparator<Block>() {
         public int compare(Block o1, Block o2) {
@@ -102,6 +104,7 @@
 
     private final boolean createUnwind;
 
+    public static HashMap<String, Integer> methodCount = new HashMap<String, Integer>();
 
     /**
      * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation.
@@ -122,6 +125,24 @@
 
         this.constantPool = runtime.getConstantPool(method);
         this.createUnwind = createUnwind;
+        this.storeResultGraph = true;
+
+//        String name = method.toString().intern();
+//        if (methodCount.get(name) == null) {
+//            methodCount.put(name, 1);
+//        } else {
+//            methodCount.put(name, methodCount.get(name) + 1);
+//        }
+//
+//        int inlined = 0;
+//        int duplicate = 0;
+//        for (Map.Entry<String, Integer> entry : methodCount.entrySet()) {
+//            inlined += entry.getValue();
+//            duplicate += entry.getValue() - 1;
+//        }
+//        if (inlined > 0) {
+//            System.out.printf("GraphBuilder overhead: %d (%5.3f %%)\n", duplicate, duplicate * 100.0 / inlined);
+//        }
     }
 
     @Override
@@ -149,7 +170,7 @@
         this.branchOverride = blockMap.branchOverride;
 
         blockList = new ArrayList<Block>(blockMap.blocks);
-        blockFromBci = new Block[method.code().length];
+        blockFromBci = new Block[method.codeSize()];
         for (int i = 0; i < blockList.size(); i++) {
             int blockID = nextBlockNumber();
             assert blockID == i;
@@ -205,6 +226,16 @@
                 }
             }
         }
+
+        if (storeResultGraph) {
+            // Create duplicate graph.
+            CompilerGraph duplicate = new CompilerGraph(null);
+            Map<Node, Node> replacements = new HashMap<Node, Node>();
+            replacements.put(graph.start(), duplicate.start());
+            duplicate.addDuplicate(graph.getNodes(), replacements);
+
+            method.compilerStorage().put(CompilerGraph.class, duplicate);
+        }
     }
 
     private int nextBlockNumber() {
@@ -231,11 +262,11 @@
         return unwindBlock;
     }
 
-    private Block returnBlock() {
+    private Block returnBlock(int bci) {
         if (returnBlock == null) {
             returnBlock = new Block();
-            returnBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
-            returnBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            returnBlock.startBci = bci;
+            returnBlock.endBci = bci;
             returnBlock.blockID = nextBlockNumber();
             addToWorkList(returnBlock);
         }
@@ -438,6 +469,7 @@
             // this is a load of class constant which might be unresolved
             RiType riType = (RiType) con;
             if (!riType.isResolved()) {
+                storeResultGraph = false;
                 append(new Deoptimize(DeoptAction.InvalidateRecompile, graph));
                 frameState.push(CiKind.Object, append(Constant.forObject(null, graph)));
             } else {
@@ -741,6 +773,7 @@
             NewInstance n = new NewInstance(type, cpi, constantPool, graph);
             frameState.apush(append(n));
         } else {
+            storeResultGraph = false;
             append(new Deoptimize(DeoptAction.InvalidateRecompile, graph));
             frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
         }
@@ -760,6 +793,7 @@
             NewArray n = new NewObjectArray(type, length, graph);
             frameState.apush(append(n));
         } else {
+            storeResultGraph = false;
             append(new Deoptimize(DeoptAction.InvalidateRecompile, graph));
             frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
         }
@@ -777,6 +811,7 @@
             NewArray n = new NewMultiArray(type, dims, cpi, constantPool, graph);
             frameState.apush(append(n));
         } else {
+            storeResultGraph = false;
             append(new Deoptimize(DeoptAction.InvalidateRecompile, graph));
             frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
         }
@@ -789,6 +824,7 @@
             LoadField load = new LoadField(receiver, field, graph);
             appendOptimizedLoadField(kind, load);
         } else {
+            storeResultGraph = false;
             append(new Deoptimize(DeoptAction.InvalidateRecompile, graph));
             frameState.push(kind.stackKind(), append(Constant.defaultForKind(kind, graph)));
         }
@@ -801,6 +837,7 @@
             StoreField store = new StoreField(receiver, field, value, graph);
             appendOptimizedStoreField(store);
         } else {
+            storeResultGraph = false;
             append(new Deoptimize(DeoptAction.InvalidateRecompile, graph));
         }
     }
@@ -843,6 +880,7 @@
         if (initialized) {
             return appendConstant(holder.getEncoding(representation));
         } else {
+            storeResultGraph = false;
             append(new Deoptimize(DeoptAction.InvalidateRecompile, graph));
             return null;
         }
@@ -884,6 +922,8 @@
     }
 
     private void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) {
+        assert target != null;
+        assert target.signature() != null;
         Value[] args = frameState.popArguments(target.signature().argumentSlots(true));
         invokeDirect(target, args, knownHolder, cpi, constantPool);
 
@@ -924,6 +964,7 @@
     private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) {
         CiKind resultType = returnKind(target);
         if (GraalOptions.DeoptALot) {
+            storeResultGraph = false;
             Deoptimize deoptimize = new Deoptimize(DeoptAction.None, graph);
             deoptimize.setMessage("invoke " + target.name());
             append(deoptimize);
@@ -997,7 +1038,7 @@
         if (x != null) {
             frameState.push(x.kind, x);
         }
-        appendGoto(createTarget(returnBlock(), frameState));
+        appendGoto(createTarget(returnBlock(bci()), frameState));
     }
 
     private void genMonitorEnter(Value x, int bci) {
@@ -1223,6 +1264,7 @@
 //        Merge x = new Merge(graph);
 //        x.setStateBefore(((StateSplit) block.firstInstruction).stateBefore());
 //        append(x);
+        storeResultGraph = false;
         append(new Deoptimize(DeoptAction.InvalidateReprofile, graph));
     }
 
@@ -1230,7 +1272,9 @@
         if (Modifier.isSynchronized(method.accessFlags())) {
             genMonitorExit(methodSynchronizedObject);
         }
-        append(graph.createUnwind(frameState.apop()));
+        Unwind unwindNode = new Unwind(frameState.apop(), graph);
+        graph.setUnwind(unwindNode);
+        append(unwindNode);
     }
 
     private void createReturnBlock(Block block) {
@@ -1244,7 +1288,9 @@
         if (Modifier.isSynchronized(method.accessFlags())) {
             genMonitorExit(methodSynchronizedObject);
         }
-        append(graph.createReturn(x));
+        Return returnNode = new Return(x, graph);
+        graph.setReturn(returnNode);
+        append(returnNode);
     }
 
     private void createExceptionDispatch(ExceptionBlock block) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jun 16 20:36:17 2011 +0200
@@ -55,44 +55,41 @@
     private void addToQueue(Invoke invoke, RiMethod method) {
         invokes.add(invoke);
         methods.add(method);
-        inliningSize += method.code().length;
+        inliningSize += method.codeSize();
     }
 
-    static HashMap<RiMethod, Integer> methodCount = new HashMap<RiMethod, Integer>();
+    public static HashMap<RiMethod, Integer> methodCount = new HashMap<RiMethod, Integer>();
     @Override
     protected void run(Graph graph) {
         float ratio = GraalOptions.MaximumInlineRatio;
-        inliningSize = compilation.method.code().length;
+        inliningSize = compilation.method.codeSize();
         for (int iterations = 0; iterations < GraalOptions.MaximumInlineLevel; iterations++) {
             for (Invoke invoke : graph.getNodes(Invoke.class)) {
-                RiMethod target = invoke.target;
-                if (invoke.stateAfter() == null || invoke.stateAfter().locksSize() > 0) {
-                    if (trace) {
-                        System.out.println("lock...");
-                    }
+                RiTypeProfile profile = compilation.method.typeProfile(invoke.bci);
+                if (!checkInliningConditions(invoke)) {
                     continue;
                 }
-
-                RiTypeProfile profile = compilation.method.typeProfile(invoke.bci);
-                if (!checkInliningConditions(invoke, profile, ratio) || !target.isResolved() || Modifier.isNative(target.accessFlags())) {
-                    continue;
-                }
-                if (target.canBeStaticallyBound()) {
-                    if (checkInliningConditions(invoke.target, iterations)) {
+                if (invoke.target.canBeStaticallyBound()) {
+                    if (checkInliningConditions(invoke.target, iterations, invoke, profile, ratio)) {
                         addToQueue(invoke, invoke.target);
                     }
                 } else {
                     RiMethod concrete = invoke.target.holder().uniqueConcreteMethod(invoke.target);
-                    if (concrete != null && concrete.isResolved() && !Modifier.isNative(concrete.accessFlags()) && checkInliningConditions(concrete, iterations)) {
+                    if (concrete != null && concrete.isResolved() && checkInliningConditions(concrete, iterations, invoke, profile, ratio)) {
                         if (trace) {
-                            System.out.println("recording concrete method assumption...");
+                            String targetName = CiUtil.format("%H.%n(%p):%r", invoke.target, false);
+                            String concreteName = CiUtil.format("%H.%n(%p):%r", concrete, false);
+                            System.out.printf("recording concrete method assumption: %s -> %s\n", targetName, concreteName);
                         }
                         compilation.assumptions.recordConcreteMethod(invoke.target, concrete);
                         addToQueue(invoke, concrete);
                     } else if (profile != null && profile.probabilities != null && profile.probabilities.length > 0 && profile.morphism == 1) {
+                        if (!GraalOptions.InlineWithTypeCheck) {
+                            continue;
+                        }
                         // type check and inlining...
                         concrete = profile.types[0].resolveMethodImpl(invoke.target);
-                        if (concrete != null && concrete.isResolved() && !Modifier.isNative(concrete.accessFlags()) && checkInliningConditions(concrete, iterations)) {
+                        if (concrete != null && concrete.isResolved() && checkInliningConditions(concrete, iterations, invoke, profile, ratio)) {
                             IsType isType = new IsType(invoke.receiver(), profile.types[0], compilation.graph);
                             FixedGuard guard = new FixedGuard(graph);
                             guard.setNode(isType);
@@ -155,15 +152,24 @@
         }
     }
 
-    private boolean checkInliningConditions(Invoke invoke, RiTypeProfile profile, float ratio) {
+    private boolean checkInliningConditions(Invoke invoke) {
         String name = !trace ? null : invoke.id() + ": " + CiUtil.format("%H.%n(%p):%r", invoke.target, false);
-        RiMethod parent = parentMethod.get(invoke);
-        if (parent == null) {
-            parent = compilation.method;
+
+        if (invoke.stateAfter() == null) {
+            if (trace) {
+                System.out.println("not inlining " + name + " because the invoke has no after state");
+            }
+            return false;
         }
-        if (profile == null || profile.count < parent.invocationCount() * (1 - ratio)) {
+        if (invoke.stateAfter().locksSize() > 0) {
             if (trace) {
-                System.out.println("not inlining " + name + " because the invocation counter is too low");
+                System.out.println("not inlining " + name + " because of locks");
+            }
+            return false;
+        }
+        if (!invoke.target.isResolved()) {
+            if (trace) {
+                System.out.println("not inlining " + name + " because the invoke target is unresolved");
             }
             return false;
         }
@@ -181,8 +187,14 @@
         return true;
     }
 
-    private boolean checkInliningConditions(RiMethod method, int iterations) {
-        String name = !trace ? null : CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.code().length + " bytes)";
+    private boolean checkInliningConditions(RiMethod method, int iterations, Invoke invoke, RiTypeProfile profile, float ratio) {
+        String name = !trace ? null : CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.codeSize() + " bytes)";
+        if (Modifier.isNative(method.accessFlags())) {
+            if (trace) {
+                System.out.println("not inlining " + name + " because it is a native method");
+            }
+            return false;
+        }
         if (method.code().length > GraalOptions.MaximumInlineSize) {
             if (trace) {
                 System.out.println("not inlining " + name + " because of code size");
@@ -201,21 +213,41 @@
             }
             return false;
         }
+        if (method.code().length > GraalOptions.MaximumTrivialSize) {
+            RiMethod parent = parentMethod.get(invoke);
+            if (parent == null) {
+                parent = compilation.method;
+            }
+            if (profile == null || profile.count < parent.invocationCount() * (1 - ratio)) {
+                if (trace) {
+                    System.out.println("not inlining " + name + " because the invocation counter is too low");
+                }
+                return false;
+            }
+        }
         return true;
     }
 
     private void inlineMethod(Invoke invoke, RiMethod method) {
-        String name = !trace ? null : invoke.id() + ": " + CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.code().length + " bytes)";
+        String name = !trace ? null : invoke.id() + ": " + CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.codeSize() + " bytes)";
         FrameState stateAfter = invoke.stateAfter();
         Instruction exceptionEdge = invoke.exceptionEdge();
 
-        if (trace) {
-            System.out.printf("Building graph for %s, locals: %d, stack: %d\n", name, method.maxLocals(), method.maxStackSize());
+        CompilerGraph graph;
+        Object stored = method.compilerStorage().get(CompilerGraph.class);
+        if (stored != null) {
+            if (trace) {
+                System.out.printf("Reusing graph for %s, locals: %d, stack: %d\n", name, method.maxLocals(), method.maxStackSize());
+            }
+            graph = (CompilerGraph) stored;
+        } else {
+            if (trace) {
+                System.out.printf("Building graph for %s, locals: %d, stack: %d\n", name, method.maxLocals(), method.maxStackSize());
+            }
+            graph = new CompilerGraph(null);
+            new GraphBuilderPhase(compilation, method, true, true).apply(graph);
         }
 
-        CompilerGraph graph = new CompilerGraph(compilation);
-        new GraphBuilderPhase(compilation, method, true, true).apply(graph);
-
         boolean withReceiver = !Modifier.isStatic(method.accessFlags());
 
         int argumentCount = method.signature().argumentCount(false);
@@ -258,7 +290,6 @@
         }
 
         if (trace) {
-            ir.printGraph("Subgraph " + CiUtil.format("%H.%n(%p):%r", method, false), graph);
             System.out.println("inlining " + name + ": " + frameStates.size() + " frame states, " + nodes.size() + " nodes");
         }
 
@@ -270,7 +301,7 @@
             clipNode.setNode(new IsNonNull(parameters[0], compilation.graph));
             pred = clipNode;
         } else {
-            pred = new Placeholder(compilation.graph);//(Instruction) invoke.predecessors().get(0);//new Merge(compilation.graph);
+            pred = new Placeholder(compilation.graph); // (Instruction) invoke.predecessors().get(0);//new Merge(compilation.graph);
         }
         invoke.predecessors().get(0).successors().replace(invoke, pred);
         replacements.put(startNode, pred);
@@ -295,7 +326,7 @@
         }
 
         if (pred instanceof Placeholder) {
-            pred.replace(((Placeholder)pred).next());
+            pred.replace(((Placeholder) pred).next());
         }
 
         if (returnNode != null) {
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java	Thu Jun 16 20:36:17 2011 +0200
@@ -83,14 +83,14 @@
     }
 
     public Node replace(Node other) {
-        assert !isDeleted() && (other == null || !other.isDeleted());
+        assert !isDeleted() && (other == null || !other.isDeleted()) : "id: " + id() + ", other: " + other;
         assert other == null || other.graph == graph;
         for (Node usage : usages) {
             usage.inputs.replaceFirstOccurrence(this, other);
         }
         int z = 0;
         for (Node predecessor : predecessors) {
-            for (int i=0; i<predecessor.successors.size(); i++) {
+            for (int i = 0; i < predecessor.successors.size(); i++) {
                 if (predecessor.successors.get(i) == this) {
                     predecessor.successors.silentSet(i, other);
                 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethod.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethod.java	Thu Jun 16 20:36:17 2011 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.graal.runtime;
 
+import java.util.*;
+
 import com.sun.cri.ri.*;
 
 
@@ -29,6 +31,7 @@
 
     protected RiType holder;
     protected String name;
+    public Map<Object, Object> compilerStorage;
 
     protected HotSpotMethod(Compiler compiler) {
         super(compiler);
@@ -43,4 +46,12 @@
     public final String name() {
         return name;
     }
+
+    @Override
+    public Map<Object, Object> compilerStorage() {
+        if (compilerStorage == null) {
+            compilerStorage = new HashMap<Object, Object>();
+        }
+        return compilerStorage;
+    }
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java	Thu Jun 16 20:36:17 2011 +0200
@@ -1,208 +1,31 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.graal.runtime;
-
-import java.lang.reflect.*;
-
-import com.sun.cri.ci.*;
-import com.sun.cri.ri.*;
-
-/**
- * Implementation of RiMethod for resolved HotSpot methods.
- */
-public final class HotSpotMethodResolved extends HotSpotMethod {
-
-    private final long vmId;
-
-    // cached values
-    private byte[] code;
-    private int accessFlags = -1;
-    private int maxLocals = -1;
-    private int maxStackSize = -1;
-    private int invocationCount = -1;
-    private RiExceptionHandler[] exceptionHandlers;
-    private RiSignature signature;
-    private Boolean hasBalancedMonitors;
-
-    public HotSpotMethodResolved(Compiler compiler, long vmId, String name) {
-        super(compiler);
-        this.vmId = vmId;
-        this.name = name;
-        this.holder = compiler.getVMEntries().RiMethod_holder(vmId);
-    }
-
-    @Override
-    public int accessFlags() {
-        if (accessFlags == -1) {
-            accessFlags = compiler.getVMEntries().RiMethod_accessFlags(vmId);
-        }
-        return accessFlags;
-    }
-
-    @Override
-    public boolean canBeStaticallyBound() {
-        return isLeafMethod() || Modifier.isStatic(accessFlags());
-    }
-
-    @Override
-    public byte[] code() {
-        if (code == null) {
-            code = compiler.getVMEntries().RiMethod_code(vmId);
-        }
-        return code;
-    }
-
-    @Override
-    public RiExceptionHandler[] exceptionHandlers() {
-        if (exceptionHandlers == null) {
-            exceptionHandlers = compiler.getVMEntries().RiMethod_exceptionHandlers(vmId);
-        }
-        return exceptionHandlers;
-    }
-
-    @Override
-    public boolean hasBalancedMonitors() {
-        if (hasBalancedMonitors == null) {
-            hasBalancedMonitors = compiler.getVMEntries().RiMethod_hasBalancedMonitors(vmId);
-        }
-        return hasBalancedMonitors;
-    }
-
-    @Override
-    public boolean isClassInitializer() {
-        return "<clinit>".equals(name) && Modifier.isStatic(accessFlags());
-    }
-
-    @Override
-    public boolean isConstructor() {
-        return "<init>".equals(name) && !Modifier.isStatic(accessFlags());
-    }
-
-    @Override
-    public boolean isLeafMethod() {
-        return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags());
-    }
-
-    @Override
-    public boolean isOverridden() {
-        throw new UnsupportedOperationException("isOverridden");
-    }
-
-    @Override
-    public boolean noSafepoints() {
-        return false;
-    }
-
-    @Override
-    public boolean isResolved() {
-        return true;
-    }
-
-    @Override
-    public String jniSymbol() {
-        throw new UnsupportedOperationException("jniSymbol");
-    }
-
-    public CiBitMap[] livenessMap() {
-        return null;
-    }
-
-    @Override
-    public int maxLocals() {
-        if (maxLocals == -1) {
-            maxLocals = compiler.getVMEntries().RiMethod_maxLocals(vmId);
-        }
-        return maxLocals;
-    }
-
-    @Override
-    public int maxStackSize() {
-        if (maxStackSize == -1) {
-            maxStackSize = compiler.getVMEntries().RiMethod_maxStackSize(vmId);
-        }
-        return maxStackSize;
-    }
-
-    @Override
-    public RiMethodProfile methodData() {
-        return null;
-    }
-
-    @Override
-    public StackTraceElement toStackTraceElement(int bci) {
-        return CiUtil.toStackTraceElement(this, bci);
-    }
-
-    public RiMethod uniqueConcreteMethod() {
-        return compiler.getVMEntries().RiMethod_uniqueConcreteMethod(vmId);
-    }
-
-    @Override
-    public RiSignature signature() {
-        if (signature == null) {
-            signature = new HotSpotSignature(compiler, compiler.getVMEntries().RiMethod_signature(vmId));
-        }
-        return signature;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotMethod<" + holder().name() + ". " + name + ">";
-    }
-
-    public boolean hasCompiledCode() {
-        // TODO: needs a VMEntries to go cache the result of that method.
-        // This isn't used by GRAAL for now, so this is enough.
-        return false;
-    }
-
-    @Override
-    public RiType accessor() {
-        return null;
-    }
-
-    @Override
-    public int intrinsic() {
-        return 0;
-    }
-
-    @Override
-    public boolean minimalDebugInfo() {
-        return false;
-    }
-
-    public int invocationCount() {
-        if (invocationCount == -1) {
-            invocationCount = compiler.getVMEntries().RiMethod_invocationCount(vmId);
-        }
-        return invocationCount;
-    }
-
-    public RiTypeProfile typeProfile(int bci) {
-        return compiler.getVMEntries().RiMethod_typeProfile(vmId, bci);
-    }
-
-    public int branchProbability(int bci) {
-        return compiler.getVMEntries().RiMethod_branchProbability(vmId, bci);
-    }
-}
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.runtime;
+
+import com.oracle.max.graal.runtime.server.*;
+import com.sun.cri.ri.*;
+
+public interface HotSpotMethodResolved extends RiMethod, Remote {
+
+    RiMethod uniqueConcreteMethod();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java	Thu Jun 16 20:36:17 2011 +0200
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.runtime;
+
+import java.lang.reflect.*;
+
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
+
+/**
+ * Implementation of RiMethod for resolved HotSpot methods.
+ */
+public final class HotSpotMethodResolvedImpl extends HotSpotMethod implements HotSpotMethodResolved {
+
+    private AccessibleObject javaMirror;
+
+    // cached values
+    private final int codeSize;
+    private final int accessFlags;
+    private final int maxLocals;
+    private final int maxStackSize;
+    private final int invocationCount;
+    private RiExceptionHandler[] exceptionHandlers;
+    private RiSignature signature;
+    private Boolean hasBalancedMonitors;
+
+    private HotSpotMethodResolvedImpl() {
+        super(null);
+        codeSize = -1;
+        accessFlags = -1;
+        maxLocals = -1;
+        maxStackSize = -1;
+        invocationCount = -1;
+    }
+
+    @Override
+    public int accessFlags() {
+        return accessFlags;
+    }
+
+    @Override
+    public boolean canBeStaticallyBound() {
+        return isLeafMethod() || Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public byte[] code() {
+        assert holder.isResolved();
+
+        byte[] ret = compiler.getVMEntries().RiMethod_code(this);
+        assert ret.length == codeSize : "expected: " + codeSize + ", actual: " + ret.length;
+        return ret;
+    }
+
+    @Override
+    public int codeSize() {
+        return codeSize;
+    }
+
+    @Override
+    public RiExceptionHandler[] exceptionHandlers() {
+        if (exceptionHandlers == null) {
+            exceptionHandlers = compiler.getVMEntries().RiMethod_exceptionHandlers(this);
+        }
+        return exceptionHandlers;
+    }
+
+    @Override
+    public boolean hasBalancedMonitors() {
+        if (hasBalancedMonitors == null) {
+            hasBalancedMonitors = compiler.getVMEntries().RiMethod_hasBalancedMonitors(this);
+        }
+        return hasBalancedMonitors;
+    }
+
+    @Override
+    public boolean isClassInitializer() {
+        return "<clinit>".equals(name) && Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public boolean isConstructor() {
+        return "<init>".equals(name) && !Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public boolean isLeafMethod() {
+        return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags());
+    }
+
+    @Override
+    public boolean isOverridden() {
+        throw new UnsupportedOperationException("isOverridden");
+    }
+
+    @Override
+    public boolean noSafepoints() {
+        return false;
+    }
+
+    @Override
+    public boolean isResolved() {
+        return true;
+    }
+
+    @Override
+    public String jniSymbol() {
+        throw new UnsupportedOperationException("jniSymbol");
+    }
+
+    public CiBitMap[] livenessMap() {
+        return null;
+    }
+
+    @Override
+    public int maxLocals() {
+        return maxLocals;
+    }
+
+    @Override
+    public int maxStackSize() {
+        return maxStackSize;
+    }
+
+    @Override
+    public RiMethodProfile methodData() {
+        return null;
+    }
+
+    @Override
+    public StackTraceElement toStackTraceElement(int bci) {
+        return CiUtil.toStackTraceElement(this, bci);
+    }
+
+    @Override
+    public RiMethod uniqueConcreteMethod() {
+        return compiler.getVMEntries().RiMethod_uniqueConcreteMethod(this);
+    }
+
+    @Override
+    public RiSignature signature() {
+        if (signature == null) {
+            signature = new HotSpotSignature(compiler, compiler.getVMEntries().RiMethod_signature(this));
+        }
+        return signature;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotMethod<" + holder().name() + ". " + name + ">";
+    }
+
+    public boolean hasCompiledCode() {
+        // TODO: needs a VMEntries to go cache the result of that method.
+        // This isn't used by GRAAL for now, so this is enough.
+        return false;
+    }
+
+    @Override
+    public RiType accessor() {
+        return null;
+    }
+
+    @Override
+    public int intrinsic() {
+        return 0;
+    }
+
+    @Override
+    public boolean minimalDebugInfo() {
+        return false;
+    }
+
+    public int invocationCount() {
+        return invocationCount;
+    }
+
+    public RiTypeProfile typeProfile(int bci) {
+        return compiler.getVMEntries().RiMethod_typeProfile(this, bci);
+    }
+
+    public int branchProbability(int bci) {
+        return compiler.getVMEntries().RiMethod_branchProbability(this, bci);
+    }
+}
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java	Thu Jun 16 20:36:17 2011 +0200
@@ -54,6 +54,11 @@
     }
 
     @Override
+    public int codeSize() {
+        return 0;
+    }
+
+    @Override
     public RiMethodProfile methodData() {
         throw unresolved("methodData");
     }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java	Thu Jun 16 20:36:17 2011 +0200
@@ -39,7 +39,6 @@
     private boolean hasFinalizer;
     private boolean hasSubclass;
     private boolean hasFinalizableSubclass;
-    private boolean isInitialized;
     private boolean isArrayClass;
     private boolean isInstanceClass;
     private boolean isInterface;
@@ -134,7 +133,7 @@
 
     @Override
     public boolean isInitialized() {
-        return isInitialized;
+        return compiler.getVMEntries().RiType_isInitialized(this);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java	Thu Jun 16 20:36:17 2011 +0200
@@ -33,17 +33,21 @@
 
     // Checkstyle: stop
 
-    byte[] RiMethod_code(long vmId);
+    byte[] RiMethod_code(HotSpotMethodResolved method);
+
+    String RiMethod_signature(HotSpotMethodResolved method);
 
-    int RiMethod_maxStackSize(long vmId);
+    RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method);
 
-    int RiMethod_maxLocals(long vmId);
+    boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method);
 
-    RiType RiMethod_holder(long vmId);
+    RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method);
+
+    int RiMethod_invocationCount(HotSpotMethodResolved method);
 
-    String RiMethod_signature(long vmId);
+    RiTypeProfile RiMethod_typeProfile(HotSpotMethodResolved method, int bci);
 
-    int RiMethod_accessFlags(long vmId);
+    int RiMethod_branchProbability(HotSpotMethodResolved method, int bci);
 
     RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass);
 
@@ -65,8 +69,6 @@
 
     HotSpotVMConfig getConfiguration();
 
-    RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId);
-
     RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
 
     boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
@@ -77,11 +79,9 @@
 
     RiType RiType_componentType(HotSpotTypeResolved klass);
 
-    RiType getType(Class<?> javaClass);
+    boolean RiType_isInitialized(HotSpotTypeResolved klass);
 
-    boolean RiMethod_hasBalancedMonitors(long vmId);
-
-    RiMethod RiMethod_uniqueConcreteMethod(long vmId);
+    RiType getType(Class<?> javaClass);
 
     void recordBailout(String reason);
 
@@ -95,11 +95,5 @@
 
     RiType getRiType(CiConstant constant);
 
-    int RiMethod_invocationCount(long vmId);
-
-    RiTypeProfile RiMethod_typeProfile(long vmId, int bci);
-
-    int RiMethod_branchProbability(long vmId, int bci);
-
     // Checkstyle: resume
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java	Thu Jun 16 20:36:17 2011 +0200
@@ -36,22 +36,28 @@
 
     // Checkstyle: stop
     @Override
-    public native byte[] RiMethod_code(long vmId);
+    public native byte[] RiMethod_code(HotSpotMethodResolved method);
 
     @Override
-    public native int RiMethod_maxStackSize(long vmId);
+    public native String RiMethod_signature(HotSpotMethodResolved method);
+
+    @Override
+    public native RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method);
 
     @Override
-    public native int RiMethod_maxLocals(long vmId);
+    public native boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method);
+
+    @Override
+    public native RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method);
 
     @Override
-    public native RiType RiMethod_holder(long vmId);
+    public native int RiMethod_invocationCount(HotSpotMethodResolved method);
 
     @Override
-    public native String RiMethod_signature(long vmId);
+    public native RiTypeProfile RiMethod_typeProfile(HotSpotMethodResolved method, int bci);
 
     @Override
-    public native int RiMethod_accessFlags(long vmId);
+    public native int RiMethod_branchProbability(HotSpotMethodResolved method, int bci);
 
     @Override
     public native RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass);
@@ -84,9 +90,6 @@
     public native HotSpotVMConfig getConfiguration();
 
     @Override
-    public native RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId);
-
-    @Override
     public native RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
 
     @Override
@@ -108,18 +111,15 @@
     public native RiType RiType_superType(HotSpotTypeResolved klass);
 
     @Override
+    public native boolean RiType_isInitialized(HotSpotTypeResolved klass);
+
+    @Override
     public native RiType getType(Class<?> javaClass);
 
     @Override
-    public native boolean RiMethod_hasBalancedMonitors(long vmId);
-
-    @Override
     public native void recordBailout(String reason);
 
     @Override
-    public native RiMethod RiMethod_uniqueConcreteMethod(long vmId);
-
-    @Override
     public int getArrayLength(CiConstant array) {
         return Array.getLength(array.asObject());
     }
@@ -138,14 +138,5 @@
         return getType(o.getClass());
     }
 
-    @Override
-    public native int RiMethod_invocationCount(long vmId);
-
-    @Override
-    public native RiTypeProfile RiMethod_typeProfile(long vmId, int bci);
-
-    @Override
-    public native int RiMethod_branchProbability(long vmId, int bci);
-
     // Checkstyle: resume
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExits.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExits.java	Thu Jun 16 20:36:17 2011 +0200
@@ -31,9 +31,7 @@
  */
 public interface VMExits {
 
-    void compileMethod(long methodVmId, String name, int entryBCI) throws Throwable;
-
-    RiMethod createRiMethodResolved(long vmId, String name);
+    void compileMethod(HotSpotMethodResolved method, int entryBCI) throws Throwable;
 
     RiMethod createRiMethodUnresolved(String name, String signature, RiType holder);
 
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Thu Jun 16 12:09:54 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Thu Jun 16 20:36:17 2011 +0200
@@ -135,7 +135,7 @@
     }
 
     @Override
-    public void compileMethod(final long methodVmId, final String name, final int entryBCI) throws Throwable {
+    public void compileMethod(final HotSpotMethodResolved method, final int entryBCI) throws Throwable {
         if (!compileMethods) {
             return;
         }
@@ -144,10 +144,9 @@
             @Override
             public void run() throws Throwable {
                 try {
-                    HotSpotMethodResolved riMethod = new HotSpotMethodResolved(compiler, methodVmId, name);
-                    CiResult result = compiler.getCompiler().compileMethod(riMethod, -1, null, null);
+                    CiResult result = compiler.getCompiler().compileMethod(method, -1, null, null);
                     if (LogCompiledMethods) {
-                        String qualifiedName = CiUtil.toJavaName(riMethod.holder()) + "::" + riMethod.name();
+                        String qualifiedName = CiUtil.toJavaName(method.holder()) + "::" + method.name();
                         compiledMethods.add(qualifiedName);
                     }
 
@@ -175,12 +174,12 @@
                         }
                         compiler.getVMEntries().recordBailout(s);
                     } else {
-                        HotSpotTargetMethod.installMethod(compiler, riMethod, result.targetMethod());
+                        HotSpotTargetMethod.installMethod(compiler, method, result.targetMethod());
                     }
                 } catch (Throwable t) {
                     StringWriter out = new StringWriter();
                     t.printStackTrace(new PrintWriter(out));
-                    TTY.println("Compilation interrupted: (" + name + ")\n" + out.toString());
+                    TTY.println("Compilation interrupted: (" + method.name() + ")\n" + out.toString());
                     throw t;
                 }
             }
@@ -188,11 +187,6 @@
     }
 
     @Override
-    public RiMethod createRiMethodResolved(long vmId, String name) {
-        return new HotSpotMethodResolved(compiler, vmId, name);
-    }
-
-    @Override
     public RiMethod createRiMethodUnresolved(String name, String signature, RiType holder) {
         return new HotSpotMethodUnresolved(compiler, name, signature, holder);
     }
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -257,19 +257,19 @@
   NOT_LP64(  do_alias(machine_word_signature,         int_signature)  )                           \
   LP64_ONLY( do_alias(machine_word_signature,         long_signature) )                           \
                                                                                                                         \
-  /* support for graal */                                                                                                 \
-  template(com_sun_hotspot_graal_VMExits,               "com/oracle/max/graal/runtime/VMExits")                               \
-  template(com_sun_hotspot_graal_HotSpotMethodResolved, "com/oracle/max/graal/runtime/HotSpotMethodResolved")                 \
-  template(com_sun_hotspot_graal_HotSpotTargetMethod,   "com/oracle/max/graal/runtime/HotSpotTargetMethod")                   \
-  template(com_sun_hotspot_graal_HotSpotField,          "com/oracle/max/graal/runtime/HotSpotField")                          \
-  template(com_sun_graal_graalOptions,                    "com/sun/graal/graalOptions")                                         \
-  template(com_sun_hotspot_graal_HotSpotOptions,        "com/oracle/max/graal/runtime/HotSpotOptions")                        \
-  template(com_sun_hotspot_graal_HotSpotTypeResolved,   "com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl")               \
-  template(com_sun_hotspot_graal_HotSpotType,           "com/oracle/max/graal/runtime/HotSpotType")                           \
-  template(com_sun_hotspot_graal_HotSpotExceptionHandler,"com/oracle/max/graal/runtime/HotSpotExceptionHandler")              \
-  template(com_sun_hotspot_graal_HotSpotProxy,          "com/oracle/max/graal/runtime/HotSpotProxy")                          \
-  template(com_sun_hotspot_graal_Compiler,              "com/oracle/max/graal/runtime/Compiler")                              \
-  template(com_sun_hotspot_graal_CompilerImpl,          "com/oracle/max/graal/runtime/CompilerImpl")                          \
+  /* support for graal */                                                                                               \
+  template(com_sun_hotspot_graal_VMExits,               "com/oracle/max/graal/runtime/VMExits")                         \
+  template(com_sun_hotspot_graal_HotSpotMethodResolved, "com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl")       \
+  template(com_sun_hotspot_graal_HotSpotTargetMethod,   "com/oracle/max/graal/runtime/HotSpotTargetMethod")             \
+  template(com_sun_hotspot_graal_HotSpotField,          "com/oracle/max/graal/runtime/HotSpotField")                    \
+  template(com_sun_graal_graalOptions,                    "com/sun/graal/graalOptions")                                 \
+  template(com_sun_hotspot_graal_HotSpotOptions,        "com/oracle/max/graal/runtime/HotSpotOptions")                  \
+  template(com_sun_hotspot_graal_HotSpotTypeResolved,   "com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl")         \
+  template(com_sun_hotspot_graal_HotSpotType,           "com/oracle/max/graal/runtime/HotSpotType")                     \
+  template(com_sun_hotspot_graal_HotSpotExceptionHandler,"com/oracle/max/graal/runtime/HotSpotExceptionHandler")        \
+  template(com_sun_hotspot_graal_HotSpotProxy,          "com/oracle/max/graal/runtime/HotSpotProxy")                    \
+  template(com_sun_hotspot_graal_Compiler,              "com/oracle/max/graal/runtime/Compiler")                        \
+  template(com_sun_hotspot_graal_CompilerImpl,          "com/oracle/max/graal/runtime/CompilerImpl")                    \
   template(com_sun_cri_ri_RiMethod,                   "com/sun/cri/ri/RiMethod")                                        \
   template(com_sun_cri_ri_RiField,                    "com/sun/cri/ri/RiField")                                         \
   template(com_sun_cri_ri_RiType,                     "com/sun/cri/ri/RiType")                                          \
@@ -300,7 +300,7 @@
   template(startCompiler_name,                        "startCompiler")                                                  \
   template(shutdownCompiler_name,                     "shutdownCompiler")                                               \
   template(compileMethod_name,                        "compileMethod")                                                  \
-  template(compileMethod_signature,                   "(JLjava/lang/String;I)V")                                        \
+  template(compileMethod_signature,                   "(Lcom/oracle/max/graal/runtime/HotSpotMethodResolved;I)V")       \
   template(setOption_name,                            "setOption")                                                      \
   template(setDefaultOptions_name,                    "setDefaultOptions")                                              \
   template(setOption_signature,                       "(Ljava/lang/String;)Z")                                          \
@@ -329,10 +329,10 @@
   template(createCiConstantObject_name,               "createCiConstantObject")                                         \
   template(createCiConstantObject_signature,          "(Ljava/lang/Object;)Lcom/sun/cri/ci/CiConstant;")                \
   template(getVMExits_name,                           "getVMExits")                                                     \
-  template(getVMExits_signature,                      "()Lcom/oracle/max/graal/runtime/VMExits;")                           \
+  template(getVMExits_signature,                      "()Lcom/oracle/max/graal/runtime/VMExits;")                       \
   template(getInstance_name,                          "getInstance")                                                    \
   template(initialize_name,                           "initialize")                                                     \
-  template(getInstance_signature,                     "()Lcom/oracle/max/graal/runtime/Compiler;")                          \
+  template(getInstance_signature,                     "()Lcom/oracle/max/graal/runtime/Compiler;")                      \
   template(forObject_name,                            "forObject")                                                      \
                                                                                                                         \
   /* common method and field names */                                                             \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Thu Jun 16 20:36:17 2011 +0200
@@ -25,6 +25,7 @@
 #include "graal/graalCompiler.hpp"
 #include "graal/graalCodeInstaller.hpp"
 #include "graal/graalJavaAccess.hpp"
+#include "graal/graalVMEntries.hpp"
 #include "graal/graalVmIds.hpp"
 #include "c1/c1_Runtime1.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -200,7 +201,7 @@
     assert(_hotspot_method != NULL && _name == NULL, "installMethod needs NON-NULL method and NULL name");
     assert(_hotspot_method->is_a(HotSpotMethodResolved::klass()), "installMethod needs a HotSpotMethodResolved");
 
-    methodOop method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(_hotspot_method));
+    methodOop method = getMethodFromHotSpotMethod(_hotspot_method);
     ciMethodObject = (ciMethod *) _env->get_object(method);
     _parameter_count = method->size_of_parameters();
   }
@@ -346,10 +347,8 @@
 void CodeInstaller::assumption_ConcreteMethod(oop assumption) {
   oop context_oop = CiAssumptions_ConcreteMethod::context(assumption);
   oop method_oop = CiAssumptions_ConcreteMethod::method(assumption);
-  jlong context_oop_id = HotSpotMethodResolved::vmId(context_oop);
-  jlong method_oop_id = HotSpotMethodResolved::vmId(method_oop);
-  methodOop method = VmIds::get<methodOop>(method_oop_id);
-  methodOop context = VmIds::get<methodOop>(context_oop_id);
+  methodOop method = getMethodFromHotSpotMethod(method_oop);
+  methodOop context = getMethodFromHotSpotMethod(context_oop);
 
   ciMethod* m = (ciMethod*) CURRENT_ENV->get_object(method);
   ciMethod* c = (ciMethod*) CURRENT_ENV->get_object(context);
@@ -433,8 +432,7 @@
   }
 
   oop hotspot_method = CiCodePos::method(code_pos);
-  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotMethodResolved::klass()), "unexpected hotspot method");
-  methodOop method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(hotspot_method));
+  methodOop method = getMethodFromHotSpotMethod(hotspot_method);
   ciMethod *cimethod = (ciMethod *) _env->get_object(method);
   jint bci = CiCodePos::bci(code_pos);
   bool reexecute;
@@ -594,7 +592,10 @@
     assert(debug_info != NULL, "debug info expected");
 
     methodOop method = NULL;
-    if (hotspot_method->is_a(HotSpotMethodResolved::klass())) method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(hotspot_method));
+    // we need to check, this might also be an unresolved method
+    if (hotspot_method->is_a(HotSpotMethodResolved::klass())) {
+      method = getMethodFromHotSpotMethod(hotspot_method);
+    }
 
     assert(debug_info != NULL, "debug info expected");
 
--- a/src/share/vm/graal/graalCompiler.cpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Thu Jun 16 20:36:17 2011 +0200
@@ -111,7 +111,9 @@
 
   CompilerThread::current()->set_compiling(true);
   methodOop method = (methodOop) target->get_oop();
-  VMExits::compileMethod(VmIds::add<methodOop>(method), VmIds::toString<Handle>(method->name(), THREAD), entry_bci);
+  Handle name = VmIds::toString<Handle>(method->name(), CHECK);
+  Handle hotspot_method = GraalCompiler::createHotSpotMethodResolved(method, name, CHECK);
+  VMExits::compileMethod(hotspot_method, entry_bci);
   CompilerThread::current()->set_compiling(false);
 
   VmIds::cleanupLocalObjects();
@@ -182,7 +184,6 @@
   } else {
     HotSpotTypeResolved::set_isArrayClass(obj, false);
     HotSpotTypeResolved::set_componentType(obj, NULL);
-    HotSpotTypeResolved::set_isInitialized(obj, instanceKlass::cast(klass())->is_initialized());
     HotSpotTypeResolved::set_instanceSize(obj, instanceKlass::cast(klass())->size_helper() * HeapWordSize);
     HotSpotTypeResolved::set_hasFinalizer(obj, klass->has_finalizer());
   }
@@ -196,6 +197,36 @@
   return obj();
 }
 
+oop GraalCompiler::createHotSpotMethodResolved(methodHandle method, Handle name, TRAPS) {
+  if (method->graal_mirror() != NULL) {
+    assert(method->graal_mirror()->is_a(HotSpotMethodResolved::klass()), "unexpected class...");
+    return method->graal_mirror();
+  }
+
+  instanceKlass::cast(HotSpotMethodResolved::klass())->initialize(CHECK_NULL);
+  Handle obj = instanceKlass::cast(HotSpotMethodResolved::klass())->allocate_instance(CHECK_NULL);
+  assert(obj() != NULL, "must succeed in allocating instance");
+
+  HotSpotMethodResolved::set_compiler(obj, VMExits::compilerInstance()());
+  oop reflected = getReflectedMethod(method(), CHECK_NULL);
+  HotSpotMethodResolved::set_javaMirror(obj, reflected);
+  HotSpotMethodResolved::set_name(obj, name());
+
+  KlassHandle klass = method->method_holder();
+  Handle holder_name = VmIds::toString<Handle>(klass->name(), CHECK_NULL);
+  oop holder = GraalCompiler::createHotSpotTypeResolved(klass, holder_name, CHECK_NULL);
+  HotSpotMethodResolved::set_holder(obj, holder);
+
+  HotSpotMethodResolved::set_codeSize(obj, method->code_size());
+  HotSpotMethodResolved::set_accessFlags(obj, method->access_flags().as_int());
+  HotSpotMethodResolved::set_maxLocals(obj, method->max_locals());
+  HotSpotMethodResolved::set_maxStackSize(obj, method->max_stack());
+  HotSpotMethodResolved::set_invocationCount(obj, method->invocation_count());
+
+  method->set_graal_mirror(obj());
+  return obj();
+}
+
 BasicType GraalCompiler::kindToBasicType(jchar ch) {
   switch(ch) {
     case 'z': return T_BOOLEAN;
--- a/src/share/vm/graal/graalCompiler.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalCompiler.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -61,6 +61,7 @@
   static oop get_RiField(ciField *ciField, ciInstanceKlass* accessor_klass, KlassHandle accessor, Bytecodes::Code byteCode, TRAPS);
 
   static oop createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS);
+  static oop createHotSpotMethodResolved(methodHandle method, Handle name, TRAPS);
 
   void exit();
 
--- a/src/share/vm/graal/graalJavaAccess.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -53,22 +53,29 @@
     boolean_field(HotSpotTypeResolved, hasFinalizer)                                    \
     boolean_field(HotSpotTypeResolved, hasSubclass)                                     \
     boolean_field(HotSpotTypeResolved, hasFinalizableSubclass)                          \
-    boolean_field(HotSpotTypeResolved, isInitialized)                                   \
     boolean_field(HotSpotTypeResolved, isArrayClass)                                    \
     boolean_field(HotSpotTypeResolved, isInstanceClass)                                 \
     boolean_field(HotSpotTypeResolved, isInterface)                                     \
     int_field(HotSpotTypeResolved, instanceSize)                                        \
     oop_field(HotSpotTypeResolved, componentType, "Lcom/sun/cri/ri/RiType;")            \
   end_class                                                                             \
+  start_class(HotSpotMethodResolved)                                                    \
+    oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/max/graal/runtime/Compiler;") \
+    oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;")                        \
+    oop_field(HotSpotMethodResolved, holder, "Lcom/sun/cri/ri/RiType;")                 \
+    oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/reflect/AccessibleObject;") \
+    int_field(HotSpotMethodResolved, codeSize)                                          \
+    int_field(HotSpotMethodResolved, accessFlags)                                       \
+    int_field(HotSpotMethodResolved, maxLocals)                                         \
+    int_field(HotSpotMethodResolved, maxStackSize)                                      \
+    int_field(HotSpotMethodResolved, invocationCount)                                   \
+  end_class                                                                             \
   start_class(HotSpotType)                                                              \
     oop_field(HotSpotType, name, "Ljava/lang/String;")                                  \
   end_class                                                                             \
   start_class(HotSpotField)                                                             \
     oop_field(HotSpotField, constant, "Lcom/sun/cri/ci/CiConstant;")                    \
   end_class                                                                             \
-  start_class(HotSpotMethodResolved)                                                    \
-    long_field(HotSpotMethodResolved, vmId)                                             \
-  end_class                                                                             \
   start_class(HotSpotProxy)                                                             \
     static_oop_field(HotSpotProxy, DUMMY_CONSTANT_OBJ, "Ljava/lang/Long;")              \
   end_class                                                                             \
--- a/src/share/vm/graal/graalVMEntries.cpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalVMEntries.cpp	Thu Jun 16 20:36:17 2011 +0200
@@ -32,57 +32,69 @@
 #include "memory/oopFactory.hpp"
 #include "ci/ciMethodData.hpp"
 
+methodOop getMethodFromHotSpotMethod(jobject hotspot_method) {
+  return getMethodFromHotSpotMethod(JNIHandles::resolve(hotspot_method));
+}
+
+methodOop getMethodFromHotSpotMethod(oop hotspot_method) {
+  oop reflected = HotSpotMethodResolved::javaMirror(hotspot_method);
+  assert(reflected != NULL, "NULL not expected");
+
+  // method is a handle to a java.lang.reflect.Method object
+  oop mirror     = NULL;
+  int slot       = 0;
+
+  if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {
+    mirror = java_lang_reflect_Constructor::clazz(reflected);
+    slot   = java_lang_reflect_Constructor::slot(reflected);
+  } else {
+    assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
+    mirror = java_lang_reflect_Method::clazz(reflected);
+    slot   = java_lang_reflect_Method::slot(reflected);
+  }
+  klassOop k     = java_lang_Class::as_klassOop(mirror);
+
+  // Make sure class is initialized before handing id's out to methods
+//  assert(instanceKlass::cast(k)->is_initialized(), "only initialized classes expected");
+  methodOop m = instanceKlass::cast(k)->method_with_idnum(slot);
+  assert(m != NULL, "deleted method?");
+  return m;
+}
+
+oop getReflectedMethod(methodOop method, TRAPS) {
+  assert(method != NULL, "NULL not expected");
+
+  if (!method->is_initializer() || method->is_static()) {
+    return Reflection::new_method(method, true, true, CHECK_NULL);
+  } else {
+    return Reflection::new_constructor(method, CHECK_NULL);
+  }
+}
+
 // public byte[] RiMethod_code(long vmId);
-JNIEXPORT jbyteArray JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1code(JNIEnv *env, jobject, jlong vmId) {
+JNIEXPORT jbyteArray JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1code(JNIEnv *env, jobject, jobject hotspot_method) {
   TRACE_graal_3("VMEntries::RiMethod_code");
-  methodHandle method = VmIds::get<methodOop>(vmId);
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
   int code_size = method->code_size();
   jbyteArray result = env->NewByteArray(code_size);
   env->SetByteArrayRegion(result, 0, code_size, (const jbyte *) method->code_base());
   return result;
 }
 
-// public int RiMethod_maxStackSize(long vmId);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1maxStackSize(JNIEnv *, jobject, jlong vmId) {
-  TRACE_graal_3("VMEntries::RiMethod_maxStackSize");
-  return VmIds::get<methodOop>(vmId)->max_stack();
-}
-
-// public int RiMethod_maxLocals(long vmId);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1maxLocals(JNIEnv *, jobject, jlong vmId) {
-  TRACE_graal_3("VMEntries::RiMethod_maxLocals");
-  return VmIds::get<methodOop>(vmId)->max_locals();
-}
-
-// public RiType RiMethod_holder(long vmId);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1holder(JNIEnv *, jobject, jlong vmId) {
-  TRACE_graal_3("VMEntries::RiMethod_holder");
-  VM_ENTRY_MARK
-  KlassHandle klass = VmIds::get<methodOop>(vmId)->method_holder();
-  Handle name = VmIds::toString<Handle>(klass->name(), CHECK_NULL);
-  oop holder = GraalCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, holder);
-}
-
 // public String RiMethod_signature(long vmId);
-JNIEXPORT jstring JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1signature(JNIEnv *env, jobject, jlong vmId) {
+JNIEXPORT jstring JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1signature(JNIEnv *env, jobject, jobject hotspot_method) {
   TRACE_graal_3("VMEntries::RiMethod_signature");
   VM_ENTRY_MARK
-  methodOop method = VmIds::get<methodOop>(vmId);
+  methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+  assert(method != NULL && method->signature() != NULL, "signature required");
   return VmIds::toString<jstring>(method->signature(), THREAD);
 }
 
-// public int RiMethod_accessFlags(long vmId);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1accessFlags(JNIEnv *, jobject, jlong vmId) {
-  TRACE_graal_3("VMEntries::RiMethod_accessFlags");
-  return VmIds::get<methodOop>(vmId)->access_flags().as_int();
-}
-
 // public RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId);
-JNIEXPORT jobjectArray JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1exceptionHandlers(JNIEnv *, jobject, jlong vmId) {
+JNIEXPORT jobjectArray JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1exceptionHandlers(JNIEnv *, jobject, jobject hotspot_method) {
   TRACE_graal_3("VMEntries::RiMethod_exceptionHandlers");
   VM_ENTRY_MARK
-  methodHandle method = VmIds::get<methodOop>(vmId);
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
   typeArrayHandle handlers = method->exception_table();
   int handler_count = handlers.is_null() ? 0 : handlers->length() / 4;
 
@@ -117,21 +129,23 @@
 }
 
 // public boolean RiMethod_hasBalancedMonitors(long vmId);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1hasBalancedMonitors(JNIEnv *, jobject, jlong vmId) {
+JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1hasBalancedMonitors(JNIEnv *, jobject, jobject hotspot_method) {
   TRACE_graal_3("VMEntries::RiMethod_hasBalancedMonitors");
   ciMethod* cimethod;
   {
     VM_ENTRY_MARK;
-    cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get<methodOop>(vmId));
+    methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+    cimethod = (ciMethod*)CURRENT_ENV->get_object(method);
   }
   return cimethod->has_balanced_monitors();
 }
 
 // public boolean RiMethod_uniqueConcreteMethod(long vmId);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1uniqueConcreteMethod(JNIEnv *, jobject, jlong vmId) {
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1uniqueConcreteMethod(JNIEnv *, jobject, jobject hotspot_method) {
   TRACE_graal_3("VMEntries::RiMethod_uniqueConcreteMethod");
   VM_ENTRY_MARK;
-  ciMethod* cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get<methodOop>(vmId));
+  methodOop m = getMethodFromHotSpotMethod(hotspot_method);
+  ciMethod* cimethod = (ciMethod*)CURRENT_ENV->get_object(m);
   if (cimethod->holder()->is_interface()) {
     // Cannot trust interfaces. Because of:
     // interface I { void foo(); }
@@ -155,23 +169,25 @@
   }
 
   Handle name = VmIds::toString<Handle>(unique_concrete->name(), CHECK_NULL);
-  oop method_resolved = VMExits::createRiMethodResolved(VmIds::add<methodOop>(unique_concrete()), name, CHECK_NULL);
+  oop method_resolved = GraalCompiler::createHotSpotMethodResolved(unique_concrete(), name, CHECK_NULL);
   return JNIHandles::make_local(THREAD, method_resolved);
 }
 
 // public native int RiMethod_invocationCount(long vmId);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1invocationCount(JNIEnv *, jobject, jlong vmId) {
+JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1invocationCount(JNIEnv *, jobject, jobject hotspot_method) {
   TRACE_graal_3("VMEntries::RiMethod_invocationCount");
-  return VmIds::get<methodOop>(vmId)->invocation_count();
+  methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+  return method->invocation_count();
 }
 
 // public native RiTypeProfile RiMethod_typeProfile(long vmId, int bci);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1typeProfile(JNIEnv *, jobject, jlong vmId, jint bci) {
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1typeProfile(JNIEnv *, jobject, jobject hotspot_method, jint bci) {
   TRACE_graal_3("VMEntries::RiMethod_typeProfile");
   ciMethod* cimethod;
   {
     VM_ENTRY_MARK;
-    cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get<methodOop>(vmId));
+    methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+    cimethod = (ciMethod*)CURRENT_ENV->get_object(method);
   }
 
   ciCallProfile profile = cimethod->call_profile_at_bci(bci);
@@ -206,13 +222,14 @@
 }
 
 // public native RiTypeProfile RiMethod_branchProfile(long vmId, int bci);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1branchProbability(JNIEnv *, jobject, jlong vmId, jint bci) {
+JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1branchProbability(JNIEnv *, jobject, jobject hotspot_method, jint bci) {
   TRACE_graal_3("VMEntries::RiMethod_typeProfile");
   ciMethodData* method_data;
   ciMethod* cimethod;
   {
     VM_ENTRY_MARK;
-    cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get<methodOop>(vmId));
+    methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+    cimethod = (ciMethod*)CURRENT_ENV->get_object(method);
   }
   method_data = cimethod->method_data();
 
@@ -361,7 +378,8 @@
   if (cimethod->is_loaded()) {
     methodOop method = (methodOop) cimethod->get_oop();
     Handle name = VmIds::toString<Handle>(method->name(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add<methodOop>(method), name, THREAD));
+    oop ret = GraalCompiler::createHotSpotMethodResolved(method, name, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, ret);
   } else {
     Handle name = VmIds::toString<Handle>(cimethod->name()->get_symbol(), CHECK_NULL);
     Handle signature = VmIds::toString<Handle>(cimethod->signature()->as_symbol()->get_symbol(), CHECK_NULL);
@@ -481,7 +499,8 @@
     }
     return NULL;
   }
-  return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add<methodOop>(method), Handle(JNIHandles::resolve(name)), THREAD));
+  oop ret = GraalCompiler::createHotSpotMethodResolved(method, Handle(JNIHandles::resolve(name)), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, ret);
 }
 
 // public boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
@@ -565,6 +584,13 @@
   return NULL;
 }
 
+// public bool RiType_isInitialized(HotSpotResolvedType klass);
+JNIEXPORT jboolean JNICALL Java_com_oracle_graal_runtime_VMEntries_RiType_1isInitialized(JNIEnv *, jobject, jobject hotspot_klass) {
+  TRACE_graal_3("VMEntries::RiType_isInitialized");
+  klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(hotspot_klass));
+  return instanceKlass::cast(klass)->is_initialized();
+}
+
 // public RiType RiType_arrayOf(HotSpotTypeResolved klass);
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiType_1arrayOf(JNIEnv *, jobject, jobject klass) {
   TRACE_graal_3("VMEntries::RiType_arrayOf");
@@ -754,6 +780,7 @@
 #define TYPE            "Lcom/sun/cri/ri/RiType;"
 #define RESOLVED_TYPE   "Lcom/oracle/max/graal/runtime/HotSpotTypeResolved;"
 #define METHOD          "Lcom/sun/cri/ri/RiMethod;"
+#define RESOLVED_METHOD "Lcom/oracle/max/graal/runtime/HotSpotMethodResolved;"
 #define TYPE_PROFILE    "Lcom/sun/cri/ri/RiTypeProfile;"
 #define SIGNATURE       "Lcom/sun/cri/ri/RiSignature;"
 #define FIELD           "Lcom/sun/cri/ri/RiField;"
@@ -769,18 +796,14 @@
 #define CLASS           "Ljava/lang/Class;"
 
 JNINativeMethod VMEntries_methods[] = {
-  {CC"RiMethod_code",                   CC"("PROXY")[B",                            FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1code)},
-  {CC"RiMethod_maxStackSize",           CC"("PROXY")I",                             FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1maxStackSize)},
-  {CC"RiMethod_maxLocals",              CC"("PROXY")I",                             FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1maxLocals)},
-  {CC"RiMethod_holder",                 CC"("PROXY")"TYPE,                          FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1holder)},
-  {CC"RiMethod_signature",              CC"("PROXY")"STRING,                        FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1signature)},
-  {CC"RiMethod_accessFlags",            CC"("PROXY")I",                             FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1accessFlags)},
-  {CC"RiMethod_exceptionHandlers",      CC"("PROXY")"EXCEPTION_HANDLERS,            FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1exceptionHandlers)},
-  {CC"RiMethod_hasBalancedMonitors",    CC"("PROXY")Z",                             FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1hasBalancedMonitors)},
-  {CC"RiMethod_uniqueConcreteMethod",   CC"("PROXY")"METHOD,                        FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1uniqueConcreteMethod)},
-  {CC"RiMethod_invocationCount",        CC"("PROXY")I",                             FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1invocationCount)},
-  {CC"RiMethod_typeProfile",            CC"("PROXY"I)"TYPE_PROFILE,                 FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1typeProfile)},
-  {CC"RiMethod_branchProbability",      CC"("PROXY"I)I",                            FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1branchProbability)},
+  {CC"RiMethod_code",                   CC"("RESOLVED_METHOD")[B",                  FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1code)},
+  {CC"RiMethod_signature",              CC"("RESOLVED_METHOD")"STRING,              FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1signature)},
+  {CC"RiMethod_exceptionHandlers",      CC"("RESOLVED_METHOD")"EXCEPTION_HANDLERS,  FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1exceptionHandlers)},
+  {CC"RiMethod_hasBalancedMonitors",    CC"("RESOLVED_METHOD")Z",                   FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1hasBalancedMonitors)},
+  {CC"RiMethod_uniqueConcreteMethod",   CC"("RESOLVED_METHOD")"METHOD,              FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1uniqueConcreteMethod)},
+  {CC"RiMethod_typeProfile",            CC"("RESOLVED_METHOD"I)"TYPE_PROFILE,       FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1typeProfile)},
+  {CC"RiMethod_branchProbability",      CC"("RESOLVED_METHOD"I)I",                  FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1branchProbability)},
+  {CC"RiMethod_invocationCount",        CC"("RESOLVED_METHOD")I",                   FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1invocationCount)},
   {CC"RiSignature_lookupType",          CC"("STRING RESOLVED_TYPE")"TYPE,           FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiSignature_1lookupType)},
   {CC"RiConstantPool_lookupConstant",   CC"("PROXY"I)"OBJECT,                       FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiConstantPool_1lookupConstant)},
   {CC"RiConstantPool_lookupMethod",     CC"("PROXY"IB)"METHOD,                      FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiConstantPool_1lookupMethod)},
@@ -794,6 +817,7 @@
   {CC"RiType_uniqueConcreteSubtype",    CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1uniqueConcreteSubtype)},
   {CC"RiType_superType",                CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1superType)},
   {CC"RiType_arrayOf",                  CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1arrayOf)},
+  {CC"RiType_isInitialized",            CC"("RESOLVED_TYPE")Z",                     FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1isInitialized)},
   {CC"getPrimitiveArrayType",           CC"("CI_KIND")"TYPE,                        FN_PTR(Java_com_oracle_graal_runtime_VMEntries_getPrimitiveArrayType)},
   {CC"getType",                         CC"("CLASS")"TYPE,                          FN_PTR(Java_com_oracle_graal_runtime_VMEntries_getType)},
   {CC"getConfiguration",                CC"()"CONFIG,                               FN_PTR(Java_com_oracle_graal_runtime_VMEntries_getConfiguration)},
--- a/src/share/vm/graal/graalVMEntries.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalVMEntries.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -26,6 +26,10 @@
 extern JNINativeMethod VMEntries_methods[];
 int VMEntries_methods_count();
 
+methodOop getMethodFromHotSpotMethod(oop hotspotMethod);
+
+oop getReflectedMethod(methodOop method, TRAPS);
+
 // nothing here - no need to define the jni method implementations in a header file
 
 
--- a/src/share/vm/graal/graalVMExits.cpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalVMExits.cpp	Thu Jun 16 20:36:17 2011 +0200
@@ -25,9 +25,9 @@
 #include "graal/graalVMExits.hpp"
 
 // this is a *global* handle
-jobject VMExits::_compilerPermObject;
-jobject VMExits::_vmExitsPermObject;
-jobject VMExits::_vmExitsPermKlass;
+jobject VMExits::_compilerPermObject = NULL;
+jobject VMExits::_vmExitsPermObject = NULL;
+jobject VMExits::_vmExitsPermKlass = NULL;
 
 KlassHandle VMExits::vmExitsKlass() {
   if (JNIHandles::resolve(_vmExitsPermKlass) == NULL) {
@@ -99,27 +99,36 @@
   check_pending_exception("Error while calling setDefaultOptions");
 }
 
-void VMExits::compileMethod(jlong methodVmId, Handle name, int entry_bci) {
-  assert(!name.is_null(), "just checking");
+void VMExits::compileMethod(Handle hotspot_method, int entry_bci) {
+  assert(!hotspot_method.is_null(), "just checking");
   Thread* THREAD = Thread::current();
   JavaValue result(T_VOID);
   JavaCallArguments args;
   args.push_oop(instance());
-  args.push_long(methodVmId);
-  args.push_oop(name);
+  args.push_oop(hotspot_method);
   args.push_int(entry_bci);
   JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
   check_pending_exception("Error while calling compileMethod");
 }
 
 void VMExits::shutdownCompiler() {
-  HandleMark hm;
-  JavaThread* THREAD = JavaThread::current();
-  JavaValue result(T_VOID);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::shutdownCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
-  check_pending_exception("Error while calling shutdownCompiler");
+  if (_compilerPermObject != NULL) {
+    HandleMark hm;
+    JavaThread* THREAD = JavaThread::current();
+    JavaValue result(T_VOID);
+    JavaCallArguments args;
+    args.push_oop(instance());
+    JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::shutdownCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
+    check_pending_exception("Error while calling shutdownCompiler");
+
+    JNIHandles::destroy_global(_compilerPermObject);
+    JNIHandles::destroy_global(_vmExitsPermObject);
+    JNIHandles::destroy_global(_vmExitsPermKlass);
+
+    _compilerPermObject = NULL;
+    _vmExitsPermObject = NULL;
+    _vmExitsPermKlass = NULL;
+  }
 }
 
 void VMExits::startCompiler() {
--- a/src/share/vm/graal/graalVMExits.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalVMExits.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -51,7 +51,7 @@
   static void setDefaultOptions();
 
   // public abstract void compileMethod(long vmId, String name, int entry_bci);
-  static void compileMethod(jlong vmId, Handle name, int entry_bci);
+  static void compileMethod(Handle hotspot_method, int entry_bci);
 
   // public abstract void shutdownCompiler();
   static void shutdownCompiler();
--- a/src/share/vm/graal/graalVmIds.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/graal/graalVmIds.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -82,11 +82,6 @@
 };
 
 
-template <> inline jlong VmIds::add<methodOop>(methodOop obj){
-  assert(obj != NULL, "trying to add NULL<methodOop>");
-  assert(obj->is_method(), "trying to add mistyped object");
-  return add(Handle(obj), METHOD);
-}
 template <> inline jlong VmIds::add<klassOop>(klassOop obj) {
   assert(obj != NULL, "trying to add NULL<klassOop>");
   assert(obj->is_klass(), "trying to add mistyped object");
@@ -104,11 +99,6 @@
 }
 
 
-template <> inline methodOop VmIds::get<methodOop>(jlong id){
-  assert((id & TYPE_MASK) == METHOD, "METHOD expected");
-  assert(getObject(id)->is_method(), "methodOop expected");
-  return (methodOop)getObject(id);
-}
 template <> inline klassOop VmIds::get<klassOop>(jlong id) {
   assert((id & TYPE_MASK) == CLASS, "CLASS expected");
   assert(getObject(id)->is_klass(), "klassOop expected");
--- a/src/share/vm/oops/klass.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/oops/klass.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -368,7 +368,7 @@
   oop* adr_secondary_super_cache() const { return (oop*)&_secondary_super_cache; }
   oop* adr_secondary_supers()const { return (oop*)&_secondary_supers;  }
   oop* adr_java_mirror()     const { return (oop*)&_java_mirror;       }
-  oop* adr_graal_mirror()      const { return (oop*)&_graal_mirror;        }
+  oop* adr_graal_mirror()    const { return (oop*)&_graal_mirror;      }
   oop* adr_subklass()        const { return (oop*)&_subklass;          }
   oop* adr_next_sibling()    const { return (oop*)&_next_sibling;      }
 
--- a/src/share/vm/oops/methodKlass.cpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/oops/methodKlass.cpp	Thu Jun 16 20:36:17 2011 +0200
@@ -102,6 +102,7 @@
   m->invocation_counter()->init();
   m->backedge_counter()->init();
   m->clear_number_of_breakpoints();
+  m->set_graal_mirror(NULL);
 
 #ifdef TIERED
   m->set_rate(0);
@@ -127,6 +128,7 @@
   // know that Universe::methodKlassObj never moves.
   MarkSweep::mark_and_push(m->adr_constMethod());
   MarkSweep::mark_and_push(m->adr_constants());
+  MarkSweep::mark_and_push(m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     MarkSweep::mark_and_push(m->adr_method_data());
   }
@@ -141,6 +143,7 @@
   // know that Universe::methodKlassObj never moves.
   PSParallelCompact::mark_and_push(cm, m->adr_constMethod());
   PSParallelCompact::mark_and_push(cm, m->adr_constants());
+  PSParallelCompact::mark_and_push(cm, m->adr_graal_mirror());
 #ifdef COMPILER2
   if (m->method_data() != NULL) {
     PSParallelCompact::mark_and_push(cm, m->adr_method_data());
@@ -159,6 +162,7 @@
   // know that Universe::methodKlassObj never moves
   blk->do_oop(m->adr_constMethod());
   blk->do_oop(m->adr_constants());
+  blk->do_oop(m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     blk->do_oop(m->adr_method_data());
   }
@@ -179,6 +183,8 @@
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = m->adr_constants();
   if (mr.contains(adr)) blk->do_oop(adr);
+  adr = m->adr_graal_mirror();
+  if (mr.contains(adr)) blk->do_oop(adr);
   if (m->method_data() != NULL) {
     adr = m->adr_method_data();
     if (mr.contains(adr)) blk->do_oop(adr);
@@ -197,6 +203,7 @@
   // know that Universe::methodKlassObj never moves.
   MarkSweep::adjust_pointer(m->adr_constMethod());
   MarkSweep::adjust_pointer(m->adr_constants());
+  MarkSweep::adjust_pointer(m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     MarkSweep::adjust_pointer(m->adr_method_data());
   }
@@ -213,6 +220,7 @@
   methodOop m = methodOop(obj);
   PSParallelCompact::adjust_pointer(m->adr_constMethod());
   PSParallelCompact::adjust_pointer(m->adr_constants());
+  PSParallelCompact::adjust_pointer(m->adr_graal_mirror());
 #ifdef COMPILER2
   if (m->method_data() != NULL) {
     PSParallelCompact::adjust_pointer(m->adr_method_data());
--- a/src/share/vm/oops/methodOop.hpp	Thu Jun 16 12:09:54 2011 +0200
+++ b/src/share/vm/oops/methodOop.hpp	Thu Jun 16 20:36:17 2011 +0200
@@ -129,6 +129,8 @@
   InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
   InvocationCounter _backedge_counter;           // Incremented before each backedge taken - used to trigger frequencey-based optimizations
 
+  // com/oracle/max/graal/runtime/HotSpotMethodResolved mirroring this method
+  oop               _graal_mirror;
 #ifdef TIERED
   jlong             _prev_time;                   // Previous time the rate was acquired
   float             _rate;                        // Events (invocation and backedge counter increments) per millisecond
@@ -328,6 +330,10 @@
   int invocation_count();
   int backedge_count();
 
+  // graal mirror
+  oop graal_mirror() const               { return _graal_mirror; }
+  void set_graal_mirror(oop m)           { oop_store((oop*) &_graal_mirror, m); }
+
   bool was_executed_more_than(int n);
   bool was_never_executed()                      { return !was_executed_more_than(0); }
 
@@ -715,6 +721,7 @@
   // Garbage collection support
   oop*  adr_constMethod() const                  { return (oop*)&_constMethod;     }
   oop*  adr_constants() const                    { return (oop*)&_constants;       }
+  oop*  adr_graal_mirror() const                 { return (oop*)&_graal_mirror;    }
   oop*  adr_method_data() const                  { return (oop*)&_method_data;     }
 };