解释器入口 Interp.c
2012-04-10 20:51 至上 阅读(757) 评论(0) 编辑 收藏 举报- void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
- {
- InterpState interpState;
- //glue结构体实例 glue就是存放信息的一个结构体 类似于ecb
- bool change;
- #if defined(WITH_JIT)
- //解释器是否使用jit 编译热路径使用的 纯汇编编写 提高速度使用
- /* Target-specific save/restore */
- //保存信息 以便回复 有一种调用函数的感觉 最后还会有返回值
- //那么解释器是否以一个方法作为最小单位澹(或者是一小段代码)
- extern void dvmJitCalleeSave(double *saveArea);
- extern void dvmJitCalleeRestore(double *saveArea);
- /* Interpreter entry points from compiled code */
- extern void dvmJitToInterpNormal();
- extern void dvmJitToInterpNoChain();
- extern void dvmJitToInterpPunt();
- extern void dvmJitToInterpSingleStep();
- extern void dvmJitToInterpTraceSelectNoChain();
- extern void dvmJitToInterpTraceSelect();
- extern void dvmJitToPatchPredictedChain();
- //使用jit 需要的方法
- #if defined(WITH_SELF_VERIFICATION)
- extern void dvmJitToInterpBackwardBranch();
- //关于验证的
- #endif
- /*
- * Reserve a static entity here to quickly setup runtime contents as
- * gcc will issue block copy instructions.
- */
- static struct JitToInterpEntries jitToInterpEntries = {
- dvmJitToInterpNormal,
- dvmJitToInterpNoChain,
- dvmJitToInterpPunt,
- dvmJitToInterpSingleStep,
- dvmJitToInterpTraceSelectNoChain,
- dvmJitToInterpTraceSelect,
- dvmJitToPatchPredictedChain,
- #if defined(WITH_SELF_VERIFICATION)
- dvmJitToInterpBackwardBranch,
- #endif
- };
- /*
- * If the previous VM left the code cache through single-stepping the
- * inJitCodeCache flag will be set when the VM is re-entered (for example,
- * in self-verification mode we single-step NEW_INSTANCE which may re-enter
- * the VM through findClassFromLoaderNoInit). Because of that, we cannot
- * assert that self->inJitCodeCache is NULL here.
- */
- #endif
- #if defined(WITH_TRACKREF_CHECKS)
- interpState.debugTrackedRefStart =
- dvmReferenceTableEntries(&self->internalLocalRefTable);
- #endif
- interpState.debugIsMethodEntry = true;
- //假设是dbg模式
- #if defined(WITH_JIT)
- dvmJitCalleeSave(interpState.calleeSave);
- //调用外部方法
- /* Initialize the state to kJitNot */
- interpState.jitState = kJitNot;
- //jit状态就是指是否使用jit
- /* Setup the Jit-to-interpreter entry points */
- interpState.jitToInterpEntries = jitToInterpEntries;
- //jit的入口信息
- /*
- * Initialize the threshold filter [don't bother to zero out the
- * actual table. We're looking for matches, and an occasional
- * false positive is acceptible.
- */
- interpState.lastThreshFilter = 0;
- interpState.icRechainCount = PREDICTED_CHAIN_COUNTER_RECHAIN;
- #endif
- /*
- * Initialize working state.
- *
- * No need to initialize "retval".
- //返回值不需要初始化
- */
- //对glue结构里面的变量赋值
- interpState.method = method;
- interpState.fp = (u4*) self->curFrame;
- interpState.pc = method->insns;
- interpState.entryPoint = kInterpEntryInstr;
- //glue结构下的模式参数更改
- if (dvmDebuggerOrProfilerActive())
- interpState.nextMode = INTERP_DBG;
- else
- interpState.nextMode = INTERP_STD;
- //是不是本地方法
- assert(!dvmIsNativeMethod(method));
- /*
- * Make sure the class is ready to go. Shouldn't be possible to get
- * here otherwise.
- */
- if (method->clazz->status < CLASS_INITIALIZING ||
- method->clazz->status == CLASS_ERROR)
- {
- LOGE("ERROR: tried to execute code in unprepared class '%s' (%d)\n",
- method->clazz->descriptor, method->clazz->status);
- dvmDumpThread(self, false);
- dvmAbort();
- }
- typedef bool (*Interpreter)(Thread*, InterpState*);
- //入口参数是线持刚胩与glue结构体指针
- Interpreter stdInterp;
- //这里是定义的一个解释器实例?
- if (gDvm.executionMode == kExecutionModeInterpFast)
- stdInterp = dvmMterpStd;
- //如果是快速行得 就是汇编行得
- #if defined(WITH_JIT)
- else if (gDvm.executionMode == kExecutionModeJit)
- /* If profiling overhead can be kept low enough, we can use a profiling
- * mterp fast for both Jit and "fast" modes. If overhead is too high,
- * create a specialized profiling interpreter.
- */
- stdInterp = dvmMterpStd;
- //汇编实现
- #endif
- else
- stdInterp = dvmInterpretStd;
- //c语言实现
- change = true;
- while (change) {
- switch (interpState.nextMode) {
- case INTERP_STD:
- LOGVV("threadid=%d: interp STD\n", self->threadId);
- change = (*stdInterp)(self, &interpState); 这里就进入解释器执行了 传入参数就是解释器类型 所属线程 所使用的glue结构体
- break;
- case INTERP_DBG:
- LOGVV("threadid=%d: interp DBG\n", self->threadId);
- change = dvmInterpretDbg(self, &interpState); 这里也是
- break;
- default:
- dvmAbort();
- }
- }
- *pResult = interpState.retval;
- //返回值
- #if defined(WITH_JIT)
- dvmJitCalleeRestore(interpState.calleeSave);
- //如果使用了jit 就采用这种回复方式
- #endif
- }
主要做了三点
1.glue结构体中变量的赋值
2.选择解释器的类型
3.判断是否是本地方法 采取不同的解释路径
- typedef struct InterpState {
- const u2* pc; //程序计数器
- u4* fp; //帧指针
- JValue retval; //返回值
- const Method* method; //将要执行的方法
- DvmDex* methodClassDex; //dex文件生成的结构
- Thread* self; //所属线程
- void* bailPtr; //出错以后跳转的目标
- const u1* interpStackEnd; //为加速复制到这里
- volatile int* pSelfSuspendCount; //为加速复制到这里
- InterpEntry entryPoint; //下一步该做什么
- int nextMode; //INTERP_STD还是INTERP_DBG
- } InterpState;
这是glue结构体 存储一定的信息 解释器在解释执行时会查看或者更改 像是存放即时信息的地方
还有一个问题 是谁调用了解释器的入口呢 ?
线程与解释的关系可以通过下面的代码得到:
VMThread_createà
dvmCreateInterpThreadà
interpThreadStartà
dvmCallMethodà
dvmCallMethod*à
dvmInterpret
由此可以看出,每个线程都最终调用了解释器代码。因此可以说线程与解释器是一一对应的关系。
所以线程与解释器有很大的关系 根据程序创建进程 创建主线程 程序代码调入内存 类加载器加载 调用解释器入口 开始解释执行