Use shared reservation state for interface partition

Bug: 211822928
Bug: 213041051
Change-Id: I1077e483a42fe8f3dca89171b757c3952ac1aa22
diff --git a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
index bec8073..f948457 100644
--- a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
@@ -180,6 +180,7 @@
 
               ReservedFieldNamingState reservedNames =
                   getOrCreateReservedFieldNamingState(clazz.type);
+              // TODO(b/213041051): This could avoid duplication of strings downwards.
               FieldNamingState state = parentState.createChildState(reservedNames);
               if (clazz.isProgramClass()) {
                 clazz.asProgramClass().forEachProgramField(field -> renameField(field, state));
@@ -191,8 +192,8 @@
   }
 
   private void renameFieldsInInterfaces(Collection<DexClass> interfaces) {
-    InterfacePartitioning partioning = new InterfacePartitioning(this);
-    for (Set<DexClass> partition : partioning.sortedPartitions(interfaces)) {
+    InterfacePartitioning partitioning = new InterfacePartitioning(this);
+    for (Set<DexClass> partition : partitioning.sortedPartitions(interfaces)) {
       renameFieldsInInterfacePartition(partition);
     }
   }
@@ -231,11 +232,10 @@
         if (!visited.add(implementationType)) {
           continue;
         }
-
         DexClass implementation = appView.definitionFor(implementationType);
         if (implementation != null) {
           getOrCreateReservedFieldNamingState(implementationType)
-              .includeReservations(namesToBeReservedInImplementsSubclasses);
+              .setInterfaceMinificationState(namesToBeReservedInImplementsSubclasses);
         }
       }
     }
diff --git a/src/main/java/com/android/tools/r8/naming/ReservedFieldNamingState.java b/src/main/java/com/android/tools/r8/naming/ReservedFieldNamingState.java
index 4e3e98c..258646e 100644
--- a/src/main/java/com/android/tools/r8/naming/ReservedFieldNamingState.java
+++ b/src/main/java/com/android/tools/r8/naming/ReservedFieldNamingState.java
@@ -14,16 +14,32 @@
 
 class ReservedFieldNamingState extends FieldNamingStateBase<InternalState> {
 
+  private ReservedFieldNamingState interfaceMinificationState = null;
+
   ReservedFieldNamingState(AppView<? extends AppInfoWithClassHierarchy> appView) {
     super(appView, new IdentityHashMap<>());
   }
 
   boolean isReserved(DexString name, DexType type) {
-    return getReservedByName(name, type) != null;
+    return getReservedByName(name, type) != null
+        || getReservedByNameInInterfaces(name, type) != null;
   }
 
-  DexString getReservedByName(DexString name, DexType type) {
-    InternalState internalState = getInternalState(type);
+  private DexString getReservedByName(DexString name, DexType type) {
+    DexString reservedByNameInState = getReservedByNameInState(getInternalState(type), name);
+    if (reservedByNameInState != null) {
+      return reservedByNameInState;
+    }
+    return getReservedByNameInInterfaces(name, type);
+  }
+
+  private DexString getReservedByNameInInterfaces(DexString name, DexType type) {
+    return interfaceMinificationState == null
+        ? null
+        : getReservedByNameInState(interfaceMinificationState.getInternalState(type), name);
+  }
+
+  private static DexString getReservedByNameInState(InternalState internalState, DexString name) {
     return internalState == null ? null : internalState.getReservedByName(name);
   }
 
@@ -35,12 +51,28 @@
     for (Map.Entry<DexType, InternalState> entry : reservedNames.internalStates.entrySet()) {
       getOrCreateInternalState(entry.getKey()).includeReservations(entry.getValue());
     }
+    includeInterfaceReservationState(reservedNames);
   }
 
   void includeReservationsFromBelow(ReservedFieldNamingState reservedNames) {
     for (Map.Entry<DexType, InternalState> entry : reservedNames.internalStates.entrySet()) {
       getOrCreateInternalState(entry.getKey()).includeReservationsFromBelow(entry.getValue());
     }
+    includeInterfaceReservationState(reservedNames);
+  }
+
+  private void includeInterfaceReservationState(ReservedFieldNamingState reservedNames) {
+    if (reservedNames.interfaceMinificationState != null) {
+      assert interfaceMinificationState == null
+          || interfaceMinificationState == reservedNames.interfaceMinificationState;
+      interfaceMinificationState = reservedNames.interfaceMinificationState;
+    }
+  }
+
+  void setInterfaceMinificationState(ReservedFieldNamingState namingState) {
+    assert namingState != null;
+    assert interfaceMinificationState == null;
+    this.interfaceMinificationState = namingState;
   }
 
   @Override