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

C2: ZGC fails with 'Incorrect load shift' when invoking Object.clone() reflectively on an array

    XMLWordPrintable

Details

    • b26

    Backports

      Description

        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.

        Attachments

          Issue Links

            Activity

              People

                rcastanedalo Roberto Castaneda Lozano
                rcastanedalo Roberto Castaneda Lozano
                Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: