blob: 9dd4ff834974da6916776a7b469cfc47abd8fc97 [file] [log] [blame]
%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;
* const ClassObject *clazz;
* const Method *method;
* u4 counter;
* } PredictedChainingCell;
*
* Upon returning to the callsite:
* - lr : to branch to the chaining cell
* - lr+2: to punt to the interpreter
* - lr+4: to fully resolve the callee and may rechain.
* r3 <- class
* r9 <- counter
*/
@ r0 = this, r1 = returnCell, r2 = predictedChainCell, rPC = dalvikCallsite
ldr r3, [r0, #offObject_clazz] @ r3 <- this->class
ldr r8, [r2, #4] @ r8 <- predictedChainCell->clazz
ldr r0, [r2, #8] @ r0 <- predictedChainCell->method
ldr r9, [rSELF, #offThread_icRechainCount] @ r1 <- shared rechainCount
cmp r3, r8 @ predicted class == actual class?
#if defined(WITH_JIT_TUNING)
ldr r7, .LdvmICHitCount
#if defined(WORKAROUND_CORTEX_A9_745320)
/* Don't use conditional loads if the HW defect exists */
bne 101f
ldr r10, [r7, #0]
101:
#else
ldreq r10, [r7, #0]
#endif
add r10, r10, #1
streq r10, [r7, #0]
#endif
ldreqh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize
ldreqh r2, [r0, #offMethod_outsSize] @ r2<- methodToCall->outsSize
beq $chaintgt @ predicted chain is valid
ldr r7, [r3, #offClassObject_vtable] @ r7 <- this->class->vtable
cmp r8, #0 @ initialized class or not
moveq r1, #0
subne r1, r9, #1 @ count--
strne r1, [rSELF, #offThread_icRechainCount] @ write back to thread
add lr, lr, #4 @ return to fully-resolve landing pad
/*
* r1 <- count
* r2 <- &predictedChainCell
* r3 <- this->class
* r4 <- dPC
* r7 <- this->class->vtable
*/
bx lr