8338937: Optimize the string concatenation of ClassDesc
Reviewed-by: liach
This commit is contained in:
parent
d4dfa0127f
commit
55312e1549
@ -4647,7 +4647,7 @@ public final class Class<T> implements java.io.Serializable,
|
||||
return Wrapper.forPrimitiveType(this).basicTypeString();
|
||||
|
||||
if (isArray()) {
|
||||
return "[" + componentType.descriptorString();
|
||||
return "[".concat(componentType.descriptorString());
|
||||
} else if (isHidden()) {
|
||||
String name = getName();
|
||||
int index = name.indexOf('/');
|
||||
@ -4660,11 +4660,7 @@ public final class Class<T> implements java.io.Serializable,
|
||||
.toString();
|
||||
} else {
|
||||
String name = getName().replace('.', '/');
|
||||
return new StringBuilder(name.length() + 2)
|
||||
.append('L')
|
||||
.append(name)
|
||||
.append(';')
|
||||
.toString();
|
||||
return StringConcatHelper.concat("L", name, ";");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -783,4 +783,20 @@ final class StringConcatHelper {
|
||||
}
|
||||
throw new OutOfMemoryError("Overflow: String length out of range");
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
private static String concat0(String prefix, String str, String suffix) {
|
||||
byte coder = (byte) (prefix.coder() | str.coder() | suffix.coder());
|
||||
int len = prefix.length() + str.length();
|
||||
byte[] buf = newArrayWithSuffix(suffix, len, coder);
|
||||
prepend(len, coder, buf, str, prefix);
|
||||
return new String(buf, coder);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static String concat(String prefix, Object value, String suffix) {
|
||||
if (prefix == null) prefix = "null";
|
||||
if (suffix == null) suffix = "null";
|
||||
return concat0(prefix, stringOf(value), suffix);
|
||||
}
|
||||
}
|
||||
|
@ -2650,6 +2650,10 @@ public final class System {
|
||||
return String.join(prefix, suffix, delimiter, elements, size);
|
||||
}
|
||||
|
||||
public String concat(String prefix, Object value, String suffix) {
|
||||
return StringConcatHelper.concat(prefix, value, suffix);
|
||||
}
|
||||
|
||||
public Object classData(Class<?> c) {
|
||||
return c.getClassData();
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import static java.util.stream.Collectors.joining;
|
||||
import static jdk.internal.constant.ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS;
|
||||
import static jdk.internal.constant.ConstantUtils.arrayDepth;
|
||||
import static jdk.internal.constant.ConstantUtils.binaryToInternal;
|
||||
import static jdk.internal.constant.ConstantUtils.concat;
|
||||
import static jdk.internal.constant.ConstantUtils.forPrimitiveType;
|
||||
import static jdk.internal.constant.ConstantUtils.internalToBinary;
|
||||
import static jdk.internal.constant.ConstantUtils.validateBinaryClassName;
|
||||
@ -83,7 +84,7 @@ public sealed interface ClassDesc
|
||||
*/
|
||||
static ClassDesc of(String name) {
|
||||
validateBinaryClassName(name);
|
||||
return ClassDesc.ofDescriptor("L" + binaryToInternal(name) + ";");
|
||||
return ClassDesc.ofDescriptor(concat("L", binaryToInternal(name), ";"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +110,7 @@ public sealed interface ClassDesc
|
||||
*/
|
||||
static ClassDesc ofInternalName(String name) {
|
||||
validateInternalClassName(name);
|
||||
return ClassDesc.ofDescriptor("L" + name + ";");
|
||||
return ClassDesc.ofDescriptor(concat("L", name, ";"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,8 +133,8 @@ public sealed interface ClassDesc
|
||||
return of(className);
|
||||
}
|
||||
validateMemberName(className, false);
|
||||
return ofDescriptor("L" + binaryToInternal(packageName) +
|
||||
"/" + className + ";");
|
||||
return ofDescriptor('L' + binaryToInternal(packageName) +
|
||||
'/' + className + ';');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,7 +362,7 @@ public sealed interface ClassDesc
|
||||
ClassDesc c = this;
|
||||
for (int i=0; i<depth; i++)
|
||||
c = c.componentType();
|
||||
return c.displayName() + "[]".repeat(depth);
|
||||
return c.displayName().concat("[]".repeat(depth));
|
||||
}
|
||||
else
|
||||
throw new IllegalStateException(descriptorString());
|
||||
|
@ -125,7 +125,7 @@ class InvokerBytecodeGenerator {
|
||||
name = makeDumpableClassName(name);
|
||||
}
|
||||
this.name = name;
|
||||
this.className = CLASS_PREFIX + name;
|
||||
this.className = CLASS_PREFIX.concat(name);
|
||||
this.classDesc = ClassDesc.ofInternalName(className);
|
||||
this.lambdaForm = lambdaForm;
|
||||
this.invokerName = invokerName;
|
||||
@ -180,11 +180,16 @@ class InvokerBytecodeGenerator {
|
||||
if (ctr == null) ctr = 0;
|
||||
DUMP_CLASS_FILES_COUNTERS.put(className, ctr+1);
|
||||
}
|
||||
String sfx = ctr.toString();
|
||||
while (sfx.length() < 3)
|
||||
sfx = "0" + sfx;
|
||||
className += sfx;
|
||||
return className;
|
||||
|
||||
var buf = new StringBuilder(className.length() + 3).append(className);
|
||||
int ctrVal = ctr;
|
||||
if (ctrVal < 10) {
|
||||
buf.repeat('0', 2);
|
||||
} else if (ctrVal < 100) {
|
||||
buf.append('0');
|
||||
}
|
||||
buf.append(ctrVal);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
static class ClassData {
|
||||
|
@ -457,6 +457,11 @@ public interface JavaLangAccess {
|
||||
*/
|
||||
String join(String prefix, String suffix, String delimiter, String[] elements, int size);
|
||||
|
||||
/**
|
||||
* Concatenation of prefix and suffix characters to a String for early bootstrap
|
||||
*/
|
||||
String concat(String prefix, Object value, String suffix);
|
||||
|
||||
/*
|
||||
* Get the class data associated with the given class.
|
||||
* @param c the class
|
||||
|
@ -35,12 +35,16 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.access.JavaLangAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import static jdk.internal.constant.PrimitiveClassDescImpl.*;
|
||||
|
||||
/**
|
||||
* Helper methods for the implementation of {@code java.lang.constant}.
|
||||
*/
|
||||
public final class ConstantUtils {
|
||||
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
/** an empty constant descriptor */
|
||||
public static final ConstantDesc[] EMPTY_CONSTANTDESC = new ConstantDesc[0];
|
||||
public static final ClassDesc[] EMPTY_CLASSDESC = new ClassDesc[0];
|
||||
@ -66,7 +70,7 @@ public final class ConstantUtils {
|
||||
* @param binaryName a binary name
|
||||
*/
|
||||
public static ClassDesc binaryNameToDesc(String binaryName) {
|
||||
return ReferenceClassDescImpl.ofValidated("L" + binaryToInternal(binaryName) + ";");
|
||||
return ReferenceClassDescImpl.ofValidated(concat("L", binaryToInternal(binaryName), ";"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -378,4 +382,8 @@ public final class ConstantUtils {
|
||||
"Cannot create an array type descriptor with more than %d dimensions",
|
||||
ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS));
|
||||
}
|
||||
|
||||
public static String concat(String prefix, Object value, String suffix) {
|
||||
return JLA.concat(prefix, value, suffix);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user