blob: c54f4f79e4cfd2ef1ba5c6b7ffd139a9e2520a61 [file] [log] [blame]
%verify "executed"
%verify "null object"
%verify "class cast exception thrown, with correct class name"
%verify "class cast exception not thrown on same class"
%verify "class cast exception not thrown on subclass"
%verify "class not resolved"
%verify "class already resolved"
/*
* Check to see if an object reference is an instance of a class.
*
* Most common situation is a non-null object, being compared against
* an already-resolved class.
*/
/* instance-of vA, vB, class@CCCC */
movl rINST,%eax # eax<- BA
sarl $$4,%eax # eax<- B
GET_VREG_R %eax %eax # eax<- vB (obj)
movl rSELF,%ecx
testl %eax,%eax # object null?
movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
SPILL(rIBASE) # preserve rIBASE
je .L${opcode}_store # null obj, not instance, store it
movzwl 2(rPC),rIBASE # rIBASE<- CCCC
movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
movl (%ecx,rIBASE,4),%ecx # ecx<- resolved class
movl offObject_clazz(%eax),%eax # eax<- obj->clazz
testl %ecx,%ecx # have we resolved this before?
je .L${opcode}_resolve # not resolved, do it now
.L${opcode}_resolved: # eax<- obj->clazz, ecx<- resolved class
cmpl %eax,%ecx # same class (trivial success)?
je .L${opcode}_trivial # yes, trivial finish
/*
* Trivial test failed, need to perform full check. This is common.
* eax holds obj->clazz
* ecx holds class resolved from BBBB
* rINST has BA
*/
movl %eax,OUT_ARG0(%esp)
movl %ecx,OUT_ARG1(%esp)
call dvmInstanceofNonTrivial # eax<- boolean result
# fall through to ${opcode}_store
/*
* eax holds boolean result
* rINST holds BA
*/
.L${opcode}_store:
FETCH_INST_OPCODE 2 %ecx
UNSPILL(rIBASE)
andb $$0xf,rINSTbl # <- A
ADVANCE_PC 2
SET_VREG %eax rINST # vA<- eax
GOTO_NEXT_R %ecx
/*
* Trivial test succeeded, save and bail.
* r9 holds A
*/
.L${opcode}_trivial:
FETCH_INST_OPCODE 2 %ecx
UNSPILL(rIBASE)
andb $$0xf,rINSTbl # <- A
ADVANCE_PC 2
movl $$1,%eax
SET_VREG %eax rINST # vA<- true
GOTO_NEXT_R %ecx
/*
* Resolution required. This is the least-likely path.
*
* rIBASE holds BBBB
* rINST holds BA
*/
.L${opcode}_resolve:
movl rIBASE,OUT_ARG1(%esp) # arg1<- BBBB
movl rSELF,%ecx
movl offThread_method(%ecx),%ecx
movl $$1,OUT_ARG2(%esp) # arg2<- true
movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
EXPORT_PC
movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz
call dvmResolveClass # eax<- resolved ClassObject ptr
testl %eax,%eax # success?
je common_exceptionThrown # no, handle exception
/* Now, we need to sync up with fast path. We need eax to
* hold the obj->clazz, and ecx to hold the resolved class
*/
movl %eax,%ecx # ecx<- resolved class
movl rINST,%eax # eax<- BA
sarl $$4,%eax # eax<- B
GET_VREG_R %eax %eax # eax<- vB (obj)
movl offObject_clazz(%eax),%eax # eax<- obj->clazz
jmp .L${opcode}_resolved