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

[lworld] Fix JVM crash at Unsafe_FinishPrivateBuffer

    XMLWordPrintable

Details

    Description

      JVM crash with following assertion failure:
      ```
      # Internal Error (valhalla/src/hotspot/share/prims/unsafe.cpp:388), pid=29517, tid=29518
      # assert(v->mark().is_larval_state()) failed: must be a larval value
      #
      # JRE version: OpenJDK Runtime Environment (21.0) (fastdebug build 21-internal-git-05e4d0dba)
      # Java VM: OpenJDK 64-Bit Server VM (fastdebug 21-internal-git-05e4d0dba, mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-aarch64)
      # Problematic frame:
      # V [libjvm.so+0x1a92a64] Unsafe_FinishPrivateBuffer+0xc0
      ```
      When running following java test:
      ```
      import java.lang.reflect.*;

      import jdk.internal.misc.Unsafe;

      public class Test {
          private static int LENGTH = 10000;
          static byte[] arr = new byte[LENGTH];

          static {
              for (int i = 0; i < LENGTH; i++) {
                  arr[i] = (byte) i;
              }
          }

          public static byte test(byte b) {
              Value obj = new Value();
              obj = Unsafe.getUnsafe().makePrivateBuffer(obj);
              Unsafe.getUnsafe().putByte(obj, obj.offset, b);
              obj = Unsafe.getUnsafe().finishPrivateBuffer(obj);
              return Unsafe.getUnsafe().getByte(obj, obj.offset);
          }

          public static void main(String[] args) {
              byte actual = 0;
              for (int i = 0; i < LENGTH; i++) {
                  actual += test(arr[i]);
              }
          }

          primitive static class Value {
              byte field = 0;
              static long offset = fieldOffset();

              private static long fieldOffset() {
                  try {
                      var f = Value.class.getDeclaredField("field");
                      return Unsafe.getUnsafe().objectFieldOffset(f);
                  } catch (Exception e) {
                      System.out.println(e);
                  }
                  return -1L;
              }
          }
      }
      ```
      The root cause is the allocated buffer created by "makePrivateBuffer" is optimized to the default oop of the primitive class in C2 compiler. The optimization miss the larval state of the allocated buffer, which is not marked to the default oop. The assertion happens when the "finishPrivateBuffer" is compiled by interpreter, and the failure happens when it checks whether the expected larval state is set.

      Attachments

        Issue Links

          Activity

            People

              xgong Xiaohong Gong (Inactive)
              xgong Xiaohong Gong (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: