%default { "chaintgt" : ".LinvokeChain" } /* * For polymorphic callsite, check whether the cached class pointer matches * the current one. If so setup the Dalvik frame and return to the * Thumb code through the link register to transfer control to the callee * method through a dedicated chaining cell. * * The predicted chaining cell is declared in ArmLIR.h with the * following layout: * * typedef struct PredictedChainingCell { * u4 branch; * u4 delay_slot; * const ClassObject *clazz; * const Method *method; * u4 counter; * } PredictedChainingCell; * * Upon returning to the callsite: * - lr : to branch to the chaining cell * - lr+8 : to punt to the interpreter * - lr+16: to fully resolve the callee and may rechain. * a3 <- class */ # a0 = this, a1 = returnCell, a2 = predictedChainCell, rPC = dalvikCallsite lw a3, offObject_clazz(a0) # a3 <- this->class lw rIBASE, 8(a2) # t0 <- predictedChainCell->clazz lw a0, 12(a2) # a0 <- predictedChainCell->method lw t1, offThread_icRechainCount(rSELF) # t1 <- shared rechainCount #if defined(WITH_JIT_TUNING) la rINST, .LdvmICHitCount #add t2, t2, 1 bne a3, rIBASE, 1f nop lw t2, 0(rINST) add t2, t2, 1 sw t2, 0(rINST) 1: #add t2, t2, 1 #endif beq a3, rIBASE, $chaintgt # branch if predicted chain is valid lw rINST, offClassObject_vtable(a3) # rINST <- this->class->vtable beqz rIBASE, 2f # initialized class or not sub a1, t1, 1 # count-- sw a1, offThread_icRechainCount(rSELF) # write back to InterpState b 3f 2: move a1, zero 3: add ra, ra, 16 # return to fully-resolve landing pad /* * a1 <- count * a2 <- &predictedChainCell * a3 <- this->class * rPC <- dPC * rINST <- this->class->vtable */ RETURN