1%default { "chaintgt" : ".LinvokeChain" }
2    /*
3     * For polymorphic callsite, check whether the cached class pointer matches
4     * the current one. If so setup the Dalvik frame and return to the
5     * Thumb code through the link register to transfer control to the callee
6     * method through a dedicated chaining cell.
7     *
8     * The predicted chaining cell is declared in ArmLIR.h with the
9     * following layout:
10     *
11     *  typedef struct PredictedChainingCell {
12     *      u4 branch;
13     *      u4 delay_slot;
14     *      const ClassObject *clazz;
15     *      const Method *method;
16     *      u4 counter;
17     *  } PredictedChainingCell;
18     *
19     * Upon returning to the callsite:
20     *    - lr   : to branch to the chaining cell
21     *    - lr+8 : to punt to the interpreter
22     *    - lr+16: to fully resolve the callee and may rechain.
23     *             a3 <- class
24     */
25    # a0 = this, a1 = returnCell, a2 = predictedChainCell, rPC = dalvikCallsite
26    lw      a3, offObject_clazz(a0)     # a3 <- this->class
27    lw      rIBASE, 8(a2)                   # t0 <- predictedChainCell->clazz
28    lw      a0, 12(a2)                  # a0 <- predictedChainCell->method
29    lw      t1, offThread_icRechainCount(rSELF)    # t1 <- shared rechainCount
30
31#if defined(WITH_JIT_TUNING)
32    la      rINST, .LdvmICHitCount
33    #add     t2, t2, 1
34    bne    a3, rIBASE, 1f
35    nop
36    lw      t2, 0(rINST)
37    add     t2, t2, 1
38    sw      t2, 0(rINST)
391:
40    #add     t2, t2, 1
41#endif
42    beq     a3, rIBASE, $chaintgt       # branch if predicted chain is valid
43    lw      rINST, offClassObject_vtable(a3)     # rINST <- this->class->vtable
44    beqz    rIBASE, 2f                      # initialized class or not
45    sub     a1, t1, 1                   # count--
46    sw      a1, offThread_icRechainCount(rSELF)   # write back to InterpState
47    b       3f
482:
49    move    a1, zero
503:
51    add     ra, ra, 16                  # return to fully-resolve landing pad
52    /*
53     * a1 <- count
54     * a2 <- &predictedChainCell
55     * a3 <- this->class
56     * rPC <- dPC
57     * rINST <- this->class->vtable
58     */
59    RETURN
60