Skip to content

Commit

Permalink
8340710: Optimize DirectClassBuilder::build
Browse files Browse the repository at this point in the history
Reviewed-by: liach
  • Loading branch information
wenshao committed Sep 25, 2024
1 parent 2d38af6 commit 2e0554a
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

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();
Expand Down Expand Up @@ -99,6 +100,7 @@ public void writeU1(int x) {
elems[offset++] = (byte) x;
}

@ForceInline
@Override
public void writeU2(int x) {
reserveSpace(2);
Expand Down Expand Up @@ -283,19 +285,34 @@ public void copyTo(byte[] array, int bufferOffset) {
// 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)
writeU2(0);
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,16 @@ public byte[] build() {
// 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;
Expand All @@ -197,26 +199,22 @@ else if ((flags & ClassFile.ACC_MODULE) == 0 && !"java/lang/Object".equals(thisC
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);
head.writeIndexOrZero(superclass);
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ private void writeExceptionHandlers(BufWriterImpl buf) {
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());
Expand Down
17 changes: 11 additions & 6 deletions src/java.base/share/classes/jdk/internal/classfile/impl/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
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;
Expand Down Expand Up @@ -249,17 +250,21 @@ private static <T extends Attribute<T>> void writeAttribute(BufWriterImpl writer
}
}

@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);
}
}

Expand Down

1 comment on commit 2e0554a

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.