I and Ross looked on the checkcast_arraycopy stub's code and we found the bug - 2 arguments use the same register: 2399 array_store_check(O1_to, O2_count, O2); // store check on O1[0..O2] array_store_check(Register addr, Register count, Register tmp) { ... 1082 __ sub(count, addr, count); 1083 assert( tmp != addr, "need separate temp reg"); 1084 Address rs(tmp, (address)ct->byte_map_base); 1085 __ load_address(rs); The 'count' is destroyed when Address rs is created: 0xfc439828: sub %o2, %o1, %o2 0xfc43982c: sethi %hi(0xfbac2000), %o2 0xfc439830: inc 0, %o2 0xfc439834: clrb [%o2 + %o1] 0xfc439838: deccc %o2 0xfc43983c: bge,pt %icc,0xfc439834 ! 0xfc439834 0xfc439840: inc %o1 0xfc439844: retl We are lucky when ct->byte_map_base address is negative as in the code above. Other problem: card marks were not done. But in Tim's case, it seems, ct->byte_map_base address is positive: The loopy thread stack looks like this: ----------------- t@2 ----------------- 0x7c839834 <StubRoutines> 0x7c94e8e8 0x7c94e8e8 * com.sun.java.util.jar.pack.ConstantPool.partition(com.sun.java.util.jar.pack.ConstantPool$Index, int[]) bci:201 line:922 (Compiled frame; information may be imprecise) Tim Bell wrote: > The loop is very tight: > > 0x7c839834: clrb [%o2 + %o1] > 0x7c839838: deccc %o2 > 0x7c83983c: bge,pt %icc,0x7c839834 ! 0x7c839834 > 0x7c839840: inc %o1 > > > (dbx) where > current thread: t@2 > [1] 0x7c839834(0x0, 0x7abea9b9, 0x3e866a6, 0x20, 0x5824cf48, 0x4), at 0x7c839834 > [2] 0x7c9d2df0(0x7620be70, 0x7620bf20, 0x75d77128, 0xffffcca3, 0x7e6c0000, 0x7620bea0), at 0x7c9d2df0 > [...snip...] > > (dbx) print -fx $pc > $pc = 0x7c839834 > > (dbx) regs > current thread: t@2 > current frame: [1] > g0-g3 0x00000000 0x00000000 0x0002f800 0x60dedba8 > g4-g7 0x5825b0c0 0x5824cf48 0x00000000 0x7fb62400 > o0-o3 0x00000000 0x7abea9b9 0x03e866a6 0x00000020 > o4-o7 0x5824cf48 0x00000004 0x7ed7f528 0x7c9d2df0 > l0-l3 0x58071d40 0x00000000 0x00000000 0x00000001 > l4-l7 0x75d77140 0x7e6c0000 0x7620bf70 0x0002f800 > i0-i3 0x7620be70 0x7620bf20 0x75d77128 0xffffcca3 > i4-i7 0x7e6c0000 0x7620bea0 0x7ed7f590 0x7c94e8e8 > y 0x00000000 > ccr 0x00000000 > pc 0x7c839834:0x7c839834 clrb [%o2 + %o1] > npc 0x7c839838:0x7c839838 deccc %o2 > > > (dbx) dis __1cMStubRoutinesU_checkcast_arraycopy_/50 > 0x7c839780: addcc %o2, 0, %g1 > 0x7c839784: bne,pt %icc,0x7c8397b0 ! 0x7c8397b0 > 0x7c839788: clr %o5 > 0x7c83978c: retl > 0x7c839790: clr %o0 > 0x7c839794: nop > 0x7c839798: nop > 0x7c83979c: nop > 0x7c8397a0: st %g3, [%o1 + %o5] > 0x7c8397a4: inc 4, %o5 > 0x7c8397a8: be,a,pt %icc,0x7c839814 ! 0x7c839814 > 0x7c8397ac: clr %o0 > 0x7c8397b0: ld [%o0 + %o5], %g3 > 0x7c8397b4: tst %g3 > 0x7c8397b8: be,a,pt %icc,0x7c8397a0 ! 0x7c8397a0 > 0x7c8397bc: deccc %g1 > 0x7c8397c0: ld [%g3 + 4], %g4 > 0x7c8397c4: cmp %g4, %o4 > 0x7c8397c8: be,a,pt %icc,0x7c8397a0 ! 0x7c8397a0 > 0x7c8397cc: deccc %g1 > 0x7c8397d0: ld [%g4 + %o3], %g5 > 0x7c8397d4: cmp %o4, %g5 > 0x7c8397d8: be,a,pt %icc,0x7c8397a0 ! 0x7c8397a0 > 0x7c8397dc: deccc %g1 > 0x7c8397e0: cmp %o4, 20 > 0x7c8397e4: bne,a,pt %icc,0x7c839808 ! 0x7c839808 > 0x7c8397e8: nop > 0x7c8397ec: save %sp, -96, %sp > 0x7c8397f0: mov %g4, %o1 > 0x7c8397f4: call 0x7c800720 ! 0x7c800720 > 0x7c8397f8: mov %i4, %o2 > 0x7c8397fc: restore > 0x7c839800: be,a,pt %icc,0x7c8397a0 ! 0x7c8397a0 > 0x7c839804: deccc %g1 > 0x7c839808: subcc %o2, %g1, %o2 > 0x7c83980c: be,pt %icc,0x7c839844 ! 0x7c839844 > 0x7c839810: not %o2, %o0 > 0x7c839814: sll %o2, 2, %o2 > 0x7c839818: dec 4, %o2 > 0x7c83981c: add %o2, %o1, %o2 > 0x7c839820: srl %o1, 9, %o1 > 0x7c839824: srl %o2, 9, %o2 > 0x7c839828: sub %o2, %o1, %o2 > 0x7c83982c: sethi %hi(0x7e6c0000), %o2 > 0x7c839830: inc 0, %o2 > 0x7c839834: clrb [%o2 + %o1] > 0x7c839838: deccc %o2 > 0x7c83983c: bge,pt %icc,0x7c839834 ! 0x7c839834 > 0x7c839840: inc %o1 > 0x7c839844: retl >
|