changeset 2933:7300d86deac2

Merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Fri, 10 Jun 2011 10:27:34 +0200
parents 5f1778eb3854 (current diff) 1e13559b112d (diff)
children e6dd12397b1d
files
diffstat 20 files changed, 242 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jun 10 10:27:34 2011 +0200
@@ -104,8 +104,9 @@
     // Code generator settings
     public static boolean GenLIR                             = true;
     public static boolean GenCode                            = true;
+    public static boolean UseBranchPrediction                = ____;
 
-    public static boolean UseConstDirectCall                 = false;
+    public static boolean UseConstDirectCall                 = ____;
 
     public static boolean GenSpecialDivChecks                = ____;
     public static boolean GenAssertionCode                   = ____;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Fri Jun 10 10:27:34 2011 +0200
@@ -164,7 +164,12 @@
                 assert lastOp instanceof LIRBranch : "branch must be of type LIRBranch";
                 LIRBranch lastBranch = (LIRBranch) lastOp;
 
-                assert lastBranch.block() != null : "last branch must always have a block as target";
+                if (lastBranch.block() == null) {
+                    // this might target a deoptimization stub...
+                    // TODO check if the target is really a deopt stub...
+//                    assert lastBranch.block() != null : "last branch must always have a block as target, current block #" + block.blockID();
+                    continue;
+                }
                 assert lastBranch.label() == lastBranch.block().label() : "must be equal";
 
                 if (lastBranch.info == null) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Fri Jun 10 10:27:34 2011 +0200
@@ -140,6 +140,7 @@
         stream.println("  </controlFlow>");
 
         stream.println(" </graph>");
+        flush();
     }
 
     private List<Edge> printNodes(Collection<Node> nodes, boolean shortNames, NodeMap<Block> nodeToBlock) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Fri Jun 10 10:27:34 2011 +0200
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.sun.cri.bytecode.*;
@@ -133,6 +134,14 @@
         public Block next;
     }
 
+    public static class DeoptBlock  extends Block {
+    }
+
+    public static class BranchOverride {
+        public DeoptBlock block;
+        public boolean taken;
+    }
+
     private static final Block[] NO_SUCCESSORS = new Block[0];
 
     /**
@@ -148,6 +157,8 @@
 
     private final RiMethod method;
 
+    public final HashMap<Integer, BranchOverride> branchOverride;
+
     private Block[] blockMap;
 
     private BitSet canTrap;
@@ -164,6 +175,7 @@
         }
         this.blocks = new ArrayList<Block>();
         this.storesInLoops = new BitSet(method.maxLocals());
+        branchOverride = new HashMap<Integer, BranchOverride>();
     }
 
     /**
@@ -258,8 +270,11 @@
                 case IFNULL:    // fall through
                 case IFNONNULL: {
                     current = null;
-                    Block b1 = makeBlock(bci + 3);
-                    Block b2 = makeBlock(bci + Bytes.beS2(code, bci + 1));
+
+                    int probability = GraalOptions.UseBranchPrediction ? method.branchProbability(bci) : -1;
+
+                    Block b1 = probability == 100 ? makeBranchOverrideBlock(bci, bci + 3, false) : makeBlock(bci + 3);
+                    Block b2 = probability == 0 ? makeBranchOverrideBlock(bci, bci + Bytes.beS2(code, bci + 1), true) : makeBlock(bci + Bytes.beS2(code, bci + 1));
                     setSuccessors(bci, b1, b2);
 
                     assert lengthOf(code, bci) == 3;
@@ -376,6 +391,17 @@
         }
     }
 
+    private Block makeBranchOverrideBlock(int branchBci, int startBci, boolean taken) {
+        DeoptBlock newBlock = new DeoptBlock();
+        newBlock.startBci = startBci;
+        BranchOverride override = new BranchOverride();
+        override.block = newBlock;
+        override.taken = taken;
+        assert branchOverride.get(branchBci) == null;
+        branchOverride.put(branchBci, override);
+        return newBlock;
+    }
+
     private Block[] makeSwitchSuccessors(BytecodeSwitch tswitch) {
         int max = tswitch.numberOfCases();
         Block[] successors = new Block[max + 1];
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java	Fri Jun 10 10:27:34 2011 +0200
@@ -84,6 +84,7 @@
     public final RiMethod target;
     public final RiType returnType;
     public final int bci; // XXX needed because we can not compute the bci from the sateBefore bci of this Invoke was optimized from INVOKEINTERFACE to INVOKESPECIAL
+    public final RiTypeProfile profile;
 
     /**
      * Constructs a new Invoke instruction.
@@ -95,12 +96,13 @@
      * @param target the target method being called
      * @param stateBefore the state before executing the invocation
      */
