blob: de9a8e7ca318c1b0f3bb19a5e86bfecb709bdca4 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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)
buzbee9a3147c2011-03-02 15:43:48 -080014#define JIT_STUB_HACK(x)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080015
16/*
buzbee99e3e6e2011-03-29 10:26:07 -070017 * 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.fp = fp;
25
26/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080027 * Instruction framing. For a switch-oriented implementation this is
28 * case/break, for a threaded implementation it's a goto label and an
29 * instruction fetch/computed goto.
30 *
31 * Assumes the existence of "const u2* pc" and (for threaded operation)
32 * "u2 inst".
33 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080034# define H(_op) &&op_##_op
35# define HANDLE_OPCODE(_op) op_##_op:
36# define FINISH(_offset) { \
37 ADJUST_PC(_offset); \
38 inst = FETCH(0); \
buzbee9a3147c2011-03-02 15:43:48 -080039 if (self->interpBreak.ctl.subMode) { \
40 dvmCheckBefore(pc, fp, self); \
41 } \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080042 goto *handlerTable[INST_INST(inst)]; \
43 }
Andy McFadden96516932009-10-28 17:39:02 -070044# define FINISH_BKPT(_opcode) { \
45 goto *handlerTable[_opcode]; \
46 }
jeffhao71eee1f2011-01-04 14:18:54 -080047# define DISPATCH_EXTENDED(_opcode) { \
48 goto *handlerTable[0x100 + _opcode]; \
49 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080050
51#define OP_END
52
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080053/*
54 * The "goto" targets just turn into goto statements. The "arguments" are
55 * passed through local variables.
56 */
57
58#define GOTO_exceptionThrown() goto exceptionThrown;
59
60#define GOTO_returnFromMethod() goto returnFromMethod;
61
jeffhao71eee1f2011-01-04 14:18:54 -080062#define GOTO_invoke(_target, _methodCallRange, _jumboFormat) \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080063 do { \
64 methodCallRange = _methodCallRange; \
jeffhao71eee1f2011-01-04 14:18:54 -080065 jumboFormat = _jumboFormat; \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080066 goto _target; \
67 } while(false)
68
69/* for this, the "args" are already in the locals */
70#define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst) goto invokeMethod;
71
72#define GOTO_bail() goto bail;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080073
74/*
75 * Periodically check for thread suspension.
76 *
77 * While we're at it, see if a debugger has attached or the profiler has
78 * started. If so, switch to a different "goto" table.
79 */
buzbee9a3147c2011-03-02 15:43:48 -080080#define PERIODIC_CHECKS(_pcadj) { \
The Android Open Source Project99409882009-03-18 22:20:24 -070081 if (dvmCheckSuspendQuick(self)) { \
82 EXPORT_PC(); /* need for precise GC */ \
83 dvmCheckSuspendPending(self); \
84 } \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080085 }