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