Skip to content

Commit 047c2d7

Browse files
wenshaocl4esliach
committed
8341141: Optimize DirectCodeBuilder
Co-authored-by: Claes Redestad <redestad@openjdk.org> Co-authored-by: Chen Liang <liach@openjdk.org> Reviewed-by: liach, redestad
1 parent d636e0d commit 047c2d7

19 files changed

+881
-413
lines changed

src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,12 @@ public TypeKind typeKind() {
801801

802802
@Override
803803
public void writeTo(DirectCodeBuilder writer) {
804-
writer.writeLocalVar(op, slot);
804+
var op = this.op;
805+
if (op.sizeIfFixed() == 1) {
806+
writer.writeBytecode(op);
807+
} else {
808+
writer.writeLocalVar(op, slot);
809+
}
805810
}
806811

807812
@Override
@@ -832,7 +837,12 @@ public TypeKind typeKind() {
832837

833838
@Override
834839
public void writeTo(DirectCodeBuilder writer) {
835-
writer.writeLocalVar(op, slot);
840+
var op = this.op;
841+
if (op.sizeIfFixed() == 1) {
842+
writer.writeBytecode(op);
843+
} else {
844+
writer.writeLocalVar(op, slot);
845+
}
836846
}
837847

838848
@Override

src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java

+6-14
Original file line numberDiff line numberDiff line change
@@ -461,14 +461,13 @@ public boolean equalsString(String s) {
461461

462462
@Override
463463
void writeTo(BufWriterImpl pool) {
464-
pool.writeU1(TAG_UTF8);
465464
if (rawBytes != null) {
466-
pool.writeU2(rawLen);
465+
pool.writeU1U2(TAG_UTF8, rawLen);
467466
pool.writeBytes(rawBytes, offset, rawLen);
468467
}
469468
else {
470469
// state == STRING and no raw bytes
471-
pool.writeUTF(stringValue);
470+
pool.writeUtfEntry(stringValue);
472471
}
473472
}
474473

@@ -502,8 +501,7 @@ public T ref1() {
502501
}
503502

504503
void writeTo(BufWriterImpl pool) {
505-
pool.writeU1(tag());
506-
pool.writeU2(ref1.index());
504+
pool.writeU1U2(tag(), ref1.index());
507505
}
508506

509507
@Override
@@ -532,9 +530,7 @@ public U ref2() {
532530
}
533531

534532
void writeTo(BufWriterImpl pool) {
535-
pool.writeU1(tag());
536-
pool.writeU2(ref1.index());
537-
pool.writeU2(ref2.index());
533+
pool.writeU1U2U2(tag(), ref1.index(), ref2.index());
538534
}
539535

540536
@Override
@@ -864,9 +860,7 @@ public NameAndTypeEntryImpl nameAndType() {
864860
}
865861

866862
void writeTo(BufWriterImpl pool) {
867-
pool.writeU1(tag());
868-
pool.writeU2(bsmIndex);
869-
pool.writeU2(nameAndType.index());
863+
pool.writeU1U2U2(tag(), bsmIndex, nameAndType.index());
870864
}
871865

872866
@Override
@@ -984,9 +978,7 @@ public DirectMethodHandleDesc asSymbol() {
984978

985979
@Override
986980
void writeTo(BufWriterImpl pool) {
987-
pool.writeU1(TAG_METHOD_HANDLE);
988-
pool.writeU1(refKind);
989-
pool.writeU2(reference.index());
981+
pool.writeU1U1U2(TAG_METHOD_HANDLE, refKind, reference.index());
990982
}
991983

992984
@Override

src/java.base/share/classes/jdk/internal/classfile/impl/AnnotationReader.java

+3-7
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,7 @@ public static void writeTypeAnnotation(BufWriterImpl buf, TypeAnnotation ta) {
315315
case TypeAnnotation.TypeParameterTarget tpt -> buf.writeU1(tpt.typeParameterIndex());
316316
case TypeAnnotation.SupertypeTarget st -> buf.writeU2(st.supertypeIndex());
317317
case TypeAnnotation.TypeParameterBoundTarget tpbt -> {
318-
buf.writeU1(tpbt.typeParameterIndex());
319-
buf.writeU1(tpbt.boundIndex());
318+
buf.writeU1U1(tpbt.typeParameterIndex(), tpbt.boundIndex());
320319
}
321320
case TypeAnnotation.EmptyTarget _ -> {
322321
// nothing to write
@@ -327,9 +326,7 @@ public static void writeTypeAnnotation(BufWriterImpl buf, TypeAnnotation ta) {
327326
buf.writeU2(lvt.table().size());
328327
for (var e : lvt.table()) {
329328
int startPc = labelToBci(lr, e.startLabel(), ta);
330-
buf.writeU2(startPc);
331-
buf.writeU2(labelToBci(lr, e.endLabel(), ta) - startPc);
332-
buf.writeU2(e.index());
329+
buf.writeU2U2U2(startPc, labelToBci(lr, e.endLabel(), ta) - startPc, e.index());
333330
}
334331
}
335332
case TypeAnnotation.CatchTarget ct -> buf.writeU2(ct.exceptionTableIndex());
@@ -343,8 +340,7 @@ public static void writeTypeAnnotation(BufWriterImpl buf, TypeAnnotation ta) {
343340
// target_path
344341
buf.writeU1(ta.targetPath().size());
345342
for (TypeAnnotation.TypePathComponent component : ta.targetPath()) {
346-
buf.writeU1(component.typePathKind().tag());
347-
buf.writeU1(component.typeArgumentIndex());
343+
buf.writeU1U1(component.typePathKind().tag(), component.typeArgumentIndex());
348344
}
349345

350346
// annotation data

src/java.base/share/classes/jdk/internal/classfile/impl/AttributeHolder.java

+35-16
Original file line numberDiff line numberDiff line change
@@ -24,51 +24,70 @@
2424
*/
2525
package jdk.internal.classfile.impl;
2626

27-
import java.util.ArrayList;
28-
import java.util.List;
27+
import java.util.Arrays;
2928

3029
import java.lang.classfile.Attribute;
3130
import java.lang.classfile.AttributeMapper;
3231

3332
public class AttributeHolder {
34-
private final List<Attribute<?>> attributes = new ArrayList<>();
33+
private static final Attribute<?>[] EMPTY_ATTRIBUTE_ARRAY = {};
34+
private int attributesCount = 0;
35+
private Attribute<?>[] attributes = EMPTY_ATTRIBUTE_ARRAY;
3536

3637
public <A extends Attribute<A>> void withAttribute(Attribute<?> a) {
3738
if (a == null)
3839
return;
3940

4041
@SuppressWarnings("unchecked")
4142
AttributeMapper<A> am = (AttributeMapper<A>) a.attributeMapper();
42-
if (!am.allowMultiple() && isPresent(am)) {
43-
remove(am);
43+
int attributesCount = this.attributesCount;
44+
var attributes = this.attributes;
45+
if (!am.allowMultiple()) {
46+
// remove if
47+
for (int i = attributesCount - 1; i >= 0; i--) {
48+
if (attributes[i].attributeMapper() == am) {
49+
attributesCount--;
50+
System.arraycopy(attributes, i + 1, attributes, i, attributesCount - i);
51+
}
52+
}
4453
}
45-
attributes.add(a);
54+
55+
// add attribute
56+
if (attributesCount >= attributes.length) {
57+
int newCapacity = attributesCount + 4;
58+
this.attributes = attributes = Arrays.copyOf(attributes, newCapacity);
59+
}
60+
attributes[attributesCount] = a;
61+
this.attributesCount = attributesCount + 1;
4662
}
4763

4864
public int size() {
49-
return attributes.size();
65+
return attributesCount;
5066
}
5167

5268
public void writeTo(BufWriterImpl buf) {
53-
Util.writeAttributes(buf, attributes);
69+
int attributesCount = this.attributesCount;
70+
buf.writeU2(attributesCount);
71+
for (int i = 0; i < attributesCount; i++) {
72+
Util.writeAttribute(buf, attributes[i]);
73+
}
5474
}
5575

5676
@SuppressWarnings("unchecked")
5777
<A extends Attribute<A>> A get(AttributeMapper<A> am) {
58-
for (Attribute<?> a : attributes)
78+
for (int i = 0; i < attributesCount; i++) {
79+
Attribute<?> a = attributes[i];
5980
if (a.attributeMapper() == am)
60-
return (A)a;
81+
return (A) a;
82+
}
6183
return null;
6284
}
6385

6486
boolean isPresent(AttributeMapper<?> am) {
65-
for (Attribute<?> a : attributes)
66-
if (a.attributeMapper() == am)
87+
for (int i = 0; i < attributesCount; i++) {
88+
if (attributes[i].attributeMapper() == am)
6789
return true;
90+
}
6891
return false;
6992
}
70-
71-
private void remove(AttributeMapper<?> am) {
72-
attributes.removeIf(a -> a.attributeMapper() == am);
73-
}
7493
}

src/java.base/share/classes/jdk/internal/classfile/impl/BufWriterImpl.java

+96-9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import jdk.internal.access.SharedSecrets;
3939
import jdk.internal.vm.annotation.ForceInline;
4040

41+
import static java.lang.classfile.constantpool.PoolEntry.TAG_UTF8;
4142
import static jdk.internal.util.ModifiedUtf.putChar;
4243
import static jdk.internal.util.ModifiedUtf.utfLen;
4344

@@ -114,6 +115,83 @@ public void writeU2(int x) {
114115
this.offset = offset + 2;
115116
}
116117

118+
@ForceInline
119+
public void writeU1U1(int x1, int x2) {
120+
reserveSpace(2);
121+
byte[] elems = this.elems;
122+
int offset = this.offset;
123+
elems[offset ] = (byte) x1;
124+
elems[offset + 1] = (byte) x2;
125+
this.offset = offset + 2;
126+
}
127+
128+
public void writeU1U2(int u1, int u2) {
129+
reserveSpace(3);
130+
byte[] elems = this.elems;
131+
int offset = this.offset;
132+
elems[offset ] = (byte) u1;
133+
elems[offset + 1] = (byte) (u2 >> 8);
134+
elems[offset + 2] = (byte) u2;
135+
this.offset = offset + 3;
136+
}
137+
138+
public void writeU1U1U1(int x1, int x2, int x3) {
139+
reserveSpace(3);
140+
byte[] elems = this.elems;
141+
int offset = this.offset;
142+
elems[offset ] = (byte) x1;
143+
elems[offset + 1] = (byte) x2;
144+
elems[offset + 2] = (byte) x3;
145+
this.offset = offset + 3;
146+
}
147+
148+
public void writeU1U1U2(int x1, int x2, int x3) {
149+
reserveSpace(4);
150+
byte[] elems = this.elems;
151+
int offset = this.offset;
152+
elems[offset ] = (byte) x1;
153+
elems[offset + 1] = (byte) x2;
154+
elems[offset + 2] = (byte) (x3 >> 8);
155+
elems[offset + 3] = (byte) x3;
156+
this.offset = offset + 4;
157+
}
158+
159+
public void writeU1U2U2(int x1, int x2, int x3) {
160+
reserveSpace(5);
161+
byte[] elems = this.elems;
162+
int offset = this.offset;
163+
elems[offset ] = (byte) x1;
164+
elems[offset + 1] = (byte) (x2 >> 8);
165+
elems[offset + 2] = (byte) x2;
166+
elems[offset + 3] = (byte) (x3 >> 8);
167+
elems[offset + 4] = (byte) x3;
168+
this.offset = offset + 5;
169+
}
170+
171+
public void writeU2U2(int x1, int x2) {
172+
reserveSpace(4);
173+
byte[] elems = this.elems;
174+
int offset = this.offset;
175+
elems[offset ] = (byte) (x1 >> 8);
176+
elems[offset + 1] = (byte) x1;
177+
elems[offset + 2] = (byte) (x2 >> 8);
178+
elems[offset + 3] = (byte) x2;
179+
this.offset = offset + 4;
180+
}
181+
182+
public void writeU2U2U2(int x1, int x2, int x3) {
183+
reserveSpace(6);
184+
byte[] elems = this.elems;
185+
int offset = this.offset;
186+
elems[offset ] = (byte) (x1 >> 8);
187+
elems[offset + 1] = (byte) x1;
188+
elems[offset + 2] = (byte) (x2 >> 8);
189+
elems[offset + 3] = (byte) x2;
190+
elems[offset + 4] = (byte) (x3 >> 8);
191+
elems[offset + 5] = (byte) x3;
192+
this.offset = offset + 6;
193+
}
194+
117195
@Override
118196
public void writeInt(int x) {
119197
reserveSpace(4);
@@ -162,21 +240,22 @@ public void writeBytes(BufWriterImpl other) {
162240
}
163241

164242
@SuppressWarnings("deprecation")
165-
void writeUTF(String str) {
243+
void writeUtfEntry(String str) {
166244
int strlen = str.length();
167245
int countNonZeroAscii = JLA.countNonZeroAscii(str);
168246
int utflen = utfLen(str, countNonZeroAscii);
169247
if (utflen > 65535) {
170248
throw new IllegalArgumentException("string too long");
171249
}
172-
reserveSpace(utflen + 2);
250+
reserveSpace(utflen + 3);
173251

174252
int offset = this.offset;
175253
byte[] elems = this.elems;
176254

177-
elems[offset ] = (byte) (utflen >> 8);
178-
elems[offset + 1] = (byte) utflen;
179-
offset += 2;
255+
elems[offset ] = (byte) TAG_UTF8;
256+
elems[offset + 1] = (byte) (utflen >> 8);
257+
elems[offset + 2] = (byte) utflen;
258+
offset += 3;
180259

181260
str.getBytes(0, countNonZeroAscii, elems, offset);
182261
offset += countNonZeroAscii;
@@ -269,13 +348,21 @@ public void copyTo(byte[] array, int bufferOffset) {
269348
// writeIndex methods ensure that any CP info written
270349
// is relative to the correct constant pool
271350

272-
@ForceInline
273-
@Override
274-
public void writeIndex(PoolEntry entry) {
351+
public int cpIndex(PoolEntry entry) {
275352
int idx = AbstractPoolEntry.maybeClone(constantPool, entry).index();
276353
if (idx < 1 || idx > Character.MAX_VALUE)
277354
throw invalidIndex(idx, entry);
278-
writeU2(idx);
355+
return idx;
356+
}
357+
358+
@ForceInline
359+
@Override
360+
public void writeIndex(PoolEntry entry) {
361+
writeU2(cpIndex(entry));
362+
}
363+
364+
public void writeIndex(int bytecode, PoolEntry entry) {
365+
writeU1U2(bytecode, cpIndex(entry));
279366
}
280367

281368
static IllegalArgumentException invalidIndex(int idx, PoolEntry entry) {

0 commit comments

Comments
 (0)