1%verify "executed" 2%verify "null object" 3%verify "class cast exception thrown, with correct class name" 4%verify "class cast exception not thrown on same class" 5%verify "class cast exception not thrown on subclass" 6%verify "class not resolved" 7%verify "class already resolved" 8 /* 9 * Check to see if an object reference is an instance of a class. 10 * 11 * Most common situation is a non-null object, being compared against 12 * an already-resolved class. 13 */ 14 /* instance-of vA, vB, class@CCCC */ 15 movl rINST,%eax # eax<- BA 16 sarl $$4,%eax # eax<- B 17 GET_VREG_R %eax %eax # eax<- vB (obj) 18 movl rSELF,%ecx 19 testl %eax,%eax # object null? 20 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 21 SPILL(rIBASE) # preserve rIBASE 22 je .L${opcode}_store # null obj, not instance, store it 23 movzwl 2(rPC),rIBASE # rIBASE<- CCCC 24 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 25 movl (%ecx,rIBASE,4),%ecx # ecx<- resolved class 26 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 27 testl %ecx,%ecx # have we resolved this before? 28 je .L${opcode}_resolve # not resolved, do it now 29.L${opcode}_resolved: # eax<- obj->clazz, ecx<- resolved class 30 cmpl %eax,%ecx # same class (trivial success)? 31 je .L${opcode}_trivial # yes, trivial finish 32 /* 33 * Trivial test failed, need to perform full check. This is common. 34 * eax holds obj->clazz 35 * ecx holds class resolved from BBBB 36 * rINST has BA 37 */ 38 movl %eax,OUT_ARG0(%esp) 39 movl %ecx,OUT_ARG1(%esp) 40 call dvmInstanceofNonTrivial # eax<- boolean result 41 # fall through to ${opcode}_store 42 43 /* 44 * eax holds boolean result 45 * rINST holds BA 46 */ 47.L${opcode}_store: 48 FETCH_INST_OPCODE 2 %ecx 49 UNSPILL(rIBASE) 50 andb $$0xf,rINSTbl # <- A 51 ADVANCE_PC 2 52 SET_VREG %eax rINST # vA<- eax 53 GOTO_NEXT_R %ecx 54 55 /* 56 * Trivial test succeeded, save and bail. 57 * r9 holds A 58 */ 59.L${opcode}_trivial: 60 FETCH_INST_OPCODE 2 %ecx 61 UNSPILL(rIBASE) 62 andb $$0xf,rINSTbl # <- A 63 ADVANCE_PC 2 64 movl $$1,%eax 65 SET_VREG %eax rINST # vA<- true 66 GOTO_NEXT_R %ecx 67 68 /* 69 * Resolution required. This is the least-likely path. 70 * 71 * rIBASE holds BBBB 72 * rINST holds BA 73 */ 74.L${opcode}_resolve: 75 movl rIBASE,OUT_ARG1(%esp) # arg1<- BBBB 76 movl rSELF,%ecx 77 movl offThread_method(%ecx),%ecx 78 movl $$1,OUT_ARG2(%esp) # arg2<- true 79 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 80 EXPORT_PC 81 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 82 call dvmResolveClass # eax<- resolved ClassObject ptr 83 testl %eax,%eax # success? 84 je common_exceptionThrown # no, handle exception 85/* Now, we need to sync up with fast path. We need eax to 86 * hold the obj->clazz, and ecx to hold the resolved class 87 */ 88 movl %eax,%ecx # ecx<- resolved class 89 movl rINST,%eax # eax<- BA 90 sarl $$4,%eax # eax<- B 91 GET_VREG_R %eax %eax # eax<- vB (obj) 92 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 93 jmp .L${opcode}_resolved 94