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

[lworld] Support for flat arrays needed in CDS archive

XMLWordPrintable

      The current implementation of the CDS archive doesn't support flat arrays (instances of FlatArrayKlass).
      The limitation can easily be observed when applying the following patch which enables use of flat arrays by default, causing some migrated value classes to use flat arrays instead of reference arrays.


      diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp
      index a346d55f016..e5daa8b3aee 100644
      --- a/src/hotspot/share/cds/filemap.hpp
      +++ b/src/hotspot/share/cds/filemap.hpp
      @@ -107,7 +107,8 @@ class FileMapRegion: private CDSFileMapRegion {
         f(InlineTypeReturnedAsFields) \
         f(UseNonAtomicValueFlattening) \
         f(UseAtomicValueFlattening) \
      - f(UseNullableValueFlattening)
      + f(UseNullableValueFlattening) \
      + f(UseFlatArrayByDefault)
       
       
       class CDSMustMatchFlags {
      diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp
      index 9f69f634175..14bf5c5ede1 100644
      --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp
      +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp
      @@ -291,8 +291,22 @@ JRT_END
       
       JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* current, ConstantPool* pool, int index, jint size))
         Klass* klass = pool->klass_at(index, CHECK);
      - arrayOop obj = oopFactory::new_objArray(klass, size, CHECK);
      - current->set_vm_result(obj);
      + if (!klass->is_inline_klass()) {
      + arrayOop obj = oopFactory::new_objArray(klass, size, CHECK);
      + current->set_vm_result(obj);
      + return;
      + }
      + // Inline klasses case
      + klass->initialize(CHECK);
      + InlineKlass* vk = InlineKlass::cast(klass);
      + oop array = nullptr;
      + if (UseArrayFlattening && UseFlatArrayByDefault && vk->has_nullable_atomic_layout()) {
      + array = oopFactory::new_flatArray(vk, size, LayoutKind::NULLABLE_ATOMIC_FLAT, CHECK);
      + } else {
      + array = oopFactory::new_objArray(vk, size, CHECK);
      + }
      + current->set_vm_result(array);
      +
       JRT_END
       
       JRT_ENTRY(void, InterpreterRuntime::flat_array_load(JavaThread* current, arrayOopDesc* array, int index))
      diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
      index 3bc4ad8720d..fe6fe057d6f 100644
      --- a/src/hotspot/share/runtime/globals.hpp
      +++ b/src/hotspot/share/runtime/globals.hpp
      @@ -821,12 +821,15 @@ const int ObjectAlignmentInBytes = 8;
         product(bool, UseNonAtomicValueFlattening, true, \
                 "Allow the JVM to flatten some non-atomic null-free values") \
                                                                                   \
      - product(bool, UseNullableValueFlattening, false, \
      + product(bool, UseNullableValueFlattening, true, \
                 "Allow the JVM to flatten some nullable values") \
                                                                                   \
         product(bool, UseAtomicValueFlattening, false, \
                 "Allow the JVM to flatten some atomic values") \
                                                                                   \
      + product(bool, UseFlatArrayByDefault, true, \
      + "Allow anewarray to allocate flat array") \
      + \
         product(intx, FlatArrayElementMaxOops, 4, \
                 "Max nof embedded object references in an inline type to flatten, <0 no limit") \
                                                                       


      When building the JDK with this patch, the creation of CDS archive fails with this error:

      #
      # A fatal error has been detected by the Java Runtime Environment:
      #
      # Internal Error (valhalla/open/src/hotspot/share/cds/archiveBuilder.cpp:
      810), pid=2132230, tid=2132351
      # assert(k->is_instance_klass()) failed: must be
      #
      # JRE version: Java(TM) SE Runtime Environment (25.0) (fastdebug build 25-lworld5ea-LTS-2025-04-14-1221043.fred...)
      # Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 25-lworld5ea-LTS-2025-04-14-1221043.fred..., interpreted mod
      e, compressed class ptrs, g1 gc, linux-amd64)
      # Problematic frame:
      # V [libjvm.so+0x678c7d] ArchiveBuilder::make_klasses_shareable()+0x99d
      #


      The stack trace is:

      Current thread (0x00007a29c81a9920): VMThread "VM Thread" [id=2132351, stack(0x00007a29b42f0000,0x00007a29b43f0000) (1024K)]

      Stack: [0x00007a29b42f0000,0x00007a29b43f0000], sp=0x00007a29b43ee650, free space=1017k
      Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
      V [libjvm.so+0x678c7d] ArchiveBuilder::make_klasses_shareable()+0x99d (archiveBuilder.cpp:810)
      V [libjvm.so+0x162c93e] VM_PopulateDumpSharedSpace::doit()+0x2ae (metaspaceShared.cpp:657)
      V [libjvm.so+0x1bbcc9f] VM_Operation::evaluate()+0x18f (vmOperations.cpp:74)
      V [libjvm.so+0x1bd83e6] VMThread::evaluate_operation(VM_Operation*)+0x156 (vmThread.cpp:282)
      V [libjvm.so+0x1bd9363] VMThread::inner_execute(VM_Operation*)+0x423 (vmThread.cpp:426)
      V [libjvm.so+0x1bd9504] VMThread::loop()+0x84 (vmThread.cpp:492)
      V [libjvm.so+0x1bd9614] VMThread::run()+0x94 (vmThread.cpp:176)
      V [libjvm.so+0x1ac5d06] Thread::call_run()+0xb6 (thread.cpp:231)
      V [libjvm.so+0x174b438] thread_native_entry(Thread*)+0x128 (os_linux.cpp:877)
      C [libc.so.6+0x9caa4]
      Registers:
      RAX=0x00007a29d2aae000, RBX=0x00007a287c2331f8, RCX=0x00007a29d1f2df85, RDX=0x00007a29d1f98e70
      RSP=0x00007a29b43ee650, RBP=0x00007a29b43ee7b0, RSI=0x000000000000032a, RDI=0x00007a29d1fa2480
      R8 =0x00007a29c81a9f50, R9 =0x0000000000000001, R10=0x0000000000000000, R11=0x0000000000000017
      R12=0x00007a29d25bb5a4, R13=0x00007a29d1f25162, R14=0x00007a29d01fc7a0, R15=0x0000000000000099
      RIP=0x00007a29d0878c7d, EFLAGS=0x0000000000010202, CSGSFS=0x002b000000000033, ERR=0x0000000000000006
        TRAPNO=0x000000000000000e


      Looking at the archive builder, here's the logic involved in make_klasses_shareable():

          if (k->is_objArray_klass()) {
            // InstanceKlass and TypeArrayKlass will in turn call remove_unshareable_info
            // on their array classes.
            num_obj_array_klasses ++;
            type = "array";
          } else if (k->is_typeArray_klass()) {
            num_type_array_klasses ++;
            type = "array";
            k->remove_unshareable_info();
          } else {
            assert(k->is_instance_klass(), " must be");


      The logic handles objArrayKlasses, typeArrayKlasses, InstanceKlasses but not FlatArrayKlasses.

            matsaave Matias Saavedra Silva
            fparain Frederic Parain
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: