Ensure deterministic ordering of debug info items.

Bug: 151418574
Change-Id: Ie873022ccd0caea4ace0e8f321caa078e347f297
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index ffae5aa..a7c3ec0 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -21,6 +21,7 @@
 import com.android.tools.r8.graph.DexCode.TryHandler;
 import com.android.tools.r8.graph.DexCode.TryHandler.TypeAddrPair;
 import com.android.tools.r8.graph.DexDebugInfo;
+import com.android.tools.r8.graph.DexDebugInfoForWriting;
 import com.android.tools.r8.graph.DexEncodedAnnotation;
 import com.android.tools.r8.graph.DexEncodedArray;
 import com.android.tools.r8.graph.DexEncodedField;
@@ -63,6 +64,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
@@ -172,11 +174,22 @@
 
     // Output the debug_info_items first, as they have no dependencies.
     dest.moveTo(layout.getCodesOffset() + sizeOfCodeItems(codes));
-    writeItems(mixedSectionOffsets.getDebugInfos(), layout::setDebugInfosOffset,
-        this::writeDebugItem);
+    if (mixedSectionOffsets.getDebugInfos().isEmpty()) {
+      layout.setDebugInfosOffset(0);
+    } else {
+      // Ensure deterministic ordering of debug info by sorting consistent with the code objects.
+      layout.setDebugInfosOffset(dest.align(1));
+      Set<DexDebugInfo> seen = new HashSet<>(mixedSectionOffsets.getDebugInfos().size());
+      for (DexCode code : codes) {
+        DexDebugInfoForWriting info = code.getDebugInfoForWriting();
+        if (info != null && seen.add(info)) {
+          writeDebugItem(info);
+        }
+      }
+    }
 
     // Remember the typelist offset for later.
-    layout.setTypeListsOffset(dest.align(4));  // type_list are aligned.
+    layout.setTypeListsOffset(dest.align(4)); // type_list are aligned.
 
     // Now output the code.
     dest.moveTo(layout.getCodesOffset());
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/r8ondex/R8CompiledThroughDexTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/r8ondex/R8CompiledThroughDexTest.java
index 0cb6d09..b1a6811 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/r8ondex/R8CompiledThroughDexTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/r8ondex/R8CompiledThroughDexTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.desugar.desugaredlibrary.r8ondex;
 
 import static junit.framework.TestCase.assertEquals;
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.R8;
 import com.android.tools.r8.TestParameters;
@@ -118,7 +118,6 @@
     assertEquals(0, artProcessResult.exitCode);
 
     // Ensure both generated artifacts are equal.
-    // TODO(b/151418574): Assert equal once fixed.
-    assertFalse(BootstrapCurrentEqualityTest.filesAreEqual(ouputThroughCf, ouputThroughDex));
+    assertTrue(BootstrapCurrentEqualityTest.filesAreEqual(ouputThroughCf, ouputThroughDex));
   }
 }