blob: 57ff35c25909df3f7e5c1a0afcf3757724558e7c [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; \
buzbee30bc0d42011-04-22 10:27:14 -070024 self->interpSave.curFrame = fp;
25#define PC_TO_SELF() self->interpSave.pc = pc;
buzbee99e3e6e2011-03-29 10:26:07 -070026
27/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080028 * 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 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080035# define H(_op) &&op_##_op
36# define HANDLE_OPCODE(_op) op_##_op:
37# define FINISH(_offset) { \
38 ADJUST_PC(_offset); \
39 inst = FETCH(0); \
buzbee9a3147c2011-03-02 15:43:48 -080040 if (self->interpBreak.ctl.subMode) { \
41 dvmCheckBefore(pc, fp, self); \
42 } \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080043 goto *handlerTable[INST_INST(inst)]; \
44 }
Andy McFadden96516932009-10-28 17:39:02 -070045# define FINISH_BKPT(_opcode) { \
46 goto *handlerTable[_opcode]; \
47 }
jeffhao71eee1f2011-01-04 14:18:54 -080048# define DISPATCH_EXTENDED(_opcode) { \
49 goto *handlerTable[0x100 + _opcode]; \
50 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080051
52#define OP_END
53
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080054/*
55 * The "goto" targets just turn into goto statements. The "arguments" are
56 * passed through local variables.
57 */
58
59#define GOTO_exceptionThrown() goto exceptionThrown;
60
61#define GOTO_returnFromMethod() goto returnFromMethod;
62
jeffhao71eee1f2011-01-04 14:18:54 -080063#define GOTO_invoke(_target, _methodCallRange, _jumboFormat) \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080064 do { \
65 methodCallRange = _methodCallRange; \
jeffhao71eee1f2011-01-04 14:18:54 -080066 jumboFormat = _jumboFormat; \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080067 goto _target; \
68 } while(false)
69
70/* for this, the "args" are already in the locals */
71#define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst) goto invokeMethod;
72
73#define GOTO_bail() goto bail;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080074
75/*
76 * Periodically check for thread suspension.
77 *
78 * While we're at it, see if a debugger has attached or the profiler has
79 * started. If so, switch to a different "goto" table.
80 */
buzbee9a3147c2011-03-02 15:43:48 -080081#define PERIODIC_CHECKS(_pcadj) { \
The Android Open Source Project99409882009-03-18 22:20:24 -070082 if (dvmCheckSuspendQuick(self)) { \
83 EXPORT_PC(); /* need for precise GC */ \
84 dvmCheckSuspendPending(self); \
85 } \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080086 }