RFR: 8307818: Convert Indify tool to Classfile API [v16]
ExE Boss
duke at openjdk.org
Wed Jul 24 08:10:45 UTC 2024
On Sat, 22 Jun 2024 15:55:28 GMT, Oussama Louati <duke at openjdk.org> wrote:
>> An indify tool in j.l.i tests (also in vmTestBase) convert some source-code private static methods with MT_ MH_, and INDY_ prefixes into MethodHandle, MethodType, and CallSite constants.
>> ### Purpose of Indify
>>
>> - **Transformation Tool**: `Indify` transforms existing class files to leverage `invokedynamic` and other JSR 292 features. This transformation allows for dynamic method calls.
>>
>> ### Key Functions
>>
>> - **Method Handle and Method Type Constants**:
>> - **MH_x and MT_x Methods**: These methods are used to generate `MethodHandle` and `MethodType` constants. The tool transforms calls to these methods into `CONSTANT_MethodHandle` and `CONSTANT_MethodType` "ldc" (load constant) instructions.
>> - **Invokedynamic Call Sites**:
>> - **INDY_x Methods**: These methods generate `invokedynamic` call sites. Each `INDY_x` method starts with a call to an `MH_x` method, which acts as the bootstrap method. This is followed by an `invokeExact` call.
>> - **Transformation**: The tool transforms pairs of calls (to `INDY_x` followed by `invokeExact`) into `invokedynamic` instructions. This mimics the JVM's handling of `invokedynamic` instructions, creating dynamic call sites that are linked at runtime.
>>
>> It currently uses ad-hoc code to process class files and intends to migrate to ASM; but since we have the Classfile API, we can migrate to Classfile API instead.
>
> Oussama Louati has updated the pull request incrementally with one additional commit since the last revision:
>
> remove: removed unnecessary logging
Even more formatting nits:
test/jdk/java/lang/invoke/indify/Indify.java line 483:
> 481: final char[] poolMarks;
> 482: final Map<String, PoolEntry> constants = new HashMap<>();
> 483: Logic(ClassModel classModel){
Suggestion:
Logic(ClassModel classModel) {
test/jdk/java/lang/invoke/indify/Indify.java line 566:
> 564: )) b.with(e);
> 565: else{
> 566: if(!quietly) System.err.println("Removing pattern method: " + ((MethodModel) e).methodName());
Suggestion:
else {
if (!quietly) System.err.println("Removing pattern method: " + ((MethodModel) e).methodName());
test/jdk/java/lang/invoke/indify/Indify.java line 640:
> 638: }
> 639:
> 640: char nameAndTypeMark(Utf8Entry name, Utf8Entry type){
Suggestion:
char nameAndTypeMark(Utf8Entry name, Utf8Entry type) {
test/jdk/java/lang/invoke/indify/Indify.java line 716:
> 714:
> 715: private PoolEntry scanPattern(MethodModel method, char patternMark) {
> 716: if(verbose) System.err.println("Scanning the method: " + method.methodName().stringValue() + "for the pattern mark: " + patternMark);
Suggestion:
if (verbose) System.err.println("Scanning the method: " + method.methodName().stringValue() + "for the pattern mark: " + patternMark);
test/jdk/java/lang/invoke/indify/Indify.java line 731:
> 729: List<Object> bsmArgs = null; // args to invokeGeneric
> 730: decode:
> 731: for(Instruction instruction : instructions){
Suggestion:
for (Instruction instruction : instructions) {
test/jdk/java/lang/invoke/indify/Indify.java line 735:
> 733: int bc = instruction.opcode().bytecode();
> 734: String UNKNOWN_CON = "<unknown>";
> 735: switch (bc){
Suggestion:
switch (bc) {
test/jdk/java/lang/invoke/indify/Indify.java line 743:
> 741: case ANEWARRAY :
> 742: arg = jvm.pop();
> 743: if( !(arg instanceof Integer)) break decode;
Suggestion:
if (!(arg instanceof Integer)) break decode;
test/jdk/java/lang/invoke/indify/Indify.java line 859:
> 857: buf.append(argClass.descriptorString());
> 858: }else if (typeArg instanceof PoolEntry argCon) {
> 859: if(argCon.tag() == TAG_CLASS) {
Suggestion:
for (Object typeArg : args) {
if (typeArg instanceof Class<?> argClass) {
buf.append(argClass.descriptorString());
} else if (typeArg instanceof PoolEntry argCon) {
if (argCon.tag() == TAG_CLASS) {
test/jdk/java/lang/invoke/indify/Indify.java line 888:
> 886: continue;
> 887: case "lookupClass":
> 888: if(args.equals(List.of("lookup"))) {
Suggestion:
if (args.equals(List.of("lookup"))) {
test/jdk/java/lang/invoke/indify/Indify.java line 907:
> 905: case "Double.valueOf":
> 906: removeEmptyJVMSlots(args);
> 907: if(args.size() == 1 ) {
Suggestion:
if (args.size() == 1) {
test/jdk/java/lang/invoke/indify/Indify.java line 923:
> 921: continue;
> 922: }
> 923: if(!hasReceiver && ownMethod != null) {
Suggestion:
if (!hasReceiver && ownMethod != null) {
test/jdk/java/lang/invoke/indify/Indify.java line 937:
> 935: {
> 936: ++branchCount;
> 937: if(bsmArgs != null){
Suggestion:
if (bsmArgs != null) {
test/jdk/java/lang/invoke/indify/Indify.java line 952:
> 950: break;
> 951: if((arg instanceof PoolEntry) && ((PoolEntry) arg).tag() == wantedTag)
> 952: return (PoolEntry) arg;
Suggestion:
if (branchCount == 2 && UNKNOWN_CON.equals(arg))
break;
if ((arg instanceof PoolEntry) && ((PoolEntry) arg).tag() == wantedTag)
return (PoolEntry) arg;
test/jdk/java/lang/invoke/indify/Indify.java line 956:
> 954: }
> 955: default:
> 956: if(jvm.stackMotion(instruction.opcode().bytecode())) break;
Suggestion:
if (jvm.stackMotion(instruction.opcode().bytecode())) break;
test/jdk/java/lang/invoke/indify/Indify.java line 1008:
> 1006:
> 1007: }
> 1008: }
Suggestion:
private PoolEntry makeMethodTypeCon(Object x) {
if (x instanceof StringEntry stringEntry) {
return poolBuilder.methodTypeEntry(stringEntry.utf8());
} else {
return poolBuilder.methodTypeEntry(poolBuilder.utf8Entry((String) x));
}
}
test/jdk/java/lang/invoke/indify/Indify.java line 1044:
> 1042: }
> 1043: return poolBuilder.methodHandleEntry(refKind, ref);
> 1044: }
Suggestion:
private PoolEntry parseMemberLookup(byte refKind, List<Object> args) {
//E.g.: lookup().findStatic(Foo.class, "name", MethodType)
if (args.size() != 4) return null;
NameAndTypeEntry nameAndTypeEntry;
Utf8Entry name, type;
ClassEntry ownerClass;
if (!"lookup".equals(args.getFirst())) return null;
if (args.get(1) instanceof ClassEntry classEntry) ownerClass = classEntry;
else return null;
if (args.get(2) instanceof StringEntry stringEntry) name = stringEntry.utf8();
else return null;
if (args.get(3) instanceof MethodTypeEntry methodTypeEntry) type = methodTypeEntry.descriptor();
else return null;
nameAndTypeEntry = poolBuilder.nameAndTypeEntry(name,type);
MemberRefEntry ref;
if (refKind <= (byte) STATIC_SETTER.refKind) {
ref = poolBuilder.fieldRefEntry(ownerClass, nameAndTypeEntry);
return poolBuilder.methodHandleEntry(refKind, ref);
}
else if (refKind == (byte) INTERFACE_VIRTUAL.refKind) {
ref = poolBuilder.interfaceMethodRefEntry(ownerClass, nameAndTypeEntry);
return poolBuilder.methodHandleEntry(refKind, ref);
}
else {
ref = poolBuilder.methodRefEntry(ownerClass, nameAndTypeEntry);
}
return poolBuilder.methodHandleEntry(refKind, ref);
}
test/jdk/java/lang/invoke/indify/Indify.java line 1049:
> 1047: // E.g.: MH_bsm.invokeGeneric(lookup(), "name", MethodType, "extraArg")
> 1048: removeEmptyJVMSlots(args);
> 1049: if(args.size() < 4) return null;
Suggestion:
if (args.size() < 4) return null;
-------------
PR Review: https://git.openjdk.org/jdk/pull/18841#pullrequestreview-2195922618
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689323572
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689328799
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689323765
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689330738
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689323955
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689324110
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689330906
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689330144
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689331095
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689331287
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689331509
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689324306
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689331836
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689332014
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689325088
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689326268
PR Review Comment: https://git.openjdk.org/jdk/pull/18841#discussion_r1689326428
More information about the core-libs-dev
mailing list