Skip to content

Commit

Permalink
8339683: Simplify class data generation in InvokerBytecodeGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
liach committed Sep 6, 2024
1 parent 5b72bbf commit 1602657
Showing 1 changed file with 33 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.lang.classfile.*;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import java.lang.classfile.attribute.SourceFileAttribute;
import java.lang.classfile.constantpool.FieldRefEntry;
import java.lang.classfile.instruction.SwitchCase;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDesc;
Expand Down Expand Up @@ -196,35 +197,9 @@ private static String makeDumpableClassName(String className) {
return buf.toString();
}

static class ClassData {
final String name;
final ClassDesc desc;
final Object value;

ClassData(String name, ClassDesc desc, Object value) {
this.name = name;
this.desc = desc;
this.value = value;
}

public String name() { return name; }
public String toString() {
return name + ",value="+value;
}
}

String classData(Object arg) {
ClassDesc desc;
if (arg instanceof Class) {
desc = CD_Class;
} else if (arg instanceof MethodHandle) {
desc = CD_MethodHandle;
} else if (arg instanceof LambdaForm) {
desc = CD_LambdaForm;
} else {
desc = CD_Object;
}
record ClassData(FieldRefEntry field, Object value) {}

FieldRefEntry classData(ClassFileBuilder<?, ?> cfb, Object arg, ClassDesc desc) {
// unique static variable name
String name;
List<ClassData> classData = this.classData;
Expand All @@ -237,8 +212,9 @@ String classData(Object arg) {
} else {
name = "_D_" + classData.size();
}
classData.add(new ClassData(name, desc, arg));
return name;
var field = cfb.constantPool().fieldRefEntry(classDesc, name, desc);
classData.add(new ClassData(field, arg));
return field;
}

/**
Expand Down Expand Up @@ -328,27 +304,31 @@ public void accept(CodeBuilder cob) {
.invokestatic(CD_MethodHandles, "classData", MTD_Object_Class);
int size = classData.size();
if (size == 1) {
ClassData p = classData.get(0);
var field = classData.getFirst().field;
// add the static field
clb.withField(p.name, p.desc, ACC_STATIC | ACC_FINAL);
clb.withField(field.name(), field.type(), ACC_STATIC | ACC_FINAL);

cob.checkcast(p.desc)
.putstatic(classDesc, p.name, p.desc);
var ft = field.typeSymbol();
if (ft != CD_Object)
cob.checkcast(ft);
cob.putstatic(field);
} else {
cob.checkcast(CD_List)
.astore(0);
int index = 0;
var listGet = cob.constantPool().interfaceMethodRefEntry(CD_List, "get", MTD_Object_int);
for (int i = 0; i < size; i++) {
ClassData p = classData.get(i);
var field = classData.get(i).field;
// add the static field
clb.withField(p.name, p.desc, ACC_STATIC | ACC_FINAL);
clb.withField(field.name(), field.type(), ACC_STATIC | ACC_FINAL);
// initialize the static field
cob.aload(0)
.loadConstant(index++)
.invokeinterface(listGet)
.checkcast(p.desc)
.putstatic(classDesc, p.name, p.desc);
.invokeinterface(listGet);
var ft = field.typeSymbol();
if (ft != CD_Object)
cob.checkcast(ft);
cob.putstatic(field);
}
}
cob.return_();
Expand All @@ -366,17 +346,13 @@ private void emitStoreInsn(CodeBuilder cob, TypeKind type, int index) {

/**
* Emit a boxing call.
*
* @param wrapper primitive type class to box.
*/
private void emitBoxing(CodeBuilder cob, TypeKind tk) {
TypeConvertingMethodAdapter.box(cob, tk);
}

/**
* Emit an unboxing call (plus preceding checkcast).
*
* @param wrapper wrapper type class to unbox.
*/
private void emitUnboxing(CodeBuilder cob, TypeKind target) {
switch (target) {
Expand Down Expand Up @@ -445,7 +421,7 @@ private void emitReferenceCast(CodeBuilder cob, Class<?> cls, Object arg) {
ClassDesc sig = classDesc(cls);
cob.checkcast(sig);
} else {
cob.getstatic(classDesc, classData(cls), CD_Class)
cob.getstatic(classData(cob, cls, CD_Class))
.swap()
.invokevirtual(CD_Class, "cast", MTD_Object_Object);
if (Object[].class.isAssignableFrom(cls))
Expand Down Expand Up @@ -554,7 +530,7 @@ private boolean checkActualReceiver(CodeBuilder cob) {
* Generate an invoker method for the passed {@link LambdaForm}.
*/
private byte[] generateCustomizedCodeBytes() {
final byte[] classFile = classFileSetup(new Consumer<ClassBuilder>() {
final byte[] classFile = classFileSetup(new Consumer<>() {
@Override
public void accept(ClassBuilder clb) {
addMethod(clb);
Expand All @@ -566,7 +542,7 @@ public void accept(ClassBuilder clb) {
}

void addMethod(ClassBuilder clb) {
methodSetup(clb, new Consumer<MethodBuilder>() {
methodSetup(clb, new Consumer<>() {
@Override
public void accept(MethodBuilder mb) {

Expand All @@ -576,18 +552,17 @@ public void accept(MethodBuilder mb) {
mb.accept(LF_DONTINLINE_ANNOTATIONS);
}

classData(lambdaForm); // keep LambdaForm instance & its compiled form lifetime tightly coupled.
classData(mb, lambdaForm, CD_LambdaForm); // keep LambdaForm instance & its compiled form lifetime tightly coupled.

mb.withCode(new Consumer<CodeBuilder>() {
mb.withCode(new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
if (lambdaForm.customized != null) {
// Since LambdaForm is customized for a particular MethodHandle, it's safe to substitute
// receiver MethodHandle (at slot #0) with an embedded constant and use it instead.
// It enables more efficient code generation in some situations, since embedded constants
// are compile-time constants for JIT compiler.
cob.getstatic(classDesc, classData(lambdaForm.customized), CD_MethodHandle)
.checkcast(CD_MethodHandle);
cob.getstatic(classData(cob, lambdaForm.customized, CD_MethodHandle));
assert(checkActualReceiver(cob)); // expects MethodHandle on top of the stack
cob.astore(0);
}
Expand Down Expand Up @@ -720,7 +695,7 @@ void emitInvoke(CodeBuilder cob, Name name) {
// push receiver
MethodHandle target = name.function.resolvedHandle();
assert(target != null) : name.exprString();
cob.getstatic(classDesc, classData(target), CD_MethodHandle);
cob.getstatic(classData(cob, target, CD_MethodHandle));
emitReferenceCast(cob, MethodHandle.class, target);
} else {
// load receiver
Expand Down Expand Up @@ -1445,7 +1420,7 @@ private void emitPushArgument(CodeBuilder cob, Class<?> ptype, Object arg) {
if (Wrapper.isWrapperType(arg.getClass()) && bptype != L_TYPE) {
cob.loadConstant((ConstantDesc)arg);
} else {
cob.getstatic(classDesc, classData(arg), CD_Object);
cob.getstatic(classData(cob, arg, CD_Object));
emitImplicitConversion(cob, L_TYPE, ptype, arg);
}
}
Expand Down Expand Up @@ -1524,10 +1499,10 @@ static MemberName generateLambdaFormInterpreterEntryPoint(MethodType mt) {
}

private byte[] generateLambdaFormInterpreterEntryPointBytes() {
final byte[] classFile = classFileSetup(new Consumer<ClassBuilder>() {
final byte[] classFile = classFileSetup(new Consumer<>() {
@Override
public void accept(ClassBuilder clb) {
methodSetup(clb, new Consumer<MethodBuilder>() {
methodSetup(clb, new Consumer<>() {
@Override
public void accept(MethodBuilder mb) {

Expand All @@ -1536,7 +1511,7 @@ public void accept(MethodBuilder mb) {
DONTINLINE // Don't inline the interpreter entry.
)));

mb.withCode(new Consumer<CodeBuilder>() {
mb.withCode(new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
// create parameter array
Expand Down Expand Up @@ -1593,10 +1568,10 @@ static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) {

private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) {
MethodType dstType = typeForm.erasedType();
final byte[] classFile = classFileSetup(new Consumer<ClassBuilder>() {
final byte[] classFile = classFileSetup(new Consumer<>() {
@Override
public void accept(ClassBuilder clb) {
methodSetup(clb, new Consumer<MethodBuilder>() {
methodSetup(clb, new Consumer<>() {
@Override
public void accept(MethodBuilder mb) {

Expand All @@ -1605,7 +1580,7 @@ public void accept(MethodBuilder mb) {
FORCEINLINE // Force inlining of this invoker method.
)));

mb.withCode(new Consumer<CodeBuilder>() {
mb.withCode(new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
// Load receiver
Expand Down

0 comments on commit 1602657

Please sign in to comment.