Merge "Use more lit8 dex instruction form"
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 fa19a7c..e1f9c63 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -14,9 +14,13 @@
public class CfCode extends Code {
+ private final int maxStack;
+ private final int maxLocals;
private final List<CfInstruction> instructions;
- public CfCode(List<CfInstruction> instructions) {
+ public CfCode(int maxStack, int maxLocals, List<CfInstruction> instructions) {
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
this.instructions = instructions;
}
@@ -35,8 +39,7 @@
instruction.write(visitor);
}
visitor.visitEnd();
- // TODO(zerny): Consider computing max-stack (and frames?) height as part of building Cf.
- visitor.visitMaxs(0, 0); // Trigger computation of max stack (and frames).
+ visitor.visitMaxs(maxStack, maxLocals);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 0a907c3..cdcf070 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -950,6 +950,6 @@
public abstract Constraint inliningConstraint(AppInfoWithSubtyping info, DexType holder);
public void insertLoadAndStores(InstructionListIterator it, StackHelper stack) {
- throw new Unimplemented("Implment load/store insertion for: " + getInstructionName());
+ throw new Unimplemented("Implement load/store insertion for: " + getInstructionName());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index 15b0f69..bc5df81 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.ir.code.Store;
import com.android.tools.r8.ir.code.Value;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
public class CfBuilder {
@@ -98,12 +99,35 @@
}
private CfCode buildCfCode() {
+ int maxLocalNumber = -1;
+ int maxStack = 0;
+ int currentStack = 0;
instructions = new ArrayList<>();
- InstructionIterator it = code.instructionIterator();
- while (it.hasNext()) {
- it.next().buildCf(this);
+ Iterator<BasicBlock> blockIterator = code.listIterator();
+ while (blockIterator.hasNext()) {
+ BasicBlock block = blockIterator.next();
+ InstructionIterator it = block.iterator();
+ while (it.hasNext()) {
+ Instruction instruction = it.next();
+ if (instruction.outValue() != null) {
+ Value outValue = instruction.outValue();
+ if (outValue instanceof StackValue) {
+ ++currentStack;
+ maxStack = Math.max(maxStack, currentStack);
+ } else {
+ maxLocalNumber = Math.max(maxLocalNumber, outValue.getNumber());
+ }
+ }
+ for (Value inValue : instruction.inValues()) {
+ if (inValue instanceof StackValue) {
+ --currentStack;
+ }
+ }
+ instruction.buildCf(this);
+ }
}
- return new CfCode(instructions);
+ assert currentStack == 0;
+ return new CfCode(maxStack, maxLocalNumber + 1, instructions);
}
// Callbacks
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 bd5ae63..ede2e85 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -58,7 +58,24 @@
}
private void writeClass(DexProgramClass clazz, OutputSink outputSink) throws IOException {
- ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ // If there are CF representations for all methods manually compute stack height and frames.
+ // TODO(zerny): This is a temporary hack since we will need to manually compute stack maps for
+ // any methods that are IR processed.
+ int flags = 0;
+ for (DexEncodedMethod method : clazz.directMethods()) {
+ if (!method.getCode().isCfCode()) {
+ flags = ClassWriter.COMPUTE_FRAMES;
+ break;
+ }
+ }
+ if (flags == 0) {
+ for (DexEncodedMethod method : clazz.virtualMethods()) {
+ if (!method.getCode().isCfCode()) {
+ flags = ClassWriter.COMPUTE_FRAMES;
+ }
+ }
+ }
+ ClassWriter writer = new ClassWriter(flags);
writer.visitSource(clazz.sourceFile.toString(), null);
int version = clazz.getClassFileVersion();
int access = clazz.accessFlags.getAsCfAccessFlags();