Skip to content

Commit

Permalink
8338545: Functional interface implementations for common pre-boot Cla…
Browse files Browse the repository at this point in the history
…ssFile operations

Reviewed-by: asotona
  • Loading branch information
liach committed Aug 21, 2024
1 parent 7458952 commit 80adea8
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ 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, Util.buildingFlags(flags));
}

/**
Expand Down Expand Up @@ -194,7 +194,7 @@ 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, Util.buildingFlags(flags));
}

/**
Expand Down Expand Up @@ -241,7 +241,7 @@ 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, Util.buildingCode(handler));
}

/**
Expand Down Expand Up @@ -276,7 +276,7 @@ default ClassBuilder withMethodBody(String name,
MethodTypeDesc descriptor,
int methodFlags,
Consumer<? super CodeBuilder> handler) {
return withMethod(name, descriptor, methodFlags, mb -> mb.withCode(handler));
return withMethod(name, descriptor, methodFlags, Util.buildingCode(handler));
}

/**
Expand Down
27 changes: 12 additions & 15 deletions src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -31,7 +31,6 @@
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.LambdaForm.BasicType;
import java.lang.invoke.InnerClassLambdaMetafactory.MethodBody;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -68,8 +67,6 @@ abstract class ClassSpecializer<T,K,S extends ClassSpecializer<T,K,S>.SpeciesDat

private static final ClassDesc CD_LambdaForm = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/LambdaForm;");
private static final ClassDesc CD_BoundMethodHandle = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/BoundMethodHandle;");
private static final Consumer<FieldBuilder> STATIC_FIELD_FLAGS = new InnerClassLambdaMetafactory.FieldFlags(ACC_STATIC);
private static final Consumer<FieldBuilder> FINAL_FIELD_FLAGS = new InnerClassLambdaMetafactory.FieldFlags(ACC_FINAL);

private final Class<T> topClass;
private final Class<K> keyType;
Expand Down Expand Up @@ -625,7 +622,7 @@ public void accept(ClassBuilder clb) {
.with(SourceFileAttribute.of(classDesc.displayName()))

// emit static types and BMH_SPECIES fields
.withField(sdFieldName, CD_SPECIES_DATA, STATIC_FIELD_FLAGS);
.withField(sdFieldName, CD_SPECIES_DATA, ACC_STATIC);

// handy holder for dealing with groups of typed values (ctor arguments and fields)
class Var {
Expand Down Expand Up @@ -709,26 +706,26 @@ void emitLoadInstruction(CodeBuilder cob) {

// emit bound argument fields
for (Var field : fields) {
clb.withField(field.name, field.desc, FINAL_FIELD_FLAGS);
clb.withField(field.name, field.desc, ACC_FINAL);
}

// emit implementation of speciesData()
clb.withMethod(SPECIES_DATA_NAME, MTD_SPECIES_DATA, (SPECIES_DATA_MODS & ACC_PPP) | ACC_FINAL,
new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody(SPECIES_DATA_NAME, MTD_SPECIES_DATA, (SPECIES_DATA_MODS & ACC_PPP) | ACC_FINAL,
new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
cob.getstatic(classDesc, sdFieldName, CD_SPECIES_DATA)
.areturn();
}
}));
});

// figure out the constructor arguments
MethodType superCtorType = ClassSpecializer.this.baseConstructorType();
MethodType thisCtorType = superCtorType.appendParameterTypes(fieldTypes);

// emit constructor
clb.withMethod(INIT_NAME, methodDesc(thisCtorType), ACC_PRIVATE,
new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody(INIT_NAME, methodDesc(thisCtorType), ACC_PRIVATE,
new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
cob.aload(0); // this
Expand All @@ -753,12 +750,12 @@ public void accept(CodeBuilder cob) {

cob.return_();
}
}));
});

// emit make() ...factory method wrapping constructor
MethodType ftryType = thisCtorType.changeReturnType(topClass());
clb.withMethod("make", methodDesc(ftryType), ACC_STATIC,
new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody("make", methodDesc(ftryType), ACC_STATIC,
new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
// make instance
Expand All @@ -773,7 +770,7 @@ public void accept(CodeBuilder cob) {
cob.invokespecial(classDesc, INIT_NAME, methodDesc(thisCtorType))
.areturn();
}
}));
});

// For each transform, emit the customized override of the transform method.
// This method mixes together some incoming arguments (from the transform's
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,6 @@
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private static final ClassDesc[] EMPTY_CLASSDESC_ARRAY = ConstantUtils.EMPTY_CLASSDESC;

// Static builders to avoid lambdas
record FieldFlags(int flags) implements Consumer<FieldBuilder> {
@Override
public void accept(FieldBuilder fb) {
fb.withFlags(flags);
}
};
record MethodBody(Consumer<CodeBuilder> code) implements Consumer<MethodBuilder> {
@Override
public void accept(MethodBuilder mb) {
mb.withCode(code);
}
};

// For dumping generated classes to disk, for debugging purposes
private static final ClassFileDumper lambdaProxyClassFileDumper;

Expand Down Expand Up @@ -324,7 +310,7 @@ public void accept(ClassBuilder clb) {
.withInterfaceSymbols(interfaces);
// Generate final fields to be filled in by constructor
for (int i = 0; i < argDescs.length; i++) {
clb.withField(argNames[i], argDescs[i], new FieldFlags(ACC_PRIVATE | ACC_FINAL));
clb.withField(argNames[i], argDescs[i], ACC_PRIVATE | ACC_FINAL);
}

generateConstructor(clb);
Expand All @@ -334,15 +320,15 @@ public void accept(ClassBuilder clb) {
}

// Forward the SAM method
clb.withMethod(interfaceMethodName,
clb.withMethodBody(interfaceMethodName,
methodDesc(interfaceMethodType),
ACC_PUBLIC,
forwardingMethod(interfaceMethodType));

// Forward the bridges
if (altMethods != null) {
for (MethodType mt : altMethods) {
clb.withMethod(interfaceMethodName,
clb.withMethodBody(interfaceMethodName,
methodDesc(mt),
ACC_PUBLIC | ACC_BRIDGE,
forwardingMethod(mt));
Expand Down Expand Up @@ -376,10 +362,10 @@ private void generateClassInitializer(ClassBuilder clb) {
ClassDesc lambdaTypeDescriptor = classDesc(factoryType.returnType());

// Generate the static final field that holds the lambda singleton
clb.withField(LAMBDA_INSTANCE_FIELD, lambdaTypeDescriptor, new FieldFlags(ACC_PRIVATE | ACC_STATIC | ACC_FINAL));
clb.withField(LAMBDA_INSTANCE_FIELD, lambdaTypeDescriptor, ACC_PRIVATE | ACC_STATIC | ACC_FINAL);

// Instantiate the lambda and store it to the static final field
clb.withMethod(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
assert factoryType.parameterCount() == 0;
Expand All @@ -389,16 +375,16 @@ public void accept(CodeBuilder cob) {
.putstatic(lambdaClassDesc, LAMBDA_INSTANCE_FIELD, lambdaTypeDescriptor)
.return_();
}
}));
});
}

/**
* Generate the constructor for the class
*/
private void generateConstructor(ClassBuilder clb) {
// Generate constructor
clb.withMethod(INIT_NAME, constructorTypeDesc, ACC_PRIVATE,
new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody(INIT_NAME, constructorTypeDesc, ACC_PRIVATE,
new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
cob.aload(0)
Expand All @@ -412,7 +398,7 @@ public void accept(CodeBuilder cob) {
}
cob.return_();
}
}));
});
}