-    public Invoke(int bci, int opcode, CiKind result, Value[] args, RiMethod target, RiType returnType, Graph graph) {
+    public Invoke(int bci, int opcode, CiKind result, Value[] args, RiMethod target, RiType returnType, RiTypeProfile profile, Graph graph) {
         super(result, args.length, SUCCESSOR_COUNT, graph);
         this.opcode = opcode;
         this.target = target;
         this.returnType = returnType;
         this.bci = bci;
+        this.profile = profile;
 
         this.argumentCount = args.length;
         for (int i = 0; i < args.length; i++) {
@@ -147,6 +149,10 @@
         return target;
     }
 
+    public RiTypeProfile profile() {
+        return profile;
+    }
+
     /**
      * Checks whether this invocation has a receiver object.
      * @return {@code true} if this invocation has a receiver object; {@code false} otherwise, if this is a
@@ -196,7 +202,7 @@
 
     @Override
     public Node copy(Graph into) {
-        Invoke x = new Invoke(bci, opcode, kind, new Value[argumentCount], target, returnType, into);
+        Invoke x = new Invoke(bci, opcode, kind, new Value[argumentCount], target, returnType, profile, into);
         return x;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Jun 10 10:27:34 2011 +0200
@@ -77,6 +77,7 @@
     // bci-to-block mapping
     private Block[] blockFromBci;
     private ArrayList<Block> blockList;
+    private HashMap<Integer, BranchOverride> branchOverride;
 
     private int nextBlockNumber;
 
@@ -144,6 +145,7 @@
 
         // 2. compute the block map, setup exception handlers and get the entrypoint(s)
         BlockMap blockMap = compilation.getBlockMap(method);
+        this.branchOverride = blockMap.branchOverride;
 
         blockList = new ArrayList<Block>(blockMap.blocks);
         blockFromBci = new Block[method.code().length];
@@ -151,7 +153,7 @@
             int blockID = nextBlockNumber();
             assert blockID == i;
             Block block = blockList.get(i);
-            if (block.startBci >= 0) {
+            if (block.startBci >= 0 && !(block instanceof BlockMap.DeoptBlock)) {
                 blockFromBci[block.startBci] = block;
             }
         }
@@ -653,9 +655,20 @@
         assert !x.isDeleted() && !y.isDeleted();
         If ifNode = new If(new Compare(x, cond, y, graph), graph);
         append(ifNode);
-        Instruction tsucc = createTargetAt(stream().readBranchDest(), frameState);
+        BlockMap.BranchOverride override = branchOverride.get(bci());
+        Instruction tsucc;
+        if (override == null || override.taken == false) {
+            tsucc = createTargetAt(stream().readBranchDest(), frameState);
+        } else {
+            tsucc = createTarget(override.block, frameState);
+        }
         ifNode.setBlockSuccessor(0, tsucc);
-        Instruction fsucc = createTargetAt(stream().nextBCI(), frameState);
+        Instruction fsucc;
+        if (override == null || override.taken == true) {
+            fsucc = createTargetAt(stream().nextBCI(), frameState);
+        } else {
+            fsucc = createTarget(override.block, frameState);
+        }
         ifNode.setBlockSuccessor(1, fsucc);
     }
 
@@ -906,7 +919,7 @@
 
     private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) {
         CiKind resultType = returnKind(target);
-        Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(method.holder()), graph);
+        Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(method.holder()), method.typeProfile(bci()), graph);
         Value result = appendWithBCI(invoke);
         invoke.setExceptionEdge(handleException(null, bci()));
         frameState.pushReturn(resultType, result);
@@ -1093,7 +1106,8 @@
 
     private Instruction createTarget(Block block, FrameStateAccess stateAfter) {
         assert block != null && stateAfter != null;
-        assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : "non-loop block must be iterated after all its predecessors";
+        assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null :
+            "non-loop block must be iterated after all its predecessors. startBci=" + block.startBci + ", " + block.getClass().getSimpleName() + ", " + block.firstInstruction.next();
 
         if (block.isExceptionEntry) {
             assert stateAfter.stackSize() == 1;
@@ -1153,6 +1167,8 @@
                     createUnwindBlock(block);
                 } else if (block instanceof ExceptionBlock) {
                     createExceptionDispatch((ExceptionBlock) block);
+                } else if (block instanceof DeoptBlock) {
+                    createDeoptBlock((DeoptBlock) block);
                 } else {
                     iterateBytecodesForBlock(block);
                 }
@@ -1182,6 +1198,13 @@
         }
     }
 
+    private void createDeoptBlock(DeoptBlock block) {
+//        Merge x = new Merge(graph);
+//        x.setStateBefore(((StateSplit) block.firstInstruction).stateBefore());
+//        append(x);
+        append(new Deoptimize(graph));
+    }
+
     private void createUnwindBlock(Block block) {
         if (Modifier.isSynchronized(method.accessFlags())) {
             genMonitorExit(methodSynchronizedObject);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Fri Jun 10 10:27:34 2011 +0200
@@ -135,6 +135,12 @@
 
     private boolean checkInliningConditions(Invoke invoke) {
         String name = !trace ? null : invoke.id() + ": " + CiUtil.format("%H.%n(%p):%r", invoke.target, false);
+        if (invoke.profile() != null && invoke.profile().count < compilation.method.invocationCount() / 2) {
+            if (trace) {
+                System.out.println("not inlining " + name + " because the invocation counter is too low");
+            }
+            return false;
+        }
         if (invoke.predecessors().size() == 0) {
             if (trace) {
                 System.out.println("not inlining " + name + " because the invoke is dead code");
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java	Fri Jun 10 10:27:34 2011 +0200
@@ -39,6 +39,7 @@
     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;
@@ -89,12 +90,12 @@
 
     @Override
     public boolean isClassInitializer() {
-        return "<clinit>".equals(name);
+        return "<clinit>".equals(name) && Modifier.isStatic(accessFlags());
     }
 
     @Override
     public boolean isConstructor() {
-        return "<init>".equals(name);
+        return "<init>".equals(name) && !Modifier.isStatic(accessFlags());
     }
 
     @Override
@@ -189,4 +190,19 @@
     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);
+    }
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java	Fri Jun 10 10:27:34 2011 +0200
@@ -155,4 +155,16 @@
     public int intrinsic() {
         return 0;
     }
+
+    public int invocationCount() {
+        return -1;
+    }
+
+    public RiTypeProfile typeProfile(int bci) {
+        return null;
+    }
+
+    public int branchProbability(int bci) {
+        return -1;
+    }
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java	Fri Jun 10 10:27:34 2011 +0200
@@ -95,5 +95,11 @@
 
     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	Fri Jun 10 10:27:23 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java	Fri Jun 10 10:27:34 2011 +0200
@@ -138,5 +138,14 @@
         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/src/cpu/x86/vm/c1_globals_x86.hpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/cpu/x86/vm/c1_globals_x86.hpp	Fri Jun 10 10:27:34 2011 +0200
@@ -40,7 +40,7 @@
 define_pd_global(bool, ProfileTraps,                 false);
 define_pd_global(bool, UseOnStackReplacement,        true );
 define_pd_global(bool, TieredCompilation,            false);
-define_pd_global(intx, CompileThreshold,             1500 );
+define_pd_global(intx, CompileThreshold,             10000 );   // changed for GRAAL
 define_pd_global(intx, BackEdgeThreshold,            100000);
 
 define_pd_global(intx, OnStackReplacePercentage,     933  );
@@ -48,7 +48,7 @@
 define_pd_global(intx, NewSizeThreadIncrease,        4*K  );
 define_pd_global(intx, InitialCodeCacheSize,         160*K);
 define_pd_global(intx, ReservedCodeCacheSize,        32*M );
-define_pd_global(bool, ProfileInterpreter,           false);
+define_pd_global(bool, ProfileInterpreter,           true );    // changed for GRAAL
 define_pd_global(intx, CodeCacheExpansionSize,       32*K );
 define_pd_global(uintx,CodeCacheMinBlockLength,      1);
 define_pd_global(uintx,PermSize,                     12*M );
@@ -57,7 +57,7 @@
 define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
 define_pd_global(bool, CICompileOSR,                 true );
 #endif // !TIERED
-define_pd_global(bool, UseTypeProfile,               false);
+define_pd_global(bool, UseTypeProfile,               true );    // changed for GRAAL
 define_pd_global(bool, RoundFPResults,               true );
 
 define_pd_global(bool, LIRFillDelaySlots,            false);
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Jun 10 10:27:34 2011 +0200
@@ -2669,8 +2669,10 @@
   // fetch_unroll_info needs to call last_java_frame()
   __ set_last_Java_frame(noreg, noreg, NULL);
 
-  __ movl(c_rarg1, (int32_t)Deoptimization::Unpack_reexecute);
-  __ movl(r14, c_rarg1); // save into r14 for later call to unpack_frames
+  //  __ movl(c_rarg1, (int32_t)Deoptimization::Unpack_reexecute);
+  //  __ movl(r14, c_rarg1); // save into r14 for later call to unpack_frames
+  __ movl(c_rarg1, (int32_t)-1);
+  __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
   __ mov(c_rarg0, r15_thread);
   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
 
--- a/src/share/vm/c1/c1_Runtime1.cpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Fri Jun 10 10:27:34 2011 +0200
@@ -216,7 +216,6 @@
 
     // All other stubs should have oopmaps
     default:
-      tty->print_cr("No oopmap found for %d", id);
       assert(oop_maps != NULL, "must have an oopmap");
   }
 #endif
--- a/src/share/vm/classfile/systemDictionary.hpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Fri Jun 10 10:27:34 2011 +0200
@@ -182,14 +182,14 @@
   template(Integer_klass,                java_lang_Integer,              Pre) \
   template(Long_klass,                   java_lang_Long,                 Pre) \
                                                                               \
-  template(graalOptions_klass,             com_sun_graal_graalOptions,                                    Opt) \
-  template(HotSpotTypeResolved_klass,    com_sun_hotspot_graal_HotSpotTypeResolved,                   Opt) \
-  template(HotSpotType_klass,            com_sun_hotspot_graal_HotSpotType,                           Opt) \
-  template(HotSpotField_klass,           com_sun_hotspot_graal_HotSpotField,                          Opt) \
-  template(HotSpotMethodResolved_klass,  com_sun_hotspot_graal_HotSpotMethodResolved,                 Opt) \
-  template(HotSpotTargetMethod_klass,    com_sun_hotspot_graal_HotSpotTargetMethod,                   Opt) \
-  template(HotSpotExceptionHandler_klass,com_sun_hotspot_graal_HotSpotExceptionHandler,               Opt) \
-  template(HotSpotProxy_klass,           com_sun_hotspot_graal_HotSpotProxy,                          Opt) \
+  template(graalOptions_klass,           com_sun_graal_graalOptions,                                Opt) \
+  template(HotSpotTypeResolved_klass,    com_sun_hotspot_graal_HotSpotTypeResolved,                 Opt) \
+  template(HotSpotType_klass,            com_sun_hotspot_graal_HotSpotType,                         Opt) \
+  template(HotSpotField_klass,           com_sun_hotspot_graal_HotSpotField,                        Opt) \
+  template(HotSpotMethodResolved_klass,  com_sun_hotspot_graal_HotSpotMethodResolved,               Opt) \
+  template(HotSpotTargetMethod_klass,    com_sun_hotspot_graal_HotSpotTargetMethod,                 Opt) \
+  template(HotSpotExceptionHandler_klass,com_sun_hotspot_graal_HotSpotExceptionHandler,             Opt) \
+  template(HotSpotProxy_klass,           com_sun_hotspot_graal_HotSpotProxy,                        Opt) \
   template(CiAssumptions_klass,          com_sun_cri_ci_CiAssumptions,                              Opt) \
   template(CiAssumptions_ConcreteSubtype_klass, com_sun_cri_ci_CiAssumptions_ConcreteSubtype,       Opt) \
   template(CiAssumptions_ConcreteMethod_klass,  com_sun_cri_ci_CiAssumptions_ConcreteMethod,        Opt) \
@@ -213,6 +213,7 @@
   template(CiRuntimeCall_klass,          com_sun_cri_ci_CiRuntimeCall,                              Opt) \
   template(RiMethod_klass,               com_sun_cri_ri_RiMethod,                                   Opt) \
   template(RiExceptionHandler_klass,     com_sun_cri_ri_RiExceptionHandler,                         Opt) \
+  template(RiTypeProfile_klass,          com_sun_cri_ri_RiTypeProfile,                              Opt) \
 
   /*end*/
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Jun 10 10:27:34 2011 +0200
@@ -273,6 +273,7 @@
   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")                                          \
+  template(com_sun_cri_ri_RiTypeProfile,              "com/sun/cri/ri/RiTypeProfile")                                   \
   template(com_sun_cri_ri_RiConstantPool,             "com/sun/cri/ri/RiConstantPool")                                  \
   template(com_sun_cri_ri_RiExceptionHandler,         "com/sun/cri/ri/RiExceptionHandler")                              \
   template(com_sun_cri_ci_CiAssumptions,              "com/sun/cri/ci/CiAssumptions")                                   \
--- a/src/share/vm/graal/graalJavaAccess.cpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/share/vm/graal/graalJavaAccess.cpp	Fri Jun 10 10:27:34 2011 +0200
@@ -61,12 +61,13 @@
 #define INT_FIELD(klass, name) FIELD(klass, name, "I", false)
 #define BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", false)
 #define LONG_FIELD(klass, name) FIELD(klass, name, "J", false)
+#define FLOAT_FIELD(klass, name) FIELD(klass, name, "F", false)
 #define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false)
 #define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true)
 
 
 void graal_compute_offsets() {
-  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD)
+  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD)
 }
 
 #define EMPTY0
