RFR: 8293187: Store initialized Enum classes in AOTCache [v3]

Ioi Lam iklam at openjdk.org
Wed Sep 18 01:03:43 UTC 2024


On Tue, 17 Sep 2024 20:33:23 GMT, Ashutosh Mehra <asmehra at openjdk.org> wrote:

> Does _runtime_default_subgraph_info only hold information about archived mirrors?

The default graph records classes of objects created in this step:


void HeapShared::copy_objects() {
  assert(HeapShared::can_write(), "must be");

  copy_interned_strings(); // << here
  copy_special_objects();  // << and here


So apart from mirrors, it also records the class of String and 6 exception instances archived by `HeapShared::archive_exception_instance`


> If we are init-ing classes required for archived mirrors here, why do we need special aot-initialization for PrimitiveClassDescImpl, ReferenceClassDescImpl and ConstantDescs in AOTClassInitializer::can_archive_initialized_mirror?

I've added the following comments into `AOTClassInitializer::can_archive_initialized_mirror()`


  } else if (ik->is_initialized() &&
             (ik->name()->equals("jdk/internal/constant/PrimitiveClassDescImpl") ||
              ik->name()->equals("jdk/internal/constant/ReferenceClassDescImpl") ||
              ik->name()->equals("java/lang/constant/ConstantDescs"))) {
    // The above 3 classes are special cases needed to support the aot-caching of
    // java.lang.invoke.MethodType instances:
    // - MethodType points to sun.invoke.util.Wrapper enums
    // - The Wrapper enums point to static final fields in the above 3 classes.
    //   E.g., ConstantDescs.CD_Boolean.
    // - If we re-run the <clinit> of these 3 classes again during the production
    //   run, ConstantDescs.CD_Boolean will get a new value that has a different
    //   object identity than the value referenced the the Wrapper enums.
    // - However, Wrapper requires object identity (it allows the use of == to
    //   test the equality of ClassDesc, etc).
    // Therefore, we must preserve the static fields of these 3 classes from
    // the assembly phase.
    return true;


> The comment seems to indicate this function should initialize the classes that are referenced by archived mirrors of aot-initialized classes. But there is no check for aot-initialized class in the body.

I amended the comments above `HeapShared::init_classes_reachable_from_archived_mirrors()` to say:


//    enum Fruit {
//       APPLE, ORANGE, BANANA;
//       static final Set<Fruit> HAVE_SEEDS = new HashSet<>(Arrays.asList(APPLE, ORANGE));
//   }
//
// the pre-inited mirror of Fruit references HashSet, which should be initialized
// before any Java code can access the Fruit class. Note that HashSet itself doesn't
// necessary need to be an aot-initialized class.


That's why there's no check for `k` to be aot-initialized.

This is necessary because the `<clinit>` of `k` could have environment dependencies so it cannot be aot-initialized.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/20958#discussion_r1764254366


More information about the hotspot-dev mailing list