Account for unordered mapped positions in LineNumberOptimizer

Bug: 157758209
Change-Id: I269b9ae5d2e576052f4f74ff5cc4e8f9325d5728
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 a785262b..e1572f5 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -408,7 +408,14 @@
                   || !Objects.equals(mp.caller, lastPosition.caller)) {
                 break;
               }
-              lastPosition = mp;
+              // The mapped positions are not guaranteed to be in order, so maintain first and last
+              // position.
+              if (firstPosition.obfuscatedLine > mp.obfuscatedLine) {
+                firstPosition = mp;
+              }
+              if (lastPosition.obfuscatedLine < mp.obfuscatedLine) {
+                lastPosition = mp;
+              }
             }
             Range obfuscatedRange =
                 new Range(firstPosition.obfuscatedLine, lastPosition.obfuscatedLine);
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/LineNumberRangeTest.java b/src/test/java/com/android/tools/r8/naming/retrace/LineNumberRangeTest.java
index 18cac88..02ed76d 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/LineNumberRangeTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/LineNumberRangeTest.java
@@ -4,8 +4,6 @@
 
 package com.android.tools.r8.naming.retrace;
 
-import static com.android.tools.r8.naming.retrace.StackTrace.isSame;
-import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.CompilationMode;
@@ -66,14 +64,18 @@
   }
 
   @Test
-  public void testSourceFileAndLineNumberTable() throws Exception {
+  public void testRuntime() throws Exception {
     StackTrace expectedStackTrace =
-        testForJvm()
+        testForRuntime(parameters)
             .addProgramClassFileData(MainDump.dump())
             .run(parameters.getRuntime(), Main.class)
             .assertFailure()
             .map(StackTrace::extractFromJvm);
     assertThat(expectedStackTrace, Matchers.containsLinePositions(EXPECTED_STACK_TRACE));
+  }
+
+  @Test
+  public void testSourceFileAndLineNumberTable() throws Exception {
     R8TestRunResult result =
         testForR8(parameters.getBackend())
             .addProgramClassFileData(MainDump.dump())
@@ -97,7 +99,7 @@
           StackTrace.extractFromArt(result.getStdErr(), parameters.getRuntime().asDex().getVm());
     }
     StackTrace retracedStackTrace = actualStackTrace.retrace(result.proguardMap());
-    assertThat(retracedStackTrace, not(isSame(expectedStackTrace)));
+    assertThat(retracedStackTrace, Matchers.containsLinePositions(EXPECTED_STACK_TRACE));
   }
 
   // This class is generated by taking the output of InliningRetraceTest without running the