blob: e95ab32401c7d5ccb01cd29df044f12bea4041ad [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;
* 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