8341548: More concise use of classfile API

Reviewed-by: liach
This commit is contained in:
Shaojin Wen 2024-10-08 20:35:14 +00:00
parent 7312eea382
commit 62acc9c174
5 changed files with 323 additions and 342 deletions

View file

@ -891,10 +891,9 @@ class InvokerBytecodeGenerator {
emitStaticInvoke(cob, invokeBasicName);
// goto L_done
cob.goto_w(L_done);
// L_fallback:
cob.labelBinding(L_fallback);
cob.goto_w(L_done)
// L_fallback:
.labelBinding(L_fallback);
// invoke selectAlternativeName.arguments[2]
System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
@ -945,26 +944,23 @@ class InvokerBytecodeGenerator {
.dropParameterTypes(0,1)
.changeReturnType(returnType);
cob.exceptionCatch(L_startBlock, L_endBlock, L_handler, CD_Throwable);
// Normal case
cob.labelBinding(L_startBlock);
cob.exceptionCatch(L_startBlock, L_endBlock, L_handler, CD_Throwable)
// Normal case
.labelBinding(L_startBlock);
// load target
emitPushArgument(cob, invoker, 0);
emitPushArguments(cob, args, 1); // skip 1st argument: method handle
cob.invokevirtual(CD_MethodHandle, "invokeBasic", methodDesc(type.basicType()));
cob.labelBinding(L_endBlock);
cob.goto_w(L_done);
// Exceptional case
cob.labelBinding(L_handler);
// Check exception's type
cob.dup();
cob.invokevirtual(CD_MethodHandle, "invokeBasic", methodDesc(type.basicType()))
.labelBinding(L_endBlock)
.goto_w(L_done)
// Exceptional case
.labelBinding(L_handler)
// Check exception's type
.dup();
// load exception class
emitPushArgument(cob, invoker, 1);
cob.swap();
cob.invokevirtual(CD_Class, "isInstance", MTD_boolean_Object);
cob.swap()
.invokevirtual(CD_Class, "isInstance", MTD_boolean_Object);
Label L_rethrow = cob.newLabel();
cob.ifeq(L_rethrow);
@ -974,13 +970,11 @@ class InvokerBytecodeGenerator {
cob.swap();
emitPushArguments(cob, args, 1); // skip 1st argument: method handle
MethodType catcherType = type.insertParameterTypes(0, Throwable.class);
cob.invokevirtual(CD_MethodHandle, "invokeBasic", methodDesc(catcherType.basicType()));
cob.goto_w(L_done);
cob.labelBinding(L_rethrow);
cob.athrow();
cob.labelBinding(L_done);
cob.invokevirtual(CD_MethodHandle, "invokeBasic", methodDesc(catcherType.basicType()))
.goto_w(L_done)
.labelBinding(L_rethrow)
.athrow()
.labelBinding(L_done);
return result;
}
@ -1075,8 +1069,8 @@ class InvokerBytecodeGenerator {
cob.labelBinding(lFrom);
emitPushArgument(cob, invoker, 0); // load target
emitPushArguments(cob, args, 1); // load args (skip 0: method handle)
cob.invokevirtual(CD_MethodHandle, "invokeBasic", methodDesc(type.basicType()));
cob.labelBinding(lTo);
cob.invokevirtual(CD_MethodHandle, "invokeBasic", methodDesc(type.basicType()))
.labelBinding(lTo);
// FINALLY_NORMAL:
int index = extendLocalsMap(new Class<?>[]{ returnType });
@ -1084,17 +1078,16 @@ class InvokerBytecodeGenerator {
emitStoreInsn(cob, basicReturnType.basicTypeKind(), index);
}
emitPushArgument(cob, invoker, 1); // load cleanup
cob.loadConstant(null);
cob.aconst_null();
if (isNonVoid) {
emitLoadInsn(cob, basicReturnType.basicTypeKind(), index);
}
emitPushArguments(cob, args, 1); // load args (skip 0: method handle)
cob.invokevirtual(CD_MethodHandle, "invokeBasic", cleanupDesc);
cob.goto_w(lDone);
// CATCH:
cob.labelBinding(lCatch);
cob.dup();
cob.invokevirtual(CD_MethodHandle, "invokeBasic", cleanupDesc)
.goto_w(lDone)
// CATCH:
.labelBinding(lCatch)
.dup();
// FINALLY_EXCEPTIONAL:
emitPushArgument(cob, invoker, 1); // load cleanup
@ -1107,10 +1100,9 @@ class InvokerBytecodeGenerator {
if (isNonVoid) {
emitPopInsn(cob, basicReturnType);
}
cob.athrow();
// DONE:
cob.labelBinding(lDone);
cob.athrow()
// DONE:
.labelBinding(lDone);
return result;
}
@ -1147,26 +1139,24 @@ class InvokerBytecodeGenerator {
}
emitPushArgument(cob, invoker, 0); // push switch input
cob.tableswitch(0, numCases - 1, defaultLabel, cases);
cob.labelBinding(defaultLabel);
cob.tableswitch(0, numCases - 1, defaultLabel, cases)
.labelBinding(defaultLabel);
emitPushArgument(cob, invoker, 1); // push default handle
emitPushArguments(cob, args, 1); // again, skip collector
cob.invokevirtual(CD_MethodHandle, "invokeBasic", caseDescriptor);
cob.goto_(endLabel);
cob.invokevirtual(CD_MethodHandle, "invokeBasic", caseDescriptor)
.goto_(endLabel);
for (int i = 0; i < numCases; i++) {
cob.labelBinding(cases.get(i).target());
// Load the particular case:
emitLoadInsn(cob, TypeKind.REFERENCE, casesLocal);
cob.loadConstant(i);
cob.aaload();
cob.loadConstant(i)
.aaload();
// invoke it:
emitPushArguments(cob, args, 1); // again, skip collector
cob.invokevirtual(CD_MethodHandle, "invokeBasic", caseDescriptor);
cob.goto_(endLabel);
cob.invokevirtual(CD_MethodHandle, "invokeBasic", caseDescriptor)
.goto_(endLabel);
}
cob.labelBinding(endLabel);
@ -1335,16 +1325,14 @@ class InvokerBytecodeGenerator {
// invoke fini
emitLoopHandleInvoke(cob, invoker, finis, c, args, true, finiType, loopLocalStateTypes, clauseDataIndex,
firstLoopStateIndex);
cob.goto_w(lDone);
// this is the beginning of the next loop clause
cob.labelBinding(lNext);
cob.goto_w(lDone)
// this is the beginning of the next loop clause
.labelBinding(lNext);
}
cob.goto_w(lLoop);
// DONE:
cob.labelBinding(lDone);
cob.goto_w(lLoop)
// DONE:
.labelBinding(lDone);
return result;
}
@ -1370,8 +1358,8 @@ class InvokerBytecodeGenerator {
int firstLoopStateSlot) {
// load handle for clause
emitPushClauseArray(cob, clauseDataSlot, handles);
cob.loadConstant(clause);
cob.aaload();
cob.loadConstant(clause)
.aaload();
// load loop state (preceding the other arguments)
if (pushLocalState) {
for (int s = 0; s < loopLocalStateTypes.length; ++s) {
@ -1385,8 +1373,8 @@ class InvokerBytecodeGenerator {
private void emitPushClauseArray(CodeBuilder cob, int clauseDataSlot, int which) {
emitLoadInsn(cob, TypeKind.REFERENCE, clauseDataSlot);
cob.loadConstant(which - 1);
cob.aaload();
cob.loadConstant(which - 1)
.aaload();
}
private void emitZero(CodeBuilder cob, BasicType type) {
@ -1519,14 +1507,14 @@ class InvokerBytecodeGenerator {
@Override
public void accept(CodeBuilder cob) {
// create parameter array
cob.loadConstant(invokerType.parameterCount());
cob.anewarray(CD_Object);
cob.loadConstant(invokerType.parameterCount())
.anewarray(CD_Object);
// fill parameter array
for (int i = 0; i < invokerType.parameterCount(); i++) {
Class<?> ptype = invokerType.parameterType(i);
cob.dup();
cob.loadConstant(i);
cob.dup()
.loadConstant(i);
emitLoadInsn(cob, basicType(ptype).basicTypeKind(), i);
// box if primitive type
if (ptype.isPrimitive()) {
@ -1535,10 +1523,10 @@ class InvokerBytecodeGenerator {
cob.aastore();
}
// invoke
cob.aload(0);
cob.getfield(CD_MethodHandle, "form", CD_LambdaForm);
cob.swap(); // swap form and array; avoid local variable
cob.invokevirtual(CD_LambdaForm, "interpretWithArguments", MethodTypeDescImpl.ofValidated(CD_Object, CD_Object_array));
cob.aload(0)
.getfield(CD_MethodHandle, "form", CD_LambdaForm)
.swap() // swap form and array; avoid local variable
.invokevirtual(CD_LambdaForm, "interpretWithArguments", MethodTypeDescImpl.ofValidated(CD_Object, CD_Object_array));
// maybe unbox
Class<?> rtype = invokerType.returnType();
@ -1592,9 +1580,9 @@ class InvokerBytecodeGenerator {
// Load arguments from array
for (int i = 0; i < dstType.parameterCount(); i++) {
cob.aload(1);
cob.loadConstant(i);
cob.aaload();
cob.aload(1)
.loadConstant(i)
.aaload();
// Maybe unbox
Class<?> dptype = dstType.parameterType(i);
@ -1645,9 +1633,9 @@ class InvokerBytecodeGenerator {
clb.withMethodBody("dummy", MTD_void, ACC_STATIC, new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
cob.ldc(os.toString());
cob.pop();
cob.return_();
cob.ldc(os.toString())
.pop()
.return_();
}
});
}