OSDN Git Service

am e421d118: am 007c01f8: Merge "Fix a minor leak in dvmCreateInlineSubsTable"
[android-x86/dalvik.git] / vm / compiler / Frontend.cpp
index 723de86..47c1898 100644 (file)
@@ -49,7 +49,7 @@ static inline int parseInsn(const u2 *codePtr, DecodedInstruction *decInsn,
     dexDecodeInstruction(codePtr, decInsn);
     if (printMe) {
         char *decodedString = dvmCompilerGetDalvikDisassembly(decInsn, NULL);
-        LOGD("%p: %#06x %s", codePtr, opcode, decodedString);
+        ALOGD("%p: %#06x %s", codePtr, opcode, decodedString);
     }
     return dexGetWidthFromOpcode(opcode);
 }
@@ -76,17 +76,14 @@ static inline bool findBlockBoundary(const Method *caller, MIR *insn,
           break;
         case OP_INVOKE_VIRTUAL:
         case OP_INVOKE_VIRTUAL_RANGE:
-        case OP_INVOKE_VIRTUAL_JUMBO:
         case OP_INVOKE_INTERFACE:
         case OP_INVOKE_INTERFACE_RANGE:
-        case OP_INVOKE_INTERFACE_JUMBO:
         case OP_INVOKE_VIRTUAL_QUICK:
         case OP_INVOKE_VIRTUAL_QUICK_RANGE:
             *isInvoke = true;
             break;
         case OP_INVOKE_SUPER:
-        case OP_INVOKE_SUPER_RANGE:
-        case OP_INVOKE_SUPER_JUMBO: {
+        case OP_INVOKE_SUPER_RANGE: {
             int mIndex = caller->clazz->pDvmDex->
                 pResMethods[insn->dalvikInsn.vB]->methodIndex;
             const Method *calleeMethod =
@@ -100,8 +97,7 @@ static inline bool findBlockBoundary(const Method *caller, MIR *insn,
             break;
         }
         case OP_INVOKE_STATIC:
-        case OP_INVOKE_STATIC_RANGE:
-        case OP_INVOKE_STATIC_JUMBO: {
+        case OP_INVOKE_STATIC_RANGE: {
             const Method *calleeMethod =
                 caller->clazz->pDvmDex->pResMethods[insn->dalvikInsn.vB];
 
@@ -125,8 +121,7 @@ static inline bool findBlockBoundary(const Method *caller, MIR *insn,
             break;
         }
         case OP_INVOKE_DIRECT:
-        case OP_INVOKE_DIRECT_RANGE:
-        case OP_INVOKE_DIRECT_JUMBO: {
+        case OP_INVOKE_DIRECT_RANGE: {
             const Method *calleeMethod =
                 caller->clazz->pDvmDex->pResMethods[insn->dalvikInsn.vB];
             if (calleeMethod && !dvmIsNativeMethod(calleeMethod)) {
@@ -362,22 +357,22 @@ CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
 #if 0
     /* Uncomment the following to explore various callee patterns */
     if (attributes & METHOD_IS_THROW_FREE) {
-        LOGE("%s%s is inlinable%s", method->clazz->descriptor, method->name,
+        ALOGE("%s%s is inlinable%s", method->clazz->descriptor, method->name,
              (attributes & METHOD_IS_EMPTY) ? " empty" : "");
     }
 
     if (attributes & METHOD_IS_LEAF) {
-        LOGE("%s%s is leaf %d%s", method->clazz->descriptor, method->name,
+        ALOGE("%s%s is leaf %d%s", method->clazz->descriptor, method->name,
              insnSize, insnSize < 5 ? " (small)" : "");
     }
 
     if (attributes & (METHOD_IS_GETTER | METHOD_IS_SETTER)) {
-        LOGE("%s%s is %s", method->clazz->descriptor, method->name,
+        ALOGE("%s%s is %s", method->clazz->descriptor, method->name,
              attributes & METHOD_IS_GETTER ? "getter": "setter");
     }
     if (attributes ==
         (METHOD_IS_LEAF | METHOD_IS_THROW_FREE | METHOD_IS_CALLEE)) {
-        LOGE("%s%s is inlinable non setter/getter", method->clazz->descriptor,
+        ALOGE("%s%s is inlinable non setter/getter", method->clazz->descriptor,
              method->name);
     }
 #endif
@@ -403,7 +398,7 @@ static bool filterMethodByCallGraph(Thread *thread, const char *curMethodName)
                                (HashCompareFunc) strcmp, false) !=
                 NULL;
             if (found) {
-                LOGD("Method %s (--> %s) found on the JIT %s list",
+                ALOGD("Method %s (--> %s) found on the JIT %s list",
                      method->name, curMethodName,
                      gDvmJit.includeSelectedMethod ? "white" : "black");
                 return true;
@@ -428,9 +423,7 @@ bool dvmCompilerCanIncludeThisInstruction(const Method *method,
 {
     switch (insn->opcode) {
         case OP_NEW_INSTANCE:
-        case OP_NEW_INSTANCE_JUMBO:
-        case OP_CHECK_CAST:
-        case OP_CHECK_CAST_JUMBO: {
+        case OP_CHECK_CAST: {
             ClassObject *classPtr = (ClassObject *)(void*)
               (method->clazz->pDvmDex->pResClasses[insn->vB]);
 
@@ -441,33 +434,19 @@ bool dvmCompilerCanIncludeThisInstruction(const Method *method,
             return true;
         }
         case OP_SGET:
-        case OP_SGET_JUMBO:
         case OP_SGET_WIDE:
-        case OP_SGET_WIDE_JUMBO:
         case OP_SGET_OBJECT:
-        case OP_SGET_OBJECT_JUMBO:
         case OP_SGET_BOOLEAN:
-        case OP_SGET_BOOLEAN_JUMBO:
         case OP_SGET_BYTE:
-        case OP_SGET_BYTE_JUMBO:
         case OP_SGET_CHAR:
-        case OP_SGET_CHAR_JUMBO:
         case OP_SGET_SHORT:
-        case OP_SGET_SHORT_JUMBO:
         case OP_SPUT:
-        case OP_SPUT_JUMBO:
         case OP_SPUT_WIDE:
-        case OP_SPUT_WIDE_JUMBO:
         case OP_SPUT_OBJECT:
-        case OP_SPUT_OBJECT_JUMBO:
         case OP_SPUT_BOOLEAN:
-        case OP_SPUT_BOOLEAN_JUMBO:
         case OP_SPUT_BYTE:
-        case OP_SPUT_BYTE_JUMBO:
         case OP_SPUT_CHAR:
-        case OP_SPUT_CHAR_JUMBO:
-        case OP_SPUT_SHORT:
-        case OP_SPUT_SHORT_JUMBO: {
+        case OP_SPUT_SHORT: {
             void *fieldPtr = (void*)
               (method->clazz->pDvmDex->pResFields[insn->vB]);
 
@@ -477,8 +456,7 @@ bool dvmCompilerCanIncludeThisInstruction(const Method *method,
             return true;
         }
         case OP_INVOKE_SUPER:
-        case OP_INVOKE_SUPER_RANGE:
-        case OP_INVOKE_SUPER_JUMBO: {
+        case OP_INVOKE_SUPER_RANGE: {
             int mIndex = method->clazz->pDvmDex->
                 pResMethods[insn->vB]->methodIndex;
             const Method *calleeMethod = method->clazz->super->vtable[mIndex];
@@ -497,10 +475,8 @@ bool dvmCompilerCanIncludeThisInstruction(const Method *method,
         }
         case OP_INVOKE_STATIC:
         case OP_INVOKE_STATIC_RANGE:
-        case OP_INVOKE_STATIC_JUMBO:
         case OP_INVOKE_DIRECT:
-        case OP_INVOKE_DIRECT_RANGE:
-        case OP_INVOKE_DIRECT_JUMBO: {
+        case OP_INVOKE_DIRECT_RANGE: {
             const Method *calleeMethod =
                 method->clazz->pDvmDex->pResMethods[insn->vB];
             if (calleeMethod == NULL) {
@@ -508,8 +484,7 @@ bool dvmCompilerCanIncludeThisInstruction(const Method *method,
             }
             return true;
         }
-        case OP_CONST_CLASS:
-        case OP_CONST_CLASS_JUMBO: {
+        case OP_CONST_CLASS: {
             void *classPtr = (void*)
                 (method->clazz->pDvmDex->pResClasses[insn->vB]);
 
@@ -545,7 +520,7 @@ static BasicBlock *splitBlock(CompilationUnit *cUnit,
         insn = insn->next;
     }
     if (insn == NULL) {
-        LOGE("Break split failed");
+        ALOGE("Break split failed");
         dvmAbort();
     }
     BasicBlock *bottomBlock = dvmCompilerNewBB(kDalvikByteCode,
@@ -855,7 +830,7 @@ static bool verifyPredInfo(CompilationUnit *cUnit, BasicBlock *bb)
             dvmGetBlockName(bb, blockName1);
             dvmGetBlockName(predBB, blockName2);
             dvmDumpCFG(cUnit, "/sdcard/cfg/");
-            LOGE("Successor %s not found from %s",
+            ALOGE("Successor %s not found from %s",
                  blockName1, blockName2);
             dvmAbort();
         }
@@ -952,7 +927,7 @@ static void processCanBranch(CompilationUnit *cUnit, BasicBlock *curBlock,
             target += (int) insn->dalvikInsn.vB;
             break;
         default:
-            LOGE("Unexpected opcode(%d) with kInstrCanBranch set",
+            ALOGE("Unexpected opcode(%d) with kInstrCanBranch set",
                  insn->dalvikInsn.opcode);
             dvmAbort();
     }
@@ -1048,7 +1023,7 @@ static void processCanSwitch(CompilationUnit *cUnit, BasicBlock *curBlock,
     }
 
     if (curBlock->successorBlockList.blockListType != kNotUsed) {
-        LOGE("Successor block list already in use: %d",
+        ALOGE("Successor block list already in use: %d",
              curBlock->successorBlockList.blockListType);
         dvmAbort();
     }
@@ -1103,13 +1078,13 @@ static void processCanThrow(CompilationUnit *cUnit, BasicBlock *curBlock,
         DexCatchIterator iterator;
 
         if (!dexFindCatchHandler(&iterator, dexCode, curOffset)) {
-            LOGE("Catch block not found in dexfile for insn %x in %s",
+            ALOGE("Catch block not found in dexfile for insn %x in %s",
                  curOffset, method->name);
             dvmAbort();
 
         }
         if (curBlock->successorBlockList.blockListType != kNotUsed) {
-            LOGE("Successor block list already in use: %d",
+            ALOGE("Successor block list already in use: %d",
                  curBlock->successorBlockList.blockListType);
             dvmAbort();
         }
@@ -1339,10 +1314,12 @@ bool dvmCompileMethod(const Method *method, JitTranslationInfo *info)
     /* Perform SSA transformation for the whole method */
     dvmCompilerMethodSSATransformation(&cUnit);
 
+#ifndef ARCH_IA32
     dvmCompilerInitializeRegAlloc(&cUnit);  // Needs to happen after SSA naming
 
     /* Allocate Registers using simple local allocation scheme */
     dvmCompilerLocalRegAlloc(&cUnit);
+#endif
 
     /* Convert MIR to LIR, etc. */
     dvmCompilerMethodMIR2LIR(&cUnit);
@@ -1357,7 +1334,7 @@ bool dvmCompileMethod(const Method *method, JitTranslationInfo *info)
             dvmCompilerAssembleLIR(&cUnit, info);
             cUnit.assemblerRetries++;
             if (cUnit.printMe && cUnit.assemblerStatus != kSuccess)
-                LOGD("Assembler abort #%d on %d",cUnit.assemblerRetries,
+                ALOGD("Assembler abort #%d on %d",cUnit.assemblerRetries,
                       cUnit.assemblerStatus);
         } while (cUnit.assemblerStatus == kRetryAll);
 
@@ -1561,6 +1538,10 @@ static bool compileLoop(CompilationUnit *cUnit, unsigned int startOffset,
      */
     dvmCompilerInsertBackwardChaining(cUnit);
 
+#if defined(ARCH_IA32)
+    /* Convert MIR to LIR, etc. */
+    dvmCompilerMIR2LIR(cUnit, info);
+#else
     dvmCompilerInitializeRegAlloc(cUnit);
 
     /* Allocate Registers using simple local allocation scheme */
@@ -1568,11 +1549,12 @@ static bool compileLoop(CompilationUnit *cUnit, unsigned int startOffset,
 
     /* Convert MIR to LIR, etc. */
     dvmCompilerMIR2LIR(cUnit);
+#endif
 
     /* Loop contains never executed blocks / heavy instructions */
     if (cUnit->quitLoopMode) {
         if (cUnit->printMe || gDvmJit.receivedSIGUSR2) {
-            LOGD("Loop trace @ offset %04x aborted due to unresolved code info",
+            ALOGD("Loop trace @ offset %04x aborted due to unresolved code info",
                  cUnit->entryBlock->startOffset);
         }
         goto bail;
@@ -1583,7 +1565,7 @@ static bool compileLoop(CompilationUnit *cUnit, unsigned int startOffset,
         dvmCompilerAssembleLIR(cUnit, info);
         cUnit->assemblerRetries++;
         if (cUnit->printMe && cUnit->assemblerStatus != kSuccess)
-            LOGD("Assembler abort #%d on %d", cUnit->assemblerRetries,
+            ALOGD("Assembler abort #%d on %d", cUnit->assemblerRetries,
                   cUnit->assemblerStatus);
     } while (cUnit->assemblerStatus == kRetryAll);
 
@@ -1593,7 +1575,7 @@ static bool compileLoop(CompilationUnit *cUnit, unsigned int startOffset,
     }
 
     if (cUnit->printMe || gDvmJit.receivedSIGUSR2) {
-        LOGD("Loop trace @ offset %04x", cUnit->entryBlock->startOffset);
+        ALOGD("Loop trace @ offset %04x", cUnit->entryBlock->startOffset);
         dvmCompilerCodegenDump(cUnit);
     }
 
@@ -1629,6 +1611,23 @@ bail:
                            optHints | JIT_OPT_NO_LOOP);
 }
 
+static bool searchClassTablePrefix(const Method* method) {
+    if (gDvmJit.classTable == NULL) {
+        return false;
+    }
+    HashIter iter;
+    HashTable* pTab = gDvmJit.classTable;
+    for (dvmHashIterBegin(pTab, &iter); !dvmHashIterDone(&iter);
+        dvmHashIterNext(&iter))
+    {
+        const char* str = (const char*) dvmHashIterData(&iter);
+        if (strncmp(method->clazz->descriptor, str, strlen(str)) == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
 /*
  * Main entry point to start trace compilation. Basic blocks are constructed
  * first and they will be passed to the codegen routines to convert Dalvik
@@ -1699,6 +1698,12 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts,
     dvmInitGrowableList(blockList, 8);
 
     /* Identify traces that we don't want to compile */
+    if (gDvmJit.classTable) {
+        bool classFound = searchClassTablePrefix(desc->method);
+        if (gDvmJit.classTable && gDvmJit.includeSelectedMethod != classFound) {
+            return false;
+        }
+    }
     if (gDvmJit.methodTable) {
         int len = strlen(desc->method->clazz->descriptor) +
                   strlen(desc->method->name) + 1;
@@ -1759,8 +1764,12 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts,
          * 2) If includeSelectedMethod == true, the method does not match the
          *    full and partial signature stored in the hash table.
          */
-        if (gDvmJit.includeSelectedMethod != methodFound) {
+        if (gDvmJit.methodTable && gDvmJit.includeSelectedMethod != methodFound) {
+#ifdef ARCH_IA32
+            return false;
+#else
             cUnit.allSingleStep = true;
+#endif
         } else {
             /* Compile the trace as normal */
 
@@ -1771,6 +1780,22 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts,
         }
     }
 
+    // Each pair is a range, check whether curOffset falls into a range.
+    bool includeOffset = (gDvmJit.num_entries_pcTable < 2);
+    for (int pcOff = 0; pcOff < gDvmJit.num_entries_pcTable; ) {
+        if (pcOff+1 >= gDvmJit.num_entries_pcTable) {
+          break;
+        }
+        if (curOffset >= gDvmJit.pcTable[pcOff] && curOffset <= gDvmJit.pcTable[pcOff+1]) {
+            includeOffset = true;
+            break;
+        }
+        pcOff += 2;
+    }
+    if (!includeOffset) {
+        return false;
+    }
+
     /* Allocate the entry block */
     curBB = dvmCompilerNewBB(kEntryBlock, numBlocks++);
     dvmInsertGrowableList(blockList, (intptr_t) curBB);
@@ -1783,7 +1808,7 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts,
     curBB = entryCodeBB;
 
     if (cUnit.printMe) {
-        LOGD("--------\nCompiler: Building trace for %s, offset %#x",
+        ALOGD("--------\nCompiler: Building trace for %s, offset %#x",
              desc->method->name, curOffset);
     }
 
@@ -2051,7 +2076,7 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts,
     if (cUnit.printMe) {
         char* signature =
             dexProtoCopyMethodDescriptor(&desc->method->prototype);
-        LOGD("TRACEINFO (%d): 0x%08x %s%s.%s %#x %d of %d, %d blocks",
+        ALOGD("TRACEINFO (%d): 0x%08x %s%s.%s %#x %d of %d, %d blocks",
             compilationId,
             (intptr_t) desc->method->insns,
             desc->method->clazz->descriptor,
@@ -2081,31 +2106,38 @@ bool dvmCompileTrace(JitTraceDescription *desc, int numMaxInsts,
 
     dvmCompilerNonLoopAnalysis(&cUnit);
 
+#ifndef ARCH_IA32
     dvmCompilerInitializeRegAlloc(&cUnit);  // Needs to happen after SSA naming
+#endif
 
     if (cUnit.printMe) {
         dvmCompilerDumpCompilationUnit(&cUnit);
     }
 
+#ifndef ARCH_IA32
     /* Allocate Registers using simple local allocation scheme */
     dvmCompilerLocalRegAlloc(&cUnit);
 
     /* Convert MIR to LIR, etc. */
     dvmCompilerMIR2LIR(&cUnit);
+#else /* ARCH_IA32 */
+    /* Convert MIR to LIR, etc. */
+    dvmCompilerMIR2LIR(&cUnit, info);
+#endif
 
     /* Convert LIR into machine code. Loop for recoverable retries */
     do {
         dvmCompilerAssembleLIR(&cUnit, info);
         cUnit.assemblerRetries++;
         if (cUnit.printMe && cUnit.assemblerStatus != kSuccess)
-            LOGD("Assembler abort #%d on %d",cUnit.assemblerRetries,
+            ALOGD("Assembler abort #%d on %d",cUnit.assemblerRetries,
                   cUnit.assemblerStatus);
     } while (cUnit.assemblerStatus == kRetryAll);
 
     if (cUnit.printMe) {
-        LOGD("Trace Dalvik PC: %p", startCodePtr);
+        ALOGD("Trace Dalvik PC: %p", startCodePtr);
         dvmCompilerCodegenDump(&cUnit);
-        LOGD("End %s%s, %d Dalvik instructions",
+        ALOGD("End %s%s, %d Dalvik instructions",
              desc->method->clazz->descriptor, desc->method->name,
              cUnit.numInsts);
     }