代码改变世界

解释器入口 Interp.c

2012-04-10 20:51  至上  阅读(756)  评论(0编辑  收藏  举报
  1. void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
  2. {
  3.     InterpState interpState;
  4.     //glue结构体实例   glue就是存放信息的一个结构体  类似于ecb
  5.     bool change;
  6. #if defined(WITH_JIT)
  7. //解释器是否使用jit    编译热路径使用的  纯汇编编写 提高速度使用
  8.     /* Target-specific save/restore */
  9. //保存信息 以便回复  有一种调用函数的感觉  最后还会有返回值
  10. //那么解释器是否以一个方法作为最小单位澹(或者是一小段代码)
  11.     extern void dvmJitCalleeSave(double *saveArea);
  12.     extern void dvmJitCalleeRestore(double *saveArea);
  13.     /* Interpreter entry points from compiled code */
  14.     extern void dvmJitToInterpNormal();
  15.     extern void dvmJitToInterpNoChain();
  16.     extern void dvmJitToInterpPunt();
  17.     extern void dvmJitToInterpSingleStep();
  18.     extern void dvmJitToInterpTraceSelectNoChain();
  19.     extern void dvmJitToInterpTraceSelect();
  20.     extern void dvmJitToPatchPredictedChain();
  21.     //使用jit  需要的方法
  22. #if defined(WITH_SELF_VERIFICATION)
  23.     extern void dvmJitToInterpBackwardBranch();
  24. //关于验证的
  25. #endif
  26.     /*
  27.      * Reserve a static entity here to quickly setup runtime contents as
  28.      * gcc will issue block copy instructions.
  29.      */
  30.     static struct JitToInterpEntries jitToInterpEntries = {
  31.         dvmJitToInterpNormal,
  32.         dvmJitToInterpNoChain,
  33.         dvmJitToInterpPunt,
  34.         dvmJitToInterpSingleStep,
  35.         dvmJitToInterpTraceSelectNoChain,
  36.         dvmJitToInterpTraceSelect,
  37.         dvmJitToPatchPredictedChain,
  38. #if defined(WITH_SELF_VERIFICATION)
  39.         dvmJitToInterpBackwardBranch,
  40. #endif
  41.     };
  42.     /*
  43.      * If the previous VM left the code cache through single-stepping the
  44.      * inJitCodeCache flag will be set when the VM is re-entered (for example,
  45.      * in self-verification mode we single-step NEW_INSTANCE which may re-enter
  46.      * the VM through findClassFromLoaderNoInit). Because of that, we cannot
  47.      * assert that self->inJitCodeCache is NULL here.
  48.      */
  49. #endif
  50. #if defined(WITH_TRACKREF_CHECKS)
  51.     interpState.debugTrackedRefStart =
  52.         dvmReferenceTableEntries(&self->internalLocalRefTable);
  53. #endif
  54.     interpState.debugIsMethodEntry = true;
  55. //假设是dbg模式
  56. #if defined(WITH_JIT)
  57.     dvmJitCalleeSave(interpState.calleeSave);
  58. //调用外部方法
  59.     /* Initialize the state to kJitNot */
  60.     interpState.jitState = kJitNot;
  61. //jit状态就是指是否使用jit
  62.     /* Setup the Jit-to-interpreter entry points */
  63.     interpState.jitToInterpEntries = jitToInterpEntries;
  64. //jit的入口信息
  65.     /*
  66.      * Initialize the threshold filter [don't bother to zero out the
  67.      * actual table.  We're looking for matches, and an occasional
  68.      * false positive is acceptible.
  69.      */
  70.     interpState.lastThreshFilter = 0;
  71.     interpState.icRechainCount = PREDICTED_CHAIN_COUNTER_RECHAIN;
  72. #endif
  73.     /*
  74.      * Initialize working state.
  75.      *
  76.      * No need to initialize "retval".
  77.      //返回值不需要初始化
  78.      */
  79. //对glue结构里面的变量赋值
  80.     interpState.method = method;
  81.     interpState.fp = (u4*) self->curFrame;
  82.     interpState.pc = method->insns;
  83.     interpState.entryPoint = kInterpEntryInstr;
  84. //glue结构下的模式参数更改
  85.     if (dvmDebuggerOrProfilerActive())
  86.         interpState.nextMode = INTERP_DBG;
  87.     else
  88.         interpState.nextMode = INTERP_STD;
  89. //是不是本地方法
  90.     assert(!dvmIsNativeMethod(method));  
  91.     /*
  92.      * Make sure the class is ready to go.  Shouldn't be possible to get
  93.      * here otherwise.
  94.      */
  95.     if (method->clazz->status < CLASS_INITIALIZING ||
  96.         method->clazz->status == CLASS_ERROR)
  97.     {
  98.         LOGE("ERROR: tried to execute code in unprepared class '%s' (%d)\n",
  99.             method->clazz->descriptor, method->clazz->status);
  100.         dvmDumpThread(self, false);
  101.         dvmAbort();
  102.     }
  103.     typedef bool (*Interpreter)(Thread*, InterpState*);
  104.     //入口参数是线持刚胩与glue结构体指针
  105.     Interpreter stdInterp;
  106.     //这里是定义的一个解释器实例?
  107.     if (gDvm.executionMode == kExecutionModeInterpFast)
  108.         stdInterp = dvmMterpStd;
  109.     //如果是快速行得 就是汇编行得
  110. #if defined(WITH_JIT)
  111.     else if (gDvm.executionMode == kExecutionModeJit)
  112. /* If profiling overhead can be kept low enough, we can use a profiling
  113.  * mterp fast for both Jit and "fast" modes.  If overhead is too high,
  114.  * create a specialized profiling interpreter.
  115.  */
  116.         stdInterp = dvmMterpStd;
  117.     //汇编实现
  118. #endif
  119.     else
  120.         stdInterp = dvmInterpretStd;
  121. //c语言实现
  122.     change = true;
  123.     while (change) {
  124.         switch (interpState.nextMode) {
  125.         case INTERP_STD:
  126.             LOGVV("threadid=%d: interp STD\n", self->threadId);
  127.             change = (*stdInterp)(self, &interpState);    这里就进入解释器执行了  传入参数就是解释器类型  所属线程   所使用的glue结构体
  128.             break;
  129.         case INTERP_DBG:
  130.             LOGVV("threadid=%d: interp DBG\n", self->threadId);
  131.             change = dvmInterpretDbg(self, &interpState);    这里也是
  132.             break;
  133.         default:
  134.             dvmAbort();
  135.         }
  136.     }
  137.     *pResult = interpState.retval;
  138.     //返回值
  139. #if defined(WITH_JIT)
  140.     dvmJitCalleeRestore(interpState.calleeSave);
  141. //如果使用了jit  就采用这种回复方式
  142. #endif
  143. }

主要做了三点

1.glue结构体中变量的赋值

2.选择解释器的类型

3.判断是否是本地方法  采取不同的解释路径

 

  1. typedef struct InterpState {
  2.     const u2*   pc;                       //程序计数器
  3.     u4*         fp;                     //帧指针
  4.     JValue      retval;                      //返回值
  5.     const Method* method;                  //将要执行的方法
  6.     DvmDex*         methodClassDex;        //dex文件生成的结构
  7.     Thread*         self;                              //所属线程
  8.     void*           bailPtr;                          //出错以后跳转的目标
  9.     const u1*       interpStackEnd;                     //为加速复制到这里
  10.     volatile int*   pSelfSuspendCount;            //为加速复制到这里
  11.     InterpEntry entryPoint;                     //下一步该做什么
  12.     int         nextMode;                  //INTERP_STD还是INTERP_DBG
  13. } InterpState;

这是glue结构体  存储一定的信息  解释器在解释执行时会查看或者更改  像是存放即时信息的地方

 

还有一个问题   是谁调用了解释器的入口呢  ?

    线程与解释的关系可以通过下面的代码得到:

 

VMThread_createà

dvmCreateInterpThreadà

interpThreadStartà

dvmCallMethodà

dvmCallMethod*à

dvmInterpret

 

       由此可以看出,每个线程都最终调用了解释器代码。因此可以说线程与解释器是一一对应的关系。

所以线程与解释器有很大的关系   根据程序创建进程 创建主线程 程序代码调入内存 类加载器加载  调用解释器入口  开始解释执行