private static class SerializationSupport {
Expand All @@ -439,8 +425,8 @@ private static class SerializationSupport {
* Generate a writeReplace method that supports serialization
*/
private void generateSerializationFriendlyMethods(ClassBuilder clb) {
clb.withMethod(SerializationSupport.NAME_METHOD_WRITE_REPLACE, SerializationSupport.MTD_Object, ACC_PRIVATE | ACC_FINAL,
new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody(SerializationSupport.NAME_METHOD_WRITE_REPLACE, SerializationSupport.MTD_Object, ACC_PRIVATE | ACC_FINAL,
new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
cob.new_(SerializationSupport.CD_SerializedLambda)
Expand Down Expand Up @@ -468,7 +454,7 @@ public void accept(CodeBuilder cob) {
SerializationSupport.MTD_CTOR_SERIALIZED_LAMBDA)
.areturn();
}
}));
});
}

/**
Expand Down Expand Up @@ -504,8 +490,8 @@ public void accept(CodeBuilder cob) {
* This method generates a method body which calls the lambda implementation
* method, converting arguments, as needed.
*/
Consumer<MethodBuilder> forwardingMethod(MethodType methodType) {
return new MethodBody(new Consumer<CodeBuilder>() {
Consumer<CodeBuilder> forwardingMethod(MethodType methodType) {
return new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
Expand Down Expand Up @@ -542,7 +528,7 @@ public void accept(CodeBuilder cob) {
TypeConvertingMethodAdapter.convertType(cob, implReturnClass, samReturnClass, samReturnClass);
cob.return_(TypeKind.from(samReturnClass));
}
});
};
}

