mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-07 21:48:41 +00:00
8149459: StringConcatFactory should be synced up with LambdaMetafactory
Reviewed-by: psandoz, vlivanov, forax
This commit is contained in:
parent
32687876fa
commit
7bee07b465
@ -182,22 +182,30 @@ public final class StringConcatFactory {
|
||||
|
||||
private static final ConcurrentMap<Key, MethodHandle> CACHE;
|
||||
|
||||
/**
|
||||
* Dump generated classes to disk, for debugging purposes.
|
||||
*/
|
||||
private static final ProxyClassesDumper DUMPER;
|
||||
|
||||
static {
|
||||
// Poke the privileged block once, taking everything we need:
|
||||
final Object[] values = new Object[3];
|
||||
final Object[] values = new Object[4];
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
values[0] = System.getProperty("java.lang.invoke.stringConcat");
|
||||
values[1] = Boolean.getBoolean("java.lang.invoke.stringConcat.cache");
|
||||
values[2] = Boolean.getBoolean("java.lang.invoke.stringConcat.debug");
|
||||
values[3] = System.getProperty("java.lang.invoke.stringConcat.dumpClasses");
|
||||
return null;
|
||||
});
|
||||
|
||||
final String strategy = (String) values[0];
|
||||
CACHE_ENABLE = (Boolean) values[1];
|
||||
DEBUG = (Boolean) values[2];
|
||||
final String dumpPath = (String) values[3];
|
||||
|
||||
STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy);
|
||||
CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
|
||||
DUMPER = (dumpPath == null) ? null : ProxyClassesDumper.getInstance(dumpPath);
|
||||
}
|
||||
|
||||
private static final class Key {
|
||||
@ -552,6 +560,12 @@ public final class StringConcatFactory {
|
||||
Objects.requireNonNull(o, "Cannot accept null constants");
|
||||
}
|
||||
|
||||
if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) {
|
||||
throw new StringConcatException(String.format(
|
||||
"Invalid caller: %s",
|
||||
lookup.lookupClass().getName()));
|
||||
}
|
||||
|
||||
int cCount = 0;
|
||||
int oCount = 0;
|
||||
if (generateRecipe) {
|
||||
@ -1035,6 +1049,10 @@ public final class StringConcatFactory {
|
||||
final byte[] classBytes = cw.toByteArray();
|
||||
final Class<?> innerClass = UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
|
||||
|
||||
if (DUMPER != null) {
|
||||
DUMPER.dumpClass(innerClass.getName(), classBytes);
|
||||
}
|
||||
|
||||
try {
|
||||
UNSAFE.ensureClassInitialized(innerClass);
|
||||
return lookup.findStatic(innerClass, NAME_FACTORY, args);
|
||||
|
||||
@ -66,7 +66,7 @@ public class StringConcatFactoryInvariants {
|
||||
private static final char TAG_CONST = '\u0002';
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
String methodName = "foo";
|
||||
MethodType mt = MethodType.methodType(String.class, String.class, int.class);
|
||||
String recipe = "" + TAG_ARG + TAG_ARG + TAG_CONST;
|
||||
@ -236,6 +236,14 @@ public class StringConcatFactoryInvariants {
|
||||
// Advanced factory: test empty arguments
|
||||
ok("Ok to pass empty arguments",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtEmpty, recipeEmpty));
|
||||
|
||||
// Simple factory: public Lookup is rejected
|
||||
fail("Passing public Lookup",
|
||||
() -> StringConcatFactory.makeConcat(MethodHandles.publicLookup(), methodName, mtEmpty));
|
||||
|
||||
// Advanced factory: public Lookup is rejected
|
||||
fail("Passing public Lookup",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(MethodHandles.publicLookup(), methodName, mtEmpty, recipeEmpty));
|
||||
}
|
||||
|
||||
public static void ok(String msg, Callable runnable) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user