Skip to content

Commit 2882ee7

Browse files
committed
Shift constructor logic to shared superclass
1 parent c3b433f commit 2882ee7

File tree

2 files changed

+32
-67
lines changed

2 files changed

+32
-67
lines changed

src/java.base/share/classes/java/lang/StringConcatHelper.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import jdk.internal.misc.Unsafe;
2929
import jdk.internal.util.DecimalDigits;
3030
import jdk.internal.vm.annotation.ForceInline;
31+
import jdk.internal.vm.annotation.Stable;
3132

3233
import java.lang.invoke.MethodHandle;
3334
import java.lang.invoke.MethodHandles;
@@ -40,6 +41,24 @@
4041
*/
4142
final class StringConcatHelper {
4243

44+
45+
static class StringConcatBase {
46+
@Stable String[] constants;
47+
@Stable int length;
48+
@Stable byte coder;
49+
StringConcatBase(String[] constants) {
50+
int length = 0;
51+
byte coder = String.LATIN1;
52+
this.constants = constants;
53+
for (String c : constants) {
54+
length += c.length();
55+
coder |= c.coder();
56+
}
57+
this.length = length;
58+
this.coder = coder;
59+
}
60+
}
61+
4362
private StringConcatHelper() {
4463
// no instantiation
4564
}

src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java

Lines changed: 13 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,10 @@
3636
import jdk.internal.vm.annotation.Stable;
3737
import sun.invoke.util.Wrapper;
3838

39-
import java.lang.classfile.Annotation;
4039
import java.lang.classfile.ClassBuilder;
4140
import java.lang.classfile.ClassFile;
4241
import java.lang.classfile.CodeBuilder;
43-
import java.lang.classfile.FieldBuilder;
44-
import java.lang.classfile.Label;
4542
import java.lang.classfile.TypeKind;
46-
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
4743
import java.lang.constant.ClassDesc;
4844
import java.lang.constant.MethodTypeDesc;
4945
import java.lang.invoke.MethodHandles.Lookup;
@@ -1076,6 +1072,7 @@ private static final class SimpleStringBuilderStrategy {
10761072
static final ClassFileDumper DUMPER =
10771073
ClassFileDumper.getInstance("java.lang.invoke.StringConcatFactory.dump", "stringConcatClasses");
10781074
static final ClassDesc CD_StringConcatHelper = ClassDesc.ofDescriptor("Ljava/lang/StringConcatHelper;");
1075+
static final ClassDesc CD_StringConcatBase = ClassDesc.ofDescriptor("Ljava/lang/StringConcatHelper$StringConcatBase;");
10791076
static final ClassDesc CD_Array_byte = ClassDesc.ofDescriptor("[B");
10801077
static final ClassDesc CD_Array_String = ClassDesc.ofDescriptor("[Ljava/lang/String;");
10811078
static final MethodTypeDesc ARRAY_STRING_TO_VOID = MethodTypeDesc.of(CD_void, CD_Array_String);
@@ -1086,9 +1083,7 @@ private static final class SimpleStringBuilderStrategy {
10861083
static final MethodTypeDesc NEW_ARRAY_SUFFIX = MethodTypeDesc.of(CD_Array_byte, CD_String, CD_long);
10871084
static final MethodTypeDesc NEW_STRING = MethodTypeDesc.of(CD_String, CD_Array_byte, CD_long);
10881085

1089-
static final MethodTypeDesc MTD_Object = MethodTypeDesc.of(CD_Object);
10901086
static final MethodTypeDesc MTD_int = MethodTypeDesc.of(CD_int);
1091-
static final MethodTypeDesc MTD_byte = MethodTypeDesc.of(CD_byte);
10921087

10931088
static final MethodTypeDesc MIX_int = MethodTypeDesc.of(CD_long, CD_long, CD_int);
10941089
static final MethodTypeDesc MIX_long = MethodTypeDesc.of(CD_long, CD_long, CD_long);
@@ -1102,13 +1097,15 @@ private static final class SimpleStringBuilderStrategy {
11021097
static final MethodTypeDesc PREPEND_char = MethodTypeDesc.of(CD_long, CD_long, CD_Array_byte, CD_char, CD_String);
11031098
static final MethodTypeDesc PREPEND_String = MethodTypeDesc.of(CD_long, CD_long, CD_Array_byte, CD_String, CD_String);
11041099

1105-
public static final RuntimeVisibleAnnotationsAttribute STABLE_ANNOTATION = RuntimeVisibleAnnotationsAttribute.of(
1106-
Annotation.of(ClassDesc.ofDescriptor("Ljdk/internal/vm/annotation/Stable;")));
1107-
1108-
private static final Consumer<FieldBuilder> FINAL_STABLE_FIELD = new Consumer<FieldBuilder>() {
1109-
public void accept(FieldBuilder fb) {
1110-
fb.withFlags(ClassFile.ACC_FINAL)
1111-
.with(STABLE_ANNOTATION);
1100+
private static final Consumer<CodeBuilder> CONSTRUCTOR_BUILDER = new Consumer<CodeBuilder>() {
1101+
@Override
1102+
public void accept(CodeBuilder cb) {
1103+
int thisSlot = cb.receiverSlot();
1104+
int constantsSlot = cb.parameterSlot(0);
1105+
cb.aload(thisSlot);
1106+
cb.aload(constantsSlot);
1107+
cb.invokespecial(CD_StringConcatBase, INIT_NAME, ARRAY_STRING_TO_VOID, false);
1108+
cb.return_();
11121109
}
11131110
};
11141111

@@ -1158,14 +1155,12 @@ private static MethodHandle generate(Lookup lookup, MethodType args, String[] co
11581155
new Consumer<ClassBuilder>() {
11591156
@Override
11601157
public void accept(ClassBuilder clb) {
1161-
clb.withFlags(ClassFile.ACC_FINAL | ClassFile.ACC_SUPER | ClassFile.ACC_SYNTHETIC)
1162-
.withField(LENGTH, CD_int, FINAL_STABLE_FIELD)
1163-
.withField(CODER, CD_byte, FINAL_STABLE_FIELD)
1164-
.withField(CONSTANTS, CD_Array_String, FINAL_STABLE_FIELD)
1158+
clb.withSuperclass(CD_StringConcatBase)
1159+
.withFlags(ClassFile.ACC_FINAL | ClassFile.ACC_SUPER | ClassFile.ACC_SYNTHETIC)
11651160
.withMethodBody("<init>",
11661161
ARRAY_STRING_TO_VOID,
11671162
ClassFile.ACC_PRIVATE,
1168-
generateConstructor(concatClass, constants.length)
1163+
CONSTRUCTOR_BUILDER
11691164
)
11701165
.withMethodBody(METHOD_NAME,
11711166
ConstantUtils.methodTypeDesc(concatArgs),
@@ -1186,55 +1181,6 @@ public void accept(ClassBuilder clb) {
11861181
}
11871182
}
11881183

1189-
private static Consumer<CodeBuilder> generateConstructor(ClassDesc concatClass, int numConstants) {
1190-
return new Consumer<CodeBuilder>() {
1191-
@Override
1192-
public void accept(CodeBuilder cb) {
1193-
cb.aload(0);
1194-
cb.invokespecial(CD_Object, INIT_NAME, MTD_void, false);
1195-
cb.aload(0);
1196-
cb.aload(1);
1197-
cb.putfield(concatClass, CONSTANTS, CD_Array_String);
1198-
cb.iconst_0();
1199-
cb.istore(2);
1200-
cb.iconst_0();
1201-
cb.istore(3);
1202-
cb.iconst_0();
1203-
cb.istore(4);
1204-
Label loopStart = cb.newLabel();
1205-
Label loopEnd = cb.newLabel();
1206-
{
1207-
cb.labelBinding(loopStart);
1208-
cb.iload(4);
1209-
cb.ldc(numConstants);
1210-
cb.if_icmpge(loopEnd);
1211-
cb.aload(1);
1212-
cb.iload(4);
1213-
cb.aaload();
1214-
cb.dup();
1215-
cb.invokevirtual(CD_String, LENGTH, MTD_int);
1216-
cb.iload(2);
1217-
cb.iadd();
1218-
cb.istore(2);
1219-
cb.invokevirtual(CD_String, CODER, MTD_byte);
1220-
cb.iload(3);
1221-
cb.ior();
1222-
cb.istore(3);
1223-
cb.iinc(4, 1);
1224-
cb.goto_(loopStart);
1225-
}
1226-
cb.labelBinding(loopEnd);
1227-
cb.aload(0);
1228-
cb.iload(2);
1229-
cb.putfield(concatClass, LENGTH, CD_int);
1230-
cb.aload(0);
1231-
cb.iload(3);
1232-
cb.putfield(concatClass, CODER, CD_byte);
1233-
cb.return_();
1234-
}
1235-
};
1236-
}
1237-
12381184
/**
12391185
* Generate InlineCopy-based code. <p>
12401186
*

0 commit comments

Comments
 (0)