OP_EXECUTE_INLINE.cpp revision 0c2dc522d0e120f346cf0a40c8cf0c93346131c2
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         * 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 & kSubModeDebugProfile) {
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);
59OP_END
60