stubdefs.cpp revision ab35b50311951feea3782151dd5422ee944685c2
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