8198888: Reduce string allocation churn in InvokerBytecodeGenerator
Reviewed-by: psandoz, plevart
--- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Mar 01 15:31:04 2018 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Mar 01 13:08:06 2018 +0100
@@ -93,6 +93,10 @@
private ClassWriter cw;
private MethodVisitor mv;
+ /** Single element internal class name lookup cache. */
+ private Class<?> lastClass;
+ private String lastInternalName;
+
private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
private static final Class<?> HOST_CLASS = LambdaForm.class;
@@ -602,13 +606,18 @@
mv.visitInsn(opcode);
}
- private static String getInternalName(Class<?> c) {
+ private String getInternalName(Class<?> c) {
if (c == Object.class) return OBJ;
else if (c == Object[].class) return OBJARY;
else if (c == Class.class) return CLS;
else if (c == MethodHandle.class) return MH;
assert(VerifyAccess.isTypeVisible(c, Object.class)) : c.getName();
- return c.getName().replace('.', '/');
+
+ if (c == lastClass) {
+ return lastInternalName;
+ }
+ lastClass = c;
+ return lastInternalName = c.getName().replace('.', '/');
}
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
--- a/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Thu Mar 01 15:31:04 2018 -0800
+++ b/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Thu Mar 01 13:08:06 2018 +0100
@@ -107,6 +107,11 @@
}
public static String unparse(Class<?> type) {
+ if (type == Object.class) {
+ return "Ljava/lang/Object;";
+ } else if (type == int.class) {
+ return "I";
+ }
StringBuilder sb = new StringBuilder();
unparseSig(type, sb);
return sb.toString();
@@ -148,6 +153,8 @@
char c = Wrapper.forBasicType(t).basicTypeChar();
if (c != 'L') {
sb.append(c);
+ } else if (t == Object.class) {
+ sb.append("Ljava/lang/Object;");
} else {
boolean lsemi = (!t.isArray());
if (lsemi) sb.append('L');