Home | History | Annotate | Download | only in mterp
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * Mterp entry point and support functions.
     19  */
     20 #include "mterp/Mterp.h"
     21 
     22 #include <stddef.h>
     23 
     24 
     25 /*
     26  * Verify some constants used by the mterp interpreter.
     27  */
     28 bool dvmCheckAsmConstants(void)
     29 {
     30     bool failed = false;
     31 
     32 #ifndef DVM_NO_ASM_INTERP
     33 
     34     extern char dvmAsmInstructionStart[];
     35     extern char dvmAsmInstructionEnd[];
     36     extern char dvmAsmSisterStart[];
     37     extern char dvmAsmSisterEnd[];
     38 
     39 #define ASM_DEF_VERIFY
     40 #include "mterp/common/asm-constants.h"
     41 
     42     if (failed) {
     43         LOGE("Please correct the values in mterp/common/asm-constants.h\n");
     44         dvmAbort();
     45     }
     46 
     47     /*
     48      * If an instruction overflows the 64-byte handler size limit, it will
     49      * push everything up and alter the total size.  Check it here.
     50      */
     51     const int width = 64;
     52     int interpSize = dvmAsmInstructionEnd - dvmAsmInstructionStart;
     53     if (interpSize != 0 && interpSize != 256*width) {
     54         LOGE("ERROR: unexpected asm interp size %d\n", interpSize);
     55         LOGE("(did an instruction handler exceed %d bytes?)\n", width);
     56         dvmAbort();
     57     }
     58     int sisterSize = dvmAsmSisterEnd - dvmAsmSisterStart;
     59     LOGV("mterp: interp is %d bytes, sisters are %d bytes\n",
     60         interpSize, sisterSize);
     61 
     62 #endif // ndef DVM_NO_ASM_INTERP
     63 
     64     return !failed;
     65 }
     66 
     67 
     68 /*
     69  * "Standard" mterp entry point.  This sets up a "glue" structure and then
     70  * calls into the assembly interpreter implementation.
     71  *
     72  * (There is presently no "debug" entry point.)
     73  */
     74 bool dvmMterpStd(Thread* self, InterpState* glue)
     75 {
     76     int changeInterp;
     77 
     78     /* configure mterp items */
     79     glue->self = self;
     80     glue->methodClassDex = glue->method->clazz->pDvmDex;
     81 
     82     glue->interpStackEnd = self->interpStackEnd;
     83     glue->pSelfSuspendCount = &self->suspendCount;
     84 #if defined(WITH_JIT)
     85     glue->pJitProfTable = gDvmJit.pProfTable;
     86     glue->ppJitProfTable = &gDvmJit.pProfTable;
     87     glue->jitThreshold = gDvmJit.threshold;
     88 #endif
     89 #if defined(WITH_DEBUGGER)
     90     glue->pDebuggerActive = &gDvm.debuggerActive;
     91 #endif
     92 #if defined(WITH_PROFILER)
     93     glue->pActiveProfilers = &gDvm.activeProfilers;
     94 #endif
     95 
     96     IF_LOGVV() {
     97         char* desc = dexProtoCopyMethodDescriptor(&glue->method->prototype);
     98         LOGVV("mterp threadid=%d entry %d: %s.%s %s\n",
     99             dvmThreadSelf()->threadId,
    100             glue->entryPoint,
    101             glue->method->clazz->descriptor,
    102             glue->method->name,
    103             desc);
    104         free(desc);
    105     }
    106     //LOGI("glue is %p, pc=%p, fp=%p\n", glue, glue->pc, glue->fp);
    107     //LOGI("first instruction is 0x%04x\n", glue->pc[0]);
    108 
    109     changeInterp = dvmMterpStdRun(glue);
    110 
    111 #if defined(WITH_JIT)
    112     if (glue->jitState != kJitSingleStep) {
    113         glue->self->inJitCodeCache = NULL;
    114     }
    115 #endif
    116 
    117     if (!changeInterp) {
    118         /* this is a "normal" exit; we're not coming back */
    119 #ifdef LOG_INSTR
    120         LOGD("|-- Leaving interpreter loop");
    121 #endif
    122         return false;
    123     } else {
    124         /* we're "standard", so switch to "debug" */
    125         LOGVV("  mterp returned, changeInterp=%d\n", changeInterp);
    126         glue->nextMode = INTERP_DBG;
    127         return true;
    128     }
    129 }
    130