Version 1.0.12.
Merge: Block the receiver register always before Android M.
CL: https://r8-review.googlesource.com/c/r8/+/17201
R=sgjesse@google.com
Change-Id: Ied1f3a807c08288eeb343900c08c6aff72ba1e87
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 96af965..9781dc5 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "v1.0.11";
+ public static final String LABEL = "v1.0.12";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index 7af0451..15c186f 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -1973,6 +1973,24 @@
private void computeLiveRanges() {
computeLiveRanges(options, code, liveAtEntrySets, liveIntervals);
+ // Art VMs before Android M assume that the register for the receiver never changes its value.
+ // This assumption is used during verification. Allowing the receiver register to be
+ // overwritten can therefore lead to verification errors. If we could be targeting one of these
+ // VMs we block the receiver register throughout the method.
+ if (options.canHaveThisTypeVerifierBug() && !code.method.accessFlags.isStatic()) {
+ for (Instruction instruction : code.blocks.get(0).getInstructions()) {
+ if (instruction.isArgument() && instruction.outValue().isThis()) {
+ Value thisValue = instruction.outValue();
+ LiveIntervals thisIntervals = thisValue.getLiveIntervals();
+ thisIntervals.getRanges().clear();
+ thisIntervals.addRange(new LiveRange(0, code.getNextInstructionNumber()));
+ for (Set<Value> values : liveAtEntrySets.values()) {
+ values.add(thisValue);
+ }
+ return;
+ }
+ }
+ }
}
/**
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 4ebe661..610d547 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -475,4 +475,11 @@
public boolean canUseNotInstruction() {
return minApiLevel >= AndroidApiLevel.L.getLevel();
}
+
+ // Art before M has a verifier bug where the type of the contents of the receiver register is
+ // assumed to not change. If the receiver register is reused for something else the verifier
+ // will fail and the code will not run.
+ public boolean canHaveThisTypeVerifierBug() {
+ return minApiLevel < AndroidApiLevel.M.getLevel();
+ }
}