@@ -1194,22 +1194,21 @@ private static boolean methodTypeFromDescriptor(JNIEnvironment jni, JNIObjectHan
11941194 return true ;
11951195 }
11961196
1197- /**
1198- * This method should be intercepted when we are predefining a lambda class. This is the only
1199- * spot in the lambda-class creation pipeline where we can get lambda-class bytecode so the
1200- * class can be predefined. We do not want to predefine all lambda classes, but only the ones
1201- * that are actually created at runtime, so we have a method that checks wheter the lambda
1202- * should be predefined or not.
1203- */
1204- private static boolean onMethodHandleClassFileInit (JNIEnvironment jni , JNIObjectHandle thread , @ SuppressWarnings ("unused" ) Breakpoint bp , InterceptedState state ) {
1197+ private record LambdaClassNameAndBytecode (String lambdaClassName , byte [] lambdaClassBytecode ) {
1198+ }
1199+
1200+ private static LambdaClassNameAndBytecode getLambdaClassNameAndBytecodeFromThread (JNIEnvironment jni , JNIObjectHandle thread , int bytecodeArgumentIndex ) {
1201+ LambdaClassNameAndBytecode emptyLambdaClassNameAndBytecode = new LambdaClassNameAndBytecode (null , null );
1202+
12051203 String className = Support .fromJniString (jni , getObjectArgument (thread , 1 ));
1204+ assert className != null ;
12061205
12071206 if (LambdaUtils .isLambdaClassName (className )) {
12081207 if (shouldIgnoreLambdaClassForPredefinition (jni )) {
1209- return true ;
1208+ return emptyLambdaClassNameAndBytecode ;
12101209 }
12111210
1212- JNIObjectHandle bytesArray = getObjectArgument (thread , 3 );
1211+ JNIObjectHandle bytesArray = getObjectArgument (thread , bytecodeArgumentIndex );
12131212 int length = jniFunctions ().getGetArrayLength ().invoke (jni , bytesArray );
12141213 byte [] data = new byte [length ];
12151214
@@ -1222,9 +1221,29 @@ private static boolean onMethodHandleClassFileInit(JNIEnvironment jni, JNIObject
12221221 }
12231222
12241223 className += Digest .digest (data );
1225- tracer . traceCall ( "classloading" , "onMethodHandleClassFileInit" , null , null , null , null , state . getFullStackTraceOrNull (), className , data );
1224+ return new LambdaClassNameAndBytecode ( className , data );
12261225 }
12271226 }
1227+
1228+ return emptyLambdaClassNameAndBytecode ;
1229+ }
1230+
1231+ /**
1232+ * This method should be intercepted on JDK 24 or later when we are predefining a lambda class.
1233+ * We do not want to predefine all lambda classes, but only the ones that are actually created
1234+ * at runtime, so we have a method that checks whether the lambda should be predefined or not.
1235+ */
1236+ private static boolean makeHiddenClassDefiner (JNIEnvironment jni , JNIObjectHandle thread , @ SuppressWarnings ("unused" ) Breakpoint bp , InterceptedState state ) {
1237+ LambdaClassNameAndBytecode lambdaClassNameAndBytecode = getLambdaClassNameAndBytecodeFromThread (jni , thread , 2 );
1238+ return lambdaPredefinition (state , lambdaClassNameAndBytecode .lambdaClassName (), lambdaClassNameAndBytecode .lambdaClassBytecode ());
1239+ }
1240+
1241+ private static boolean lambdaPredefinition (InterceptedState state , String className , byte [] data ) {
1242+ if (className == null ) {
1243+ return false ;
1244+ }
1245+
1246+ tracer .traceCall ("classloading" , "lambdaPredefinition" , null , null , null , null , state .getFullStackTraceOrNull (), className , data );
12281247 return true ;
12291248 }
12301249
@@ -1923,7 +1942,8 @@ private static boolean allocateInstance(JNIEnvironment jni, JNIObjectHandle thre
19231942 };
19241943
19251944 private static final BreakpointSpecification [] CLASS_PREDEFINITION_BREAKPOINT_SPECIFICATIONS = {
1926- optionalBrk ("java/lang/invoke/MethodHandles$Lookup$ClassFile" , "<init>" , "(Ljava/lang/String;I[B)V" , BreakpointInterceptor ::onMethodHandleClassFileInit ),
1945+ optionalBrk ("java/lang/invoke/MethodHandles$Lookup" , "makeHiddenClassDefiner" ,
1946+ "(Ljava/lang/String;[BZLjdk/internal/util/ClassFileDumper;I)Ljava/lang/invoke/MethodHandles$Lookup$ClassDefiner;" , BreakpointInterceptor ::makeHiddenClassDefiner )
19271947 };
19281948
19291949 private static BreakpointSpecification brk (String className , String methodName , String signature , BreakpointHandler handler ) {
0 commit comments