@@ -75,7 +76,7 @@
 #define FIELD2(klass, name) int klass::_##name##_offset = 0;
 #define FIELD3(klass, name, sig) FIELD2(klass, name)
 
-COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3)
+COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3)
 
 
 
--- a/src/share/vm/graal/graalJavaAccess.hpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Fri Jun 10 10:27:34 2011 +0200
@@ -44,7 +44,7 @@
  *
  */
 
-#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, oop_field, static_oop_field)   \
+#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(HotSpotTypeResolved)                                                      \
     oop_field(HotSpotTypeResolved, compiler, "Lcom/oracle/max/graal/runtime/Compiler;") \
     oop_field(HotSpotTypeResolved, javaMirror, "Ljava/lang/Class;")                     \
@@ -200,11 +200,14 @@
   start_class(CiStackSlot)                                                              \
     int_field(CiStackSlot, index)                                                       \
   end_class                                                                             \
+  start_class(RiTypeProfile)                                                            \
+    int_field(RiTypeProfile, count)                                                     \
+    int_field(RiTypeProfile, morphism)                                                  \
+    oop_field(RiTypeProfile, probabilities, "[F")                                       \
+    oop_field(RiTypeProfile, types, "[Lcom/sun/cri/ri/RiType;")                         \
+  end_class                                                                             \
   /* end*/
 
