changeset 2944:cc4b538852e3

Merge.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Thu, 09 Jun 2011 17:34:10 +0200
parents 3891afa020da (current diff) f9c6d9bc4fbc (diff)
children 41318fcb6b56
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java
diffstat 8 files changed, 85 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Thu Jun 09 17:33:59 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Thu Jun 09 17:34:10 2011 +0200
@@ -133,6 +133,9 @@
         public Block next;
     }
 
+    public static class DeoptBlock  extends Block {
+    }
+
     private static final Block[] NO_SUCCESSORS = new Block[0];
 
     /**
@@ -257,9 +260,15 @@
                 case IF_ACMPNE: // fall through
                 case IFNULL:    // fall through
                 case IFNONNULL: {
+                    int probability = method.branchProbability(bci);
+//                    if (probability == 0 || probability == 100) {
+//                        System.out.println("prob: " + probability);
+//                    }
                     current = null;
                     Block b1 = makeBlock(bci + 3);
                     Block b2 = makeBlock(bci + Bytes.beS2(code, bci + 1));
+//                    Block b1 = probability == 100 ? makeDeoptBlock(bci + 3) : makeBlock(bci + 3);
+//                    Block b2 = probability == 0 ? makeDeoptBlock(bci + Bytes.beS2(code, bci + 1)) : makeBlock(bci + Bytes.beS2(code, bci + 1));
                     setSuccessors(bci, b1, b2);
 
                     assert lengthOf(code, bci) == 3;
@@ -376,6 +385,14 @@
         }
     }
 
+    private Block makeDeoptBlock(int startBci) {
+        System.out.println("Deopt block created");
+        DeoptBlock newBlock = new DeoptBlock();
+        newBlock.startBci = startBci;
+        blockMap[startBci] = newBlock;
+        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/phases/GraphBuilderPhase.java	Thu Jun 09 17:33:59 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jun 09 17:34:10 2011 +0200
@@ -31,6 +31,7 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.compiler.graph.BlockMap.DeoptBlock;
 import com.oracle.max.graal.compiler.graph.BlockMap.*;
 import com.oracle.max.graal.compiler.graph.BlockMap.Block;
 import com.oracle.max.graal.compiler.ir.*;
@@ -1155,6 +1156,8 @@
                     createUnwindBlock(block);
                 } else if (block instanceof ExceptionBlock) {
                     createExceptionDispatch((ExceptionBlock) block);
+                } else if (block instanceof DeoptBlock) {
+                    createDeoptBlock((DeoptBlock) block);
                 } else {
                     iterateBytecodesForBlock(block);
                 }
@@ -1184,6 +1187,10 @@
         }
     }
 
+    private void createDeoptBlock(DeoptBlock block) {
+        append(new Deoptimize(graph));
+    }
+
     private void createUnwindBlock(Block block) {
         if (Modifier.isSynchronized(method.accessFlags())) {
             genMonitorExit(methodSynchronizedObject);
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java	Thu Jun 09 17:33:59 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolved.java	Thu Jun 09 17:34:10 2011 +0200
@@ -201,4 +201,8 @@
     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	Thu Jun 09 17:33:59 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java	Thu Jun 09 17:34:10 2011 +0200
@@ -163,4 +163,8 @@
     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	Thu Jun 09 17:33:59 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java	Thu Jun 09 17:34:10 2011 +0200
@@ -99,5 +99,7 @@
 
     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 09 17:33:59 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java	Thu Jun 09 17:34:10 2011 +0200
@@ -144,5 +144,8 @@
     @Override
     public native RiTypeProfile RiMethod_typeProfile(long vmId, int bci);
 
+    @Override
+    public native int RiMethod_branchProbability(long vmId, int bci);
+
     // Checkstyle: resume
 }
--- a/src/share/vm/c1/c1_Runtime1.cpp	Thu Jun 09 17:33:59 2011 +0200
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Thu Jun 09 17:34:10 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/graal/graalVMEntries.cpp	Thu Jun 09 17:33:59 2011 +0200
+++ b/src/share/vm/graal/graalVMEntries.cpp	Thu Jun 09 17:34:10 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,13 +159,13 @@
   return JNIHandles::make_local(THREAD, method_resolved);
 }
 
-// public native int RiMethod_invocationCount();
+// 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(int bci);
+// 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;
@@ -192,6 +193,50 @@
   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");
@@ -723,6 +768,7 @@
   {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)},