Fix incorrect equals in pc2pc computation.
This also adds some checks and fixes two incorrect "last offset"
computations.
Bug: b/231903117
Change-Id: I2343994b708b8c503de8a7ec4c520e689e64a94a
diff --git a/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java b/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java
index 667e5b0..8b530e8 100644
--- a/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java
+++ b/src/main/java/com/android/tools/r8/debuginfo/DebugRepresentation.java
@@ -62,7 +62,10 @@
}
VirtualFile file = classMapping.get(holder);
DebugRepresentation cutoffs = file.getDebugRepresentation();
- return cutoffs.getDexPcEncodingCutoff(method);
+ int maxPc = cutoffs.getDexPcEncodingCutoff(method);
+ assert maxPc == NO_PC_ENCODING
+ || verifyLastExecutableInstructionWithinBound(method.getCode().asDexCode(), maxPc);
+ return maxPc;
};
}
@@ -269,7 +272,14 @@
}
}
- private static Instruction getLastExecutableInstruction(DexCode code) {
+ public static boolean verifyLastExecutableInstructionWithinBound(DexCode code, int maxPc) {
+ Instruction lastExecutableInstruction = getLastExecutableInstruction(code);
+ int offset = lastExecutableInstruction.getOffset();
+ assert offset <= maxPc;
+ return true;
+ }
+
+ public static Instruction getLastExecutableInstruction(DexCode code) {
Instruction lastInstruction = null;
for (Instruction instruction : code.instructions) {
if (!instruction.isPayload()) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java b/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java
index 09f740e..0b944c3 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.graph;
import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.debuginfo.DebugRepresentation;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.dex.DebugBytecodeWriter;
import com.android.tools.r8.dex.IndexedItemCollection;
@@ -97,6 +98,10 @@
this.maxPc = maxPc;
}
+ public int getMaxPc() {
+ return maxPc;
+ }
+
@Override
public int getStartLine() {
return START_LINE;
@@ -294,19 +299,18 @@
}
assert code.getDebugInfo().isPcBasedInfo();
PcBasedDebugInfo pcBasedDebugInfo = code.getDebugInfo().asPcBasedInfo();
+ assert DebugRepresentation.verifyLastExecutableInstructionWithinBound(
+ code, pcBasedDebugInfo.maxPc);
// Generate a line event at each throwing instruction.
List<DexDebugEvent> events = new ArrayList<>(code.instructions.length);
- int pc = 0;
int delta = 0;
for (Instruction instruction : code.instructions) {
if (instruction.canThrow()) {
DexDebugEventBuilder.addDefaultEventWithAdvancePcIfNecessary(delta, delta, events, factory);
- pc += delta;
delta = 0;
}
delta += instruction.getSize();
}
- assert pc + delta - ArrayUtils.last(code.instructions).getSize() <= pcBasedDebugInfo.maxPc;
return new EventBasedDebugInfo(
PcBasedDebugInfo.START_LINE,
new DexString[pcBasedDebugInfo.getParameterCount()],
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index e1d4ce4..56ed94d 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfPosition;
+import com.android.tools.r8.debuginfo.DebugRepresentation;
import com.android.tools.r8.debuginfo.DebugRepresentation.DebugRepresentationPredicate;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -392,7 +393,7 @@
@Override
public boolean equals(Object o) {
UpdateInfo that = (UpdateInfo) o;
- return paramCount == that.paramCount && maxEncodingPc != that.maxEncodingPc;
+ return paramCount == that.paramCount && maxEncodingPc == that.maxEncodingPc;
}
@Override
@@ -413,6 +414,7 @@
@Override
public void recordPcMappingFor(DexCode code, int parameterCount, int maxEncodingPc) {
+ assert DebugRepresentation.verifyLastExecutableInstructionWithinBound(code, maxEncodingPc);
codesToUpdate.add(new UpdateInfo(code, parameterCount, maxEncodingPc));
}
@@ -431,9 +433,12 @@
new Object2ReferenceOpenHashMap<>();
codesToUpdate.forEach(
entry -> {
+ assert DebugRepresentation.verifyLastExecutableInstructionWithinBound(
+ entry.code, entry.maxEncodingPc);
DexDebugInfo debugInfo =
debugInfos.computeIfAbsent(
entry, key -> buildPc2PcDebugInfo(key.maxEncodingPc, key.paramCount));
+ assert debugInfo.asPcBasedInfo().getMaxPc() == entry.maxEncodingPc;
entry.code.setDebugInfo(debugInfo);
});
if (singleLineCodesToClear != null) {
@@ -1173,7 +1178,7 @@
event.accept(visitor);
}
- int lastInstructionPc = ArrayUtils.last(dexCode.instructions).getOffset();
+ int lastInstructionPc = DebugRepresentation.getLastExecutableInstruction(dexCode).getOffset();
if (lastPosition.getSecond() != null) {
remapAndAddForPc(
lastPosition.getFirst(),