1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In the C mterp stubs, "goto" is a function call followed immediately 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by a return. 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_TARGET_DECL(_target, ...) \ 7cd8f5e701547739f241594b43e9470c92d98e9cfCarl Shapiro extern "C" void dvmMterp_##_target(Thread* self, ## __VA_ARGS__); 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 97520ee7ff226e12e06818561b15741d2575072e3buzbee/* (void)xxx to quiet unused variable compiler warnings. */ 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_TARGET(_target, ...) \ 119f601a917c8878204482c37aec7005054b6776fabuzbee void dvmMterp_##_target(Thread* self, ## __VA_ARGS__) { \ 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 ref, vsrc1, vsrc2, vdst; \ 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 inst = FETCH(0); \ 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* methodToCall; \ 157520ee7ff226e12e06818561b15741d2575072e3buzbee StackSaveArea* debugSaveArea; \ 167520ee7ff226e12e06818561b15741d2575072e3buzbee (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst; \ 177520ee7ff226e12e06818561b15741d2575072e3buzbee (void)methodToCall; (void)debugSaveArea; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_TARGET_END } 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 229f601a917c8878204482c37aec7005054b6776fabuzbee * Redefine what used to be local variable accesses into Thread struct 23bbf31b58c50fb892423b7fef0d8c1093bd0c1a6cBrian Carlstrom * references. (These are undefined down in "footer.cpp".) 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 25cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee#define retval self->interpSave.retval 269f601a917c8878204482c37aec7005054b6776fabuzbee#define pc self->interpSave.pc 2730bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee#define fp self->interpSave.curFrame 289f601a917c8878204482c37aec7005054b6776fabuzbee#define curMethod self->interpSave.method 299f601a917c8878204482c37aec7005054b6776fabuzbee#define methodClassDex self->interpSave.methodClassDex 309f601a917c8878204482c37aec7005054b6776fabuzbee#define debugTrackedRefStart self->interpSave.debugTrackedRefStart 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* ugh */ 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define STUB_HACK(x) x 349a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) 359a3147c7412f4794434b4c2604aa2ba784867774buzbee#define JIT_STUB_HACK(x) x 369a3147c7412f4794434b4c2604aa2ba784867774buzbee#else 379a3147c7412f4794434b4c2604aa2ba784867774buzbee#define JIT_STUB_HACK(x) 389a3147c7412f4794434b4c2604aa2ba784867774buzbee#endif 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4099e3e6e72e3471eb85fc2e405866392b01c080febuzbee/* 4199e3e6e72e3471eb85fc2e405866392b01c080febuzbee * InterpSave's pc and fp must be valid when breaking out to a 4299e3e6e72e3471eb85fc2e405866392b01c080febuzbee * "Reportxxx" routine. Because the portable interpreter uses local 4399e3e6e72e3471eb85fc2e405866392b01c080febuzbee * variables for these, we must flush prior. Stubs, however, use 4499e3e6e72e3471eb85fc2e405866392b01c080febuzbee * the interpSave vars directly, so this is a nop for stubs. 4599e3e6e72e3471eb85fc2e405866392b01c080febuzbee */ 4699e3e6e72e3471eb85fc2e405866392b01c080febuzbee#define PC_FP_TO_SELF() 4730bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee#define PC_TO_SELF() 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Opcode handler framing macros. Here, each opcode is a separate function 519f601a917c8878204482c37aec7005054b6776fabuzbee * that takes a "self" argument and returns void. We can't declare 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * these "static" because they may be called from an assembly stub. 537520ee7ff226e12e06818561b15741d2575072e3buzbee * (void)xxx to quiet unused variable compiler warnings. 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OPCODE(_op) \ 56cd8f5e701547739f241594b43e9470c92d98e9cfCarl Shapiro extern "C" void dvmMterp_##_op(Thread* self); \ 579f601a917c8878204482c37aec7005054b6776fabuzbee void dvmMterp_##_op(Thread* self) { \ 586aed656b06aa274948bf5c5f8f65873814554c13Andy McFadden u4 ref; \ 596aed656b06aa274948bf5c5f8f65873814554c13Andy McFadden u2 vsrc1, vsrc2, vdst; \ 607520ee7ff226e12e06818561b15741d2575072e3buzbee u2 inst = FETCH(0); \ 617520ee7ff226e12e06818561b15741d2575072e3buzbee (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define OP_END } 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Like the "portable" FINISH, but don't reload "inst", and return to caller 679a3147c7412f4794434b4c2604aa2ba784867774buzbee * when done. Further, debugger/profiler checks are handled 689a3147c7412f4794434b4c2604aa2ba784867774buzbee * before handler execution in mterp, so we don't do them here either. 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 709a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define FINISH(_offset) { \ 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ADJUST_PC(_offset); \ 739a3147c7412f4794434b4c2604aa2ba784867774buzbee if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) { \ 749a3147c7412f4794434b4c2604aa2ba784867774buzbee dvmCheckJit(pc, self); \ 759a3147c7412f4794434b4c2604aa2ba784867774buzbee } \ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; \ 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 789a3147c7412f4794434b4c2604aa2ba784867774buzbee#else 799a3147c7412f4794434b4c2604aa2ba784867774buzbee#define FINISH(_offset) { \ 809a3147c7412f4794434b4c2604aa2ba784867774buzbee ADJUST_PC(_offset); \ 819a3147c7412f4794434b4c2604aa2ba784867774buzbee return; \ 829a3147c7412f4794434b4c2604aa2ba784867774buzbee } 839a3147c7412f4794434b4c2604aa2ba784867774buzbee#endif 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8575425b731c514bf90c985275d80aa7886727d83fChris Dearman#define FINISH_BKPT(_opcode) /* FIXME? */ 8675425b731c514bf90c985275d80aa7886727d83fChris Dearman#define DISPATCH_EXTENDED(_opcode) /* FIXME? */ 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The "goto label" statements turn into function calls followed by 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return statements. Some of the functions take arguments, which in the 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * portable interpreter are handled by assigning values to globals. 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_exceptionThrown() \ 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { \ 969f601a917c8878204482c37aec7005054b6776fabuzbee dvmMterp_exceptionThrown(self); \ 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; \ 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while(false) 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_returnFromMethod() \ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { \ 1029f601a917c8878204482c37aec7005054b6776fabuzbee dvmMterp_returnFromMethod(self); \ 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; \ 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while(false) 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106ab35b50311951feea3782151dd5422ee944685c2Elliott Hughes#define GOTO_invoke(_target, _methodCallRange) \ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { \ 108ab35b50311951feea3782151dd5422ee944685c2Elliott Hughes dvmMterp_##_target(self, _methodCallRange); \ 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; \ 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while(false) 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst) \ 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { \ 1149f601a917c8878204482c37aec7005054b6776fabuzbee dvmMterp_invokeMethod(self, _methodCallRange, _methodToCall, \ 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project _vsrc1, _vdst); \ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; \ 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while(false) 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1209a3147c7412f4794434b4c2604aa2ba784867774buzbee * As a special case, "goto bail" turns into a longjmp. 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_bail() \ 12375425b731c514bf90c985275d80aa7886727d83fChris Dearman dvmMterpStdBail(self) 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Periodically check for thread suspension. 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * While we're at it, see if a debugger has attached or the profiler has 1299a3147c7412f4794434b4c2604aa2ba784867774buzbee * started. 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1319a3147c7412f4794434b4c2604aa2ba784867774buzbee#define PERIODIC_CHECKS(_pcadj) { \ 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (dvmCheckSuspendQuick(self)) { \ 13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project EXPORT_PC(); /* need for precise GC */ \ 13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project dvmCheckSuspendPending(self); \ 13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } \ 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 137