diff options
| author | buzbee <buzbee@google.com> | 2010-12-13 15:33:46 -0800 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-12-13 15:33:46 -0800 |
| commit | 823a87840e570ad06c4426537477a21243474a1c (patch) | |
| tree | 7f0b30ca78f0241da3510159a4de249cff227cc4 /vm/compiler/codegen/x86/CodegenDriver.c | |
| parent | 199873ed768a8a7b0fd5525ca24407583d593345 (diff) | |
| parent | dfd1bbf07d98c82a6072182f705f64a30ebf480b (diff) | |
Merge "Experimental x86 Jit trace selection" into dalvik-dev
Diffstat (limited to 'vm/compiler/codegen/x86/CodegenDriver.c')
| -rw-r--r-- | vm/compiler/codegen/x86/CodegenDriver.c | 53 |
1 files changed, 53 insertions, 0 deletions
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,10 +24,63 @@ * 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 * or produce corresponding Thumb instructions directly. |
