Calculate conservative bytecode size of CF instructions
Bug: b/225839019
Change-Id: I150e12cf6cc4b8184485fd0630f258fe59e7f0bf
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
index efad6db..67e44d4 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
@@ -162,6 +162,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public boolean canThrow() {
return (type != NumericType.FLOAT && type != NumericType.DOUBLE)
&& (opcode == Opcode.Div || opcode == Opcode.Rem);
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
index 0af6a11..35a03f2 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
@@ -40,6 +40,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public int getCompareToId() {
return Opcodes.ARRAYLENGTH;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
index 44f0e60..dc6a732 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -89,6 +89,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
index 68d6b2d..39db93e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
@@ -87,6 +87,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
index 6098e98..edd6603 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
@@ -92,6 +92,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
index c997da1..5b3c937 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
@@ -112,6 +112,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
int right = state.pop().register;
int left = state.pop().register;
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index 0e878ae..abc6070 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -94,6 +94,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // ldc or ldc_w
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
index 4efa8ae..3416ff7 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
@@ -189,6 +189,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // ldc or ldc_w
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
index 5f5837a..48db7ef 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
@@ -67,6 +67,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // ldc or ldc_w
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
index 3ef0e8d..855690f 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
@@ -65,6 +65,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // ldc or ldc_w
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
index 4d7dbb7..d58b161 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
@@ -40,6 +40,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public int getCompareToId() {
return Opcodes.ACONST_NULL;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
index abd71c5..b1d9c5b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
@@ -146,6 +146,64 @@
}
}
+ @Override
+ public int bytecodeSizeUpperBound() {
+ switch (type) {
+ case INT:
+ {
+ int value = getIntValue();
+ if (-1 <= value && value <= 5) {
+ // iconst_0 .. iconst_5
+ return 1;
+ } else if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE) {
+ // bipush byte
+ return 2;
+ } else if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE) {
+ // sipush byte1 byte2
+ return 3;
+ } else {
+ // ldc or ldc_w
+ return 3;
+ }
+ }
+ case LONG:
+ {
+ long value = getLongValue();
+ if (value == 0 || value == 1) {
+ // lconst_0 .. lconst_1
+ return 1;
+ } else {
+ // ldc or ldc_w
+ return 3;
+ }
+ }
+ case FLOAT:
+ {
+ float value = getFloatValue();
+ if (value == 0 || value == 1 || value == 2) {
+ // fconst_0 .. fconst_2 followed by fneg if negative
+ return isNegativeZeroFloat(value) ? 2 : 1;
+ } else {
+ // ldc or ldc_w
+ return 3;
+ }
+ }
+ case DOUBLE:
+ {
+ double value = getDoubleValue();
+ if (value == 0 || value == 1) {
+ // dconst_0 .. dconst_2 followed by dneg if negative
+ return isNegativeZeroDouble(value) ? 2 : 1;
+ } else {
+ // ldc2_w
+ return 3;
+ }
+ }
+ default:
+ throw new Unreachable("Non supported type in cf backend: " + type);
+ }
+ }
+
public static boolean isNegativeZeroDouble(double value) {
return Double.doubleToLongBits(value) == Double.doubleToLongBits(-0.0);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
index 1b46a48..f03e9c7 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
@@ -74,6 +74,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // ldc or ldc_w
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
index 0a6887a..cdc4235 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
@@ -82,6 +82,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // ldc or ldc_w
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
index 99c9151..29dc73f 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
@@ -122,6 +122,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
index 31bc71c..7f7f08b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
@@ -404,6 +404,11 @@
visitor.visitFrame(F_NEW, localsCount, localsTypes, stackCount, stackTypes);
}
+ @Override
+ public int bytecodeSizeUpperBound() {
+ return 0;
+ }
+
private int computeStackCount() {
return stack.size();
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
index eb82f47..fa3a8a5 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
@@ -76,6 +76,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIf.java b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
index 9db12ec..833ac44 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
@@ -104,6 +104,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public boolean isConditionalJump() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
index 2340a89..c8129a6 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
@@ -105,6 +105,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public boolean isConditionalJump() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
index 735dde8..1b5763c 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
@@ -64,6 +64,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // iinc or wide iinc
+ return var < 256 && increment < 256 ? 3 : 6;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
index 1092bfe..c307d45 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
@@ -82,6 +82,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
index 0f93c4d..0469499 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
@@ -91,6 +91,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
index a1b7023..40b9737 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.code.CfOrDexInstruction;
import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.CfCompareHelper;
@@ -66,6 +67,10 @@
public abstract int internalAcceptCompareTo(
CfInstruction other, CompareToVisitor visitor, CfCompareHelper helper);
+ public int bytecodeSizeUpperBound() {
+ throw new Unreachable("Instruction must specify size");
+ }
+
public final int acceptCompareTo(
CfInstruction o, CompareToVisitor visitor, CfCompareHelper helper) {
int diff = visitor.visitInt(getCompareToId(), o.getCompareToId());
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index 9fb383a..8397bc6 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -112,6 +112,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return opcode == Opcodes.INVOKEINTERFACE ? 5 : 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
index 2082290..a02060b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
@@ -92,6 +92,11 @@
bsmArgs);
}
+ @Override
+ public int bytecodeSizeUpperBound() {
+ return 5;
+ }
+
private Object decodeBootstrapArgument(DexValue value, NamingLens lens) {
switch (value.getValueKind()) {
case DOUBLE:
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
index 51829ec..bc866cb 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
@@ -62,6 +62,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ throw error();
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
index 1f611b1..9e3b1ee 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
@@ -74,6 +74,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 0;
+ }
+
+ @Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
// Intentionally left empty.
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
index 4f9a4db..99a32da 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
@@ -88,6 +88,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // xload_0 .. xload_3, xload or wide xload, where x is a, i, f, l or d
+ return var <= 3 ? 1 : ((var < 256) ? 2 : 4);
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
index 71e31d8..2407b10 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
@@ -137,6 +137,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
int right = state.pop().register;
int left = state.pop().register;
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
index 557d380..11df4ee 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
@@ -62,6 +62,11 @@
visitor.visitInsn(getAsmOpcode());
}
+ @Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
private int getAsmOpcode() {
return type == Type.ENTER ? Opcodes.MONITORENTER : Opcodes.MONITOREXIT;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
index 33fed6e..509e0cf 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
@@ -93,6 +93,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 4;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
index a2621a8..da12fc5 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
@@ -64,6 +64,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNew.java b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
index 95deb22..b4c070a 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNew.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
@@ -82,6 +82,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 3;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
index 50f82d0..5149789 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
@@ -128,6 +128,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 2;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java b/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
index 0d283d4..0c75328 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewUnboxedEnum.java
@@ -85,6 +85,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ throw new Unreachable();
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNop.java b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
index 3518f2a..f77241e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
@@ -50,6 +50,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
index 13c737d..b8fe9c1 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
@@ -74,6 +74,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
index e7bf24a..6f82c07 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
@@ -63,6 +63,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 0;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java b/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
index ec9b7df..f8fad92 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfRecordFieldValues.java
@@ -54,6 +54,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ throw new Unreachable();
+ }
+
+ @Override
public CfRecordFieldValues asRecordFieldValues() {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
index 68038a4..d06db87 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
@@ -67,6 +67,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public boolean isJump() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
index 9072b97..d492b04 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
@@ -55,6 +55,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
index 289846f..366033d 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
@@ -108,6 +108,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStore.java b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
index b096223..616ed84 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
@@ -91,6 +91,12 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ // xstore_0 .. xstore_3, xstore or wide xstore, where x is a, i, f, l or d
+ return var <= 3 ? 1 : ((var < 256) ? 2 : 4);
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
index 6321c35..a86bcd1 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.CfCompareHelper;
@@ -121,6 +122,20 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ switch (kind) {
+ case LOOKUP:
+ return 8 + keys.length * 8;
+ case TABLE:
+ int min = keys[0];
+ int max = min + targets.size() - 1;
+ return 16 + (max - min + 1) * 4;
+ default:
+ throw new Unreachable();
+ }
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
index fc36a53..6e5eb78 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
@@ -66,6 +66,11 @@
}
@Override
+ public int bytecodeSizeUpperBound() {
+ return 1;
+ }
+
+ @Override
public void print(CfPrinter printer) {
printer.print(this);
}
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index 5f31229..910d5f5 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -311,6 +311,16 @@
return estimatedSizeForInlining() * Base5Format.SIZE;
}
+ public int bytecodeSizeUpperBound() {
+ int result = 0;
+ for (CfInstruction instruction : instructions) {
+ int delta = instruction.bytecodeSizeUpperBound();
+ assert delta > 0 || !instruction.emitsIR();
+ result += delta;
+ }
+ return result;
+ }
+
private int countNonStackOperations(int threshold) {
int result = 0;
for (CfInstruction instruction : instructions) {
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 1332bf7..11f0a2c 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -594,6 +594,7 @@
MethodVisitor visitor) {
Code code = method.getDefinition().getCode();
assert code.isCfWritableCode();
+ assert code.estimatedDexCodeSizeUpperBoundInBytes() > 0;
code.asCfWritableCode()
.writeCf(method, classFileVersion, appView, namingLens, rewriter, visitor);
}