@@ -245,7 +245,7 @@ private static final Object resolveInvokeDynamic(long j9class, String name, Stri
245
245
/*[ELSE] JAVA_SPEC_VERSION >= 11*/
246
246
try {
247
247
type = MethodTypeHelper .vmResolveFromMethodDescriptorString (methodDescriptor , access .getClassloader (classObject ), null );
248
- /*[ENDIF] JAVA_SPEC_VERSION >= 11 */
248
+ /*[ENDIF] JAVA_SPEC_VERSION >= 11*/
249
249
250
250
int bsmIndex = UNSAFE .getShort (bsmData );
251
251
int bsmArgCount = UNSAFE .getShort (bsmData + BSM_ARGUMENT_COUNT_OFFSET );
@@ -265,13 +265,10 @@ private static final Object resolveInvokeDynamic(long j9class, String name, Stri
265
265
266
266
Object [] appendixResult = new Object [1 ];
267
267
268
- /* result[0] stores a MemberName object, which specifies the caller method (generated bytecodes), or a Throwable.
269
- *
270
- * This leads to a type check in the interpreter for the object stored in result[0].
271
- *
272
- * TODO: Investigate if the Throwable can be wrapped in a MemberName. This will help prevent type checks in the
273
- * interpreter since result[0] will always be a MemberName. This will improve performance.
274
- */
268
+ /*[IF JAVA_SPEC_VERSION >= 11]*/
269
+ try {
270
+ /*[ENDIF] JAVA_SPEC_VERSION >= 11*/
271
+ /* result[0] stores a MemberName object, which specifies the caller method (generated bytecodes). */
275
272
result [0 ] = MethodHandleNatives .linkCallSite (classObject ,
276
273
/* The second parameter is not used in Java 8 and Java 18+ (JDK bug: 8272614). */
277
274
/*[IF (JAVA_SPEC_VERSION > 8) & (JAVA_SPEC_VERSION < 18)]*/
@@ -281,23 +278,39 @@ private static final Object resolveInvokeDynamic(long j9class, String name, Stri
281
278
282
279
/* result[1] stores a MethodHandle object, which is used as the last argument to the caller method. */
283
280
result [1 ] = appendixResult [0 ];
284
- /*[IF JAVA_SPEC_VERSION < 11]*/
285
281
} catch (Throwable e ) {
286
- if ( type == null ) {
287
- throw new BootstrapMethodError ( e );
288
- }
289
-
290
- /* linkCallSite may correctly throw a BootstrapMethodError. */
282
+ /*[IF JAVA_SPEC_VERSION < 11]*/
283
+ /* Before Java 11, if linkCallSite throws a BootstrapMethodError due to the CallSite binding
284
+ * resolving to null, throw it at resolution time. This ensures that resolution will be
285
+ * reattempted on the subsequent visit to the invokedynamic instruction in the interpreter.
286
+ */
291
287
if (e instanceof BootstrapMethodError ) {
292
288
throw e ;
293
289
}
294
-
295
- /* Any other throwables are wrapped in an invoke-time BootstrapMethodError exception throw. */
290
+ /*[ENDIF] JAVA_SPEC_VERSION < 11*/
291
+ /* Any throwables are wrapped in an invoke-time BootstrapMethodError exception throw. */
296
292
try {
293
+ MethodHandle resultHandle ;
297
294
MethodHandle thrower = MethodHandles .throwException (type .returnType (), BootstrapMethodError .class );
298
295
MethodHandle constructor = IMPL_LOOKUP .findConstructor (BootstrapMethodError .class , MethodType .methodType (void .class , Throwable .class ));
299
- MethodHandle resultHandle = MethodHandles .foldArguments (thrower , constructor .bindTo (e ));
296
+
297
+ MethodHandle combiner = null ;
298
+ if (e instanceof BootstrapMethodError ) {
299
+ Throwable cause = e .getCause ();
300
+ if (cause == null ) {
301
+ combiner = constructor .bindTo (e .getMessage ());
302
+ } else {
303
+ combiner = constructor .bindTo (cause );
304
+ }
305
+ } else {
306
+ combiner = constructor .bindTo (e );
307
+ }
308
+ resultHandle = MethodHandles .foldArguments (thrower , combiner );
309
+ /*[IF JAVA_SPEC_VERSION >= 11]*/
310
+ MemberName memberName = resultHandle .internalForm ().vmentry ;
311
+ /*[ELSE] JAVA_SPEC_VERSION >= 11*/
300
312
MemberName memberName = resultHandle .internalForm ().compileToBytecode ();
313
+ /*[ENDIF] JAVA_SPEC_VERSION >= 11*/
301
314
result [0 ] = memberName ;
302
315
result [1 ] = resultHandle ;
303
316
} catch (IllegalAccessException iae ) {
@@ -306,7 +319,6 @@ private static final Object resolveInvokeDynamic(long j9class, String name, Stri
306
319
throw new Error (nsme );
307
320
}
308
321
}
309
- /*[ENDIF] JAVA_SPEC_VERSION < 11 */
310
322
return (Object )result ;
311
323
/*[ELSE] OPENJDK_METHODHANDLES*/
312
324
MethodHandle result = null ;
@@ -332,7 +344,7 @@ private static final Object resolveInvokeDynamic(long j9class, String name, Stri
332
344
int bsmArgCount = UNSAFE .getShort (bsmData + BSM_ARGUMENT_COUNT_OFFSET );
333
345
long bsmArgs = bsmData + BSM_ARGUMENTS_OFFSET ;
334
346
MethodHandle bsm = getCPMethodHandleAt (internalConstantPool , bsmIndex );
335
- if (null == bsm ) {
347
+ if (bsm == null ) {
336
348
/*[MSG "K05cd", "unable to resolve 'bootstrap_method_ref' in '{0}' at index {1}"]*/
337
349
throw new NullPointerException (Msg .getString ("K05cd" , classObject .toString (), bsmIndex )); //$NON-NLS-1$
338
350
}
0 commit comments