mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8337225: Demote maxStack and maxLocals from CodeModel to CodeAttribute
Reviewed-by: asotona
This commit is contained in:
parent
bd36b6ae5d
commit
ab27090aa0
13 changed files with 166 additions and 88 deletions
|
@ -43,17 +43,7 @@ import jdk.internal.javac.PreviewFeature;
|
|||
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
|
||||
public sealed interface CodeModel
|
||||
extends CompoundElement<CodeElement>, AttributedElement, MethodElement
|
||||
permits CodeAttribute, BufferedCodeBuilder.Model, CodeImpl {
|
||||
|
||||
/**
|
||||
* {@return the maximum size of the local variable table}
|
||||
*/
|
||||
int maxLocals();
|
||||
|
||||
/**
|
||||
* {@return the maximum size of the operand stack}
|
||||
*/
|
||||
int maxStack();
|
||||
permits CodeAttribute, BufferedCodeBuilder.Model {
|
||||
|
||||
/**
|
||||
* {@return the enclosing method, if known}
|
||||
|
|
|
@ -47,6 +47,16 @@ import jdk.internal.javac.PreviewFeature;
|
|||
public sealed interface CodeAttribute extends Attribute<CodeAttribute>, CodeModel
|
||||
permits BoundAttribute.BoundCodeAttribute {
|
||||
|
||||
/**
|
||||
* {@return the maximum size of the local variable table}
|
||||
*/
|
||||
int maxLocals();
|
||||
|
||||
/**
|
||||
* {@return the maximum size of the operand stack}
|
||||
*/
|
||||
int maxStack();
|
||||
|
||||
/**
|
||||
* {@return The length of the code array in bytes}
|
||||
*/
|
||||
|
|
|
@ -35,7 +35,7 @@ import java.lang.classfile.CompoundElement;
|
|||
|
||||
public abstract sealed class AbstractUnboundModel<E extends ClassFileElement>
|
||||
extends AbstractElement
|
||||
implements CompoundElement<E>, AttributedElement, Util.Writable
|
||||
implements CompoundElement<E>, AttributedElement
|
||||
permits BufferedCodeBuilder.Model, BufferedFieldBuilder.Model, BufferedMethodBuilder.Model {
|
||||
private final List<E> elements;
|
||||
private List<Attribute<?>> attributes;
|
||||
|
@ -63,8 +63,11 @@ public abstract sealed class AbstractUnboundModel<E extends ClassFileElement>
|
|||
public List<Attribute<?>> attributes() {
|
||||
if (attributes == null)
|
||||
attributes = elements.stream()
|
||||
.filter(e -> e instanceof Attribute)
|
||||
.<Attribute<?>>map(e -> (Attribute<?>) e)
|
||||
.<Attribute<?>>mapMulti((e, sink) -> {
|
||||
if (e instanceof Attribute<?> attr) {
|
||||
sink.accept(attr);
|
||||
}
|
||||
})
|
||||
.toList();
|
||||
return attributes;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,6 @@ import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
|||
import java.lang.classfile.Label;
|
||||
import java.lang.classfile.MethodModel;
|
||||
import java.lang.classfile.instruction.ExceptionCatch;
|
||||
import java.lang.classfile.instruction.IncrementInstruction;
|
||||
import java.lang.classfile.instruction.LoadInstruction;
|
||||
import java.lang.classfile.instruction.StoreInstruction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -47,7 +44,6 @@ public final class BufferedCodeBuilder
|
|||
private final ClassFileImpl context;
|
||||
private final List<CodeElement> elements = new ArrayList<>();
|
||||
private final LabelImpl startLabel, endLabel;
|
||||
private final CodeModel original;
|
||||
private final MethodInfo methodInfo;
|
||||
private boolean finished;
|
||||
private int maxLocals;
|
||||
|
@ -60,12 +56,8 @@ public final class BufferedCodeBuilder
|
|||
this.context = context;
|
||||
this.startLabel = new LabelImpl(this, -1);
|
||||
this.endLabel = new LabelImpl(this, -1);
|
||||
this.original = original;
|
||||
this.methodInfo = methodInfo;
|
||||
this.maxLocals = Util.maxLocals(methodInfo.methodFlags(), methodInfo.methodTypeSymbol());
|
||||
if (original != null)
|
||||
this.maxLocals = Math.max(this.maxLocals, original.maxLocals());
|
||||
|
||||
this.maxLocals = TerminalCodeBuilder.setupTopLocal(methodInfo, original);
|
||||
elements.add(startLabel);
|
||||
}
|
||||
|
||||
|
@ -162,27 +154,16 @@ public final class BufferedCodeBuilder
|
|||
@Override
|
||||
public List<ExceptionCatch> exceptionHandlers() {
|
||||
return elements.stream()
|
||||
.filter(x -> x instanceof ExceptionCatch)
|
||||
.map(x -> (ExceptionCatch) x)
|
||||
.<ExceptionCatch>mapMulti((x, sink) -> {
|
||||
if (x instanceof ExceptionCatch ec) {
|
||||
sink.accept(ec);
|
||||
}
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxLocals() {
|
||||
for (CodeElement element : elements) {
|
||||
if (element instanceof LoadInstruction i)
|
||||
maxLocals = Math.max(maxLocals, i.slot() + i.typeKind().slotSize());
|
||||
else if (element instanceof StoreInstruction i)
|
||||
maxLocals = Math.max(maxLocals, i.slot() + i.typeKind().slotSize());
|
||||
else if (element instanceof IncrementInstruction i)
|
||||
maxLocals = Math.max(maxLocals, i.slot() + 1);
|
||||
}
|
||||
return maxLocals;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxStack() {
|
||||
throw new UnsupportedOperationException("nyi");
|
||||
int curTopLocal() {
|
||||
return BufferedCodeBuilder.this.curTopLocal();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -200,11 +181,6 @@ public final class BufferedCodeBuilder
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
DirectCodeBuilder.build(methodInfo, cb -> elements.forEach(cb), constantPool, context, null).writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("CodeModel[id=%s]", Integer.toHexString(System.identityHashCode(this)));
|
||||
|
|
|
@ -103,7 +103,7 @@ public final class BufferedFieldBuilder
|
|||
|
||||
@Override
|
||||
public void writeTo(DirectClassBuilder builder) {
|
||||
builder.withField(name, desc, new Consumer<FieldBuilder>() {
|
||||
builder.withField(name, desc, new Consumer<>() {
|
||||
@Override
|
||||
public void accept(FieldBuilder fieldBuilder) {
|
||||
elements.forEach(fieldBuilder);
|
||||
|
@ -111,13 +111,6 @@ public final class BufferedFieldBuilder
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
DirectFieldBuilder fb = new DirectFieldBuilder(constantPool, context, name, desc, null);
|
||||
elements.forEach(fb);
|
||||
fb.writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("FieldModel[fieldName=%s, fieldType=%s, flags=%d]", name.stringValue(), desc.stringValue(), flags.flagsMask());
|
||||
|
|
|
@ -196,7 +196,11 @@ public final class BufferedMethodBuilder
|
|||
|
||||
@Override
|
||||
public Optional<CodeModel> code() {
|
||||
throw new UnsupportedOperationException("nyi");
|
||||
return elements.stream().<CodeModel>mapMulti((e, sink) -> {
|
||||
if (e instanceof CodeModel cm) {
|
||||
sink.accept(cm);
|
||||
}
|
||||
}).findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -209,13 +213,6 @@ public final class BufferedMethodBuilder
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
DirectMethodBuilder mb = new DirectMethodBuilder(constantPool, context, name, desc, methodFlags(), null);
|
||||
elements.forEach(mb);
|
||||
mb.writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("MethodModel[methodName=%s, methodType=%s, flags=%d]",
|
||||
|
|
|
@ -43,7 +43,7 @@ import static java.lang.classfile.ClassFile.*;
|
|||
|
||||
public final class CodeImpl
|
||||
extends BoundAttribute.BoundCodeAttribute
|
||||
implements CodeModel, LabelContext {
|
||||
implements LabelContext {
|
||||
|
||||
static final Instruction[] SINGLETON_INSTRUCTIONS = new Instruction[256];
|
||||
|
||||
|
|
|
@ -127,12 +127,10 @@ public final class DirectCodeBuilder
|
|||
this.transformFwdJumps = transformFwdJumps;
|
||||
this.transformBackJumps = context.shortJumpsOption() == ClassFile.ShortJumpsOption.FIX_SHORT_JUMPS;
|
||||
bytecodesBufWriter = (original instanceof CodeImpl cai) ? new BufWriterImpl(constantPool, context, cai.codeLength())
|
||||
: new BufWriterImpl(constantPool, context);
|
||||
: new BufWriterImpl(constantPool, context);
|
||||
this.startLabel = new LabelImpl(this, 0);
|
||||
this.endLabel = new LabelImpl(this, -1);
|
||||
this.topLocal = Util.maxLocals(methodInfo.methodFlags(), methodInfo.methodTypeSymbol());
|
||||
if (original != null)
|
||||
this.topLocal = Math.max(this.topLocal, original.maxLocals());
|
||||
this.topLocal = TerminalCodeBuilder.setupTopLocal(methodInfo, original);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -312,8 +310,9 @@ public final class DirectCodeBuilder
|
|||
|
||||
private void writeCounters(boolean codeMatch, BufWriterImpl buf) {
|
||||
if (codeMatch) {
|
||||
buf.writeU2(original.maxStack());
|
||||
buf.writeU2(original.maxLocals());
|
||||
var originalAttribute = (CodeImpl) original;
|
||||
buf.writeU2(originalAttribute.maxStack());
|
||||
buf.writeU2(originalAttribute.maxLocals());
|
||||
} else {
|
||||
StackCounter cntr = StackCounter.of(DirectCodeBuilder.this, buf);
|
||||
buf.writeU2(cntr.maxStack());
|
||||
|
|
|
@ -25,8 +25,24 @@
|
|||
package jdk.internal.classfile.impl;
|
||||
|
||||
import java.lang.classfile.CodeBuilder;
|
||||
import java.lang.classfile.CodeModel;
|
||||
import java.lang.classfile.attribute.CodeAttribute;
|
||||
|
||||
public sealed interface TerminalCodeBuilder extends CodeBuilder, LabelContext
|
||||
permits DirectCodeBuilder, BufferedCodeBuilder {
|
||||
int curTopLocal();
|
||||
|
||||
static int setupTopLocal(MethodInfo methodInfo, CodeModel original) {
|
||||
int paramSlots = Util.maxLocals(methodInfo.methodFlags(), methodInfo.methodTypeSymbol());
|
||||
if (original == null) {
|
||||
return paramSlots;
|
||||
}
|
||||
if (original instanceof CodeAttribute attr) {
|
||||
return Math.max(paramSlots, attr.maxLocals());
|
||||
}
|
||||
if (original instanceof BufferedCodeBuilder.Model buffered) {
|
||||
return Math.max(paramSlots, buffered.curTopLocal());
|
||||
}
|
||||
throw new InternalError("Unknown code model " + original);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue