Make sure that we never emit 'goto next instruction'.
R=zerny@google.com
Bug: b/65570643
Change-Id: I7b4c8d463dbfc0fbe45ca7a03e04d17f8bd53405
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
index 8540bf3..92f768e 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
@@ -898,16 +898,26 @@
int source = builder.getInfo(jump).getOffset();
Info targetInfo = builder.getTargetInfo(jump.getTarget());
int relativeOffset = targetInfo.getOffset() - source;
- // We should never generate a goto to the following instruction or two consecutive returns.
- // TODO(b/34726595): We might have a goto to the following instruction if we fail to DCE.
- // assert relativeOffset != size;
- Instruction dex;
// Emit a return if the target is a return and the size of the return is the computed
// size of this instruction.
Return ret = targetInfo.getIR().asReturn();
if (ret != null && size == targetInfo.getSize() && canTargetReturn(ret)) {
- dex = ret.createDexInstruction(builder);
+ Instruction dex = ret.createDexInstruction(builder);
+ dex.setOffset(getOffset()); // for better printing of the dex code.
+ instructions.add(dex);
+ } else if (size == relativeOffset) {
+ // We should never generate a goto targeting the next instruction. However, if we do
+ // we replace it with nops. This works around a dalvik bug where the dalvik tracing
+ // jit crashes on 'goto next instruction' on Android 4.1.1.
+ // TODO(b/34726595): We currently do hit this case and we should see if we can avoid that.
+ for (int i = 0; i < size; i++) {
+ Instruction dex = new Nop();
+ assert dex.getSize() == 1;
+ dex.setOffset(getOffset() + i); // for better printing of the dex code.
+ instructions.add(dex);
+ }
} else {
+ Instruction dex;
switch (size) {
case 1:
assert relativeOffset != 0;
@@ -928,9 +938,9 @@
default:
throw new Unreachable("Unexpected size for goto instruction: " + size);
}
+ dex.setOffset(getOffset()); // for better printing of the dex code.
+ instructions.add(dex);
}
- dex.setOffset(getOffset()); // for better printing of the dex code.
- instructions.add(dex);
}
private static boolean canTargetReturn(Return ret) {