Include preamble position in single-line judgment.
Bug: b/232212653
Change-Id: Ic4453deab0fbdef2106f66c8ff5e4970bacca637
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 f277168..86b7c35 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.code.Instruction;
import com.android.tools.r8.debuginfo.DebugRepresentation.DebugRepresentationPredicate;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -1139,6 +1140,7 @@
EventBasedDebugInfo debugInfo =
DexDebugInfo.convertToEventBased(dexCode, appView.dexItemFactory());
assert debugInfo != null;
+ IntBox firstDefaultEventPc = new IntBox(-1);
BooleanBox singleOriginalLine = new BooleanBox(true);
Pair<Integer, Position> lastPosition = new Pair<>();
DexDebugEventVisitor visitor =
@@ -1149,6 +1151,9 @@
public void visit(Default defaultEvent) {
super.visit(defaultEvent);
assert getCurrentLine() >= 0;
+ if (firstDefaultEventPc.get() < 0) {
+ firstDefaultEventPc.set(getCurrentPc());
+ }
Position currentPosition = getPositionFromPositionState(this);
if (lastPosition.getSecond() != null) {
if (singleOriginalLine.isTrue()
@@ -1172,6 +1177,20 @@
event.accept(visitor);
}
+ // If the method has a single non-preamble line, check that the preamble is not active on any
+ // throwing instruction before the single line becomes active.
+ if (singleOriginalLine.isTrue() && firstDefaultEventPc.get() > 0) {
+ for (Instruction instruction : dexCode.instructions) {
+ if (instruction.getOffset() < firstDefaultEventPc.get()) {
+ if (instruction.canThrow()) {
+ singleOriginalLine.set(false);
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
int lastInstructionPc = ArrayUtils.last(dexCode.instructions).getOffset();
if (lastPosition.getSecond() != null) {
remapAndAddForPc(
diff --git a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
index 921d4d9..f8e88c6 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
@@ -179,14 +179,12 @@
StackTraceLine fooLine =
isRuntimeWithPcAsLineNumberSupport() ? inputLine("foo", 1) : inputLine("foo", -1);
- // TODO(b/232212653): Retracing builds with stripped line table will retrace incorrectly.
- StackTraceLine barLine =
- (isRuntimeWithPcAsLineNumberSupport() && customSourceFile)
- || !isCompileWithPcAsLineNumberSupport()
- ? inputLine("bar", 100)
- : inputLine("bar", 0);
+ // TODO(b/232212653): Normal line-opt will cause a single-line mapping. Retrace should not
+ // optimize that to mean it represents a single possible line. (<noline> should not match 1:x).
+ StackTraceLine barLine = parameters.isCfRuntime() ? inputLine("bar", 100) : inputLine("bar", 0);
// TODO(b/232212653): The retracing in CF where the line table is preserved is incorrect.
+ // same issue as for bar.
StackTraceLine bazLine = parameters.isCfRuntime() ? inputLine("baz", 100) : inputLine("baz", 0);
return StackTrace.builder()
@@ -218,16 +216,9 @@
? line(UNKNOWN_SOURCE_FILE, "foo", 1)
: residualLine("foo", -1);
- // TODO(b/232212653): If not using a custom source file, then the single line identification
- // strips the line table.
- StackTraceLine barLine =
- isRuntimeWithPcAsLineNumberSupport() && !customSourceFile
- ? line(UNKNOWN_SOURCE_FILE, "bar", 0)
- : residualLine("bar", customSourceFile ? 0 : -1);
-
return StackTrace.builder()
.add(fooLine)
- .add(barLine)
+ .add(residualLine("bar", 0))
.add(residualLine("baz", 0))
.add(residualLine("main", 6))
.build();