From 55312e1549c36be46b0f3b3b40763a33311c3e25 Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Wed, 4 Sep 2024 22:45:17 +0000 Subject: [PATCH] 8338937: Optimize the string concatenation of ClassDesc Reviewed-by: liach --- .../share/classes/java/lang/Class.java | 8 ++------ .../classes/java/lang/StringConcatHelper.java | 16 ++++++++++++++++ .../share/classes/java/lang/System.java | 4 ++++ .../classes/java/lang/constant/ClassDesc.java | 11 ++++++----- .../lang/invoke/InvokerBytecodeGenerator.java | 17 +++++++++++------ .../jdk/internal/access/JavaLangAccess.java | 5 +++++ .../jdk/internal/constant/ConstantUtils.java | 10 +++++++++- 7 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index e2ec0909f45..f7fa0dbe96b 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -4647,7 +4647,7 @@ public final class Class 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 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, ";"); } } diff --git a/src/java.base/share/classes/java/lang/StringConcatHelper.java b/src/java.base/share/classes/java/lang/StringConcatHelper.java index ae2b9693409..d0c558ed93a 100644 --- a/src/java.base/share/classes/java/lang/StringConcatHelper.java +++ b/src/java.base/share/classes/java/lang/StringConcatHelper.java @@ -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); + } } diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 503167bc2dd..3c25ad3720d 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -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(); } diff --git a/src/java.base/share/classes/java/lang/constant/ClassDesc.java b/src/java.base/share/classes/java/lang/constant/ClassDesc.java index 0c714850a8f..b93d9522352 100644 --- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java +++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java @@ -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