mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8285633: Take better advantage of generic MethodType cache
Reviewed-by: jvernee
This commit is contained in:
parent
5b42747ba1
commit
6c79671e50
8 changed files with 118 additions and 23 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -622,7 +622,7 @@ class LambdaForm {
|
|||
for (int i = 0; i < arity; ++i) {
|
||||
ptypes[i] = parameterType(i).btClass;
|
||||
}
|
||||
return MethodType.makeImpl(returnType().btClass, ptypes, true);
|
||||
return MethodType.methodType(returnType().btClass, ptypes, true);
|
||||
}
|
||||
|
||||
/** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -153,7 +153,7 @@ final class MemberName implements Member, Cloneable {
|
|||
} else if (type instanceof Object[] typeInfo) {
|
||||
Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
|
||||
Class<?> rtype = (Class<?>) typeInfo[0];
|
||||
MethodType res = MethodType.makeImpl(rtype, ptypes, true);
|
||||
MethodType res = MethodType.methodType(rtype, ptypes, true);
|
||||
type = res;
|
||||
}
|
||||
// Make sure type is a MethodType for racing threads.
|
||||
|
|
|
@ -323,7 +323,7 @@ abstract class MethodHandleImpl {
|
|||
for (int pos : positions) {
|
||||
ptypes[pos - 1] = newType;
|
||||
}
|
||||
midType = MethodType.makeImpl(midType.rtype(), ptypes, true);
|
||||
midType = MethodType.methodType(midType.rtype(), ptypes, true);
|
||||
}
|
||||
LambdaForm form2;
|
||||
if (positions.length > 1) {
|
||||
|
|
|
@ -393,7 +393,7 @@ class MethodHandleNatives {
|
|||
* The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
|
||||
*/
|
||||
static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
|
||||
return MethodType.makeImpl(rtype, ptypes, true);
|
||||
return MethodType.methodType(rtype, ptypes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -561,7 +561,7 @@ class MethodHandleNatives {
|
|||
}
|
||||
// Access descriptor at end
|
||||
guardParams[guardParams.length - 1] = VarHandle.AccessDescriptor.class;
|
||||
MethodType guardType = MethodType.makeImpl(guardReturnType, guardParams, true);
|
||||
MethodType guardType = MethodType.methodType(guardReturnType, guardParams, true);
|
||||
|
||||
MemberName linker = new MemberName(
|
||||
VarHandleGuards.class, getVarHandleGuardMethodName(guardType),
|
||||
|
|
|
@ -5601,7 +5601,7 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
|
|||
for (int pos : positions) {
|
||||
ptypes[pos - 1] = newParamType;
|
||||
}
|
||||
MethodType newType = MethodType.makeImpl(targetType.rtype(), ptypes, true);
|
||||
MethodType newType = MethodType.methodType(targetType.rtype(), ptypes, true);
|
||||
|
||||
LambdaForm lform = result.editor().filterRepeatedArgumentForm(BasicType.basicType(newParamType), positions);
|
||||
return result.copyWithExtendL(newType, lform, filter);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -240,7 +240,7 @@ class MethodType
|
|||
* @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
|
||||
*/
|
||||
public static MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
|
||||
return makeImpl(rtype, ptypes, false);
|
||||
return methodType(rtype, ptypes, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,7 +254,7 @@ class MethodType
|
|||
*/
|
||||
public static MethodType methodType(Class<?> rtype, List<Class<?>> ptypes) {
|
||||
boolean notrust = false; // random List impl. could return evil ptypes array
|
||||
return makeImpl(rtype, listToArray(ptypes), notrust);
|
||||
return methodType(rtype, listToArray(ptypes), notrust);
|
||||
}
|
||||
|
||||
private static Class<?>[] listToArray(List<Class<?>> ptypes) {
|
||||
|
@ -275,9 +275,23 @@ class MethodType
|
|||
* @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
|
||||
*/
|
||||
public static MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
|
||||
Class<?>[] ptypes1 = new Class<?>[1+ptypes.length];
|
||||
int len = ptypes.length;
|
||||
if (rtype == Object.class && ptype0 == Object.class) {
|
||||
if (len == 0) {
|
||||
return genericMethodType(1, false);
|
||||
}
|
||||
if (isAllObject(ptypes, len - 1)) {
|
||||
Class<?> lastParam = ptypes[len - 1];
|
||||
if (lastParam == Object.class) {
|
||||
return genericMethodType(len + 1, false);
|
||||
} else if (lastParam == Object[].class) {
|
||||
return genericMethodType(len, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Class<?>[] ptypes1 = new Class<?>[1 + len];
|
||||
ptypes1[0] = ptype0;
|
||||
System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
|
||||
System.arraycopy(ptypes, 0, ptypes1, 1, len);
|
||||
return makeImpl(rtype, ptypes1, true);
|
||||
}
|
||||
|
||||
|
@ -290,6 +304,9 @@ class MethodType
|
|||
* @throws NullPointerException if {@code rtype} is null
|
||||
*/
|
||||
public static MethodType methodType(Class<?> rtype) {
|
||||
if (rtype == Object.class) {
|
||||
return genericMethodType(0, false);
|
||||
}
|
||||
return makeImpl(rtype, NO_PTYPES, true);
|
||||
}
|
||||
|
||||
|
@ -304,6 +321,13 @@ class MethodType
|
|||
* @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
|
||||
*/
|
||||
public static MethodType methodType(Class<?> rtype, Class<?> ptype0) {
|
||||
if (rtype == Object.class) {
|
||||
if (ptype0 == Object.class) {
|
||||
return genericMethodType(1, false);
|
||||
} else if (ptype0 == Object[].class) {
|
||||
return genericMethodType(0, true);
|
||||
}
|
||||
}
|
||||
return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
|
||||
}
|
||||
|
||||
|
@ -318,7 +342,35 @@ class MethodType
|
|||
* @throws NullPointerException if {@code rtype} or {@code ptypes} is null
|
||||
*/
|
||||
public static MethodType methodType(Class<?> rtype, MethodType ptypes) {
|
||||
return makeImpl(rtype, ptypes.ptypes, true);
|
||||
return methodType(rtype, ptypes.ptypes, true);
|
||||
}
|
||||
|
||||
private static boolean isAllObject(Class<?>[] ptypes, int to) {
|
||||
for (int i = 0; i < to; i++) {
|
||||
if (ptypes[i] != Object.class) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*trusted*/
|
||||
static MethodType methodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
|
||||
if (rtype == Object.class) {
|
||||
int last = ptypes.length - 1;
|
||||
if (last < 0) {
|
||||
return genericMethodType(0, false);
|
||||
}
|
||||
if (isAllObject(ptypes, last)) {
|
||||
Class<?> lastParam = ptypes[last];
|
||||
if (lastParam == Object.class) {
|
||||
return genericMethodType(last + 1, false);
|
||||
} else if (lastParam == Object[].class) {
|
||||
return genericMethodType(last, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return makeImpl(rtype, ptypes, trusted);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -332,8 +384,7 @@ class MethodType
|
|||
* @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
|
||||
* @return the unique method type of the desired structure
|
||||
*/
|
||||
/*trusted*/
|
||||
static MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
|
||||
private static MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
|
||||
if (ptypes.length == 0) {
|
||||
ptypes = NO_PTYPES; trusted = true;
|
||||
}
|
||||
|
@ -629,7 +680,7 @@ class MethodType
|
|||
System.arraycopy(ptypes, end, nptypes, start, tail);
|
||||
}
|
||||
}
|
||||
return makeImpl(rtype, nptypes, true);
|
||||
return methodType(rtype, nptypes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -641,7 +692,7 @@ class MethodType
|
|||
*/
|
||||
public MethodType changeReturnType(Class<?> nrtype) {
|
||||
if (returnType() == nrtype) return this;
|
||||
return makeImpl(nrtype, ptypes, true);
|
||||
return methodType(nrtype, ptypes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1164,7 +1215,7 @@ class MethodType
|
|||
List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
|
||||
Class<?> rtype = types.remove(types.size() - 1);
|
||||
Class<?>[] ptypes = listToArray(types);
|
||||
return makeImpl(rtype, ptypes, true);
|
||||
return methodType(rtype, ptypes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -194,7 +194,7 @@ final class MethodTypeForm {
|
|||
this.lambdaForms = new SoftReference[LF_LIMIT];
|
||||
this.methodHandles = new SoftReference[MH_LIMIT];
|
||||
} else {
|
||||
this.basicType = MethodType.makeImpl(basicReturnType, basicPtypes, true);
|
||||
this.basicType = MethodType.methodType(basicReturnType, basicPtypes, true);
|
||||
// fill in rest of data from the basic type:
|
||||
MethodTypeForm that = this.basicType.form();
|
||||
assert(this != that);
|
||||
|
@ -250,7 +250,7 @@ final class MethodTypeForm {
|
|||
// Find the erased version of the method type:
|
||||
if (rtypeCanonical == null) rtypeCanonical = rtype;
|
||||
if (ptypesCanonical == null) ptypesCanonical = ptypes;
|
||||
return MethodType.makeImpl(rtypeCanonical, ptypesCanonical, true);
|
||||
return MethodType.methodType(rtypeCanonical, ptypesCanonical, true);
|
||||
}
|
||||
|
||||
/** Canonicalize the given return or param type.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue