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