Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8353851

[lworld] C1: Branches added for check_flat_array are opaque to the register allocator

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P2 P2
    • repo-valhalla
    • repo-valhalla
    • hotspot

      Attached simplified TestArrayNullMarkers.java fails with "-XX:+UseSerialGC -XX:CompileCommand=quiet -XX:+PrintCompilation -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=print,*::test -XX:TieredStopAtLevel=2 -XX:-UseTLAB"

      We hit a SIGSEGV on the post barrier because the card_table_base stored in rdi is trashed. The problem is (again) that branches added for check_flat_array are opaque to the register allocator, leading to rematerialization of a spilled value inside one branch being used after both branches merge. If we are coming from the other branch, we read garbage and crash (see details below).

      Old JDK-8229382 already attempted to fix a similar issue:
      https://mail.openjdk.org/pipermail/valhalla-dev/2019-August/006228.html

      But the fix was incomplete. With JDK-8353202, I extended this to never use a cached constant in conditional code, which fixes this particular issue. I don't think this is sufficient either though. In theory, the register allocator could emit arbitrary (not only constant) spilling / rematerialization in conditional code which would be incorrect. We need to revisit code that calls set_in_conditional_code.

      Problematic code in this case:

       120 flat_array_check [r8|L] [rsi|L] [rbx|M] [label:0x00005d413b2f9fe0]
       122 convert [i2l] [rdi|I] [rdirdi|J]
       124 leal [Base:[r8|L] Index:[rdirdi|J] * 8 Disp: 16|L] [raxrax|J]
       126 move [rsi|L] [Base:[raxrax|J] Disp: 0|L]
       130 leal [Base:[raxrax|J] Disp: 0|J] [raxrax|J]
       132 ushift_right [raxrax|J] [int:9|I] [raxrax|J]
           move [dbl_stack:5|J] [rdirdi|J]
       134 move [int:0|I] [Base:[raxrax|J] Index:[rdirdi|J] Disp: 0|B]
       136 label [label:0x00005d413b2fa078]
           move [stack:7|L] [rbx|L]
       138 store_check [rsi|L] [rbx|L] [rax|L] [rdx|L] [rcx|L] [bci:59]
       140 move [int:2|I] [rdx|I]
       142 flat_array_check [rbx|L] [rsi|L] [rcx|M] [label:0x00005d413b2fad28]
       144 convert [i2l] [rdx|I] [rdxrdx|J]
       146 leal [Base:[rbx|L] Index:[rdxrdx|J] * 8 Disp: 16|L] [rbxrbx|J]
       148 move [rsi|L] [Base:[rbxrbx|J] Disp: 0|L]
       152 leal [Base:[rbxrbx|J] Disp: 0|J] [rsirsi|J]
       154 ushift_right [rsirsi|J] [int:9|I] [rsirsi|J]
       156 move [int:0|I] [Base:[rsirsi|J] Index:[rdirdi|J] Disp: 0|B]

      Below line 136, the register allocator rematerializes rdi (card_table_base) that was previously spilled on the stack, assuming that below code is always dominated, which is not true because flat_array_check will jump "around" the rematerialization. As a result, we crash in line 156 when using rdi.

            Unassigned Unassigned
            thartmann Tobias Hartmann
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: