8339519: Remove size field from instructions

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2024-09-06 14:57:12 +00:00
parent 0df10bbd96
commit 5b72bbf9d4

View file

@ -94,7 +94,6 @@ public abstract sealed class AbstractInstruction
FMT_Discontinued = "Discontinued[OP=%s]"; FMT_Discontinued = "Discontinued[OP=%s]";
final Opcode op; final Opcode op;
final int size;
@Override @Override
public Opcode opcode() { public Opcode opcode() {
@ -103,12 +102,12 @@ public abstract sealed class AbstractInstruction
@Override @Override
public int sizeInBytes() { public int sizeInBytes() {
return size; // Note: only lookupswitch and tableswitch have variable sizes
return op.sizeIfFixed();
} }
public AbstractInstruction(Opcode op, int size) { AbstractInstruction(Opcode op) {
this.op = op; this.op = op;
this.size = size;
} }
@Override @Override
@ -118,8 +117,8 @@ public abstract sealed class AbstractInstruction
final CodeImpl code; final CodeImpl code;
final int pos; final int pos;
protected BoundInstruction(Opcode op, int size, CodeImpl code, int pos) { protected BoundInstruction(Opcode op, CodeImpl code, int pos) {
super(op, size); super(op);
this.code = code; this.code = code;
this.pos = pos; this.pos = pos;
} }
@ -131,7 +130,7 @@ public abstract sealed class AbstractInstruction
@Override @Override
public void writeTo(DirectCodeBuilder writer) { public void writeTo(DirectCodeBuilder writer) {
// Override this if the instruction has any CP references or labels! // Override this if the instruction has any CP references or labels!
code.classReader.copyBytesTo(writer.bytecodesBufWriter, pos, size); code.classReader.copyBytesTo(writer.bytecodesBufWriter, pos, op.sizeIfFixed());
} }
} }
@ -139,7 +138,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements LoadInstruction { extends BoundInstruction implements LoadInstruction {
public BoundLoadInstruction(Opcode op, CodeImpl code, int pos) { public BoundLoadInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@ -155,7 +154,7 @@ public abstract sealed class AbstractInstruction
@Override @Override
public int slot() { public int slot() {
return switch (size) { return switch (sizeInBytes()) {
case 2 -> code.classReader.readU1(pos + 1); case 2 -> code.classReader.readU1(pos + 1);
case 4 -> code.classReader.readU2(pos + 2); case 4 -> code.classReader.readU2(pos + 2);
default -> throw new IllegalArgumentException("Unexpected op size: " + op.sizeIfFixed() + " -- " + op); default -> throw new IllegalArgumentException("Unexpected op size: " + op.sizeIfFixed() + " -- " + op);
@ -168,7 +167,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements StoreInstruction { extends BoundInstruction implements StoreInstruction {
public BoundStoreInstruction(Opcode op, CodeImpl code, int pos) { public BoundStoreInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -183,10 +182,10 @@ public abstract sealed class AbstractInstruction
@Override @Override
public int slot() { public int slot() {
return switch (size) { return switch (sizeInBytes()) {
case 2 -> code.classReader.readU1(pos + 1); case 2 -> code.classReader.readU1(pos + 1);
case 4 -> code.classReader.readU2(pos + 2); case 4 -> code.classReader.readU2(pos + 2);
default -> throw new IllegalArgumentException("Unexpected op size: " + size + " -- " + op); default -> throw new IllegalArgumentException("Unexpected op size: " + sizeInBytes() + " -- " + op);
}; };
} }
@ -196,17 +195,17 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements IncrementInstruction { extends BoundInstruction implements IncrementInstruction {
public BoundIncrementInstruction(Opcode op, CodeImpl code, int pos) { public BoundIncrementInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
public int slot() { public int slot() {
return size == 6 ? code.classReader.readU2(pos + 2) : code.classReader.readU1(pos + 1); return sizeInBytes() == 6 ? code.classReader.readU2(pos + 2) : code.classReader.readU1(pos + 1);
} }
@Override @Override
public int constant() { public int constant() {
return size == 6 ? code.classReader.readS2(pos + 4) : (byte) code.classReader.readS1(pos + 2); return sizeInBytes() == 6 ? code.classReader.readS2(pos + 4) : code.classReader.readS1(pos + 2);
} }
@Override @Override
@ -220,7 +219,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements BranchInstruction { extends BoundInstruction implements BranchInstruction {
public BoundBranchInstruction(Opcode op, CodeImpl code, int pos) { public BoundBranchInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -229,8 +228,8 @@ public abstract sealed class AbstractInstruction
} }
public int branchByteOffset() { public int branchByteOffset() {
return size == 3 return sizeInBytes() == 3
? (int) (short) code.classReader.readU2(pos + 1) ? code.classReader.readS2(pos + 1)
: code.classReader.readInt(pos + 1); : code.classReader.readInt(pos + 1);
} }
@ -256,33 +255,31 @@ public abstract sealed class AbstractInstruction
// will always need size, cache everything to there // will always need size, cache everything to there
private final int afterPad; private final int afterPad;
private final int npairs; private final int npairs;
private final int size;
BoundLookupSwitchInstruction(Opcode op, CodeImpl code, int pos) { BoundLookupSwitchInstruction(Opcode op, CodeImpl code, int pos) {
super(op, size(code, code.codeStart, pos), code, pos); super(op, code, pos);
this.afterPad = code.codeStart + RawBytecodeHelper.align(pos + 1 - code.codeStart);
this.afterPad = pos + 1 + ((4 - ((pos + 1 - code.codeStart) & 3)) & 3);
this.npairs = code.classReader.readInt(afterPad + 4); this.npairs = code.classReader.readInt(afterPad + 4);
if (npairs < 0 || npairs > code.codeLength >> 3) { if (npairs < 0 || npairs > code.codeLength >> 3) {
throw new IllegalArgumentException("Invalid lookupswitch npairs value: " + npairs); throw new IllegalArgumentException("Invalid lookupswitch npairs value: " + npairs);
} }
} this.size = afterPad + 8 + npairs * 8 - pos;
static int size(CodeImpl code, int codeStart, int pos) {
int afterPad = pos + 1 + ((4 - ((pos + 1 - codeStart) & 3)) & 3);
int pad = afterPad - (pos + 1);
int npairs = code.classReader.readInt(afterPad + 4);
return 1 + pad + 8 + npairs * 8;
} }
private int defaultOffset() { private int defaultOffset() {
return code.classReader.readInt(afterPad); return code.classReader.readInt(afterPad);
} }
@Override
public int sizeInBytes() {
return size;
}
@Override @Override
public List<SwitchCase> cases() { public List<SwitchCase> cases() {
var cases = new SwitchCase[npairs]; var cases = new SwitchCase[npairs];
for (int i = 0; i < npairs; ++i) { for (int i = 0, z = afterPad + 8; i < npairs; ++i, z += 8) {
int z = afterPad + 8 + 8 * i;
cases[i] = SwitchCase.of(code.classReader.readInt(z), offsetToLabel(code.classReader.readInt(z + 4))); cases[i] = SwitchCase.of(code.classReader.readInt(z), offsetToLabel(code.classReader.readInt(z + 4)));
} }
return List.of(cases); return List.of(cases);
@ -308,25 +305,26 @@ public abstract sealed class AbstractInstruction
public static final class BoundTableSwitchInstruction public static final class BoundTableSwitchInstruction
extends BoundInstruction implements TableSwitchInstruction { extends BoundInstruction implements TableSwitchInstruction {
BoundTableSwitchInstruction(Opcode op, CodeImpl code, int pos) { private final int afterPad;
super(op, size(code, code.codeStart, pos), code, pos); private final int low;
} private final int high;
private final int size;
static int size(CodeImpl code, int codeStart, int pos) { BoundTableSwitchInstruction(Opcode op, CodeImpl code, int pos) {
int ap = pos + 1 + ((4 - ((pos + 1 - codeStart) & 3)) & 3); super(op, code, pos);
int pad = ap - (pos + 1); afterPad = code.codeStart + RawBytecodeHelper.align(pos + 1 - code.codeStart);
int low = code.classReader.readInt(ap + 4); low = code.classReader.readInt(afterPad + 4);
int high = code.classReader.readInt(ap + 8); high = code.classReader.readInt(afterPad + 8);
if (high < low || (long)high - low > code.codeLength >> 2) { if (high < low || (long)high - low > code.codeLength >> 2) {
throw new IllegalArgumentException("Invalid tableswitch values low: " + low + " high: " + high); throw new IllegalArgumentException("Invalid tableswitch values low: " + low + " high: " + high);
} }
int cnt = high - low + 1; int cnt = high - low + 1;
return 1 + pad + 12 + cnt * 4; size = afterPad + 12 + cnt * 4 - pos;
} }
private int afterPadding() { @Override
int p = pos; public int sizeInBytes() {
return p + 1 + ((4 - ((p + 1 - code.codeStart) & 3)) & 3); return size;
} }
@Override @Override
@ -336,12 +334,12 @@ public abstract sealed class AbstractInstruction
@Override @Override
public int lowValue() { public int lowValue() {
return code.classReader.readInt(afterPadding() + 4); return low;
} }
@Override @Override
public int highValue() { public int highValue() {
return code.classReader.readInt(afterPadding() + 8); return high;
} }
@Override @Override
@ -350,19 +348,17 @@ public abstract sealed class AbstractInstruction
int high = highValue(); int high = highValue();
int defOff = defaultOffset(); int defOff = defaultOffset();
var cases = new ArrayList<SwitchCase>(high - low + 1); var cases = new ArrayList<SwitchCase>(high - low + 1);
int z = afterPadding() + 12; for (int i = low, z = afterPad + 12; i <= high; ++i, z += 4) {
for (int i = lowValue(); i <= high; ++i) {
int off = code.classReader.readInt(z); int off = code.classReader.readInt(z);
if (defOff != off) { if (defOff != off) {
cases.add(SwitchCase.of(i, offsetToLabel(off))); cases.add(SwitchCase.of(i, offsetToLabel(off)));
} }
z += 4;
} }
return Collections.unmodifiableList(cases); return Collections.unmodifiableList(cases);
} }
private int defaultOffset() { private int defaultOffset() {
return code.classReader.readInt(afterPadding()); return code.classReader.readInt(afterPad);
} }
@Override @Override
@ -383,7 +379,7 @@ public abstract sealed class AbstractInstruction
private FieldRefEntry fieldEntry; private FieldRefEntry fieldEntry;
public BoundFieldInstruction(Opcode op, CodeImpl code, int pos) { public BoundFieldInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -413,7 +409,7 @@ public abstract sealed class AbstractInstruction
MemberRefEntry methodEntry; MemberRefEntry methodEntry;
public BoundInvokeInstruction(Opcode op, CodeImpl code, int pos) { public BoundInvokeInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -453,7 +449,7 @@ public abstract sealed class AbstractInstruction
InterfaceMethodRefEntry methodEntry; InterfaceMethodRefEntry methodEntry;
public BoundInvokeInterfaceInstruction(Opcode op, CodeImpl code, int pos) { public BoundInvokeInterfaceInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -493,7 +489,7 @@ public abstract sealed class AbstractInstruction
InvokeDynamicEntry indyEntry; InvokeDynamicEntry indyEntry;
BoundInvokeDynamicInstruction(Opcode op, CodeImpl code, int pos) { BoundInvokeDynamicInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -523,7 +519,7 @@ public abstract sealed class AbstractInstruction
ClassEntry classEntry; ClassEntry classEntry;
BoundNewObjectInstruction(CodeImpl code, int pos) { BoundNewObjectInstruction(CodeImpl code, int pos) {
super(Opcode.NEW, Opcode.NEW.sizeIfFixed(), code, pos); super(Opcode.NEW, code, pos);
} }
@Override @Override
@ -552,7 +548,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements NewPrimitiveArrayInstruction { extends BoundInstruction implements NewPrimitiveArrayInstruction {
public BoundNewPrimitiveArrayInstruction(Opcode op, CodeImpl code, int pos) { public BoundNewPrimitiveArrayInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -571,7 +567,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements NewReferenceArrayInstruction { extends BoundInstruction implements NewReferenceArrayInstruction {
public BoundNewReferenceArrayInstruction(Opcode op, CodeImpl code, int pos) { public BoundNewReferenceArrayInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -597,7 +593,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements NewMultiArrayInstruction { extends BoundInstruction implements NewMultiArrayInstruction {
public BoundNewMultidimensionalArrayInstruction(Opcode op, CodeImpl code, int pos) { public BoundNewMultidimensionalArrayInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -630,7 +626,7 @@ public abstract sealed class AbstractInstruction
ClassEntry typeEntry; ClassEntry typeEntry;
public BoundTypeCheckInstruction(Opcode op, CodeImpl code, int pos) { public BoundTypeCheckInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -659,7 +655,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements ConstantInstruction.ArgumentConstantInstruction { extends BoundInstruction implements ConstantInstruction.ArgumentConstantInstruction {
public BoundArgumentConstantInstruction(Opcode op, CodeImpl code, int pos) { public BoundArgumentConstantInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -668,7 +664,7 @@ public abstract sealed class AbstractInstruction
} }
public int constantInt() { public int constantInt() {
return size == 3 ? code.classReader.readS2(pos + 1) : code.classReader.readS1(pos + 1); return sizeInBytes() == 3 ? code.classReader.readS2(pos + 1) : code.classReader.readS1(pos + 1);
} }
@Override @Override
@ -682,7 +678,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements ConstantInstruction.LoadConstantInstruction { extends BoundInstruction implements ConstantInstruction.LoadConstantInstruction {
public BoundLoadConstantInstruction(Opcode op, CodeImpl code, int pos) { public BoundLoadConstantInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -717,7 +713,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements DiscontinuedInstruction.JsrInstruction { extends BoundInstruction implements DiscontinuedInstruction.JsrInstruction {
public BoundJsrInstruction(Opcode op, CodeImpl code, int pos) { public BoundJsrInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -726,7 +722,7 @@ public abstract sealed class AbstractInstruction
} }
public int branchByteOffset() { public int branchByteOffset() {
return size == 3 return sizeInBytes() == 3
? code.classReader.readS2(pos + 1) ? code.classReader.readS2(pos + 1)
: code.classReader.readInt(pos + 1); : code.classReader.readInt(pos + 1);
} }
@ -747,7 +743,7 @@ public abstract sealed class AbstractInstruction
extends BoundInstruction implements DiscontinuedInstruction.RetInstruction { extends BoundInstruction implements DiscontinuedInstruction.RetInstruction {
public BoundRetInstruction(Opcode op, CodeImpl code, int pos) { public BoundRetInstruction(Opcode op, CodeImpl code, int pos) {
super(op, op.sizeIfFixed(), code, pos); super(op, code, pos);
} }
@Override @Override
@ -757,7 +753,7 @@ public abstract sealed class AbstractInstruction
@Override @Override
public int slot() { public int slot() {
return switch (size) { return switch (sizeInBytes()) {
case 2 -> code.classReader.readU1(pos + 1); case 2 -> code.classReader.readU1(pos + 1);
case 4 -> code.classReader.readU2(pos + 2); case 4 -> code.classReader.readU2(pos + 2);
default -> throw new IllegalArgumentException("Unexpected op size: " + op.sizeIfFixed() + " -- " + op); default -> throw new IllegalArgumentException("Unexpected op size: " + op.sizeIfFixed() + " -- " + op);
@ -769,7 +765,7 @@ public abstract sealed class AbstractInstruction
public abstract static sealed class UnboundInstruction extends AbstractInstruction { public abstract static sealed class UnboundInstruction extends AbstractInstruction {
UnboundInstruction(Opcode op) { UnboundInstruction(Opcode op) {
super(op, op.sizeIfFixed()); super(op);
} }
@Override @Override