RFR: 8338530: CDS warning Skipping java/lang/invoke/BoundMethodHandle$Species_LLLL

Ioi Lam iklam at openjdk.org
Wed Sep 4 16:29:51 UTC 2024


On Sat, 31 Aug 2024 10:40:40 GMT, ExE Boss <duke at openjdk.org> wrote:

>> Is it possible for us at java.lang.invoke to enhance the `GenerateJliClassesHelper` to generate this class? I can look into it.
>
>> Is it possible for us at java.lang.invoke to enhance the `GenerateJliClassesHelper` to generate this class? I can look into it.
> 
> `GenerateJLIClassesPlugin`/`Helper` is fine, all that needs to be updated is the [`HelloClasslist`] script to hit the code path which generates `BoundMethodHandle$Species_LLLL`.
> 
> [`HelloClasslist`]: https://github.com/openjdk/jdk/blob/master/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java

> Yes, `Species_*` classes can be statically generated by jlink - using a build-time "training run" of the `HelloClasslist` program @ExE-Boss refers to to generate a list of classes to generate statically into the JDK image.
> 
> What happened in [JDK-8336856](https://bugs.openjdk.org/browse/JDK-8336856) is likely that the `String` concat expressions touched by `HelloClasslist` no longer needs `Species_LLLL`, but something touched when running `java -Xshare:dump` does, so we get a warning. A dynamically generated `Species_LLLL` wouldn't exist in the JDK image, so it makes sense to exclude it from a CDS dump.
> 
> Random thoughts:
> 
> 1. It would probably work to actually make these dumpable into the CDS archive - though we might need to also dump the full bytecode and patch that up when we load them.
> 2. Looking at what `-Xshare:dump` does there's some `linkMethodHandleConstant` upcall which ends up creating the `Species_LLLL` class seen here - via `MethodHandleImpl.bindCaller`. Anyone who can point me to what's making such upcalls during dump? The provided `Lookup` might need to have other privileges to avoid generating forms with caller sensitive bindings. @iklam ?

I added this inside `KlassFactory::create_from_stream()` 


  if (name->ends_with("BoundMethodHandle$Species_LLLL")) {
    fatal("here");
  }


The hs_err file shows


V  [libjvm.so+0x10e084b]  KlassFactory::create_from_stream(ClassFileStream*, Symbol*, ClassLoaderData*, ClassLoadInfo const&, JavaThread*)+0x15b  (klassFactory.cpp:185)
V  [libjvm.so+0x1547651]  SystemDictionary::resolve_class_from_stream(ClassFileStream*, Symbol*, Handle, ClassLoadInfo const&, JavaThread*)+0x13f  (systemDictionary.cpp:908)
V  [libjvm.so+0x15478f0]  SystemDictionary::resolve_from_stream(ClassFileStream*, Symbol*, Handle, ClassLoadInfo const&, JavaThread*)+0x6c  (systemDictionary.cpp:946)
V  [libjvm.so+0xf2510d]  jvm_lookup_define_class(_jclass*, char const*, signed char const*, int, _jobject*, unsigned char, int, _jobject*, JavaThread*)+0x5b0  (jvm.cpp:1011)
V  [libjvm.so+0xf256ab]  JVM_LookupDefineClass+0x133  (jvm.cpp:1086)
C  [libjava.so+0xec1b]  Java_java_lang_ClassLoader_defineClass0+0x14b
j  java.lang.ClassLoader.defineClass0(Ljava/lang/ClassLoader;Ljava/lang/Class;Ljava/lang/String;[BIILjava/security/ProtectionDomain;ZILjava/lang/Object;)Ljava/lang/Class;+0 java.base at 24-internal
j  java.lang.System$2.defineClass(Ljava/lang/ClassLoader;Ljava/lang/Class;Ljava/lang/String;[BLjava/security/ProtectionDomain;ZILjava/lang/Object;)Ljava/lang/Class;+17 java.base at 24-internal
j  java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(ZLjava/lang/Object;)Ljava/lang/Class;+57 java.base at 24-internal
j  java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(Z)Ljava/lang/Class;+3 java.base at 24-internal
j  java.lang.invoke.ClassSpecializer$Factory.generateConcreteSpeciesCode(Ljava/lang/String;Ljava/lang/invoke/ClassSpecializer$SpeciesData;)Ljava/lang/Class;+37 java.base at 24-internal
j  java.lang.invoke.ClassSpecializer$Factory.loadSpecies(Ljava/lang/invoke/ClassSpecializer$SpeciesData;)Ljava/lang/invoke/ClassSpecializer$SpeciesData;+102 java.base at 24-internal
j  java.lang.invoke.ClassSpecializer.findSpecies(Ljava/lang/Object;)Ljava/lang/invoke/ClassSpecializer$SpeciesData;+53 java.base at 24-internal
j  java.lang.invoke.BoundMethodHandle$SpeciesData.extendWith(Ljava/lang/invoke/LambdaForm$BasicType;)Ljava/lang/invoke/BoundMethodHandle$SpeciesData;+48 java.base at 24-internal
j  java.lang.invoke.LambdaFormEditor.newSpeciesData(Ljava/lang/invoke/LambdaForm$BasicType;)Ljava/lang/invoke/BoundMethodHandle$SpeciesData;+5 java.base at 24-internal
j  java.lang.invoke.LambdaFormEditor.filterReturnForm(Ljava/lang/invoke/LambdaForm$BasicType;Z)Ljava/lang/invoke/LambdaForm;+150 java.base at 24-internal
j  java.lang.invoke.MethodHandleImpl.makePairwiseConvertByEditor(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;ZZ)Ljava/lang/invoke/MethodHandle;+521 java.base at 24-internal
j  java.lang.invoke.MethodHandleImpl.makePairwiseConvert(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;ZZ)Ljava/lang/invoke/MethodHandle;+18 java.base at 24-internal
j  java.lang.invoke.MethodHandleImpl.makePairwiseConvert(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;Z)Ljava/lang/invoke/MethodHandle;+4 java.base at 24-internal
j  java.lang.invoke.MethodHandle.asTypeUncached(Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;+50 java.base at 24-internal
j  java.lang.invoke.MethodHandle.asType(Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;+25 java.base at 24-internal
j  java.lang.invoke.MethodHandleImpl$BindCaller.restoreToType(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;+26 java.base at 24-internal
j  java.lang.invoke.MethodHandleImpl$BindCaller.bindCallerWithInjectedInvoker(Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;+26 java.base at 24-internal
j  java.lang.invoke.MethodHandleImpl$BindCaller.bindCaller(Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;+175 java.base at 24-internal
j  java.lang.invoke.MethodHandleImpl.bindCaller(Ljava/lang/invoke/MethodHandle;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;+2 java.base at 24-internal
j  java.lang.invoke.MethodHandles$Lookup.maybeBindCaller(Ljava/lang/invoke/MemberName;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandles$Lookup;)Ljava/lang/invoke/MethodHandle;+64 java.base at 24-internal
j  java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(BLjava/lang/Class;Ljava/lang/invoke/MemberName;ZZLjava/lang/invoke/MethodHandles$Lookup;)Ljava/lang/invoke/MethodHandle;+284 java.base at 24-internal
j  java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(BLjava/lang/Class;Ljava/lang/invoke/MemberName;Ljava/lang/invoke/MethodHandles$Lookup;)Ljava/lang/invoke/MethodHandle;+14 java.base at 24-internal
j  java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(BLjava/lang/Class;Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/MethodHandle;+31 java.base at 24-internal
j  java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(BLjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;+153 java.base at 24-internal
j  java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;+38 java.base at 24-internal
v  ~StubRoutines::call_stub 0x00007f5f6bbbfd01
V  [libjvm.so+0xdf7fc4]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x62a  (javaCalls.cpp:421)
V  [libjvm.so+0x13225b6]  os::os_exception_wrapper(void (*)(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*), JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x36  (os_linux.cpp:4975)
V  [libjvm.so+0xdf7996]  JavaCalls::call(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x3a  (javaCalls.cpp:329)
V  [libjvm.so+0xdf72ac]  JavaCalls::call_static(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, JavaThread*)+0x154  (javaCalls.cpp:256)
V  [libjvm.so+0x154c706]  SystemDictionary::link_method_handle_constant(Klass*, int, Klass*, Symbol*, Symbol*, JavaThread*)+0x40a  (systemDictionary.cpp:2325)
V  [libjvm.so+0x9fa820]  ConstantPool::resolve_constant_at_impl(constantPoolHandle const&, int, int, bool*, JavaThread*)+0xd88  (constantPool.cpp:1192)
V  [libjvm.so+0x735099]  ConstantPool::resolve_possibly_cached_constant_at(int, JavaThread*)+0x4b  (constantPool.hpp:711)
V  [libjvm.so+0x9fb225]  ConstantPool::copy_bootstrap_arguments_at_impl(constantPoolHandle const&, int, int, int, objArrayHandle, int, bool, Handle, JavaThread*)+0x1c7  (constantPool.cpp:1312)
V  [libjvm.so+0x735182]  ConstantPool::copy_bootstrap_arguments_at(int, int, int, objArrayHandle, int, bool, Handle, JavaThread*)+0x66  (constantPool.hpp:724)
V  [libjvm.so+0x733a29]  BootstrapInfo::resolve_args(JavaThread*)+0x3a5  (bootstrapInfo.cpp:193)
V  [libjvm.so+0x7334e4]  BootstrapInfo::resolve_bsm(JavaThread*)+0x23e  (bootstrapInfo.cpp:110)
V  [libjvm.so+0x949b93]  ClassListParser::resolve_indy_impl(Symbol*, JavaThread*)+0x1db  (classListParser.cpp:613)
V  [libjvm.so+0x9498ce]  ClassListParser::resolve_indy(JavaThread*, Symbol*)+0x50  (classListParser.cpp:578)
V  [libjvm.so+0x9485d0]  ClassListParser::parse_at_tags(JavaThread*)+0x22e  (classListParser.cpp:302)
V  [libjvm.so+0x947af9]  ClassListParser::parse(JavaThread*)+0x8d  (classListParser.cpp:120)
V  [libjvm.so+0x125b889]  ClassListParser::parse_classlist(char const*, ClassListParser::ParseMode, JavaThread*)+0x66  (classListParser.hpp:144)
V  [libjvm.so+0x1258192]  MetaspaceShared::preload_classes(JavaThread*)+0xa2  (metaspaceShared.cpp:737)
V  [libjvm.so+0x1258307]  MetaspaceShared::preload_and_dump_impl(StaticArchiveBuilder&, JavaThread*)+0x29  (metaspaceShared.cpp:761)
V  [libjvm.so+0x1257d6e]  MetaspaceShared::preload_and_dump(JavaThread*)+0x54  (metaspaceShared.cpp:660)
V  [libjvm.so+0x159e76f]  Threads::create_vm(JavaVMInitArgs*, bool*)+0xafb  (threads.cpp:821)
V  [libjvm.so+0xef6538]  JNI_CreateJavaVM_inner(JavaVM_**, void**, void*)+0x93  (jni.cpp:3594)
V  [libjvm.so+0xef696e]  JNI_CreateJavaVM+0x32  (jni.cpp:3685)
C  [libjli.so+0x45ff]  JavaMain+0x8f
C  [libjli.so+0x7f49]  ThreadJavaMain+0x9


>From looking at `*ClassListParser::_instance` inside gdb, the line in the classlist being processed is this one:


@lambda-proxy java/util/logging/Level$KnownLevel apply ()Ljava/util/function/Function; (Ljava/lang/Object;)Ljava/lang/Object; REF_invokeStatic java/util/logging/Level$KnownLevel lambda$add$3 (Ljava/lang/String;)Ljava/util/List; (Ljava/lang/String;)Ljava/util/List;


This is a lambda proxy class that was generated when executing `HelloClasslist` . Perhaps it took a different path and didn't end up needing the `Species_LLLL`?

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

PR Comment: https://git.openjdk.org/jdk/pull/20799#issuecomment-2329504434


More information about the hotspot-dev mailing list