• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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