On Thu, 26 Sep 2024 17:29:38 GMT, Aleksey Shipilev <sh...@openjdk.org> wrote:

>> This is the 7th and final PR for [JEP 483: Ahead-of-Time Class Loading & 
>> Linking](https://bugs.openjdk.org/browse/JDK-8315737).
>> 
>> This PR implements the AOT-linking of invokedynamic callsites:
>> - We only link lambda expressions (`LambdaMetafactory::metafactory`) and 
>> string concat (`StringConcatFactory::makeConcatWithConstants()`) as the 
>> results of these bootstrap methods do not have environment dependencies and 
>> can be safely cached.
>> - The resolved CallSites are represented as Java heap objects. Thus, this 
>> optimizations is supported only for the static CDS archive, which can store 
>> heap objects. The dynamic CDS archive is not supported.
>> 
>> **Review Notes:**
>> 
>> - Start with `AOTConstantPoolResolver::preresolve_indy_cp_entries()` -- it 
>> checks all indys that were linked during the training run, and aot-links 
>> only those for lambdas and string concats
>> - `SystemDictionaryShared::find_all_archivable_classes()` finds all the 
>> hidden classes that are reachable from the indy CallSites
>> - In `MetaspaceShared::preload_and_dump_impl()` we call 
>> `MethodType::createArchivedObjects()` to record all MethodTypes that were 
>> created in the assembly phase. This is necessary because the identity of 
>> MethodTypes is significant (they are compared with the `==` operator). Also 
>> see MethodType.java for the corresponding code that are used in the 
>> production run.
>> - Afterwards, we enter the safepoint (`VM_PopulateDumpSharedSpace::doit()`). 
>> In this safepoint,  
>> `ConstantPoolCache::remove_resolved_indy_entries_if_non_deterministic()` is 
>> called to remove any resolved indy callsites that cannot be archived. (Such 
>> CallSites may be created as a side effect of Java code execution in the 
>> assembly phase. E.g., the bootstrap of the module system).
>> 
>> **Rough Edges:**
>> 
>> - Many archived CallSites references (directly or indirectly) the static 
>> fields of the classes listed under 
>> `AOTClassInitializer::can_archive_initialized_mirror()`, where the object 
>> identity of these static fields is significant. Therefore, we must preserve 
>> the initialized states of these classes. Otherwise, we might run into 
>> problems such as [JDK-8340836](https://bugs.openjdk.org/browse/JDK-8340836). 
>> Unfortunately, the list is created by trial-and-error, and may need to be 
>> updated to match changes in the `java.lang.invoke` and 
>> `jdk.internal.constant` packages. We expect Project Leyden to come with a 
>> general solution to this problem.
>> - If the identity is significant for a static field in a complex class, but 
>> not a...
>
> src/hotspot/share/cds/aotClassInitializer.cpp line 47:
> 
>> 45: 
>> 46:   Symbol* name = ik->name();
>> 47:   if (name->equals("jdk/internal/constant/PrimitiveClassDescImpl") ||
> 
> Could we / should we start using `vmSymbols` constants for these? I think you 
> can directly compare the `Symbol*`-s then, like `name == 
> vmSymbols::jdk_internal_constant_PrimitiveClassDescImpl_Holder() `.

Not every class in this table is inside vmSymbols, and I don't want to have to 
edit vmSymbols whenever a new class is added here (and having to do garbage 
collection in vmSymbols when a class is removed from here).

I pushed a new version that's more table driven, and avoid most strcmp calls by 
filtering with the symbol length.

> src/hotspot/share/cds/aotConstantPoolResolver.cpp line 476:
> 
>> 474:   if (bsm_klass->equals("java/lang/invoke/StringConcatFactory") &&
>> 475:       bsm_name->equals("makeConcatWithConstants")) {
>> 476:     return true;
> 
> I think all BSM entries in SCF are deterministic, really. So we can just 
> check for the class?

We haven't done much testing with the other SCF BSMs, so I think it's better to 
do that in a follow-up REF.

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

PR Review Comment: https://git.openjdk.org/jdk/pull/21143#discussion_r1782287180
PR Review Comment: https://git.openjdk.org/jdk/pull/21143#discussion_r1782282918

Reply via email to