-
Bug
-
Resolution: Fixed
-
P3
-
21, 22, 23
-
b26
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8334070 | 21.0.5-oracle | Tobias Hartmann | P3 | Resolved | Fixed | b01 |
JDK-8334207 | 21.0.5 | Martin Doerr | P3 | Resolved | Fixed | b01 |
Executing C2-generated code that for a reflective Object.clone() invocation on an array leads to the following assertion failure (see attached error log file):
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (.../src/hotspot/cpu/x86/gc/z/zAddress_x86.inline.hpp:35), pid=11538, tid=11539
# assert(index == 0 || is_power_of_2(index)) failed: Incorrect load shift: 11
#
# JRE version: Java(TM) SE Runtime Environment (23.0+24) (fastdebug build 23-ea+24-1995)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 23-ea+24-1995, mixed mode, sharing, tiered, compressed class ptrs, z gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x1984d24] ZBarrierSet::clone_obj_array(objArrayOop, objArrayOop)+0x874
#
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x1984d24] ZBarrierSet::clone_obj_array(objArrayOop, objArrayOop)+0x874 (zAddress_x86.inline.hpp:35)
V [libjvm.so+0x1009713] AccessInternal::PostRuntimeDispatch<ZBarrierSet::AccessBarrier<270400ul, ZBarrierSet>, (AccessInternal::BarrierType)9, 270400ul>::access_barrier(oop, oop, unsigned long)+0x3e3
V [libjvm.so+0x199e8f7] ZBarrierSetRuntime::clone(oopDesc*, oopDesc*, unsigned long)+0x157
How to reproduce
-------------------------
Just run the attached test case on a JDK 23 debug build as follows:
$ java --add-opens java.base/java.lang=ALL-UNNAMED -Xbatch -XX:+UseZGC -XX:-UseTypeProfile Test.java
Preliminary analysis (thanks to [~aboldtch])
-------------------------------------------------------------
When C2 compiles a reflective call to Object.clone(), it lacks type information about the receiver (the clone source). To distinguish which clone implementation to use, C2 generates a dynamic check to test if the source is an array [1]. Under this guard, C2 marks the ArrayCopy as is_clone_array(), however the source type is unknown so ZGC implements the ArrayCopy using a runtime call to ZBarrierSetRuntime::clone [2]. This runtime function fails because it expects the source array to be initialized and it is not, due to the ReduceBulkZeroing optimization (enabled by default) applied by C2 at bytecode parsing time [3].
[1] https://github.com/openjdk/jdk/blob/61db2f5b90cd40ce104cb55bf9fd52d6e141161d/src/hotspot/share/opto/library_call.cpp#L5112
[2] https://github.com/openjdk/jdk/blob/61db2f5b90cd40ce104cb55bf9fd52d6e141161d/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp#L482-L506
[3] https://github.com/openjdk/jdk/blob/61db2f5b90cd40ce104cb55bf9fd52d6e141161d/src/hotspot/share/opto/library_call.cpp#L5016-L5026
This bug affects Generational ZGC only (due to the introduction of store barriers). All JDK versions including Generational ZGC may be affected.
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (.../src/hotspot/cpu/x86/gc/z/zAddress_x86.inline.hpp:35), pid=11538, tid=11539
# assert(index == 0 || is_power_of_2(index)) failed: Incorrect load shift: 11
#
# JRE version: Java(TM) SE Runtime Environment (23.0+24) (fastdebug build 23-ea+24-1995)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 23-ea+24-1995, mixed mode, sharing, tiered, compressed class ptrs, z gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x1984d24] ZBarrierSet::clone_obj_array(objArrayOop, objArrayOop)+0x874
#
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x1984d24] ZBarrierSet::clone_obj_array(objArrayOop, objArrayOop)+0x874 (zAddress_x86.inline.hpp:35)
V [libjvm.so+0x1009713] AccessInternal::PostRuntimeDispatch<ZBarrierSet::AccessBarrier<270400ul, ZBarrierSet>, (AccessInternal::BarrierType)9, 270400ul>::access_barrier(oop, oop, unsigned long)+0x3e3
V [libjvm.so+0x199e8f7] ZBarrierSetRuntime::clone(oopDesc*, oopDesc*, unsigned long)+0x157
How to reproduce
-------------------------
Just run the attached test case on a JDK 23 debug build as follows:
$ java --add-opens java.base/java.lang=ALL-UNNAMED -Xbatch -XX:+UseZGC -XX:-UseTypeProfile Test.java
Preliminary analysis (thanks to [~aboldtch])
-------------------------------------------------------------
When C2 compiles a reflective call to Object.clone(), it lacks type information about the receiver (the clone source). To distinguish which clone implementation to use, C2 generates a dynamic check to test if the source is an array [1]. Under this guard, C2 marks the ArrayCopy as is_clone_array(), however the source type is unknown so ZGC implements the ArrayCopy using a runtime call to ZBarrierSetRuntime::clone [2]. This runtime function fails because it expects the source array to be initialized and it is not, due to the ReduceBulkZeroing optimization (enabled by default) applied by C2 at bytecode parsing time [3].
[1] https://github.com/openjdk/jdk/blob/61db2f5b90cd40ce104cb55bf9fd52d6e141161d/src/hotspot/share/opto/library_call.cpp#L5112
[2] https://github.com/openjdk/jdk/blob/61db2f5b90cd40ce104cb55bf9fd52d6e141161d/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp#L482-L506
[3] https://github.com/openjdk/jdk/blob/61db2f5b90cd40ce104cb55bf9fd52d6e141161d/src/hotspot/share/opto/library_call.cpp#L5016-L5026
This bug affects Generational ZGC only (due to the introduction of store barriers). All JDK versions including Generational ZGC may be affected.
- backported by
-
JDK-8334070 C2: ZGC fails with 'Incorrect load shift' when invoking Object.clone() reflectively on an array
- Resolved
-
JDK-8334207 C2: ZGC fails with 'Incorrect load shift' when invoking Object.clone() reflectively on an array
- Resolved
- relates to
-
JDK-8270098 ZGC: ZBarrierSetC2::clone_at_expansion fails with "Guard against surprises" assert
- Closed
- links to
-
Commit openjdk/jdk21u-dev/9dca67ba
-
Commit openjdk/jdk/e0ac8249
-
Review openjdk/jdk21u-dev/706
-
Review openjdk/jdk/19486
(2 links to)