RFR: 8338532: Speed up the ClassFile API MethodTypeDesc#ofDescriptor
Shaojin Wen
duke at openjdk.org
Mon Aug 19 06:32:23 UTC 2024
On Sat, 17 Aug 2024 00:56:22 GMT, Claes Redestad <redestad at openjdk.org> wrote:
> Under the assumption that low arity methods greatly outnumber high arity ones, some cost here would be acceptable. But let's try to avoid it while keeping things simple.
>
> An option would be to split the code into a fast-path that has an unrolled loop dealing with N args, then a slow path that does more or less the old logic with an ArrayList which we fall back to as soon as we hit either an argument that is too long or we go past N.
For the case where the number of parameters is greater than 8, we can also have another option, such as adding more lengths variables to cover more cases, such as:
private static ClassDesc[] paramTypes(String descriptor, int start, int end) {
/*
* If the length of the first 8 parameters is <= 256, save them in lengths to avoid secondary scanning,
* use 0 to indicate that the current parameter length is greater than 256 and needs to be reparsed
*/
long lengths = 0,
lengths2 = 0,
lengths3 = 0;
int paramCount = 0;
for (int cur = start; cur < end; ) {
int len = ConstantUtils.skipOverFieldSignature(descriptor, cur, end, false);
if (len == 0) {
throw badMethodDescriptor(descriptor);
}
int part = (len > 0xFF ? 0 : len);
if (paramCount < 8) {
lengths = (lengths << 8) | part;
} else if (paramCount < 16) {
lengths2 = (lengths2 << 8) | part;
} else if (paramCount < 24) {
lengths3 = (lengths3 << 8) | part;
}
paramCount++;
cur += len;
}
var paramTypes = new ClassDesc[paramCount];
int paramIndex = 0,
cur = start,
lengthsParamCount = Math.min(paramCount, 8 ) - 1,
lengths2ParamCount = Math.min(paramCount, 16) - 9,
lengths3ParamCount = Math.min(paramCount, 24) - 17;
while (cur < end) {
int len = 0
if (paramIndex < 8) {
int shift = (lengthsParamCount - paramIndex) << 3;
len = (int) ((lengths & (0xFFL << shift)) >> shift) & 0xFF;
} else if (paramIndex < 16) {
int shift = (lengths2ParamCount - paramIndex) << 3;
len = (int) ((lengths2 & (0xFFL << shift)) >> shift) & 0xFF;
} else if (paramIndex < 24) {
int shift = (lengths3ParamCount - paramIndex) << 3;
len = (int) ((lengths3 & (0xFFL << shift)) >> shift) & 0xFF;
}
if (len == 0) {
len = ConstantUtils.skipOverFieldSignature(descriptor, cur, end, false);
}
paramTypes[paramIndex++] = ConstantUtils.resolveClassDesc(descriptor, cur, len);
cur += len;
}
return paramTypes;
}
But I agree with you that it's important to keep it simple.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2294592302
More information about the core-libs-dev
mailing list