1 %verify "executed" 2 %verify "unimplemented array type" 3 /* 4 * Create a new array with elements filled from registers. 5 * 6 * TODO: convert most of this into a common subroutine, shared with 7 * OP_FILLED_NEW_ARRAY.S. 8 */ 9 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 10 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 11 FETCH(r0, 1) @ r0<- aaaa (lo) 12 FETCH(r1, 2) @ r1<- AAAA (hi) 13 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 14 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 15 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 16 EXPORT_PC() @ need for resolve and alloc 17 cmp r0, #0 @ already resolved? 18 bne .L${opcode}_continue @ yes, continue on 19 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 20 mov r2, #0 @ r2<- false 21 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 22 bl dvmResolveClass @ r0<- call(clazz, ref) 23 cmp r0, #0 @ got null? 24 beq common_exceptionThrown @ yes, handle exception 25 b .L${opcode}_continue 26 %break 27 28 /* 29 * On entry: 30 * r0 holds array class 31 */ 32 .L${opcode}_continue: 33 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 34 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 35 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 36 FETCH(r1, 3) @ r1<- BBBB (length) 37 cmp rINST, #'I' @ array of ints? 38 cmpne rINST, #'L' @ array of objects? 39 cmpne rINST, #'[' @ array of arrays? 40 mov r9, r1 @ save length in r9 41 bne .L${opcode}_notimpl @ no, not handled yet 42 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 43 cmp r0, #0 @ null return? 44 beq common_exceptionThrown @ alloc failed, handle exception 45 46 FETCH(r1, 4) @ r1<- CCCC 47 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 48 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 49 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 50 subs r9, r9, #1 @ length--, check for neg 51 FETCH_ADVANCE_INST(5) @ advance to next instr, load rINST 52 bmi 2f @ was zero, bail 53 54 @ copy values from registers into the array 55 @ r0=array, r1=CCCC, r9=BBBB (length) 56 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 57 1: ldr r3, [r2], #4 @ r3<- *r2++ 58 subs r9, r9, #1 @ count-- 59 str r3, [r0], #4 @ *contents++ = vX 60 bpl 1b 61 62 2: ldr r0, [rSELF, #offThread_retval] @ r0<- object 63 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 64 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 65 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 66 cmp r1, #'I' @ Is int array? 67 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 68 GOTO_OPCODE(ip) @ execute it 69 70 /* 71 * Throw an exception indicating that we have not implemented this 72 * mode of filled-new-array. 73 */ 74 .L${opcode}_notimpl: 75 ldr r0, .L_strFilledNewArrayNotImpl_${opcode} 76 bl dvmThrowInternalError 77 b common_exceptionThrown 78 79 /* 80 * Ideally we'd only define this once, but depending on layout we can 81 * exceed the range of the load above. 82 */ 83 84 .L_strFilledNewArrayNotImpl_${opcode}: 85 .word .LstrFilledNewArrayNotImpl 86