1 HANDLE_OPCODE(OP_EXECUTE_INLINE /*vB, {vD, vE, vF, vG}, inline@CCCC*/) 2 { 3 /* 4 * This has the same form as other method calls, but we ignore 5 * the 5th argument (vA). This is chiefly because the first four 6 * arguments to a function on ARM are in registers. 7 * 8 * We only set the arguments that are actually used, leaving 9 * the rest uninitialized. We're assuming that, if the method 10 * needs them, they'll be specified in the call. 11 * 12 * However, this annoys gcc when optimizations are enabled, 13 * causing a "may be used uninitialized" warning. Quieting 14 * the warnings incurs a slight penalty (5%: 373ns vs. 393ns 15 * on empty method). Note that valgrind is perfectly happy 16 * either way as the uninitialiezd values are never actually 17 * used. 18 */ 19 u4 arg0, arg1, arg2, arg3; 20 arg0 = arg1 = arg2 = arg3 = 0; 21 22 EXPORT_PC(); 23 24 vsrc1 = INST_B(inst); /* #of args */ 25 ref = FETCH(1); /* inline call "ref" */ 26 vdst = FETCH(2); /* 0-4 register indices */ 27 ILOGV("|execute-inline args=%d @%d {regs=0x%04x}", 28 vsrc1, ref, vdst); 29 30 assert((vdst >> 16) == 0); // 16-bit type -or- high 16 bits clear 31 assert(vsrc1 <= 4); 32 33 switch (vsrc1) { 34 case 4: 35 arg3 = GET_REGISTER(vdst >> 12); 36 /* fall through */ 37 case 3: 38 arg2 = GET_REGISTER((vdst & 0x0f00) >> 8); 39 /* fall through */ 40 case 2: 41 arg1 = GET_REGISTER((vdst & 0x00f0) >> 4); 42 /* fall through */ 43 case 1: 44 arg0 = GET_REGISTER(vdst & 0x0f); 45 /* fall through */ 46 default: // case 0 47 ; 48 } 49 50 if (self->interpBreak.ctl.subMode & kSubModeDebuggerActive) { 51 if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref)) 52 GOTO_exceptionThrown(); 53 } else { 54 if (!dvmPerformInlineOp4Std(arg0, arg1, arg2, arg3, &retval, ref)) 55 GOTO_exceptionThrown(); 56 } 57 } 58 FINISH(3); 59 OP_END 60