%verify "executed" %verify "unimplemented array type" /* * Create a new array with elements filled from registers. */ /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ movl rSELF,%eax movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex movl 2(rPC),%ecx # ecx<- AAAAAAAA movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses movl (%eax,%ecx,4),%eax # eax<- resolved class EXPORT_PC testl %eax,%eax # already resolved? jne .L${opcode}_continue # yes, continue # less frequent path, so we'll redo some work movl rSELF,%eax movl $$0,OUT_ARG2(%esp) # arg2<- false movl %ecx,OUT_ARG1(%esp) # arg1<- AAAAAAAA movl offThread_method(%eax),%eax # eax<- self->method movl offMethod_clazz(%eax),%eax # eax<- method->clazz movl %eax,OUT_ARG0(%esp) # arg0<- clazz SPILL(rIBASE) call dvmResolveClass # eax<- call(clazz,ref,flag) UNSPILL(rIBASE) testl %eax,%eax # null? je common_exceptionThrown # yes, handle it # note: fall through to .L${opcode}_continue /* * On entry: * eax holds array class [r0] * ecx is scratch */ .L${opcode}_continue: movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor movl $$ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags movzbl 1(%ecx),%ecx # ecx<- descriptor[1] movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass movl rSELF,%eax cmpb $$'I',%cl # supported? je 1f cmpb $$'L',%cl je 1f cmpb $$'[',%cl jne .L${opcode}_notimpl # no, not handled yet 1: movl %ecx,offThread_retval+4(%eax) # save type movl rINST,OUT_ARG1(%esp) # arg1<- BBBB (length) SPILL(rIBASE) call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) UNSPILL(rIBASE) movl rSELF,%ecx testl %eax,%eax # alloc successful? je common_exceptionThrown # no, handle exception movl %eax,offThread_retval(%ecx) # retval.l<- new array movzwl 8(rPC),%ecx # ecx<- CCCC leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents /* at this point: * eax is pointer to tgt * rINST is length * ecx is CCCC * We now need to copy values from registers into the array */ # set up src pointer SPILL_TMP2(%esi) SPILL_TMP3(%edi) leal (rFP,%ecx,4),%esi # set up src ptr movl %eax,%edi # set up dst ptr movl rINST,%ecx # load count register rep movsd UNSPILL_TMP2(%esi) UNSPILL_TMP3(%edi) movl rSELF,%ecx movl offThread_retval+4(%ecx),%eax # eax<- type cmpb $$'I',%al # Int array? je 5f # skip card mark if so movl offThread_retval(%ecx),%eax # eax<- object head movl offThread_cardTable(%ecx),%ecx # card table base shrl $$GC_CARD_SHIFT,%eax # convert to card num movb %cl,(%ecx,%eax) # mark card based on object head 5: FETCH_INST_OPCODE 5 %ecx ADVANCE_PC 5 GOTO_NEXT_R %ecx /* * Throw an exception indicating that we have not implemented this * mode of filled-new-array. */ .L${opcode}_notimpl: movl $$.LstrFilledNewArrayNotImplA,%eax movl %eax,OUT_ARG0(%esp) call dvmThrowInternalError jmp common_exceptionThrown