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.
```
# 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.
- relates to
-
JDK-8239003 [lworld] C2 should respect larval state when scalarizing
- Open