• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * In the C mterp stubs, "goto" is a function call followed immediately
3  * by a return.
4  */
5 
6 #define GOTO_TARGET_DECL(_target, ...)
7 
8 #define GOTO_TARGET(_target, ...) _target:
9 
10 #define GOTO_TARGET_END
11 
12 /* ugh */
13 #define STUB_HACK(x)
14 #define JIT_STUB_HACK(x)
15 
16 /*
17  * InterpSave's pc and fp must be valid when breaking out to a
18  * "Reportxxx" routine.  Because the portable interpreter uses local
19  * variables for these, we must flush prior.  Stubs, however, use
20  * the interpSave vars directly, so this is a nop for stubs.
21  */
22 #define PC_FP_TO_SELF()                                                    \
23     self->interpSave.pc = pc;                                              \
24     self->interpSave.curFrame = fp;
25 #define PC_TO_SELF() self->interpSave.pc = pc;
26 
27 /*
28  * Instruction framing.  For a switch-oriented implementation this is
29  * case/break, for a threaded implementation it's a goto label and an
30  * instruction fetch/computed goto.
31  *
32  * Assumes the existence of "const u2* pc" and (for threaded operation)
33  * "u2 inst".
34  */
35 # define H(_op)             &&op_##_op
36 # define HANDLE_OPCODE(_op) op_##_op:
37 # define FINISH(_offset) {                                                  \
38         ADJUST_PC(_offset);                                                 \
39         inst = FETCH(0);                                                    \
40         if (self->interpBreak.ctl.subMode) {                                \
41             dvmCheckBefore(pc, fp, self);                                   \
42         }                                                                   \
43         goto *handlerTable[INST_INST(inst)];                                \
44     }
45 # define FINISH_BKPT(_opcode) {                                             \
46         goto *handlerTable[_opcode];                                        \
47     }
48 
49 #define OP_END
50 
51 /*
52  * The "goto" targets just turn into goto statements.  The "arguments" are
53  * passed through local variables.
54  */
55 
56 #define GOTO_exceptionThrown() goto exceptionThrown;
57 
58 #define GOTO_returnFromMethod() goto returnFromMethod;
59 
60 #define GOTO_invoke(_target, _methodCallRange)                              \
61     do {                                                                    \
62         methodCallRange = _methodCallRange;                                 \
63         goto _target;                                                       \
64     } while(false)
65 
66 /* for this, the "args" are already in the locals */
67 #define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst) goto invokeMethod;
68 
69 #define GOTO_bail() goto bail;
70 
71 /*
72  * Periodically check for thread suspension.
73  *
74  * While we're at it, see if a debugger has attached or the profiler has
75  * started.  If so, switch to a different "goto" table.
76  */
77 #define PERIODIC_CHECKS(_pcadj) {                              \
78         if (dvmCheckSuspendQuick(self)) {                                   \
79             EXPORT_PC();  /* need for precise GC */                         \
80             dvmCheckSuspendPending(self);                                   \
81         }                                                                   \
82     }
83