Verify order of method ids.

Change-Id: I51606b018e60bf6f09327931e22b236a23097626
diff --git a/src/main/java/com/android/tools/r8/dex/DexParser.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
index 0ccf502..f69ea61 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -925,7 +925,7 @@
       int initialOffset = dexSection.offset;
       dexReader.position(initialOffset);
 
-      int prevClassIndex = dexReader.getUshort();
+      int prevHolderIndex = dexReader.getUshort();
       int prevTypeIndex = dexReader.getUshort();
       int prevNameIndex = dexReader.getUint();
 
@@ -933,19 +933,19 @@
         int offset = initialOffset + Constants.TYPE_FIELD_ID_ITEM_SIZE * index;
         dexReader.position(offset);
 
-        int classIndex = dexReader.getUshort();
+        int holderIndex = dexReader.getUshort();
         int typeIndex = dexReader.getUshort();
         int nameIndex = dexReader.getUint();
 
         boolean isValidOrder;
-        if (classIndex == prevClassIndex) {
+        if (holderIndex == prevHolderIndex) {
           if (nameIndex == prevNameIndex) {
             isValidOrder = typeIndex > prevTypeIndex;
           } else {
             isValidOrder = nameIndex > prevNameIndex;
           }
         } else {
-          isValidOrder = classIndex > prevClassIndex;
+          isValidOrder = holderIndex > prevHolderIndex;
         }
 
         assert isValidOrder
@@ -954,19 +954,19 @@
                 index - 1,
                 dexItemFactory
                     .createField(
-                        indexedItems.getType(prevClassIndex),
+                        indexedItems.getType(prevHolderIndex),
                         indexedItems.getType(prevTypeIndex),
                         indexedItems.getString(prevNameIndex))
                     .toSourceString(),
                 index,
                 dexItemFactory
                     .createField(
-                        indexedItems.getType(classIndex),
+                        indexedItems.getType(holderIndex),
                         indexedItems.getType(typeIndex),
                         indexedItems.getString(nameIndex))
                     .toSourceString());
 
-        prevClassIndex = classIndex;
+        prevHolderIndex = holderIndex;
         prevTypeIndex = typeIndex;
         prevNameIndex = nameIndex;
       }
@@ -984,12 +984,75 @@
 
   private void populateMethods() {
     DexSection dexSection = lookupSection(Constants.TYPE_METHOD_ID_ITEM);
+    assert verifyOrderOfMethodIds(dexSection);
     indexedItems.initializeMethods(dexSection.length);
     for (int i = 0; i < dexSection.length; i++) {
       indexedItems.setMethod(i, methodAt(i));
     }
   }
 
+  /**
+   * From https://source.android.com/devices/tech/dalvik/dex-format#file-layout:
+   *
+   * <p>This list must be sorted, where the defining type (by type_id index) is the major order,
+   * method name (by string_id index) is the intermediate order, and method prototype
+   * (by proto_id index) is the minor order. The list must not contain any duplicate entries.
+   *
+   */
+  private boolean verifyOrderOfMethodIds(DexSection dexSection) {
+    if (dexSection.length >= 2) {
+      int initialOffset = dexSection.offset;
+      dexReader.position(initialOffset);
+
+      int prevHolderIndex = dexReader.getUshort();
+      int prevProtoIndex = dexReader.getUshort();
+      int prevNameIndex = dexReader.getUint();
+
+      for (int index = 1; index < dexSection.length; index++) {
+        int offset = initialOffset + Constants.TYPE_METHOD_ID_ITEM_SIZE * index;
+        dexReader.position(offset);
+
+        int holderIndex = dexReader.getUshort();
+        int protoIndex = dexReader.getUshort();
+        int nameIndex = dexReader.getUint();
+
+        boolean isValidOrder;
+        if (holderIndex == prevHolderIndex) {
+          if (nameIndex == prevNameIndex) {
+            isValidOrder = protoIndex > prevProtoIndex;
+          } else {
+            isValidOrder = nameIndex > prevNameIndex;
+          }
+        } else {
+          isValidOrder = holderIndex > prevHolderIndex;
+        }
+
+        assert isValidOrder
+            : String.format(
+                "Out-of-order method ids (method #%s: `%s`, method #%s: `%s`)",
+                index - 1,
+                dexItemFactory
+                    .createMethod(
+                        indexedItems.getType(prevHolderIndex),
+                        indexedItems.getProto(prevProtoIndex),
+                        indexedItems.getString(prevNameIndex))
+                    .toSourceString(),
+                index,
+                dexItemFactory
+                    .createMethod(
+                        indexedItems.getType(holderIndex),
+                        indexedItems.getProto(protoIndex),
+                        indexedItems.getString(nameIndex))
+                    .toSourceString());
+
+        prevHolderIndex = holderIndex;
+        prevProtoIndex = protoIndex;
+        prevNameIndex = nameIndex;
+      }
+    }
+    return true;
+  }
+
   private DexString stringAt(int index) {
     final int offset = stringIDs[index];
     dexReader.position(offset);