8340710: Optimize DirectClassBuilder::build

Reviewed-by: liach
This commit is contained in:
Shaojin Wen 2024-09-25 02:35:41 +00:00
parent 2d38af61e4
commit 2e0554a695
4 changed files with 46 additions and 19 deletions

View file

@ -36,6 +36,7 @@ import java.lang.classfile.constantpool.PoolEntry;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.vm.annotation.ForceInline;
public final class BufWriterImpl implements BufWriter {
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
@ -99,6 +100,7 @@ public final class BufWriterImpl implements BufWriter {
elems[offset++] = (byte) x;
}
@ForceInline
@Override
public void writeU2(int x) {
reserveSpace(2);
@ -283,14 +285,19 @@ public final class BufWriterImpl implements BufWriter {
// writeIndex methods ensure that any CP info written
// is relative to the correct constant pool
@ForceInline
@Override
public void writeIndex(PoolEntry entry) {
int idx = AbstractPoolEntry.maybeClone(constantPool, entry).index();
if (idx < 1 || idx > Character.MAX_VALUE)
throw new IllegalArgumentException(idx + " is not a valid index. Entry: " + entry);
throw invalidIndex(idx, entry);
writeU2(idx);
}
static IllegalArgumentException invalidIndex(int idx, PoolEntry entry) {
return new IllegalArgumentException(idx + " is not a valid index. Entry: " + entry);
}
@Override
public void writeIndexOrZero(PoolEntry entry) {
if (entry == null || entry.index() == 0)
@ -298,4 +305,14 @@ public final class BufWriterImpl implements BufWriter {
else
writeIndex(entry);
}
/**
* Join head and tail into an exact-size buffer
*/
static byte[] join(BufWriterImpl head, BufWriterImpl tail) {
byte[] result = new byte[head.size() + tail.size()];
head.copyTo(result, 0);
tail.copyTo(result, head.size());
return result;
}
}

View file

@ -175,14 +175,16 @@ public final class DirectClassBuilder
// BSM writers until everything else is written.
// Do this early because it might trigger CP activity
var constantPool = this.constantPool;
ClassEntry superclass = superclassEntry;
if (superclass != null)
superclass = AbstractPoolEntry.maybeClone(constantPool, superclass);
else if ((flags & ClassFile.ACC_MODULE) == 0 && !"java/lang/Object".equals(thisClassEntry.asInternalName()))
superclass = constantPool.classEntry(ConstantDescs.CD_Object);
List<ClassEntry> ies = new ArrayList<>(interfaceEntries.size());
for (ClassEntry ce : interfaceEntries)
ies.add(AbstractPoolEntry.maybeClone(constantPool, ce));
int interfaceEntriesSize = interfaceEntries.size();
List<ClassEntry> ies = new ArrayList<>(interfaceEntriesSize);
for (int i = 0; i < interfaceEntriesSize; i++)
ies.add(AbstractPoolEntry.maybeClone(constantPool, interfaceEntries.get(i)));
// We maintain two writers, and then we join them at the end
int size = sizeHint == 0 ? 256 : sizeHint;
@ -197,16 +199,15 @@ public final class DirectClassBuilder
attributes.writeTo(tail);
// Now we have to append the BSM, if there is one
boolean written = constantPool.writeBootstrapMethods(tail);
if (written) {
if (constantPool.writeBootstrapMethods(tail)) {
// Update attributes count
tail.patchU2(attributesOffset, attributes.size() + 1);
}
// Now we can make the head
head.writeInt(ClassFile.MAGIC_NUMBER);
head.writeU2(minorVersion);
head.writeU2(majorVersion);
head.writeLong((((long) ClassFile.MAGIC_NUMBER) << 32)
| ((minorVersion & 0xFFFFL) << 16)
| (majorVersion & 0xFFFFL));
constantPool.writeTo(head);
head.writeU2(flags);
head.writeIndex(thisClassEntry);
@ -214,9 +215,6 @@ public final class DirectClassBuilder
Util.writeListIndices(head, ies);
// Join head and tail into an exact-size buffer
byte[] result = new byte[head.size() + tail.size()];
head.copyTo(result, 0);
tail.copyTo(result, head.size());
return result;
return BufWriterImpl.join(head, tail);
}
}

View file

@ -190,6 +190,13 @@ public final class DirectCodeBuilder
int pos = buf.size();
int handlersSize = handlers.size();
buf.writeU2(handlersSize);
if (handlersSize > 0) {
writeExceptionHandlers(buf, pos);
}
}
private void writeExceptionHandlers(BufWriterImpl buf, int pos) {
int handlersSize = handlers.size();
for (AbstractPseudoInstruction.ExceptionCatchImpl h : handlers) {
int startPc = labelToBci(h.tryStart());
int endPc = labelToBci(h.tryEnd());

View file

@ -50,6 +50,7 @@ import java.lang.classfile.constantpool.NameAndTypeEntry;
import java.lang.constant.ModuleDesc;
import java.lang.reflect.AccessFlag;
import jdk.internal.access.SharedSecrets;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Stable;
import static java.lang.classfile.ClassFile.ACC_STATIC;
@ -249,17 +250,21 @@ public class Util {
}
}
@ForceInline
public static void writeAttributes(BufWriterImpl buf, List<? extends Attribute<?>> list) {
buf.writeU2(list.size());
for (var e : list) {
writeAttribute(buf, e);
int size = list.size();
buf.writeU2(size);
for (int i = 0; i < size; i++) {
writeAttribute(buf, list.get(i));
}
}
@ForceInline
static void writeList(BufWriterImpl buf, List<Writable> list) {
buf.writeU2(list.size());
for (var e : list) {
e.writeTo(buf);
int size = list.size();
buf.writeU2(size);
for (int i = 0; i < size; i++) {
list.get(i).writeTo(buf);
}
}