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

riscv: Fix cmpxchg_narrow_value that needs to sign-extend non-bool results

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • repo-riscv-port
    • repo-riscv-port
    • hotspot
    • None
    • riscv
    • linux

      On behalf of Xiaolin Zheng(yunyao.zxl@alibaba-inc.com)

      A very simple program inherited from jcstress could reproduce this:

      ```
      import java.lang.invoke.MethodHandles;
      import java.lang.invoke.VarHandle;

      // run with:
      // build/linux-riscv64-server-release/images/jdk/bin/java -ea -XX:-TieredCompilation -XX:CompileCommand=compileonly,jdk.internal.misc.Unsafe::compareAndSetByte TestCASByte
      // assert will fail.
      // if we add '-XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_compareAndExchangeByte' this test will pass.

      public class TestCASByte {

          byte[] array = new byte[1];

          static final VarHandle vh;
          static {
              try {
                  vh = MethodHandles.arrayElementVarHandle(byte[].class);
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
          }

          public void test() {
              for (int i = 0; i < 100_000; i++) { // To level 4
                  // clear
                  array[0] = 0;

                  byte res1 = (byte)vh.getAndSet(array, 0, (byte)-1);
                  byte res2 = (byte)vh.getAndSet(array, 0, (byte)2);

                  assert res1 == 0 && res2 == -1;
              }
          }

          public static void main(String[] args) {
              new TestCASByte().test();
          }

      }
      ```

      In this case when we are getting the -1 value saved in memory, the shift is 0, the old is 0x00000000000000ff and the mask is 0x00000000000000ff at the end of cmpxchg_narrow_value. The final result is 0x00000000000000ff but it indeed should be 0xffffffffffffffff. In fact, I tried to use sra at first and found the problem was not gone, and then I found the shift is 0. The logic here is a bit delicate and the final result seems from and | or mask operations by only calculating the 8/16 bits regardless of high 56/48 bits. So the problem is that if the result is negative, we need to make a sign extension.

            fyang Fei Yang
            ddong Denghui Dong
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: