1    # a0 = methodToCall, a1 = returnCell, rPC = dalvikCallsite
2    lh     t7, offMethod_registersSize(a0)        # t7<- methodToCall->regsSize
3    lw     t9, offThread_interpStackEnd(rSELF)    # t9<- interpStackEnd
4    lbu    t8, offThread_breakFlags(rSELF)        # t8<- breakFlags
5    move   a3, a1                                 # a3<- returnCell
6    SAVEAREA_FROM_FP(a1, rFP)                     # a1<- stack save area
7    sll    t6, t7, 2                              # multiply regsSize by 4 (4 bytes per reg)
8    sub    a1, a1, t6                             # a1<- newFp(old savearea-regsSize)
9    SAVEAREA_FROM_FP(t0, a1)                      # t0<- stack save area
10    bgeu   t0, t9, 1f                             # bottom < interpStackEnd?
11    RETURN                                        # return to raise stack overflow excep.
12
131:
14    # a1 = newFP, a0 = methodToCall, a3 = returnCell, rPC = dalvikCallsite
15    sw     rPC, (offStackSaveArea_currentPc - sizeofStackSaveArea)(rFP)
16    sw     rPC, (offStackSaveArea_savedPc - sizeofStackSaveArea)(a1)
17    lw     rPC, offMethod_insns(a0)               # rPC<- methodToCall->insns
18
19    # set up newSaveArea
20    sw     rFP, (offStackSaveArea_prevFrame - sizeofStackSaveArea)(a1)
21    sw     a3, (offStackSaveArea_returnAddr - sizeofStackSaveArea)(a1)
22    sw     a0, (offStackSaveArea_method - sizeofStackSaveArea)(a1)
23    lw     rTEMP, offMethod_nativeFunc(a0)        # t9<- method->nativeFunc
24#if !defined(WITH_SELF_VERIFICATION)
25    beqz   t8, 2f                                 # breakFlags != 0
26    RETURN                                        # bail to the interpreter
272:
28#else
29    RETURN                                        # bail to the interpreter unconditionally
30#endif
31
32    # go ahead and transfer control to the native code
33    lw     t6, offThread_jniLocal_topCookie(rSELF)  # t6<- thread->localRef->...
34    sw     a1, offThread_curFrame(rSELF)          # self->curFrame = newFp
35    sw     zero, offThread_inJitCodeCache(rSELF)  # not in the jit code cache
36    sw     t6, (offStackSaveArea_localRefCookie - sizeofStackSaveArea)(a1)
37                                                  # newFp->localRefCookie=top
38    SAVEAREA_FROM_FP(rBIX, a1)                    # rBIX<- new stack save area
39    move   a2, a0                                 # a2<- methodToCall
40    move   a0, a1                                 # a0<- newFp
41    add    a1, rSELF, offThread_retval            # a1<- &retval
42    move   a3, rSELF                              # a3<- self
43#if defined(TEMPLATE_INLINE_PROFILING)
44    # a2: methodToCall
45    # preserve rTEMP,a0-a3
46    SCRATCH_STORE(a0, 0)
47    SCRATCH_STORE(a1, 4)
48    SCRATCH_STORE(a2, 8)
49    SCRATCH_STORE(a3, 12)
50    SCRATCH_STORE(rTEMP, 16)
51
52    move   a0, a2
53    move   a1, rSELF
54    # a0=JNIMethod, a1=rSELF
55    la      t9, dvmFastMethodTraceEnter
56    JALR(t9)                                      # off to the native code
57    lw     gp, STACK_OFFSET_GP(sp)
58
59    # restore rTEMP,a0-a3
60    SCRATCH_LOAD(rTEMP, 16)
61    SCRATCH_LOAD(a3, 12)
62    SCRATCH_LOAD(a2, 8)
63    SCRATCH_LOAD(a1, 4)
64    SCRATCH_LOAD(a0, 0)
65
66    move   rOBJ, a2                               # save a2
67#endif
68    move   t9, rTEMP
69    JALR(t9)                                   # off to the native code
70    lw     gp, STACK_OFFSET_GP(sp)
71
72#if defined(TEMPLATE_INLINE_PROFILING)
73    move   a0, rOBJ
74    move   a1, rSELF
75    # a0=JNIMethod, a1=rSELF
76    la      t9, dvmFastNativeMethodTraceExit
77    JALR(t9)
78    lw     gp, STACK_OFFSET_GP(sp)
79#endif
80
81    # native return; rBIX=newSaveArea
82    # equivalent to dvmPopJniLocals
83    lw     a2, offStackSaveArea_returnAddr(rBIX)     # a2 = chaining cell ret addr
84    lw     a0, offStackSaveArea_localRefCookie(rBIX) # a0<- saved->top
85    lw     a1, offThread_exception(rSELF)            # check for exception
86    sw     rFP, offThread_curFrame(rSELF)            # self->curFrame = fp
87    sw     a0, offThread_jniLocal_topCookie(rSELF)   # new top <- old top
88    lw     a0, (offStackSaveArea_currentPc - sizeofStackSaveArea)(rFP)
89
90    # a0 = dalvikCallsitePC
91    bnez   a1, .LhandleException                     # handle exception if any
92
93    sw     a2, offThread_inJitCodeCache(rSELF)       # set the mode properly
94    beqz   a2, 3f
95    jr     a2                                        # go if return chaining cell still exist
96
973:
98    # continue executing the next instruction through the interpreter
99    la     a1, .LdvmJitToInterpTraceSelectNoChain    # defined in footer.S
100    lw     a1, (a1)
101    add    rPC, a0, 3*2                              # reconstruct new rPC (advance 3 dalvik instr)
102
103#if defined(WITH_JIT_TUNING)
104    li     a0, kCallsiteInterpreted
105#endif
106    jr     a1
107