Home | History | Annotate | Download | only in cstubs
      1 /* this is a standard (no debug support) interpreter */
      2 #define INTERP_TYPE INTERP_STD
      3 #define CHECK_DEBUG_AND_PROF() ((void)0)
      4 # define CHECK_TRACKED_REFS() ((void)0)
      5 #define CHECK_JIT_BOOL() (false)
      6 #define CHECK_JIT_VOID()
      7 #define ABORT_JIT_TSELECT() ((void)0)
      8 
      9 /*
     10  * In the C mterp stubs, "goto" is a function call followed immediately
     11  * by a return.
     12  */
     13 
     14 #define GOTO_TARGET_DECL(_target, ...)                                      \
     15     void dvmMterp_##_target(MterpGlue* glue, ## __VA_ARGS__);
     16 
     17 #define GOTO_TARGET(_target, ...)                                           \
     18     void dvmMterp_##_target(MterpGlue* glue, ## __VA_ARGS__) {              \
     19         u2 ref, vsrc1, vsrc2, vdst;                                         \
     20         u2 inst = FETCH(0);                                                 \
     21         const Method* methodToCall;                                         \
     22         StackSaveArea* debugSaveArea;
     23 
     24 #define GOTO_TARGET_END }
     25 
     26 /*
     27  * Redefine what used to be local variable accesses into MterpGlue struct
     28  * references.  (These are undefined down in "footer.c".)
     29  */
     30 #define retval                  glue->retval
     31 #define pc                      glue->pc
     32 #define fp                      glue->fp
     33 #define curMethod               glue->method
     34 #define methodClassDex          glue->methodClassDex
     35 #define self                    glue->self
     36 #define debugTrackedRefStart    glue->debugTrackedRefStart
     37 
     38 /* ugh */
     39 #define STUB_HACK(x) x
     40 
     41 
     42 /*
     43  * Opcode handler framing macros.  Here, each opcode is a separate function
     44  * that takes a "glue" argument and returns void.  We can't declare
     45  * these "static" because they may be called from an assembly stub.
     46  */
     47 #define HANDLE_OPCODE(_op)                                                  \
     48     void dvmMterp_##_op(MterpGlue* glue) {                                  \
     49         u2 ref, vsrc1, vsrc2, vdst;                                         \
     50         u2 inst = FETCH(0);
     51 
     52 #define OP_END }
     53 
     54 /*
     55  * Like the "portable" FINISH, but don't reload "inst", and return to caller
     56  * when done.
     57  */
     58 #define FINISH(_offset) {                                                   \
     59         ADJUST_PC(_offset);                                                 \
     60         CHECK_DEBUG_AND_PROF();                                             \
     61         CHECK_TRACKED_REFS();                                               \
     62         return;                                                             \
     63     }
     64 
     65 
     66 /*
     67  * The "goto label" statements turn into function calls followed by
     68  * return statements.  Some of the functions take arguments, which in the
     69  * portable interpreter are handled by assigning values to globals.
     70  */
     71 
     72 #define GOTO_exceptionThrown()                                              \
     73     do {                                                                    \
     74         dvmMterp_exceptionThrown(glue);                                     \
     75         return;                                                             \
     76     } while(false)
     77 
     78 #define GOTO_returnFromMethod()                                             \
     79     do {                                                                    \
     80         dvmMterp_returnFromMethod(glue);                                    \
     81         return;                                                             \
     82     } while(false)
     83 
     84 #define GOTO_invoke(_target, _methodCallRange)                              \
     85     do {                                                                    \
     86         dvmMterp_##_target(glue, _methodCallRange);                         \
     87         return;                                                             \
     88     } while(false)
     89 
     90 #define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst)   \
     91     do {                                                                    \
     92         dvmMterp_invokeMethod(glue, _methodCallRange, _methodToCall,        \
     93             _vsrc1, _vdst);                                                 \
     94         return;                                                             \
     95     } while(false)
     96 
     97 /*
     98  * As a special case, "goto bail" turns into a longjmp.  Use "bail_switch"
     99  * if we need to switch to the other interpreter upon our return.
    100  */
    101 #define GOTO_bail()                                                         \
    102     dvmMterpStdBail(glue, false);
    103 #define GOTO_bail_switch()                                                  \
    104     dvmMterpStdBail(glue, true);
    105 
    106 /*
    107  * Periodically check for thread suspension.
    108  *
    109  * While we're at it, see if a debugger has attached or the profiler has
    110  * started.  If so, switch to a different "goto" table.
    111  */
    112 #define PERIODIC_CHECKS(_entryPoint, _pcadj) {                              \
    113         if (dvmCheckSuspendQuick(self)) {                                   \
    114             EXPORT_PC();  /* need for precise GC */                         \
    115             dvmCheckSuspendPending(self);                                   \
    116         }                                                                   \
    117         if (NEED_INTERP_SWITCH(INTERP_TYPE)) {                              \
    118             ADJUST_PC(_pcadj);                                              \
    119             glue->entryPoint = _entryPoint;                                 \
    120             LOGVV("threadid=%d: switch to STD ep=%d adj=%d\n",              \
    121                 self->threadId, (_entryPoint), (_pcadj));                   \
    122             GOTO_bail_switch();                                             \
    123         }                                                                   \
    124     }
    125