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(),