Skip to content

Commit

Permalink
Merge pull request #18445 from ThanHenderson/14986-14991
Browse files Browse the repository at this point in the history
Conform to spec for BootstrapMethodError for OJDK MHs for JDK 8
  • Loading branch information
babsingh authored Nov 14, 2023
2 parents 5fde7f7 + 60f121a commit f819b7e
Showing 1 changed file with 58 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -236,55 +236,77 @@ private static final Object resolveInvokeDynamic(long j9class, String name, Stri
Object internalConstantPool = access.getInternalConstantPoolFromJ9Class(j9class);
Class<?> classObject = getClassFromJ9Class(j9class);

MethodType type;
MethodType type = null;
Object[] result = new Object[2];
/*[IF JAVA_SPEC_VERSION >= 11]*/
type = MethodTypeHelper.vmResolveFromMethodDescriptorString(methodDescriptor, access.getClassloader(classObject), null);
final MethodHandles.Lookup lookup = IMPL_LOOKUP.in(classObject);
inaccessibleTypeCheck(lookup, type);
/*[ELSE] JAVA_SPEC_VERSION >= 11*/
try {
type = MethodTypeHelper.vmResolveFromMethodDescriptorString(methodDescriptor, access.getClassloader(classObject), null);
} catch(Throwable e) {
throw new BootstrapMethodError(e);
}
/*[ENDIF] JAVA_SPEC_VERSION >= 11 */

int bsmIndex = UNSAFE.getShort(bsmData);
int bsmArgCount = UNSAFE.getShort(bsmData + BSM_ARGUMENT_COUNT_OFFSET);
long bsmArgs = bsmData + BSM_ARGUMENTS_OFFSET;
MethodHandle bsm = getCPMethodHandleAt(internalConstantPool, bsmIndex);
if (null == bsm) {
/*[MSG "K05cd", "unable to resolve 'bootstrap_method_ref' in '{0}' at index {1}"]*/
throw new NullPointerException(Msg.getString("K05cd", classObject.toString(), bsmIndex)); //$NON-NLS-1$
}
int bsmIndex = UNSAFE.getShort(bsmData);
int bsmArgCount = UNSAFE.getShort(bsmData + BSM_ARGUMENT_COUNT_OFFSET);
long bsmArgs = bsmData + BSM_ARGUMENTS_OFFSET;
MethodHandle bsm = getCPMethodHandleAt(internalConstantPool, bsmIndex);
if (null == bsm) {
/*[MSG "K05cd", "unable to resolve 'bootstrap_method_ref' in '{0}' at index {1}"]*/
throw new NullPointerException(Msg.getString("K05cd", classObject.toString(), bsmIndex)); //$NON-NLS-1$
}

Object[] staticArgs = new Object[bsmArgCount];
/* Static optional arguments */
int bsmTypeArgCount = bsm.type().parameterCount();
for (int i = 0; i < bsmArgCount; i++) {
staticArgs[i] = getAdditionalBsmArg(access, internalConstantPool, classObject, bsm, bsmArgs, bsmTypeArgCount, i);
}
Object[] staticArgs = new Object[bsmArgCount];
/* Static optional arguments */
int bsmTypeArgCount = bsm.type().parameterCount();
for (int i = 0; i < bsmArgCount; i++) {
staticArgs[i] = getAdditionalBsmArg(access, internalConstantPool, classObject, bsm, bsmArgs, bsmTypeArgCount, i);
}

Object[] appendixResult = new Object[1];
Object[] result = new Object[2];
Object[] appendixResult = new Object[1];

/* result[0] stores a MemberName object, which specifies the caller method (generated bytecodes), or a Throwable.
*
* This leads to a type check in the interpreter for the object stored in result[0].
*
* TODO: Investigate if the Throwable can be wrapped in a MemberName. This will help prevent type checks in the
* interpreter since result[0] will always be a MemberName. This will improve performance.
*/
result[0] = MethodHandleNatives.linkCallSite(classObject,
/* The second parameter is not used in Java 8 and Java 18+ (JDK bug: 8272614). */
/*[IF (JAVA_SPEC_VERSION > 8) & (JAVA_SPEC_VERSION < 18)]*/
0,
/*[ENDIF] (JAVA_SPEC_VERSION > 8) & (JAVA_SPEC_VERSION < 18) */
bsm, name, type, (Object)staticArgs, appendixResult);

/* result[0] stores a MemberName object, which specifies the caller method (generated bytecodes), or a Throwable.
*
* This leads to a type check in the interpreter for the object stored in result[0].
*
* TODO: Investigate if the Throwable can be wrapped in a MemberName. This will help prevent type checks in the
* interpreter since result[0] will always be a MemberName. This will improve performance.
*/
result[0] = MethodHandleNatives.linkCallSite(classObject,
/* The second parameter is not used in Java 8 and Java 18+ (JDK bug: 8272614). */
/*[IF (JAVA_SPEC_VERSION > 8) & (JAVA_SPEC_VERSION < 18)]*/
0,
/*[ENDIF] (JAVA_SPEC_VERSION > 8) & (JAVA_SPEC_VERSION < 18) */
bsm, name, type, (Object)staticArgs, appendixResult);

/* result[1] stores a MethodHandle object, which is used as the last argument to the caller method. */
result[1] = appendixResult[0];
/* result[1] stores a MethodHandle object, which is used as the last argument to the caller method. */
result[1] = appendixResult[0];
/*[IF JAVA_SPEC_VERSION < 11]*/
} catch (Throwable e) {
if (type == null) {
throw new BootstrapMethodError(e);
}

/* linkCallSite may correctly throw a BootstrapMethodError. */
if (e instanceof BootstrapMethodError) {
throw e;
}

/* Any other throwables are wrapped in an invoke-time BootstrapMethodError exception throw. */
try {
MethodHandle thrower = MethodHandles.throwException(type.returnType(), BootstrapMethodError.class);
MethodHandle constructor = IMPL_LOOKUP.findConstructor(BootstrapMethodError.class, MethodType.methodType(void.class, Throwable.class));
MethodHandle resultHandle = MethodHandles.foldArguments(thrower, constructor.bindTo(e));
MemberName memberName = resultHandle.internalForm().compileToBytecode();
result[0] = memberName;
result[1] = resultHandle;
} catch (IllegalAccessException iae) {
throw new Error(iae);
} catch (NoSuchMethodException nsme) {
throw new Error(nsme);
}
}
/*[ENDIF] JAVA_SPEC_VERSION < 11 */
return (Object)result;
/*[ELSE] OPENJDK_METHODHANDLES*/
MethodHandle result = null;
Expand Down

0 comments on commit f819b7e

Please sign in to comment.