1 /* Copyright (C) 2008 The Android Open Source Project 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 /* 17 * File: OP_INSTANCE_OF.S 18 * 19 * Code: Checks if object is instance of a class. Uses no substitutions. 20 * 21 * For: instance-of 22 * 23 * Description: Store in the given destination register 1 if the indicated 24 * reference is an instance of the given type, or 0 if not. 25 * The type must be a reference type (not a primitive type). 26 * 27 * Format: B|A|op CCCC (22c) 28 * 29 * Syntax: op vA, vB, type@CCCC 30 * op vA, vB, field@CCCC 31 */ 32 33 movl rINST, %edx # %edx<- BA 34 shr $$4, %edx # %edx<- B 35 GET_VREG %edx # %edx<- vB 36 cmp $$0, %edx # check for null object 37 je .L${opcode}_store # null object 38 jmp .L${opcode}_break 39%break 40 41.L${opcode}_break: 42 movl rGLUE, %ecx # %ecx<- pMterpGlue 43 movl offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex 44 FETCH 1, %eax # %eax<- CCCC 45 movl offDvmDex_pResClasses(%ecx), %ecx # %ecx<- pDvmDex->pResClasses 46 movl (%ecx, %eax, 4), %ecx # %ecx<- resolved class 47 movl offObject_clazz(%edx), %edx # %edx<- obj->clazz 48 cmp $$0, %ecx # check if already resovled 49 je .L${opcode}_resolve # not resolved before, so resolve now 50 51.L${opcode}_resolved: 52 cmp %ecx, %edx # check if same class 53 je .L${opcode}_trivial # yes, finish 54 jmp .L${opcode}_fullcheck # no, do full check 55 56 /* 57 * The trivial test failed, we need to perform a full check. 58 * %edx holds obj->clazz 59 * %ecx holds class resolved from BBBB 60 */ 61 62.L${opcode}_fullcheck: 63 movl %edx, -8(%esp) # push parameter obj->clazz 64 movl %ecx, -4(%esp) # push parameter resolved class 65 lea -8(%esp), %esp 66 call dvmInstanceofNonTrivial # perform full check 67 # call: (ClassObject* instance, ClassObject* clazz) 68 # return: int 69 andl $$15, rINST # rINST<- A 70 FFETCH_ADV 2, %edx # %edx<- next instruction hi; fetch, advance 71 lea 8(%esp), %esp 72 SET_VREG %eax, rINST # vA<- r0 73 FGETOP_JMP 2, %edx # jump to next instruction; getop, jmp 74 75 /* 76 * %edx holds boolean result 77 */ 78 79.L${opcode}_store: 80 FFETCH_ADV 2, %eax # %eax<- next instruction hi; fetch, advance 81 andl $$15, rINST # rINST<- A 82 SET_VREG %edx, rINST # vA<- r0 83 FGETOP_JMP 2, %eax # jump to next instruction; getop, jmp 84 85 /* 86 * Trivial test succeeded, save and bail. 87 */ 88 89.L${opcode}_trivial: 90 FFETCH_ADV 2, %eax # %eax<- next instruction hi; fetch, advance 91 andl $$15, rINST # rINST<- A 92 SET_VREG $$1, rINST # vA<- r0 93 FGETOP_JMP 2, %eax # jump to next instruction; getop, jmp 94 95 /* 96 * Resolution required. This is the least-likely path. 97 * %eax holds BBBB 98 */ 99 100.L${opcode}_resolve: 101 102 movl rGLUE, %ecx # %ecx<- pMterpGlue 103 EXPORT_PC 104 movl offGlue_method(%ecx), %ecx # %ecx<- glue->method 105 movl offMethod_clazz(%ecx), %ecx # %ecx<- glue->method->clazz 106 movl %ecx, -12(%esp) # push parameter glue->method->clazz 107 movl %eax, -8(%esp) # push parameter CCCC; type index 108 movl $$1, -4(%esp) # push parameter true 109 lea -12(%esp), %esp 110 call dvmResolveClass # call: (const ClassObject* referrer, u4 classIdx, 111 # bool fromUnverifiedConstant) 112 # return: ClassObject* 113 lea 12(%esp), %esp 114 cmp $$0, %eax # check for null 115 je common_exceptionThrown # handle exception 116 movl rINST, %edx # %edx<- BA+ 117 shr $$4, %edx # %edx<- B 118 movl %eax, %ecx # need class in %ecx 119 GET_VREG %edx # %edx<- vB 120 movl offObject_clazz(%edx), %edx # %edx<- obj->clazz 121 jmp .L${opcode}_resolved # clazz resolved, continue 122