1HANDLE_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 * This annoys gcc when optimizations are enabled, causing a 13 * "may be used uninitialized" warning. We can quiet the warnings 14 * for a slight penalty (5%: 373ns vs. 393ns on empty method). Note 15 * that valgrind is perfectly happy with this arrangement, because 16 * the uninitialiezd values are never actually used. 17 */ 18 u4 arg0, arg1, arg2, arg3; 19 //arg0 = arg1 = arg2 = arg3 = 0; 20 21 EXPORT_PC(); 22 23 vsrc1 = INST_B(inst); /* #of args */ 24 ref = FETCH(1); /* inline call "ref" */ 25 vdst = FETCH(2); /* 0-4 register indices */ 26 ILOGV("|execute-inline args=%d @%d {regs=0x%04x}", 27 vsrc1, ref, vdst); 28 29 assert((vdst >> 16) == 0); // 16-bit type -or- high 16 bits clear 30 assert(vsrc1 <= 4); 31 32 switch (vsrc1) { 33 case 4: 34 arg3 = GET_REGISTER(vdst >> 12); 35 /* fall through */ 36 case 3: 37 arg2 = GET_REGISTER((vdst & 0x0f00) >> 8); 38 /* fall through */ 39 case 2: 40 arg1 = GET_REGISTER((vdst & 0x00f0) >> 4); 41 /* fall through */ 42 case 1: 43 arg0 = GET_REGISTER(vdst & 0x0f); 44 /* fall through */ 45 default: // case 0 46 ; 47 } 48 49#if INTERP_TYPE == INTERP_DBG 50 if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref)) 51 GOTO_exceptionThrown(); 52#else 53 if (!dvmPerformInlineOp4Std(arg0, arg1, arg2, arg3, &retval, ref)) 54 GOTO_exceptionThrown(); 55#endif 56 } 57 FINISH(3); 58OP_END 59