-
-
-
 #define START_CLASS(name)                       \
   class name : AllStatic {                      \
   private:                                      \
@@ -229,6 +232,7 @@
 #define INT_FIELD(klass, name) FIELD(name, jint, int_field)
 #define BOOLEAN_FIELD(klass, name) FIELD(name, jboolean, bool_field)
 #define LONG_FIELD(klass, name) FIELD(name, jlong, long_field)
+#define FLOAT_FIELD(klass, name) FIELD(name, jfloat, float_field)
 #define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field)
 #define STATIC_OOP_FIELD(klassName, name, signature)                \
     static int _##name##_offset;                                    \
@@ -250,7 +254,7 @@
         oopDesc::encode_store_heap_oop((oop*)addr, x);              \
       }                                                             \
     }
-COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD)
+COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD)
 #undef START_CLASS
 #undef END_CLASS
 #undef FIELD
@@ -258,6 +262,7 @@
 #undef INT_FIELD
 #undef BOOLEAN_FIELD
 #undef LONG_FIELD
+#undef FLOAT_FIELD
 #undef OOP_FIELD
 #undef STATIC_OOP_FIELD
 
--- a/src/share/vm/graal/graalVMEntries.cpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/share/vm/graal/graalVMEntries.cpp	Fri Jun 10 10:27:34 2011 +0200
@@ -30,6 +30,7 @@
 #include "graal/graalVmIds.hpp"
 #include "c1/c1_Runtime1.hpp"
 #include "memory/oopFactory.hpp"
