1%verify "executed" 2%verify "exception handled" 3 /* 4 * Execute a "native inline" instruction. 5 * 6 * We will be calling through a function table: 7 * 8 * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult) 9 * 10 * Ignores argument count - always loads 4. 11 * 12 */ 13 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 14 movl rSELF,%ecx 15 EXPORT_PC 16 movzwl 2(rPC),%eax # eax<- BBBB 17 SPILL(rIBASE) # preserve rIBASE 18 movl offThread_subMode(%ecx), %edx # edx<- submode flags 19 andl $$kSubModeDebugProfile, %edx # debug or profile mode active? 20 jnz .L${opcode}_debugprofile # yes, take slow path 21.L${opcode}_resume: 22 leal offThread_retval(%ecx),%ecx # ecx<- &self->retval 23 movl %ecx,OUT_ARG4(%esp) 24 call .L${opcode}_continue # make call; will return after 25 UNSPILL(rIBASE) # restore rIBASE 26 testl %eax,%eax # successful? 27 jz common_exceptionThrown # no, handle exception 28 FETCH_INST_OPCODE 3 %ecx 29 ADVANCE_PC 3 30 GOTO_NEXT_R %ecx 31 32.L${opcode}_continue: 33 /* 34 * Extract args, call function. 35 * ecx = #of args (0-4) 36 * eax = call index 37 * @esp = return addr 38 * esp is -4 from normal 39 * 40 * Go ahead and load all 4 args, even if not used. 41 */ 42 movzwl 4(rPC),rIBASE 43 44 movl $$0xf,%ecx 45 andl rIBASE,%ecx 46 GET_VREG_R %ecx %ecx 47 sarl $$4,rIBASE 48 movl %ecx,4+OUT_ARG0(%esp) 49 50 movl $$0xf,%ecx 51 andl rIBASE,%ecx 52 GET_VREG_R %ecx %ecx 53 sarl $$4,rIBASE 54 movl %ecx,4+OUT_ARG1(%esp) 55 56 movl $$0xf,%ecx 57 andl rIBASE,%ecx 58 GET_VREG_R %ecx %ecx 59 sarl $$4,rIBASE 60 movl %ecx,4+OUT_ARG2(%esp) 61 62 movl $$0xf,%ecx 63 andl rIBASE,%ecx 64 GET_VREG_R %ecx %ecx 65 sarl $$4,rIBASE 66 movl %ecx,4+OUT_ARG3(%esp) 67 68 sall $$4,%eax # index *= sizeof(table entry) 69 jmp *gDvmInlineOpsTable(%eax) 70 # will return to caller of .L${opcode}_continue 71 72 /* 73 * We're debugging or profiling. 74 * eax: opIndex 75 */ 76.L${opcode}_debugprofile: 77 movl %eax,OUT_ARG0(%esp) # arg0<- BBBB 78 SPILL_TMP1(%eax) # save opIndex 79 call dvmResolveInlineNative # dvmResolveInlineNative(opIndex) 80 movl rSELF,%ecx # restore self 81 testl %eax,%eax # method resolved? 82 movl %eax,%edx # save possibly resolved method in edx 83 UNSPILL_TMP1(%eax) # in case not resolved, restore opIndex 84 jz .L${opcode}_resume # not resolved, just move on 85 SPILL_TMP2(%edx) # save method 86 movl %edx,OUT_ARG0(%esp) # arg0<- method 87 movl %ecx,OUT_ARG1(%esp) # arg1<- self 88 call dvmFastMethodTraceEnter # dvmFastMethodTraceEnter(method,self) 89 movl rSELF,%ecx # restore self 90 UNSPILL_TMP1(%eax) # restore opIndex 91 leal offThread_retval(%ecx),%ecx # ecx<- &self->retval 92 movl %ecx,OUT_ARG4(%esp) # needed for pResult of inline operation handler 93 call .L${opcode}_continue # make call; will return after 94 SPILL_TMP1(%eax) # save result of inline 95 UNSPILL_TMP2(%eax) # restore method 96 movl rSELF,%ecx # restore self 97 movl %eax,OUT_ARG0(%esp) # arg0<- method 98 movl %ecx,OUT_ARG1(%esp) # arg1<- self 99 call dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self) 100 UNSPILL(rIBASE) # restore rIBASE 101 UNSPILL_TMP1(%eax) # restore result of inline 102 testl %eax,%eax # successful? 103 jz common_exceptionThrown # no, handle exception 104 FETCH_INST_OPCODE 3 %ecx 105 ADVANCE_PC 3 106 GOTO_NEXT_R %ecx 107