blob: 29258fc6599880107d49f0cafb993aa5e251d9d3 [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)
14
15/*
16 * Instruction framing. For a switch-oriented implementation this is
17 * case/break, for a threaded implementation it's a goto label and an
18 * instruction fetch/computed goto.
19 *
20 * Assumes the existence of "const u2* pc" and (for threaded operation)
21 * "u2 inst".
Andy McFadden96516932009-10-28 17:39:02 -070022 *
23 * TODO: remove "switch" version.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080024 */
25#ifdef THREADED_INTERP
26# define H(_op) &&op_##_op
27# define HANDLE_OPCODE(_op) op_##_op:
28# define FINISH(_offset) { \
29 ADJUST_PC(_offset); \
30 inst = FETCH(0); \
31 CHECK_DEBUG_AND_PROF(); \
32 CHECK_TRACKED_REFS(); \
Ben Cheng9c147b82009-10-07 16:41:46 -070033 if (CHECK_JIT()) GOTO_bail_switch(); \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080034 goto *handlerTable[INST_INST(inst)]; \
35 }
Andy McFadden96516932009-10-28 17:39:02 -070036# define FINISH_BKPT(_opcode) { \
37 goto *handlerTable[_opcode]; \
38 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080039#else
40# define HANDLE_OPCODE(_op) case _op:
41# define FINISH(_offset) { ADJUST_PC(_offset); break; }
Andy McFadden96516932009-10-28 17:39:02 -070042# define FINISH_BKPT(opcode) { > not implemented < }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080043#endif
44
45#define OP_END
46
47#if defined(WITH_TRACKREF_CHECKS)
48# define CHECK_TRACKED_REFS() \
49 dvmInterpCheckTrackedRefs(self, curMethod, debugTrackedRefStart)
50#else
51# define CHECK_TRACKED_REFS() ((void)0)
52#endif
53
54
55/*
56 * The "goto" targets just turn into goto statements. The "arguments" are
57 * passed through local variables.
58 */
59
60#define GOTO_exceptionThrown() goto exceptionThrown;
61
62#define GOTO_returnFromMethod() goto returnFromMethod;
63
64#define GOTO_invoke(_target, _methodCallRange) \
65 do { \
66 methodCallRange = _methodCallRange; \
67 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;
74#define GOTO_bail_switch() goto bail_switch;
75
76/*
77 * Periodically check for thread suspension.
78 *
79 * While we're at it, see if a debugger has attached or the profiler has
80 * started. If so, switch to a different "goto" table.
81 */
82#define PERIODIC_CHECKS(_entryPoint, _pcadj) { \
The Android Open Source Project99409882009-03-18 22:20:24 -070083 if (dvmCheckSuspendQuick(self)) { \
84 EXPORT_PC(); /* need for precise GC */ \
85 dvmCheckSuspendPending(self); \
86 } \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080087 if (NEED_INTERP_SWITCH(INTERP_TYPE)) { \
88 ADJUST_PC(_pcadj); \
89 interpState->entryPoint = _entryPoint; \
90 LOGVV("threadid=%d: switch to %s ep=%d adj=%d\n", \
91 self->threadId, \
92 (interpState->nextMode == INTERP_STD) ? "STD" : "DBG", \
93 (_entryPoint), (_pcadj)); \
94 GOTO_bail_switch(); \
95 } \
96 }