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);
}
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 =
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];
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)) {
#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
(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;
{
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]);
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]);
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];
}
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) {
}
return true;
}
- case OP_CONST_CLASS:
- case OP_CONST_CLASS_JUMBO: {
+ case OP_CONST_CLASS: {
void *classPtr = (void*)
(method->clazz->pDvmDex->pResClasses[insn->vB]);
insn = insn->next;
}
if (insn == NULL) {
- LOGE("Break split failed");
+ ALOGE("Break split failed");
dvmAbort();
}
BasicBlock *bottomBlock = dvmCompilerNewBB(kDalvikByteCode,
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();
}
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();
}
}
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();
}
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();
}
/* 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);
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);
*/
dvmCompilerInsertBackwardChaining(cUnit);
+#if defined(ARCH_IA32)
+ /* Convert MIR to LIR, etc. */
+ dvmCompilerMIR2LIR(cUnit, info);
+#else
dvmCompilerInitializeRegAlloc(cUnit);
/* Allocate Registers using simple local allocation scheme */
/* 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;
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 || gDvmJit.receivedSIGUSR2) {
- LOGD("Loop trace @ offset %04x", cUnit->entryBlock->startOffset);
+ ALOGD("Loop trace @ offset %04x", cUnit->entryBlock->startOffset);
dvmCompilerCodegenDump(cUnit);
}
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
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;
* 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 */
}
}
+ // 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);
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);
}
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,
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);
}