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

通上面的学习,先初始化解释器的状态,然后调用解释器来执行方法。解释器又分为两种,一种是使用汇编写成性能优化的解释器,一种是使用标准C语言写成的解释器,可以很通用,理解起来也容易一些。接着下来,就先来理解C语言写成的解释器,函数dvmInterpretStd的代码如下:

boolINTERP_FUNC_NAME(Thread* self,InterpState* interpState)

{

这个函数输入两个参数,第一个参数self是执行代码的线程对象;第二个参数interpState是解释器运行相关参数。



#ifdefined(EASY_GDB)

StackSaveArea* debugSaveArea =SAVEAREA_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虚拟机执行流程全部学习完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值