Home | History | Annotate | Download | only in c
      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