1 %verify "executed" 2 /* 3 * Store an object into an array. vBB[vCC] <- vAA. 4 * 5 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 6 * instructions. We use a pair of FETCH_Bs instead. 7 */ 8 /* op vAA, vBB, vCC */ 9 FETCH(r0, 1) @ r0<- CCBB 10 mov r9, rINST, lsr #8 @ r9<- AA 11 and r2, r0, #255 @ r2<- BB 12 mov r3, r0, lsr #8 @ r3<- CC 13 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 14 GET_VREG(r0, r3) @ r0<- vCC (requested index) 15 cmp rINST, #0 @ null array object? 16 GET_VREG(r9, r9) @ r9<- vAA 17 beq common_errNullObject @ yes, bail 18 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 19 add r10, rINST, r0, lsl #2 @ r10<- arrayObj + index*width 20 cmp r0, r3 @ compare unsigned index, length 21 bcc .L${opcode}_finish @ we're okay, continue on 22 b common_errArrayIndex @ index >= length, bail 23 24 %break 25 /* 26 * On entry: 27 * rINST = vBB (arrayObj) 28 * r9 = vAA (obj) 29 * r10 = offset into array (vBB + vCC * width) 30 */ 31 .L${opcode}_finish: 32 cmp r9, #0 @ storing null reference? 33 beq .L${opcode}_skip_check @ yes, skip type checks 34 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 35 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 36 bl dvmCanPutArrayElement @ test object type vs. array type 37 cmp r0, #0 @ okay? 38 beq common_errArrayStore @ no 39 mov r1, rINST @ r1<- arrayObj 40 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 41 ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base 42 add r10, #offArrayObject_contents @ r0<- pointer to slot 43 GET_INST_OPCODE(ip) @ extract opcode from rINST 44 str r9, [r10] @ vBB[vCC]<- vAA 45 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 46 GOTO_OPCODE(ip) @ jump to next instruction 47 .L${opcode}_skip_check: 48 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 49 GET_INST_OPCODE(ip) @ extract opcode from rINST 50 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 51 GOTO_OPCODE(ip) @ jump to next instruction 52