/* Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * File: OP_INSTANCE_OF.S * * Code: Checks if object is instance of a class. Uses no substitutions. * * For: instance-of * * Description: Store in the given destination register 1 if the indicated * reference is an instance of the given type, or 0 if not. * The type must be a reference type (not a primitive type). * * Format: B|A|op CCCC (22c) * * Syntax: op vA, vB, type@CCCC * op vA, vB, field@CCCC */ movl rINST, %edx # %edx<- BA shr $$4, %edx # %edx<- B GET_VREG %edx # %edx<- vB cmp $$0, %edx # check for null object je .L${opcode}_store # null object jmp .L${opcode}_break %break .L${opcode}_break: movl rGLUE, %ecx # %ecx<- pMterpGlue movl offGlue_methodClassDex(%ecx), %ecx # %ecx<- pDvmDex FETCH 1, %eax # %eax<- CCCC movl offDvmDex_pResClasses(%ecx), %ecx # %ecx<- pDvmDex->pResClasses movl (%ecx, %eax, 4), %ecx # %ecx<- resolved class movl offObject_clazz(%edx), %edx # %edx<- obj->clazz cmp $$0, %ecx # check if already resovled je .L${opcode}_resolve # not resolved before, so resolve now .L${opcode}_resolved: cmp %ecx, %edx # check if same class je .L${opcode}_trivial # yes, finish jmp .L${opcode}_fullcheck # no, do full check /* * The trivial test failed, we need to perform a full check. * %edx holds obj->clazz * %ecx holds class resolved from BBBB */ .L${opcode}_fullcheck: movl %edx, -8(%esp) # push parameter obj->clazz movl %ecx, -4(%esp) # push parameter resolved class lea -8(%esp), %esp call dvmInstanceofNonTrivial # perform full check # call: (ClassObject* instance, ClassObject* clazz) # return: int andl $$15, rINST # rINST<- A FFETCH_ADV 2, %edx # %edx<- next instruction hi; fetch, advance lea 8(%esp), %esp SET_VREG %eax, rINST # vA<- r0 FGETOP_JMP 2, %edx # jump to next instruction; getop, jmp /* * %edx holds boolean result */ .L${opcode}_store: FFETCH_ADV 2, %eax # %eax<- next instruction hi; fetch, advance andl $$15, rINST # rINST<- A SET_VREG %edx, rINST # vA<- r0 FGETOP_JMP 2, %eax # jump to next instruction; getop, jmp /* * Trivial test succeeded, save and bail. */ .L${opcode}_trivial: FFETCH_ADV 2, %eax # %eax<- next instruction hi; fetch, advance andl $$15, rINST # rINST<- A SET_VREG $$1, rINST # vA<- r0 FGETOP_JMP 2, %eax # jump to next instruction; getop, jmp /* * Resolution required. This is the least-likely path. * %eax holds BBBB */ .L${opcode}_resolve: movl rGLUE, %ecx # %ecx<- pMterpGlue EXPORT_PC movl offGlue_method(%ecx), %ecx # %ecx<- glue->method movl offMethod_clazz(%ecx), %ecx # %ecx<- glue->method->clazz movl %ecx, -12(%esp) # push parameter glue->method->clazz movl %eax, -8(%esp) # push parameter CCCC; type index movl $$1, -4(%esp) # push parameter true lea -12(%esp), %esp call dvmResolveClass # call: (const ClassObject* referrer, u4 classIdx, # bool fromUnverifiedConstant) # return: ClassObject* lea 12(%esp), %esp cmp $$0, %eax # check for null je common_exceptionThrown # handle exception movl rINST, %edx # %edx<- BA+ shr $$4, %edx # %edx<- B movl %eax, %ecx # need class in %ecx GET_VREG %edx # %edx<- vB movl offObject_clazz(%edx), %edx # %edx<- obj->clazz jmp .L${opcode}_resolved # clazz resolved, continue