mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8340710: Optimize DirectClassBuilder::build
Reviewed-by: liach
This commit is contained in:
parent
2d38af61e4
commit
2e0554a695
4 changed files with 46 additions and 19 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue