您的位置:首页 > 移动开发 > Android开发

Android培训班(77)Dalvik虚拟机的dvmInterpretStd函数

2011-10-23 09:36 363 查看
通上面的学习,先初始化解释器的状态,然后调用解释器来执行方法。解释器又分为两种,一种是使用汇编写成性能优化的解释器,一种是使用标准C语言写成的解释器,可以很通用,理解起来也容易一些。接着下来,就先来理解C语言写成的解释器,函数dvmInterpretStd的代码如下:boolINTERP_FUNC_NAME(Thread* self,InterpState* interpState){这个函数输入两个参数,第一个参数self是执行代码的线程对象;第二个参数interpState是解释器运行相关参数。

#ifdefined(EASY_GDB) StackSaveArea* debugSaveArea =S***EAREA_FROM_FP(self->curFrame);#endif这段代码保存调试数据,方便查看。

#ifINTERP_TYPE == INTERP_DBG bool debugIsMethodEntry =interpState->debugIsMethodEntry;#endif#ifdefined(WITH_TRACKREF_CHECKS) intdebugTrackedRefStart = interpState->debugTrackedRefStart;#endif DvmDex*methodClassDex; //curMethod->clazz->pDvmDex JValueretval;
/*core state */ constMethod*curMethod; // method we'reinterpreting constu2* pc; // program counter u4*fp; // frame pointer u2inst; // currentinstruction /*instruction decoding */ u2ref; // 16-bitquantity fetched directly u2vsrc1, vsrc2, vdst; // usually usedfor register indexes /*method call setup */ constMethod*methodToCall; boolmethodCallRange;这段代码是定义解释器后面使用到的变量。

#ifdefined(THREADED_INTERP) /*static computed goto table */ DEFINE_GOTO_TABLE(handlerTable);#endif
#ifdefined(WITH_JIT)#if0 LOGD("*DebugInterp- entrypointis %d, tgtis 0x%x, %s\n", interpState->entryPoint, interpState->pc, interpState->method->name);#endif
#ifINTERP_TYPE == INTERP_DBG /*Check to see if we've got a trace selection request. If we do, * but something is amiss,revert to the fast interpreter. */ if(dvmJitCheckTraceRequest(self,interpState)) { interpState->nextMode =INTERP_STD; //LOGD("**something wrong, exiting\n"); returntrue; }#endif#endif
/*copy state in */ curMethod =interpState->method; pc = interpState->pc; fp = interpState->fp; retval = interpState->retval; /* only need for kInterpEntryReturn?*/这段代码保存方法、指令指针pc、函数栈指针fp、返回指针。

methodClassDex =curMethod->clazz->pDvmDex;这行代码是保存方法所在的Dex文件指针。

LOGVV("threadid=%d:entry(%s) %s.%s pc=0x%x fp=%p ep=%d\n", self->threadId,(interpState->nextMode == INTERP_STD) ? "STD": "DBG", curMethod->clazz->descriptor,curMethod->name, pc - curMethod->insns, fp,interpState->entryPoint);
/* * DEBUG: scramble this toensure we're not relying on it. */ methodToCall = (constMethod*)-1;
#ifINTERP_TYPE == INTERP_DBG if(debugIsMethodEntry) { ILOGD("|--Now interpreting %s.%s",curMethod->clazz->descriptor, curMethod->name); DUMP_REGS(curMethod,interpState->fp, false); }#endif
switch(interpState->entryPoint) { casekInterpEntryInstr: /*just fall through to instruction loop or threaded kickstart */ break; casekInterpEntryReturn: gotoreturnFromMethod; casekInterpEntryThrow: gotoexceptionThrown; default: dvmAbort(); }这段代码是根据不同的入口点进行处理。

#ifdefTHREADED_INTERP FINISH(0); /* fetch and executefirst instruction */#else
下面开始循环地解释每条指令,直到指令完成退出为止。 while(1) { CHECK_DEBUG_AND_PROF(); /*service debugger and profiling */ CHECK_TRACKED_REFS(); /*check local reference tracking */
/*fetch the next 16 bits from the instruction stream */ inst = FETCH(0);这行代码是从指令缓冲区里获取第一条指令,在Dalvik虚拟机里每条指令的大小是两个字节,不像JAVA虚拟机,只有一个字节。

switch(INST_INST(inst)) {这行代码是根据指令选择不同的操作函数,实现每条指令实际需要操作内容,因此下面有很分支处理。
#endif
/*---start of opcodes ---*/
/*File: c/OP_NOP.c */HANDLE_OPCODE(OP_NOP) FINISH(1);OP_END这段代码,就是一个case语句,实现空指令OP_NOP的操作。空指令,就是什么事情都不做,只是简单地把执行指令的指针移到下一个指令。

/*File: c/OP_MOVE.c */HANDLE_OPCODE(OP_MOVE/*vA, vB*/) vdst = INST_A(inst); vsrc1 = INST_B(inst); ILOGV("|move%sv%d,v%d %s(v%d=0x%08x)", (INST_INST(inst) ==OP_MOVE) ? "": "-object",vdst, vsrc1, kSpacing, vdst,GET_REGISTER(vsrc1)); SET_REGISTER(vdst,GET_REGISTER(vsrc1)); FINISH(1);OP_END这段代码就是实现8位操作数的移动功能。后面还有很多指令,都是像这样的实现,就可以解释执行所有JAVA编写的应用程序了。画面漂亮、功能复杂的应用程序,就是通过这个解释器执行来实现这些功能的,到这里就把Dalvik虚拟机执行流程全部学习完成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: