From dfd1bbf07d98c82a6072182f705f64a30ebf480b Mon Sep 17 00:00:00 2001 From: buzbee Date: Wed, 22 Sep 2010 16:19:28 -0700 Subject: Experimental x86 Jit trace selection Experimental support for trace selection for x86 host mode operation. Not enabled by default. Turned on by setting WITH_HOST_DALVIK true and WITH_JIT true. When enabled, profiles during x86 fast interpreter operation, selects hot traces and "compiles" traces consisting of jumps back to the interpreter. First in a series of experimental x86 support checkins. Change-Id: I0e423ec58a7bf01f226cb486f55de2841fab1002 --- vm/compiler/codegen/x86/CodegenDriver.c | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'vm/compiler/codegen/x86/CodegenDriver.c') diff --git a/vm/compiler/codegen/x86/CodegenDriver.c b/vm/compiler/codegen/x86/CodegenDriver.c index 69f637ed7..4a5d481b9 100644 --- a/vm/compiler/codegen/x86/CodegenDriver.c +++ b/vm/compiler/codegen/x86/CodegenDriver.c @@ -24,9 +24,62 @@ * applicable directory below this one. */ +extern X86LIR *loadConstant(CompilationUnit *cUnit, int rDest, int value); +extern X86LIR *loadWordDisp(CompilationUnit *cUnit, int rBase, + int displacement, int rDest); +extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit); +extern void storeWordDisp(CompilationUnit *cUnit, int rBase, + int displacement, int rSrc); +extern X86LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc); + static int opcodeCoverage[kNumPackedOpcodes]; static intptr_t templateEntryOffsets[TEMPLATE_LAST_MARK]; +/* + * Bail to the interpreter. Will not return to this trace. + * On entry, rPC must be set correctly. + */ +static void genPuntToInterp(CompilationUnit *cUnit, unsigned int offset) +{ + dvmCompilerFlushAllRegs(cUnit); + loadConstant(cUnit, rPC, (int)(cUnit->method->insns + offset)); + loadWordDisp(cUnit, rEBP, 0, rECX); // Get glue + loadWordDisp(cUnit, rECX, + offsetof(InterpState, jitToInterpEntries.dvmJitToInterpPunt), + rEAX); + opReg(cUnit, kOpUncondBr, rEAX); +} + +static void genInterpSingleStep(CompilationUnit *cUnit, MIR *mir) +{ + int flags = dexGetFlagsFromOpcode(mir->dalvikInsn.opcode); + int flagsToCheck = kInstrCanBranch | kInstrCanSwitch | kInstrCanReturn | + kInstrCanThrow; + + //If already optimized out, just ignore + if (mir->dalvikInsn.opcode == OP_NOP) + return; + + //Ugly, but necessary. Flush all Dalvik regs so Interp can find them + dvmCompilerFlushAllRegs(cUnit); + + if ((mir->next == NULL) || (flags & flagsToCheck)) { + genPuntToInterp(cUnit, mir->offset); + return; + } + int entryAddr = offsetof(InterpState, + jitToInterpEntries.dvmJitToInterpSingleStep); + loadWordDisp(cUnit, rEBP, 0, rECX); // Get glue + loadWordDisp(cUnit, rECX, entryAddr, rEAX); // rEAX<- entry address + /* rPC = dalvik pc */ + loadConstant(cUnit, rPC, (int) (cUnit->method->insns + mir->offset)); + /* rECX = dalvik pc of following instruction */ + loadConstant(cUnit, rECX, (int) (cUnit->method->insns + mir->next->offset)); + /* Pass on the stack */ + storeWordDisp(cUnit, rESP, OUT_ARG0, rECX); + opReg(cUnit, kOpCall, rEAX); +} + /* * The following are the first-level codegen routines that analyze the format * of each bytecode then either dispatch special purpose codegen routines -- cgit v1.2.3