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 # define DISPATCH_EXTENDED(_opcode) { \ 49 goto *handlerTable[0x100 + _opcode]; \ 50 } 51 52 #define OP_END 53 54 /* 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 63 #define GOTO_invoke(_target, _methodCallRange, _jumboFormat) \ 64 do { \ 65 methodCallRange = _methodCallRange; \ 66 jumboFormat = _jumboFormat; \ 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 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 */ 81 #define PERIODIC_CHECKS(_pcadj) { \ 82 if (dvmCheckSuspendQuick(self)) { \ 83 EXPORT_PC(); /* need for precise GC */ \ 84 dvmCheckSuspendPending(self); \ 85 } \ 86 } 87