United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6579347 Solaris/SPARC Server VM: endless loop in checkcast_arraycopy stub
JDK-6579347 : Solaris/SPARC Server VM: endless loop in checkcast_arraycopy stub

Details
Type:
Bug
Submit Date:
2007-07-11
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
solaris_9
Sub-Component:
compiler
CPU:
sparc
Priority:
P2
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs11 (b03)

Related Reports
Backport:
Backport:
Backport:

Sub Tasks

Description
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
>

                                    

Comments
EVALUATION

See description.
                                     
2007-07-11
SUGGESTED FIX

-  array_store_check(O1_to, O2_count, O2);   // store check on O1[0..O2]
 +  array_store_check(O1_to, O2_count, O3);   // store check on O1[0..O2]

Also, add assert_different_registers calls to the front of generate_type_check on all platforms.
                                     
2007-07-11
SUGGESTED FIX

Webrev:                 http://analemma.sfbay.sun.com/net/prt-data.east/archives/2007/20070711185532.kvn.6579347/workspace/webrevs/webrev-2007.07.12/index.html

1. Pass different register for 'tmp' argument.
2. Replace the assert in array_store_check() which checks only
   2 arguments for different registers with the assert which
   checks all arguments.
                                     
2007-07-12



Hardware and Software, Engineered to Work Together