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 movzbl rINST_HI,%eax # eax<- BA 16 sarl $$4,%eax # eax<- B 17 GET_VREG(%eax,%eax) # eax<- vB (obj) 18 GET_GLUE(%ecx) 19 testl %eax,%eax # object null? 20 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 21 SPILL(rPC) 22 je .L${opcode}_store # null obj, not instance, store it 23 movzwl 2(rPC),rPC # rPC<- CCCC 24 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 25 movl (%ecx,rPC,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 jmp .L${opcode}_fullcheck # no, do full check 33%break 34 35 /* 36 * Trivial test failed, need to perform full check. This is common. 37 * eax holds obj->clazz 38 * ecx holds class resolved from BBBB 39 * rINST_HI has BA 40 * rPC already spilled 41 */ 42.L${opcode}_fullcheck: 43 movl %eax,OUT_ARG0(%esp) 44 movl %ecx,OUT_ARG1(%esp) 45 call dvmInstanceofNonTrivial # eax<- boolean result 46 # fall through to ${opcode}_store 47 48 /* 49 * eax holds boolean result 50 * rINST_HI holds BA 51 */ 52.L${opcode}_store: 53 UNSPILL(rPC) 54 movzbl rINST_HI,%ecx # ecx<- BA 55 FETCH_INST_WORD(2) 56 andb $$0xf,%cl # ecl<- A 57 ADVANCE_PC(2) 58 SET_VREG(%eax,%ecx) # vA<- eax 59 GOTO_NEXT 60 61 /* 62 * Trivial test succeeded, save and bail. 63 * r9 holds A 64 */ 65.L${opcode}_trivial: 66 UNSPILL(rPC) 67 movzbl rINST_HI,%ecx # ecx<- BA 68 FETCH_INST_WORD(2) 69 andb $$0xf,%cl # ecl<- A 70 ADVANCE_PC(2) 71 movl $$1,%eax 72 SET_VREG(%eax,%ecx) # vA<- true 73 GOTO_NEXT 74 75 /* 76 * Resolution required. This is the least-likely path. 77 * 78 * rPC holds BBBB 79 * rINST_HI holds BA 80 */ 81.L${opcode}_resolve: 82 movl rPC,OUT_ARG1(%esp) # arg1<- BBBB 83 GET_GLUE(%ecx) 84 UNSPILL(rPC) 85 movl offGlue_method(%ecx),%ecx 86 movl $$1,OUT_ARG2(%esp) # arg2<- true 87 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 88 EXPORT_PC() 89 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 90 call dvmResolveClass # eax<- resolved ClassObject ptr 91 UNSPILL(rPC) 92 testl %eax,%eax # success? 93 je common_exceptionThrown # no, handle exception 94/* Now, we need to sync up with fast path. We need eax to 95 * hold the obj->clazz, and ecx to hold the resolved class 96 */ 97 movl %eax,%ecx # ecx<- resolved class 98 movzbl rINST_HI,%eax # eax<- BA 99 sarl $$4,%eax # eax<- B 100 GET_VREG(%eax,%eax) # eax<- vB (obj) 101 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 102 jmp .L${opcode}_resolved 103 104