8338936: StringConcatFactory optimize the construction of MethodType and MethodTypeDesc
Reviewed-by: redestad, liach
This commit is contained in:
parent
0c744ea7e7
commit
5ecbecfbca
@ -29,6 +29,8 @@ package java.lang.invoke;
|
|||||||
import jdk.internal.access.JavaLangAccess;
|
import jdk.internal.access.JavaLangAccess;
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.constant.ConstantUtils;
|
import jdk.internal.constant.ConstantUtils;
|
||||||
|
import jdk.internal.constant.MethodTypeDescImpl;
|
||||||
|
import jdk.internal.constant.ReferenceClassDescImpl;
|
||||||
import jdk.internal.misc.VM;
|
import jdk.internal.misc.VM;
|
||||||
import jdk.internal.util.ClassFileDumper;
|
import jdk.internal.util.ClassFileDumper;
|
||||||
import jdk.internal.util.ReferenceKey;
|
import jdk.internal.util.ReferenceKey;
|
||||||
@ -1085,32 +1087,32 @@ public final class StringConcatFactory {
|
|||||||
static final MethodHandles.Lookup STR_LOOKUP = new MethodHandles.Lookup(String.class);
|
static final MethodHandles.Lookup STR_LOOKUP = new MethodHandles.Lookup(String.class);
|
||||||
|
|
||||||
static final ClassDesc CD_CONCAT = ConstantUtils.binaryNameToDesc(CLASS_NAME);
|
static final ClassDesc CD_CONCAT = ConstantUtils.binaryNameToDesc(CLASS_NAME);
|
||||||
static final ClassDesc CD_StringConcatHelper = ClassDesc.ofDescriptor("Ljava/lang/StringConcatHelper;");
|
static final ClassDesc CD_StringConcatHelper = ReferenceClassDescImpl.ofValidated("Ljava/lang/StringConcatHelper;");
|
||||||
static final ClassDesc CD_StringConcatBase = ClassDesc.ofDescriptor("Ljava/lang/StringConcatHelper$StringConcatBase;");
|
static final ClassDesc CD_StringConcatBase = ReferenceClassDescImpl.ofValidated("Ljava/lang/StringConcatHelper$StringConcatBase;");
|
||||||
static final ClassDesc CD_Array_byte = ClassDesc.ofDescriptor("[B");
|
static final ClassDesc CD_Array_byte = ReferenceClassDescImpl.ofValidated("[B");
|
||||||
static final ClassDesc CD_Array_String = ClassDesc.ofDescriptor("[Ljava/lang/String;");
|
static final ClassDesc CD_Array_String = ReferenceClassDescImpl.ofValidated("[Ljava/lang/String;");
|
||||||
|
|
||||||
static final MethodTypeDesc MTD_byte_char = MethodTypeDesc.of(CD_byte, CD_char);
|
static final MethodTypeDesc MTD_byte_char = MethodTypeDescImpl.ofValidated(CD_byte, CD_char);
|
||||||
static final MethodTypeDesc MTD_byte = MethodTypeDesc.of(CD_byte);
|
static final MethodTypeDesc MTD_byte = MethodTypeDescImpl.ofValidated(CD_byte);
|
||||||
static final MethodTypeDesc MTD_int = MethodTypeDesc.of(CD_int);
|
static final MethodTypeDesc MTD_int = MethodTypeDescImpl.ofValidated(CD_int);
|
||||||
static final MethodTypeDesc MTD_int_int_boolean = MethodTypeDesc.of(CD_int, CD_int, CD_boolean);
|
static final MethodTypeDesc MTD_int_int_boolean = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_boolean);
|
||||||
static final MethodTypeDesc MTD_int_int_char = MethodTypeDesc.of(CD_int, CD_int, CD_char);
|
static final MethodTypeDesc MTD_int_int_char = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_char);
|
||||||
static final MethodTypeDesc MTD_int_int_int = MethodTypeDesc.of(CD_int, CD_int, CD_int);
|
static final MethodTypeDesc MTD_int_int_int = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_int);
|
||||||
static final MethodTypeDesc MTD_int_int_long = MethodTypeDesc.of(CD_int, CD_int, CD_long);
|
static final MethodTypeDesc MTD_int_int_long = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_long);
|
||||||
static final MethodTypeDesc MTD_int_int_String = MethodTypeDesc.of(CD_int, CD_int, CD_String);
|
static final MethodTypeDesc MTD_int_int_String = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_String);
|
||||||
static final MethodTypeDesc MTD_String_float = MethodTypeDesc.of(CD_String, CD_float);
|
static final MethodTypeDesc MTD_String_float = MethodTypeDescImpl.ofValidated(CD_String, CD_float);
|
||||||
static final MethodTypeDesc MTD_String_double = MethodTypeDesc.of(CD_String, CD_double);
|
static final MethodTypeDesc MTD_String_double = MethodTypeDescImpl.ofValidated(CD_String, CD_double);
|
||||||
static final MethodTypeDesc MTD_String_Object = MethodTypeDesc.of(CD_String, CD_Object);
|
static final MethodTypeDesc MTD_String_Object = MethodTypeDescImpl.ofValidated(CD_String, CD_Object);
|
||||||
|
|
||||||
static final MethodTypeDesc MTD_INIT = MethodTypeDesc.of(CD_void, CD_Array_String);
|
static final MethodTypeDesc MTD_INIT = MethodTypeDescImpl.ofValidated(CD_void, CD_Array_String);
|
||||||
static final MethodTypeDesc MTD_NEW_ARRAY_SUFFIX = MethodTypeDesc.of(CD_Array_byte, CD_String, CD_int, CD_byte);
|
static final MethodTypeDesc MTD_NEW_ARRAY_SUFFIX = MethodTypeDescImpl.ofValidated(CD_Array_byte, CD_String, CD_int, CD_byte);
|
||||||
static final MethodTypeDesc MTD_STRING_INIT = MethodTypeDesc.of(CD_void, CD_Array_byte, CD_byte);
|
static final MethodTypeDesc MTD_STRING_INIT = MethodTypeDescImpl.ofValidated(CD_void, CD_Array_byte, CD_byte);
|
||||||
|
|
||||||
static final MethodTypeDesc PREPEND_int = MethodTypeDesc.of(CD_int, CD_int, CD_byte, CD_Array_byte, CD_int, CD_String);
|
static final MethodTypeDesc PREPEND_int = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_byte, CD_Array_byte, CD_int, CD_String);
|
||||||
static final MethodTypeDesc PREPEND_long = MethodTypeDesc.of(CD_int, CD_int, CD_byte, CD_Array_byte, CD_long, CD_String);
|
static final MethodTypeDesc PREPEND_long = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_byte, CD_Array_byte, CD_long, CD_String);
|
||||||
static final MethodTypeDesc PREPEND_boolean = MethodTypeDesc.of(CD_int, CD_int, CD_byte, CD_Array_byte, CD_boolean, CD_String);
|
static final MethodTypeDesc PREPEND_boolean = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_byte, CD_Array_byte, CD_boolean, CD_String);
|
||||||
static final MethodTypeDesc PREPEND_char = MethodTypeDesc.of(CD_int, CD_int, CD_byte, CD_Array_byte, CD_char, CD_String);
|
static final MethodTypeDesc PREPEND_char = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_byte, CD_Array_byte, CD_char, CD_String);
|
||||||
static final MethodTypeDesc PREPEND_String = MethodTypeDesc.of(CD_int, CD_int, CD_byte, CD_Array_byte, CD_String, CD_String);
|
static final MethodTypeDesc PREPEND_String = MethodTypeDescImpl.ofValidated(CD_int, CD_int, CD_byte, CD_Array_byte, CD_String, CD_String);
|
||||||
|
|
||||||
static final RuntimeVisibleAnnotationsAttribute FORCE_INLINE = RuntimeVisibleAnnotationsAttribute.of(Annotation.of(ClassDesc.ofDescriptor("Ljdk/internal/vm/annotation/ForceInline;")));
|
static final RuntimeVisibleAnnotationsAttribute FORCE_INLINE = RuntimeVisibleAnnotationsAttribute.of(Annotation.of(ClassDesc.ofDescriptor("Ljdk/internal/vm/annotation/ForceInline;")));
|
||||||
|
|
||||||
@ -1166,7 +1168,7 @@ public final class StringConcatFactory {
|
|||||||
}
|
}
|
||||||
paramTypes[i] = cl;
|
paramTypes[i] = cl;
|
||||||
}
|
}
|
||||||
return changed ? MethodType.methodType(args.returnType(), paramTypes) : args;
|
return changed ? MethodType.methodType(args.returnType(), paramTypes, true) : args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1191,24 +1193,36 @@ public final class StringConcatFactory {
|
|||||||
var cl = concatArgs.parameterType(i);
|
var cl = concatArgs.parameterType(i);
|
||||||
paramTypes[i + 4] = needStringOf(cl) ? CD_String : ConstantUtils.classDesc(cl);
|
paramTypes[i + 4] = needStringOf(cl) ? CD_String : ConstantUtils.classDesc(cl);
|
||||||
}
|
}
|
||||||
return MethodTypeDesc.of(CD_int, paramTypes);
|
return MethodTypeDescImpl.ofValidated(CD_int, paramTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the MethodType of the coder method,
|
* Construct the MethodType of the coder method. The first parameter is the initialized coder.
|
||||||
* The first parameter is the initialized coder, Only parameter types that can be UTF16 are added.
|
* Only parameter types which can be UTF16 are added. Returns null if no such parameter exists.
|
||||||
*/
|
*/
|
||||||
private static MethodTypeDesc coderArgs(MethodType concatArgs) {
|
private static MethodTypeDesc coderArgsIfMaybeUTF16(MethodType concatArgs) {
|
||||||
int parameterCount = concatArgs.parameterCount();
|
int parameterCount = concatArgs.parameterCount();
|
||||||
List<ClassDesc> paramTypes = new ArrayList<>();
|
|
||||||
paramTypes.add(CD_int); // init coder
|
int maybeUTF16Count = 0;
|
||||||
for (int i = 0; i < parameterCount; i++) {
|
for (int i = 0; i < parameterCount; i++) {
|
||||||
|
if (maybeUTF16(concatArgs.parameterType(i))) {
|
||||||
|
maybeUTF16Count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybeUTF16Count == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var paramTypes = new ClassDesc[maybeUTF16Count + 1];
|
||||||
|
paramTypes[0] = CD_int; // init coder
|
||||||
|
for (int i = 0, paramIndex = 1; i < parameterCount; i++) {
|
||||||
var cl = concatArgs.parameterType(i);
|
var cl = concatArgs.parameterType(i);
|
||||||
if (maybeUTF16(cl)) {
|
if (maybeUTF16(cl)) {
|
||||||
paramTypes.add(cl == char.class ? CD_char : CD_String);
|
paramTypes[paramIndex++] = cl == char.class ? CD_char : CD_String;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MethodTypeDesc.of(CD_int, paramTypes);
|
return MethodTypeDescImpl.ofValidated(CD_int, paramTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1223,7 +1237,7 @@ public final class StringConcatFactory {
|
|||||||
var cl = concatArgs.parameterType(i);
|
var cl = concatArgs.parameterType(i);
|
||||||
paramTypes[i + 1] = needStringOf(cl) ? CD_String : ConstantUtils.classDesc(cl);
|
paramTypes[i + 1] = needStringOf(cl) ? CD_String : ConstantUtils.classDesc(cl);
|
||||||
}
|
}
|
||||||
return MethodTypeDesc.of(CD_int, paramTypes);
|
return MethodTypeDescImpl.ofValidated(CD_int, paramTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodHandle generate(Lookup lookup, MethodType args, String[] constants) throws Exception {
|
private static MethodHandle generate(Lookup lookup, MethodType args, String[] constants) throws Exception {
|
||||||
@ -1250,7 +1264,7 @@ public final class StringConcatFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
MethodTypeDesc lengthArgs = lengthArgs(concatArgs),
|
MethodTypeDesc lengthArgs = lengthArgs(concatArgs),
|
||||||
coderArgs = parameterMaybeUTF16(concatArgs) ? coderArgs(concatArgs) : null,
|
coderArgs = coderArgsIfMaybeUTF16(concatArgs),
|
||||||
prependArgs = prependArgs(concatArgs);
|
prependArgs = prependArgs(concatArgs);
|
||||||
|
|
||||||
byte[] classBytes = ClassFile.of().build(CD_CONCAT,
|
byte[] classBytes = ClassFile.of().build(CD_CONCAT,
|
||||||
@ -1478,7 +1492,7 @@ public final class StringConcatFactory {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* String[] constants = this.constants;
|
* String[] constants = this.constants;
|
||||||
* suffix = constants[paranCount];
|
* suffix = constants[paramCount];
|
||||||
* length -= suffix.length();
|
* length -= suffix.length();
|
||||||
*/
|
*/
|
||||||
cb.aload(thisSlot)
|
cb.aload(thisSlot)
|
||||||
@ -1692,14 +1706,5 @@ public final class StringConcatFactory {
|
|||||||
static boolean maybeUTF16(Class<?> cl) {
|
static boolean maybeUTF16(Class<?> cl) {
|
||||||
return cl == char.class || !cl.isPrimitive();
|
return cl == char.class || !cl.isPrimitive();
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean parameterMaybeUTF16(MethodType args) {
|
|
||||||
for (int i = 0; i < args.parameterCount(); i++) {
|
|
||||||
if (maybeUTF16(args.parameterType(i))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user