8024635: Caching MethodType's descriptor string improves lambda linkage performance
Better interpreted and compiled performance of operations in MethodType important to LambdaMetafactory. Reviewed-by: jrose, twisti, mchung
This commit is contained in:
parent
f7db4eb56b
commit
bb01d169de
@ -32,6 +32,7 @@ import java.lang.ref.ReferenceQueue;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import sun.invoke.util.BytecodeDescriptor;
|
||||
@ -98,13 +99,25 @@ class MethodType implements java.io.Serializable {
|
||||
private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
|
||||
private @Stable MethodType wrapAlt; // alternative wrapped/unwrapped version
|
||||
private @Stable Invokers invokers; // cache of handy higher-order adapters
|
||||
private @Stable String methodDescriptor; // cache for toMethodDescriptorString
|
||||
|
||||
/**
|
||||
* Check the given parameters for validity and store them into the final fields.
|
||||
*/
|
||||
private MethodType(Class<?> rtype, Class<?>[] ptypes) {
|
||||
private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
|
||||
checkRtype(rtype);
|
||||
checkPtypes(ptypes);
|
||||
this.rtype = rtype;
|
||||
// defensively copy the array passed in by the user
|
||||
this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a temporary unchecked instance of MethodType for use only as a key to the intern table.
|
||||
* Does not check the given parameters for validity, and must be discarded after it is used as a searching key.
|
||||
* The parameters are reversed for this constructor, so that is is not accidentally used.
|
||||
*/
|
||||
private MethodType(Class<?>[] ptypes, Class<?> rtype) {
|
||||
this.rtype = rtype;
|
||||
this.ptypes = ptypes;
|
||||
}
|
||||
@ -146,20 +159,21 @@ class MethodType implements java.io.Serializable {
|
||||
/*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1; // deduct one more for invoker
|
||||
|
||||
private static void checkRtype(Class<?> rtype) {
|
||||
rtype.equals(rtype); // null check
|
||||
Objects.requireNonNull(rtype);
|
||||
}
|
||||
private static int checkPtype(Class<?> ptype) {
|
||||
ptype.getClass(); //NPE
|
||||
private static void checkPtype(Class<?> ptype) {
|
||||
Objects.requireNonNull(ptype);
|
||||
if (ptype == void.class)
|
||||
throw newIllegalArgumentException("parameter type cannot be void");
|
||||
if (ptype == double.class || ptype == long.class) return 1;
|
||||
return 0;
|
||||
}
|
||||
/** Return number of extra slots (count of long/double args). */
|
||||
private static int checkPtypes(Class<?>[] ptypes) {
|
||||
int slots = 0;
|
||||
for (Class<?> ptype : ptypes) {
|
||||
slots += checkPtype(ptype);
|
||||
checkPtype(ptype);
|
||||
if (ptype == double.class || ptype == long.class) {
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
checkSlotCount(ptypes.length + slots);
|
||||
return slots;
|
||||
@ -284,20 +298,16 @@ class MethodType implements java.io.Serializable {
|
||||
*/
|
||||
/*trusted*/ static
|
||||
MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
|
||||
MethodType mt = internTable.get(new MethodType(ptypes, rtype));
|
||||
if (mt != null)
|
||||
return mt;
|
||||
if (ptypes.length == 0) {
|
||||
ptypes = NO_PTYPES; trusted = true;
|
||||
}
|
||||
MethodType mt1 = new MethodType(rtype, ptypes);
|
||||
MethodType mt0 = internTable.get(mt1);
|
||||
if (mt0 != null)
|
||||
return mt0;
|
||||
if (!trusted)
|
||||
// defensively copy the array passed in by the user
|
||||
mt1 = new MethodType(rtype, ptypes.clone());
|
||||
mt = new MethodType(rtype, ptypes, trusted);
|
||||
// promote the object to the Real Thing, and reprobe
|
||||
MethodTypeForm form = MethodTypeForm.findForm(mt1);
|
||||
mt1.form = form;
|
||||
return internTable.add(mt1);
|
||||
mt.form = MethodTypeForm.findForm(mt);
|
||||
return internTable.add(mt);
|
||||
}
|
||||
private static final MethodType[] objectOnlyTypes = new MethodType[20];
|
||||
|
||||
@ -919,7 +929,12 @@ class MethodType implements java.io.Serializable {
|
||||
* @return the bytecode type descriptor representation
|
||||
*/
|
||||
public String toMethodDescriptorString() {
|
||||
return BytecodeDescriptor.unparse(this);
|
||||
String desc = methodDescriptor;
|
||||
if (desc == null) {
|
||||
desc = BytecodeDescriptor.unparse(this);
|
||||
methodDescriptor = desc;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
/*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user