Skip to content

Commit

Permalink
8294960: Convert java.base/java.lang.invoke package to use the Classf…
Browse files Browse the repository at this point in the history
…ile API to generate lambdas and method handlers
  • Loading branch information
asotona committed Dec 13, 2023
1 parent 2611a49 commit 2cb98be
Show file tree
Hide file tree
Showing 9 changed files with 1,298 additions and 1,597 deletions.
23 changes: 20 additions & 3 deletions src/java.base/share/classes/java/lang/classfile/ClassBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,12 @@ ClassBuilder withField(Utf8Entry name,
default ClassBuilder withField(Utf8Entry name,
Utf8Entry descriptor,
int flags) {
return withField(name, descriptor, fb -> fb.withFlags(flags));
return withField(name, descriptor, new Consumer<FieldBuilder>() {
@Override
public void accept(FieldBuilder fb) {
fb.withFlags(flags);
}
});
}

/**
Expand Down Expand Up @@ -199,7 +204,13 @@ default ClassBuilder withField(String name,
default ClassBuilder withField(String name,
ClassDesc descriptor,
int flags) {
return withField(name, descriptor, fb -> fb.withFlags(flags));
return withField(name, descriptor, new Consumer<FieldBuilder>() {
//cannot use lambda here
@Override
public void accept(FieldBuilder fb) {
fb.withFlags(flags);
}
});
}

/**
Expand Down Expand Up @@ -246,7 +257,13 @@ default ClassBuilder withMethodBody(Utf8Entry name,
Utf8Entry descriptor,
int methodFlags,
Consumer<? super CodeBuilder> handler) {
return withMethod(name, descriptor, methodFlags, mb -> mb.withCode(handler));
return withMethod(name, descriptor, methodFlags, new Consumer<MethodBuilder>() {
//cannot use lambda here
@Override
public void accept(MethodBuilder mb) {
mb.withCode(handler);
}
});
}

/**
Expand Down
447 changes: 196 additions & 251 deletions src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@

package java.lang.invoke;

import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
import java.lang.classfile.ClassFile;
import java.lang.classfile.attribute.SourceFileAttribute;
import java.lang.constant.ClassDesc;
import sun.invoke.util.Wrapper;

import java.util.ArrayList;
Expand All @@ -38,6 +39,7 @@
import java.util.TreeSet;
import java.util.stream.Stream;

import static java.lang.classfile.ClassFile.*;
import static java.lang.invoke.LambdaForm.BasicType.*;
import static java.lang.invoke.MethodHandleStatics.CLASSFILE_VERSION;
import static java.lang.invoke.MethodTypeForm.*;
Expand Down Expand Up @@ -504,19 +506,14 @@ static byte[] generateInvokersHolderClassBytes(String className,
* a class with a specified name.
*/
private static byte[] generateCodeBytesForLFs(String className, String[] names, LambdaForm[] forms) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
cw.visit(CLASSFILE_VERSION, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);

for (int i = 0; i < forms.length; i++) {
InvokerBytecodeGenerator g
= new InvokerBytecodeGenerator(className, names[i], forms[i], forms[i].methodType());
g.setClassWriter(cw);
g.addMethod();
}

return cw.toByteArray();
return ClassFile.of().build(ClassDesc.ofInternalName(className), clb -> {
clb.withFlags(ACC_PRIVATE | ACC_FINAL | ACC_SUPER)
.withSuperclass(InvokerBytecodeGenerator.INVOKER_SUPER_DESC)
.with(SourceFileAttribute.of(clb.constantPool().utf8Entry(className.substring(className.lastIndexOf('/') + 1))));
for (int i = 0; i < forms.length; i++) {
new InvokerBytecodeGenerator(className, names[i], forms[i], forms[i].methodType()).addMethod(clb);
}
});
}

private static LambdaForm makeReinvokerFor(MethodType type) {
Expand Down

Large diffs are not rendered by default.

Loading

0 comments on commit 2cb98be

Please sign in to comment.