+#include "ci/ciMethodData.hpp"
 
 // public byte[] RiMethod_code(long vmId);
 JNIEXPORT jbyteArray JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1code(JNIEnv *env, jobject, jlong vmId) {
@@ -158,6 +159,84 @@
   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) {
+  TRACE_graal_3("VMEntries::RiMethod_invocationCount");
+  return VmIds::get<methodOop>(vmId)->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) {
+  TRACE_graal_3("VMEntries::RiMethod_typeProfile");
+  ciMethod* cimethod;
+  {
+    VM_ENTRY_MARK;
+    cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get<methodOop>(vmId));
+  }
+
+  ciCallProfile profile = cimethod->call_profile_at_bci(bci);
+
+  Handle obj;
+  {
+    VM_ENTRY_MARK;
+    instanceKlass::cast(RiTypeProfile::klass())->initialize(CHECK_NULL);
+    obj = instanceKlass::cast(RiTypeProfile::klass())->allocate_instance(CHECK_NULL);
+    assert(obj() != NULL, "must succeed in allocating instance");
+
+    RiTypeProfile::set_count(obj, cimethod->scale_count(profile.count(), 1));
+    RiTypeProfile::set_morphism(obj, profile.morphism());
+
+    RiTypeProfile::set_probabilities(obj, NULL);
+    RiTypeProfile::set_types(obj, NULL);
+  }
+
+  return JNIHandles::make_local(obj());
+}
+
+// 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) {
+  TRACE_graal_3("VMEntries::RiMethod_typeProfile");
+  ciMethodData* method_data;
+  ciMethod* cimethod;
+  {
+    VM_ENTRY_MARK;
+    cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get<methodOop>(vmId));
+  }
+  method_data = cimethod->method_data();
+
+  jfloat probability = -1;
+
+  if (!method_data->is_mature()) return -1;
+
+  ciProfileData* data = method_data->bci_to_data(bci);
+  if (!data->is_JumpData())  return -1;
+
+  // get taken and not taken values
+  int     taken = data->as_JumpData()->taken();
+  int not_taken = 0;
+  if (data->is_BranchData()) {
+    not_taken = data->as_BranchData()->not_taken();
+  }
+
+  // scale the counts to be commensurate with invocation counts:
+  taken = cimethod->scale_count(taken);
+  not_taken = cimethod->scale_count(not_taken);
+
+  // Give up if too few (or too many, in which case the sum will overflow) counts to be meaningful.
+  // We also check that individual counters are positive first, otherwise the sum can become positive.
+  if (taken < 0 || not_taken < 0 || taken + not_taken < 40) return -1;
+
+  // Pin probability to sane limits
+  if (taken == 0)
+    return 0;
+  else if (not_taken == 0)
+    return 100;
+  else {                         // Compute probability of true path
+    int probability = (int)(taken * 100.0 / (taken + not_taken));
+    return MIN2(99, MAX2(1, probability));
+  }
+}
+
 // public RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass);
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass) {
   TRACE_graal_3("VMEntries::RiSignature_lookupType");
@@ -354,6 +433,7 @@
       default:
         constant.print();
         fatal("Unhandled constant");
+        break;
     }
     if (constant_object != NULL) {
       HotSpotField::set_constant(field_handle, constant_object);
@@ -614,6 +694,7 @@
 #endif // SERIALGC
     default:
       ShouldNotReachHere();
+      break;
     }
 
   jintArray arrayOffsets = env->NewIntArray(basicTypeCount);
@@ -661,6 +742,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 TYPE_PROFILE    "Lcom/sun/cri/ri/RiTypeProfile;"
 #define SIGNATURE       "Lcom/sun/cri/ri/RiSignature;"
 #define FIELD           "Lcom/sun/cri/ri/RiField;"
 #define CONSTANT_POOL   "Lcom/sun/cri/ri/RiConstantPool;"
@@ -684,6 +766,9 @@
   {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"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)},
--- a/src/share/vm/runtime/java.cpp	Fri Jun 10 10:27:23 2011 +0200
+++ b/src/share/vm/runtime/java.cpp	Fri Jun 10 10:27:34 2011 +0200
@@ -419,9 +419,9 @@
   #define BEFORE_EXIT_DONE    2
   static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
 
-  if (UseGraal) {
-    GraalCompiler::instance()->exit();
-  }
+//  if (UseGraal) {
+//    GraalCompiler::instance()->exit();
+//  }
 
   // Note: don't use a Mutex to guard the entire before_exit(), as
   // JVMTI post_thread_end_event and post_vm_death_event will run native code.