1 %default { "chaintgt" : ".LinvokeChain" } 2 /* 3 * For monomorphic callsite, setup the Dalvik frame and return to the 4 * Thumb code through the link register to transfer control to the callee 5 * method through a dedicated chaining cell. 6 */ 7 # a0 = methodToCall, a1 = returnCell, rPC = dalvikCallsite 8 # methodToCall is guaranteed to be non-native 9 $chaintgt: 10 lh t7, offMethod_registersSize(a0) # t7<- methodToCall->regsSize 11 lh a2, offMethod_outsSize(a0) # a2<- methodToCall->outsSize 12 lw t9, offThread_interpStackEnd(rSELF) # t9<- interpStackEnd 13 lbu t8, offThread_breakFlags(rSELF) # t8<- breakFlags 14 move a3, a1 # a3<- returnCell 15 SAVEAREA_FROM_FP(a1, rFP) # a1<- stack save area 16 sll t6, t7, 2 # multiply regsSize by 4 (4 bytes per reg) 17 sub a1, a1, t6 # a1<- newFp(old savearea-regsSize) 18 SAVEAREA_FROM_FP(t0, a1) # t0<- stack save area 19 add t2, ra, 8 # setup the punt-to-interp address 20 # 8 bytes skips branch and delay slot 21 sll t6, a2, 2 # multiply outsSize by 4 (4 bytes per reg) 22 sub t0, t0, t6 # t0<- bottom (newsave-outsSize) 23 bgeu t0, t9, 1f # bottom < interpStackEnd? 24 jr t2 # return to raise stack overflow excep. 25 26 1: 27 # a1 = newFP, a0 = methodToCall, a3 = returnCell, rPC = dalvikCallsite 28 lw t9, offMethod_clazz(a0) # t9<- methodToCall->clazz 29 sw rPC, (offStackSaveArea_currentPc - sizeofStackSaveArea)(rFP) 30 sw rPC, (offStackSaveArea_savedPc - sizeofStackSaveArea)(a1) 31 lw rPC, offMethod_insns(a0) # rPC<- methodToCall->insns 32 33 # set up newSaveArea 34 sw rFP, (offStackSaveArea_prevFrame - sizeofStackSaveArea)(a1) 35 sw a3, (offStackSaveArea_returnAddr - sizeofStackSaveArea)(a1) 36 sw a0, (offStackSaveArea_method - sizeofStackSaveArea)(a1) 37 beqz t8, 2f # breakFlags != 0 38 jr t2 # bail to the interpreter 39 40 2: 41 lw a3, offClassObject_pDvmDex(t9) # a3<- methodToCall->clazz->pDvmDex 42 43 # Update "thread" values for the new method 44 sw a0, offThread_method(rSELF) # self->method = methodToCall 45 sw a3, offThread_methodClassDex(rSELF) # self->methodClassDex = ... 46 move rFP, a1 # fp = newFp 47 sw rFP, offThread_curFrame(rSELF) # self->curFrame = newFp 48 #if defined(TEMPLATE_INLINE_PROFILING) 49 # preserve a0-a2 and ra 50 SCRATCH_STORE(a0, 0) 51 SCRATCH_STORE(a1, 4) 52 SCRATCH_STORE(a2, 8) 53 SCRATCH_STORE(ra, 12) 54 55 move a1, rSELF 56 # a0=methodToCall, a1=rSELF 57 la t9, dvmFastMethodTraceEnter 58 jalr t9 59 lw gp, STACK_OFFSET_GP(sp) 60 61 # restore a0-a2 and ra 62 SCRATCH_LOAD(ra, 12) 63 SCRATCH_LOAD(a2, 8) 64 SCRATCH_LOAD(a1, 4) 65 SCRATCH_LOAD(a0, 0) 66 #endif 67 RETURN # return to the callee-chaining cell 68