1 /* 2 * For polymorphic callsite, check whether the cached class pointer matches 3 * the current one. If so 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 * The predicted chaining cell is declared in ArmLIR.h with the 8 * following layout: 9 * 10 * typedef struct PredictedChainingCell { 11 * u4 branch; 12 * const ClassObject *clazz; 13 * const Method *method; 14 * u4 counter; 15 * } PredictedChainingCell; 16 * 17 * Upon returning to the callsite: 18 * - lr : to branch to the chaining cell 19 * - lr+2: to punt to the interpreter 20 * - lr+4: to fully resolve the callee and may rechain. 21 * r3 <- class 22 * r9 <- counter 23 */ 24 @ r0 = this, r1 = returnCell, r2 = predictedChainCell, rPC = dalvikCallsite 25 ldr r3, [r0, #offObject_clazz] @ r3 <- this->class 26 ldr r8, [r2, #4] @ r8 <- predictedChainCell->clazz 27 ldr r0, [r2, #8] @ r0 <- predictedChainCell->method 28 ldr r9, [rGLUE, #offGlue_icRechainCount] @ r1 <- shared rechainCount 29 cmp r3, r8 @ predicted class == actual class? 30 #if defined(WITH_JIT_TUNING) 31 ldr r7, .LdvmICHitCount 32 ldreq r10, [r7, #0] 33 add r10, r10, #1 34 streq r10, [r7, #0] 35 #endif 36 beq .LinvokeChain @ predicted chain is valid 37 ldr r7, [r3, #offClassObject_vtable] @ r7 <- this->class->vtable 38 cmp r8, #0 @ initialized class or not 39 moveq r1, #0 40 subne r1, r9, #1 @ count-- 41 strne r1, [rGLUE, #offGlue_icRechainCount] @ write back to InterpState 42 add lr, lr, #4 @ return to fully-resolve landing pad 43 /* 44 * r1 <- count 45 * r2 <- &predictedChainCell 46 * r3 <- this->class 47 * r4 <- dPC 48 * r7 <- this->class->vtable 49 */ 50 bx lr 51