8294062: Improve parsing performance of j.l.c.MethodTypeDesc
Reviewed-by: psandoz
This commit is contained in:
parent
c6be2cd347
commit
9f90eb0524
@ -137,6 +137,7 @@ class ConstantUtils {
|
||||
static List<String> parseMethodDescriptor(String descriptor) {
|
||||
int cur = 0, end = descriptor.length();
|
||||
ArrayList<String> ptypes = new ArrayList<>();
|
||||
ptypes.add(null); //placeholder for return type
|
||||
|
||||
if (cur >= end || descriptor.charAt(cur) != '(')
|
||||
throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
|
||||
@ -156,7 +157,7 @@ class ConstantUtils {
|
||||
int rLen = skipOverFieldSignature(descriptor, cur, end, true);
|
||||
if (rLen == 0 || cur + rLen != end)
|
||||
throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
|
||||
ptypes.add(0, descriptor.substring(cur, cur + rLen));
|
||||
ptypes.set(0, descriptor.substring(cur, cur + rLen));
|
||||
return ptypes;
|
||||
}
|
||||
|
||||
@ -203,16 +204,27 @@ class ConstantUtils {
|
||||
case JVM_SIGNATURE_DOUBLE:
|
||||
return index - start + 1;
|
||||
case JVM_SIGNATURE_CLASS:
|
||||
// Skip leading 'L' and ignore first appearance of ';'
|
||||
index++;
|
||||
int indexOfSemi = descriptor.indexOf(';', index);
|
||||
if (indexOfSemi != -1) {
|
||||
String unqualifiedName = descriptor.substring(index, indexOfSemi);
|
||||
boolean legal = verifyUnqualifiedClassName(unqualifiedName);
|
||||
if (!legal) {
|
||||
return 0;
|
||||
// state variable for detection of illegal states, such as:
|
||||
// empty unqualified name, '//', leading '/', or trailing '/'
|
||||
boolean legal = false;
|
||||
while (++index < end) {
|
||||
switch (descriptor.charAt(index)) {
|
||||
case ';' -> {
|
||||
// illegal state on parser exit indicates empty unqualified name or trailing '/'
|
||||
return legal ? index - start + 1 : 0;
|
||||
}
|
||||
case '.', '[' -> {
|
||||
// do not permit '.' or '['
|
||||
return 0;
|
||||
}
|
||||
case '/' -> {
|
||||
// illegal state when received '/' indicates '//' or leading '/'
|
||||
if (!legal) return 0;
|
||||
legal = false;
|
||||
}
|
||||
default ->
|
||||
legal = true;
|
||||
}
|
||||
return index - start + unqualifiedName.length() + 1;
|
||||
}
|
||||
return 0;
|
||||
case JVM_SIGNATURE_ARRAY:
|
||||
@ -231,25 +243,4 @@ class ConstantUtils {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static boolean verifyUnqualifiedClassName(String name) {
|
||||
for (int index = 0; index < name.length(); index++) {
|
||||
char ch = name.charAt(index);
|
||||
if (ch < 128) {
|
||||
if (ch == '.' || ch == ';' || ch == '[' ) {
|
||||
return false; // do not permit '.', ';', or '['
|
||||
}
|
||||
if (ch == '/') {
|
||||
// check for '//' or leading or trailing '/' which are not legal
|
||||
// unqualified name must not be empty
|
||||
if (index == 0 || index + 1 >= name.length() || name.charAt(index + 1) == '/') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
index ++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user