private void convertArgumentTypes(CodeBuilder cob, MethodType samType) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -83,21 +83,6 @@ class InvokerBytecodeGenerator {
private static final String CLASS_PREFIX = "java/lang/invoke/LambdaForm$";
private static final String SOURCE_PREFIX = "LambdaForm$";

// Static builders to avoid lambdas
private static final Consumer<FieldBuilder> STATIC_FINAL_FIELD = new Consumer<FieldBuilder>() {
@Override
public void accept(FieldBuilder fb) {
fb.withFlags(ACC_STATIC | ACC_FINAL);
}
};

record MethodBody(Consumer<CodeBuilder> code) implements Consumer<MethodBuilder> {
@Override
public void accept(MethodBuilder mb) {
mb.withCode(code);
}
};

/** Name of its super class*/
static final ClassDesc INVOKER_SUPER_DESC = CD_Object;

Expand Down Expand Up @@ -328,10 +313,10 @@ static void clinit(ClassBuilder clb, ClassDesc classDesc, List<ClassData> classD

for (ClassData p : classData) {
// add the static field
clb.withField(p.name, p.desc, STATIC_FINAL_FIELD);
clb.withField(p.name, p.desc, ACC_STATIC | ACC_FINAL);
}

clb.withMethod(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
cob.loadConstant(classDesc)
Expand All @@ -356,7 +341,7 @@ public void accept(CodeBuilder cob) {
}
cob.return_();
}
}));
});
}

private void emitLoadInsn(CodeBuilder cob, TypeKind type, int index) {
Expand Down Expand Up @@ -1671,14 +1656,14 @@ public void accept(CodeBuilder cob) {
*/
private void bogusMethod(ClassBuilder clb, Object os) {
if (dumper().isEnabled()) {
clb.withMethod("dummy", MTD_void, ACC_STATIC, new MethodBody(new Consumer<CodeBuilder>() {
clb.withMethodBody("dummy", MTD_void, ACC_STATIC, new Consumer<>() {
@Override
public void accept(CodeBuilder cob) {
cob.loadConstant(os.toString());
cob.pop();
cob.return_();
}
}));
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,7 @@ public Optional<MethodModel> parent() {

@Override
public void writeTo(DirectMethodBuilder builder) {
builder.withCode(new Consumer<>() {
@Override
public void accept(CodeBuilder cb) {
forEach(cb);
}
});
builder.withCode(Util.writingAll(this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,7 @@ public Utf8Entry fieldType() {

@Override
public void writeTo(DirectClassBuilder builder) {
builder.withField(name, desc, new Consumer<>() {
@Override
public void accept(FieldBuilder fieldBuilder) {
elements.forEach(fieldBuilder);
}
});
builder.withField(name, desc, Util.writingAll(this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,7 @@ public Optional<CodeModel> code() {

@Override
public void writeTo(DirectClassBuilder builder) {
builder.withMethod(methodName(), methodType(), methodFlags(), new Consumer<>() {
@Override
public void accept(MethodBuilder mb) {
forEach(mb);
}
});
builder.withMethod(methodName(), methodType(), methodFlags(), Util.writingAll(this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,7 @@ public void writeTo(BufWriterImpl buf) {
}
else {
DirectCodeBuilder.build((MethodInfo) enclosingMethod,
new Consumer<CodeBuilder>() {
@Override
public void accept(CodeBuilder cb) {
forEach(cb);
}
},
Util.writingAll(this),
(SplitConstantPool)buf.constantPool(),
buf.context(),
null).writeTo(buf);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,7 @@ public void writeTo(DirectClassBuilder builder) {
builder.withField(this);
}
else {
builder.withField(fieldName(), fieldType(), new Consumer<>() {
@Override
public void accept(FieldBuilder fb) {
FieldImpl.this.forEach(fb);
}
});
builder.withField(fieldName(), fieldType(), Util.writingAll(this));
}
}

Expand Down
Loading

0 comments on commit 80adea8

Please sign in to comment.