TEMPLATE_INVOKE_METHOD_CHAIN.S revision a8b91c52fd8a90b784835dfe1f8898035266c4dd
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
261:
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
402:
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