blob: 717e7468c352435f731c71e11986a982f04125d5 [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".
22 */
23#ifdef THREADED_INTERP
24# define H(_op) &&op_##_op
25# define HANDLE_OPCODE(_op) op_##_op:
26# define FINISH(_offset) { \
27 ADJUST_PC(_offset); \
28 inst = FETCH(0); \
29 CHECK_DEBUG_AND_PROF(); \
30 CHECK_TRACKED_REFS(); \
Ben Cheng9c147b82009-10-07 16:41:46 -070031 if (CHECK_JIT()) GOTO_bail_switch(); \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080032 goto *handlerTable[INST_INST(inst)]; \
33 }
34#else
35# define HANDLE_OPCODE(_op) case _op:
36# define FINISH(_offset) { ADJUST_PC(_offset); break; }
37#endif
38
39#define OP_END
40
41#if defined(WITH_TRACKREF_CHECKS)
42# define CHECK_TRACKED_REFS() \
43 dvmInterpCheckTrackedRefs(self, curMethod, debugTrackedRefStart)
44#else
45# define CHECK_TRACKED_REFS() ((void)0)
46#endif
47
48
49/*
50 * The "goto" targets just turn into goto statements. The "arguments" are
51 * passed through local variables.
52 */
53
54#define GOTO_exceptionThrown() goto exceptionThrown;
55
56#define GOTO_returnFromMethod() goto returnFromMethod;
57
58#define GOTO_invoke(_target, _methodCallRange) \
59 do { \
60 methodCallRange = _methodCallRange; \
61 goto _target; \
62 } while(false)
63
64/* for this, the "args" are already in the locals */
65#define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst) goto invokeMethod;
66
67#define GOTO_bail() goto bail;
68#define GOTO_bail_switch() goto bail_switch;
69
70/*
71 * Periodically check for thread suspension.
72 *
73 * While we're at it, see if a debugger has attached or the profiler has
74 * started. If so, switch to a different "goto" table.
75 */
76#define PERIODIC_CHECKS(_entryPoint, _pcadj) { \
The Android Open Source Project99409882009-03-18 22:20:24 -070077 if (dvmCheckSuspendQuick(self)) { \
78 EXPORT_PC(); /* need for precise GC */ \
79 dvmCheckSuspendPending(self); \
80 } \
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080081 if (NEED_INTERP_SWITCH(INTERP_TYPE)) { \
82 ADJUST_PC(_pcadj); \
83 interpState->entryPoint = _entryPoint; \
84 LOGVV("threadid=%d: switch to %s ep=%d adj=%d\n", \
85 self->threadId, \
86 (interpState->nextMode == INTERP_STD) ? "STD" : "DBG", \
87 (_entryPoint), (_pcadj)); \
88 GOTO_bail_switch(); \
89 } \
90 }