Skip to content

Commit 088b81c

Browse files
cl4espull[bot]
authored andcommitted
8340131: Refactor internal makeHiddenClassDefiner to take option mask instead of Set<ClassOption>
Reviewed-by: liach, jvernee
1 parent 75cd424 commit 088b81c

File tree

6 files changed

+44
-25
lines changed

6 files changed

+44
-25
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
import java.lang.classfile.constantpool.ConstantPoolBuilder;
5454
import java.lang.classfile.constantpool.MethodRefEntry;
5555
import static java.lang.constant.ConstantDescs.*;
56+
import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS;
57+
import static java.lang.invoke.MethodHandleNatives.Constants.STRONG_LOADER_LINK;
5658
import static java.lang.invoke.MethodHandles.Lookup.ClassOption.NESTMATE;
5759
import static java.lang.invoke.MethodHandles.Lookup.ClassOption.STRONG;
5860
import static java.lang.invoke.MethodType.methodType;
@@ -348,7 +350,7 @@ else if (finalAccidentallySerializable)
348350
try {
349351
// this class is linked at the indy callsite; so define a hidden nestmate
350352
var classdata = useImplMethodHandle? implementation : null;
351-
return caller.makeHiddenClassDefiner(lambdaClassName, classBytes, Set.of(NESTMATE, STRONG), lambdaProxyClassFileDumper)
353+
return caller.makeHiddenClassDefiner(lambdaClassName, classBytes, lambdaProxyClassFileDumper, NESTMATE_CLASS | STRONG_LOADER_LINK)
352354
.defineClass(!disableEagerInitialization, classdata);
353355

354356
} catch (Throwable t) {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import java.util.Arrays;
4848
import java.util.HashMap;
4949
import java.util.List;
50-
import java.util.Set;
5150
import java.util.function.Consumer;
5251
import java.util.stream.Stream;
5352
import jdk.internal.constant.MethodTypeDescImpl;
@@ -224,7 +223,7 @@ FieldRefEntry classData(ClassFileBuilder<?, ?> cfb, Object arg, ClassDesc desc)
224223
* Extract the MemberName of a newly-defined method.
225224
*/
226225
private MemberName loadMethod(byte[] classFile) {
227-
Class<?> invokerClass = LOOKUP.makeHiddenClassDefiner(className, classFile, Set.of(), dumper())
226+
Class<?> invokerClass = LOOKUP.makeHiddenClassDefiner(className, classFile, dumper())
228227
.defineClass(true, classDataValues());
229228
return resolveInvokerMember(invokerClass, invokerName, invokerType);
230229
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import static java.lang.invoke.LambdaForm.*;
6565
import static java.lang.invoke.MethodHandleNatives.Constants.MN_CALLER_SENSITIVE;
6666
import static java.lang.invoke.MethodHandleNatives.Constants.MN_HIDDEN_MEMBER;
67+
import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS;
6768
import static java.lang.invoke.MethodHandleStatics.*;
6869
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
6970
import static java.lang.invoke.MethodHandles.Lookup.ClassOption.NESTMATE;
@@ -1111,7 +1112,7 @@ private static Class<?> makeInjectedInvoker(Class<?> targetClass) {
11111112
}
11121113
name = name.replace('.', '/');
11131114
Class<?> invokerClass = new Lookup(targetClass)
1114-
.makeHiddenClassDefiner(name, INJECTED_INVOKER_TEMPLATE, Set.of(NESTMATE), dumper())
1115+
.makeHiddenClassDefiner(name, INJECTED_INVOKER_TEMPLATE, dumper(), NESTMATE_CLASS)
11151116
.defineClass(true, targetClass);
11161117
assert checkInjectedInvoker(targetClass, invokerClass);
11171118
return invokerClass;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ private static Class<?> newProxyClass(Class<?> intfc) {
285285
byte[] template = createTemplate(loader, binaryNameToDesc(className),
286286
referenceClassDesc(intfc), uniqueName, methods);
287287
// define the dynamic module to the class loader of the interface
288-
var definer = new Lookup(intfc).makeHiddenClassDefiner(className, template, Set.of(), DUMPER);
288+
var definer = new Lookup(intfc).makeHiddenClassDefiner(className, template, DUMPER);
289289

290290
@SuppressWarnings("removal")
291291
var sm = System.getSecurityManager();

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

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,9 +1906,12 @@ public enum ClassOption {
19061906
this.flag = flag;
19071907
}
19081908

1909-
static int optionsToFlag(Set<ClassOption> options) {
1909+
static int optionsToFlag(ClassOption[] options) {
19101910
int flags = 0;
19111911
for (ClassOption cp : options) {
1912+
if ((flags & cp.flag) != 0) {
1913+
throw new IllegalArgumentException("Duplicate ClassOption " + cp);
1914+
}
19121915
flags |= cp.flag;
19131916
}
19141917
return flags;
@@ -2126,14 +2129,13 @@ public Lookup defineHiddenClass(byte[] bytes, boolean initialize, ClassOption...
21262129
throws IllegalAccessException
21272130
{
21282131
Objects.requireNonNull(bytes);
2129-
Objects.requireNonNull(options);
2130-
2132+
int flags = ClassOption.optionsToFlag(options);
21312133
ensureDefineClassPermission();
21322134
if (!hasFullPrivilegeAccess()) {
21332135
throw new IllegalAccessException(this + " does not have full privilege access");
21342136
}
21352137

2136-
return makeHiddenClassDefiner(bytes.clone(), Set.of(options), false).defineClassAsLookup(initialize);
2138+
return makeHiddenClassDefiner(bytes.clone(), false, flags).defineClassAsLookup(initialize);
21372139
}
21382140

21392141
/**
@@ -2213,14 +2215,15 @@ public Lookup defineHiddenClassWithClassData(byte[] bytes, Object classData, boo
22132215
{
22142216
Objects.requireNonNull(bytes);
22152217
Objects.requireNonNull(classData);
2216-
Objects.requireNonNull(options);
2218+
2219+
int flags = ClassOption.optionsToFlag(options);
22172220

22182221
ensureDefineClassPermission();
22192222
if (!hasFullPrivilegeAccess()) {
22202223
throw new IllegalAccessException(this + " does not have full privilege access");
22212224
}
22222225

2223-
return makeHiddenClassDefiner(bytes.clone(), Set.of(options), false)
2226+
return makeHiddenClassDefiner(bytes.clone(), false, flags)
22242227
.defineClassAsLookup(initialize, classData);
22252228
}
22262229

@@ -2366,7 +2369,7 @@ ClassDefiner makeClassDefiner(String name, byte[] bytes, ClassFileDumper dumper)
23662369
*/
23672370
ClassDefiner makeHiddenClassDefiner(byte[] bytes, ClassFileDumper dumper) {
23682371
ClassFile cf = ClassFile.newInstance(bytes, lookupClass().getPackageName());
2369-
return makeHiddenClassDefiner(cf, Set.of(), false, dumper);
2372+
return makeHiddenClassDefiner(cf, false, dumper, 0);
23702373
}
23712374

23722375
/**
@@ -2378,18 +2381,33 @@ ClassDefiner makeHiddenClassDefiner(byte[] bytes, ClassFileDumper dumper) {
23782381
* before calling this factory method.
23792382
*
23802383
* @param bytes class bytes
2381-
* @param options class options
2384+
* @param flags class option flag mask
23822385
* @param accessVmAnnotations true to give the hidden class access to VM annotations
23832386
* @return ClassDefiner that defines a hidden class of the given bytes and options
23842387
*
23852388
* @throws IllegalArgumentException if {@code bytes} is not a class or interface or
23862389
* {@code bytes} denotes a class in a different package than the lookup class
23872390
*/
23882391
private ClassDefiner makeHiddenClassDefiner(byte[] bytes,
2389-
Set<ClassOption> options,
2390-
boolean accessVmAnnotations) {
2392+
boolean accessVmAnnotations,
2393+
int flags) {
23912394
ClassFile cf = ClassFile.newInstance(bytes, lookupClass().getPackageName());
2392-
return makeHiddenClassDefiner(cf, options, accessVmAnnotations, defaultDumper());
2395+
return makeHiddenClassDefiner(cf, accessVmAnnotations, defaultDumper(), flags);
2396+
}
2397+
2398+
/**
2399+
* Returns a ClassDefiner that creates a {@code Class} object of a hidden class
2400+
* from the given bytes and the given options. No package name check on the given bytes.
2401+
*
2402+
* @param name internal name that specifies the prefix of the hidden class
2403+
* @param bytes class bytes
2404+
* @param dumper dumper to write the given bytes to the dumper's output directory
2405+
* @return ClassDefiner that defines a hidden class of the given bytes and options.
2406+
*/
2407+
ClassDefiner makeHiddenClassDefiner(String name, byte[] bytes, ClassFileDumper dumper) {
2408+
Objects.requireNonNull(dumper);
2409+
// skip name and access flags validation
2410+
return makeHiddenClassDefiner(ClassFile.newInstanceNoCheck(name, bytes), false, dumper, 0);
23932411
}
23942412

23952413
/**
@@ -2398,30 +2416,30 @@ private ClassDefiner makeHiddenClassDefiner(byte[] bytes,
23982416
*
23992417
* @param name internal name that specifies the prefix of the hidden class
24002418
* @param bytes class bytes
2401-
* @param options class options
2419+
* @param flags class options flag mask
24022420
* @param dumper dumper to write the given bytes to the dumper's output directory
24032421
* @return ClassDefiner that defines a hidden class of the given bytes and options.
24042422
*/
2405-
ClassDefiner makeHiddenClassDefiner(String name, byte[] bytes, Set<ClassOption> options, ClassFileDumper dumper) {
2423+
ClassDefiner makeHiddenClassDefiner(String name, byte[] bytes, ClassFileDumper dumper, int flags) {
24062424
Objects.requireNonNull(dumper);
24072425
// skip name and access flags validation
2408-
return makeHiddenClassDefiner(ClassFile.newInstanceNoCheck(name, bytes), options, false, dumper);
2426+
return makeHiddenClassDefiner(ClassFile.newInstanceNoCheck(name, bytes), false, dumper, flags);
24092427
}
24102428

24112429
/**
24122430
* Returns a ClassDefiner that creates a {@code Class} object of a hidden class
24132431
* from the given class file and options.
24142432
*
24152433
* @param cf ClassFile
2416-
* @param options class options
2434+
* @param flags class option flag mask
24172435
* @param accessVmAnnotations true to give the hidden class access to VM annotations
24182436
* @param dumper dumper to write the given bytes to the dumper's output directory
24192437
*/
24202438
private ClassDefiner makeHiddenClassDefiner(ClassFile cf,
2421-
Set<ClassOption> options,
24222439
boolean accessVmAnnotations,
2423-
ClassFileDumper dumper) {
2424-
int flags = HIDDEN_CLASS | ClassOption.optionsToFlag(options);
2440+
ClassFileDumper dumper,
2441+
int flags) {
2442+
flags |= HIDDEN_CLASS;
24252443
if (accessVmAnnotations | VM.isSystemDomainLoader(lookupClass.getClassLoader())) {
24262444
// jdk.internal.vm.annotations are permitted for classes
24272445
// defined to boot loader and platform loader

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import java.lang.ref.SoftReference;
5252
import java.util.Map;
5353
import java.util.Objects;
54-
import java.util.Set;
5554
import java.util.concurrent.ConcurrentHashMap;
5655
import java.util.function.Consumer;
5756
import java.util.function.Supplier;
@@ -1353,7 +1352,7 @@ public void accept(MethodBuilder mb) {
13531352
}
13541353
}});
13551354
try {
1356-
var hiddenClass = lookup.makeHiddenClassDefiner(CLASS_NAME, classBytes, Set.of(), DUMPER)
1355+
var hiddenClass = lookup.makeHiddenClassDefiner(CLASS_NAME, classBytes, DUMPER)
13571356
.defineClass(true, null);
13581357

13591358
if (staticConcat) {

0 commit comments

Comments
 (0)