Skip to content

Commit 80adea8

Browse files
committed
8338545: Functional interface implementations for common pre-boot ClassFile operations
Reviewed-by: asotona
1 parent 7458952 commit 80adea8

File tree

11 files changed

+76
-106
lines changed

11 files changed

+76
-106
lines changed

src/java.base/share/classes/java/lang/classfile/ClassBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ ClassBuilder withField(Utf8Entry name,
165165
default ClassBuilder withField(Utf8Entry name,
166166
Utf8Entry descriptor,
167167
int flags) {
168-
return withField(name, descriptor, fb -> fb.withFlags(flags));
168+
return withField(name, descriptor, Util.buildingFlags(flags));
169169
}
170170

171171
/**
@@ -194,7 +194,7 @@ default ClassBuilder withField(String name,
194194
default ClassBuilder withField(String name,
195195
ClassDesc descriptor,
196196
int flags) {
197-
return withField(name, descriptor, fb -> fb.withFlags(flags));
197+
return withField(name, descriptor, Util.buildingFlags(flags));
198198
}
199199

200200
/**
@@ -241,7 +241,7 @@ default ClassBuilder withMethodBody(Utf8Entry name,
241241
Utf8Entry descriptor,
242242
int methodFlags,
243243
Consumer<? super CodeBuilder> handler) {
244-
return withMethod(name, descriptor, methodFlags, mb -> mb.withCode(handler));
244+
return withMethod(name, descriptor, methodFlags, Util.buildingCode(handler));
245245
}
246246

247247
/**
@@ -276,7 +276,7 @@ default ClassBuilder withMethodBody(String name,
276276
MethodTypeDesc descriptor,
277277
int methodFlags,
278278
Consumer<? super CodeBuilder> handler) {
279-
return withMethod(name, descriptor, methodFlags, mb -> mb.withCode(handler));
279+
return withMethod(name, descriptor, methodFlags, Util.buildingCode(handler));
280280
}
281281

282282
/**

src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
3131
import java.lang.constant.ClassDesc;
3232
import java.lang.constant.MethodTypeDesc;
3333
import java.lang.invoke.LambdaForm.BasicType;
34-
import java.lang.invoke.InnerClassLambdaMetafactory.MethodBody;
3534
import java.lang.reflect.Constructor;
3635
import java.lang.reflect.Field;
3736
import java.lang.reflect.Modifier;
@@ -68,8 +67,6 @@ abstract class ClassSpecializer<T,K,S extends ClassSpecializer<T,K,S>.SpeciesDat
6867

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

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

627624
// emit static types and BMH_SPECIES fields
628-
.withField(sdFieldName, CD_SPECIES_DATA, STATIC_FIELD_FLAGS);
625+
.withField(sdFieldName, CD_SPECIES_DATA, ACC_STATIC);
629626

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

710707
// emit bound argument fields
711708
for (Var field : fields) {
712-
clb.withField(field.name, field.desc, FINAL_FIELD_FLAGS);
709+
clb.withField(field.name, field.desc, ACC_FINAL);
713710
}
714711

715712
// emit implementation of speciesData()
716-
clb.withMethod(SPECIES_DATA_NAME, MTD_SPECIES_DATA, (SPECIES_DATA_MODS & ACC_PPP) | ACC_FINAL,
717-
new MethodBody(new Consumer<CodeBuilder>() {
713+
clb.withMethodBody(SPECIES_DATA_NAME, MTD_SPECIES_DATA, (SPECIES_DATA_MODS & ACC_PPP) | ACC_FINAL,
714+
new Consumer<>() {
718715
@Override
719716
public void accept(CodeBuilder cob) {
720717
cob.getstatic(classDesc, sdFieldName, CD_SPECIES_DATA)
721718
.areturn();
722719
}
723-
}));
720+
});
724721

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

729726
// emit constructor
730-
clb.withMethod(INIT_NAME, methodDesc(thisCtorType), ACC_PRIVATE,
731-
new MethodBody(new Consumer<CodeBuilder>() {
727+
clb.withMethodBody(INIT_NAME, methodDesc(thisCtorType), ACC_PRIVATE,
728+
new Consumer<>() {
732729
@Override
733730
public void accept(CodeBuilder cob) {
734731
cob.aload(0); // this
@@ -753,12 +750,12 @@ public void accept(CodeBuilder cob) {
753750

754751
cob.return_();
755752
}
756-
}));
753+
});
757754

758755
// emit make() ...factory method wrapping constructor
759756
MethodType ftryType = thisCtorType.changeReturnType(topClass());
760-
clb.withMethod("make", methodDesc(ftryType), ACC_STATIC,
761-
new MethodBody(new Consumer<CodeBuilder>() {
757+
clb.withMethodBody("make", methodDesc(ftryType), ACC_STATIC,
758+
new Consumer<>() {
762759
@Override
763760
public void accept(CodeBuilder cob) {
764761
// make instance
@@ -773,7 +770,7 @@ public void accept(CodeBuilder cob) {
773770
cob.invokespecial(classDesc, INIT_NAME, methodDesc(thisCtorType))
774771
.areturn();
775772
}
776-
}));
773+
});
777774

778775
// For each transform, emit the customized override of the transform method.
779776
// This method mixes together some incoming arguments (from the transform's

src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,6 @@
7272
private static final String[] EMPTY_STRING_ARRAY = new String[0];
7373
private static final ClassDesc[] EMPTY_CLASSDESC_ARRAY = ConstantUtils.EMPTY_CLASSDESC;
7474

75-
// Static builders to avoid lambdas
76-
record FieldFlags(int flags) implements Consumer<FieldBuilder> {
77-
@Override
78-
public void accept(FieldBuilder fb) {
79-
fb.withFlags(flags);
80-
}
81-
};
82-
record MethodBody(Consumer<CodeBuilder> code) implements Consumer<MethodBuilder> {
83-
@Override
84-
public void accept(MethodBuilder mb) {
85-
mb.withCode(code);
86-
}
87-
};
88-
8975
// For dumping generated classes to disk, for debugging purposes
9076
private static final ClassFileDumper lambdaProxyClassFileDumper;
9177

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

330316
generateConstructor(clb);
@@ -334,15 +320,15 @@ public void accept(ClassBuilder clb) {
334320
}
335321

336322
// Forward the SAM method
337-
clb.withMethod(interfaceMethodName,
323+
clb.withMethodBody(interfaceMethodName,
338324
methodDesc(interfaceMethodType),
339325
ACC_PUBLIC,
340326
forwardingMethod(interfaceMethodType));
341327

342328
// Forward the bridges
343329
if (altMethods != null) {
344330
for (MethodType mt : altMethods) {
345-
clb.withMethod(interfaceMethodName,
331+
clb.withMethodBody(interfaceMethodName,
346332
methodDesc(mt),
347333
ACC_PUBLIC | ACC_BRIDGE,
348334
forwardingMethod(mt));
@@ -376,10 +362,10 @@ private void generateClassInitializer(ClassBuilder clb) {
376362
ClassDesc lambdaTypeDescriptor = classDesc(factoryType.returnType());
377363

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

381367
// Instantiate the lambda and store it to the static final field
382-
clb.withMethod(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new MethodBody(new Consumer<CodeBuilder>() {
368+
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new Consumer<>() {
383369
@Override
384370
public void accept(CodeBuilder cob) {
385371
assert factoryType.parameterCount() == 0;
@@ -389,16 +375,16 @@ public void accept(CodeBuilder cob) {
389375
.putstatic(lambdaClassDesc, LAMBDA_INSTANCE_FIELD, lambdaTypeDescriptor)
390376
.return_();
391377
}
392-
}));
378+
});
393379
}
394380

395381
/**
396382
* Generate the constructor for the class
397383
*/
398384
private void generateConstructor(ClassBuilder clb) {
399385
// Generate constructor
400-
clb.withMethod(INIT_NAME, constructorTypeDesc, ACC_PRIVATE,
401-
new MethodBody(new Consumer<CodeBuilder>() {
386+
clb.withMethodBody(INIT_NAME, constructorTypeDesc, ACC_PRIVATE,
387+
new Consumer<>() {
402388
@Override
403389
public void accept(CodeBuilder cob) {
404390
cob.aload(0)
@@ -412,7 +398,7 @@ public void accept(CodeBuilder cob) {
412398
}
413399
cob.return_();
414400
}
415-
}));
401+
});
416402
}
417403

418404
private static class SerializationSupport {
@@ -439,8 +425,8 @@ private static class SerializationSupport {
439425
* Generate a writeReplace method that supports serialization
440426
*/
441427
private void generateSerializationFriendlyMethods(ClassBuilder clb) {
442-
clb.withMethod(SerializationSupport.NAME_METHOD_WRITE_REPLACE, SerializationSupport.MTD_Object, ACC_PRIVATE | ACC_FINAL,
443-
new MethodBody(new Consumer<CodeBuilder>() {
428+
clb.withMethodBody(SerializationSupport.NAME_METHOD_WRITE_REPLACE, SerializationSupport.MTD_Object, ACC_PRIVATE | ACC_FINAL,
429+
new Consumer<>() {
444430
@Override
445431
public void accept(CodeBuilder cob) {
446432
cob.new_(SerializationSupport.CD_SerializedLambda)
@@ -468,7 +454,7 @@ public void accept(CodeBuilder cob) {
468454
SerializationSupport.MTD_CTOR_SERIALIZED_LAMBDA)
469455
.areturn();
470456
}
471-
}));
457+
});
472458
}
473459

474460
/**
@@ -504,8 +490,8 @@ public void accept(CodeBuilder cob) {
504490
* This method generates a method body which calls the lambda implementation
505491
* method, converting arguments, as needed.
506492
*/
507-
Consumer<MethodBuilder> forwardingMethod(MethodType methodType) {
508-
return new MethodBody(new Consumer<CodeBuilder>() {
493+
Consumer<CodeBuilder> forwardingMethod(MethodType methodType) {
494+
return new Consumer<>() {
509495
@Override
510496
public void accept(CodeBuilder cob) {
511497
if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
@@ -542,7 +528,7 @@ public void accept(CodeBuilder cob) {
542528
TypeConvertingMethodAdapter.convertType(cob, implReturnClass, samReturnClass, samReturnClass);
543529
cob.return_(TypeKind.from(samReturnClass));
544530
}
545-
});
531+
};
546532
}
547533

548534
private void convertArgumentTypes(CodeBuilder cob, MethodType samType) {

src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -83,21 +83,6 @@ class InvokerBytecodeGenerator {
8383
private static final String CLASS_PREFIX = "java/lang/invoke/LambdaForm$";
8484
private static final String SOURCE_PREFIX = "LambdaForm$";
8585

86-
// Static builders to avoid lambdas
87-
private static final Consumer<FieldBuilder> STATIC_FINAL_FIELD = new Consumer<FieldBuilder>() {
88-
@Override
89-
public void accept(FieldBuilder fb) {
90-
fb.withFlags(ACC_STATIC | ACC_FINAL);
91-
}
92-
};
93-
94-
record MethodBody(Consumer<CodeBuilder> code) implements Consumer<MethodBuilder> {
95-
@Override
96-
public void accept(MethodBuilder mb) {
97-
mb.withCode(code);
98-
}
99-
};
100-
10186
/** Name of its super class*/
10287
static final ClassDesc INVOKER_SUPER_DESC = CD_Object;
10388

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

329314
for (ClassData p : classData) {
330315
// add the static field
331-
clb.withField(p.name, p.desc, STATIC_FINAL_FIELD);
316+
clb.withField(p.name, p.desc, ACC_STATIC | ACC_FINAL);
332317
}
333318

334-
clb.withMethod(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new MethodBody(new Consumer<CodeBuilder>() {
319+
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, new Consumer<>() {
335320
@Override
336321
public void accept(CodeBuilder cob) {
337322
cob.loadConstant(classDesc)
@@ -356,7 +341,7 @@ public void accept(CodeBuilder cob) {
356341
}
357342
cob.return_();
358343
}
359-
}));
344+
});
360345
}
361346

362347
private void emitLoadInsn(CodeBuilder cob, TypeKind type, int index) {
@@ -1671,14 +1656,14 @@ public void accept(CodeBuilder cob) {
16711656
*/
16721657
private void bogusMethod(ClassBuilder clb, Object os) {
16731658
if (dumper().isEnabled()) {
1674-
clb.withMethod("dummy", MTD_void, ACC_STATIC, new MethodBody(new Consumer<CodeBuilder>() {
1659+
clb.withMethodBody("dummy", MTD_void, ACC_STATIC, new Consumer<>() {
16751660
@Override
16761661
public void accept(CodeBuilder cob) {
16771662
cob.loadConstant(os.toString());
16781663
cob.pop();
16791664
cob.return_();
16801665
}
1681-
}));
1666+
});
16821667
}
16831668
}
16841669

src/java.base/share/classes/jdk/internal/classfile/impl/BufferedCodeBuilder.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,7 @@ public Optional<MethodModel> parent() {
173173

174174
@Override
175175
public void writeTo(DirectMethodBuilder builder) {
176-
builder.withCode(new Consumer<>() {
177-
@Override
178-
public void accept(CodeBuilder cb) {
179-
forEach(cb);
180-
}
181-
});
176+
builder.withCode(Util.writingAll(this));
182177
}
183178

184179
@Override

src/java.base/share/classes/jdk/internal/classfile/impl/BufferedFieldBuilder.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,7 @@ public Utf8Entry fieldType() {
104104

105105
@Override
106106
public void writeTo(DirectClassBuilder builder) {
107-
builder.withField(name, desc, new Consumer<>() {
108-
@Override
109-
public void accept(FieldBuilder fieldBuilder) {
110-
elements.forEach(fieldBuilder);
111-
}
112-
});
107+
builder.withField(name, desc, Util.writingAll(this));
113108
}
114109

115110
@Override

src/java.base/share/classes/jdk/internal/classfile/impl/BufferedMethodBuilder.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,7 @@ public Optional<CodeModel> code() {
205205

206206
@Override
207207
public void writeTo(DirectClassBuilder builder) {
208-
builder.withMethod(methodName(), methodType(), methodFlags(), new Consumer<>() {
209-
@Override
210-
public void accept(MethodBuilder mb) {
211-
forEach(mb);
212-
}
213-
});
208+
builder.withMethod(methodName(), methodType(), methodFlags(), Util.writingAll(this));
214209
}
215210

216211
@Override

src/java.base/share/classes/jdk/internal/classfile/impl/CodeImpl.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,7 @@ public void writeTo(BufWriterImpl buf) {
147147
}
148148
else {
149149
DirectCodeBuilder.build((MethodInfo) enclosingMethod,
150-
new Consumer<CodeBuilder>() {
151-
@Override
152-
public void accept(CodeBuilder cb) {
153-
forEach(cb);
154-
}
155-
},
150+
Util.writingAll(this),
156151
(SplitConstantPool)buf.constantPool(),
157152
buf.context(),
158153
null).writeTo(buf);

src/java.base/share/classes/jdk/internal/classfile/impl/FieldImpl.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,7 @@ public void writeTo(DirectClassBuilder builder) {
9999
builder.withField(this);
100100
}
101101
else {
102-
builder.withField(fieldName(), fieldType(), new Consumer<>() {
103-
@Override
104-
public void accept(FieldBuilder fb) {
105-
FieldImpl.this.forEach(fb);
106-
}
107-
});
102+
builder.withField(fieldName(), fieldType(), Util.writingAll(this));
108103
}
109104
}
110105

0 commit comments

Comments
 (0)