Always lens rewrite DexItemBasedConstString

Change-Id: Ib8868520d2295af6392b7a25ae469c6a6ba9ff6b
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 3c8c2fd..0d13e20 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -381,7 +381,7 @@
   }
 
   public void forEachStaticFieldMatching(
-      Predicate<DexEncodedField> predicate, Consumer<DexEncodedField> consumer) {
+      Predicate<? super DexEncodedField> predicate, Consumer<? super DexEncodedField> consumer) {
     staticFields(predicate).forEach(consumer);
   }
 
@@ -399,7 +399,7 @@
     return fieldCollection.staticFieldsAsList();
   }
 
-  public Iterable<DexEncodedField> staticFields(Predicate<DexEncodedField> predicate) {
+  public Iterable<DexEncodedField> staticFields(Predicate<? super DexEncodedField> predicate) {
     return IterableUtils.filter(staticFields(), predicate);
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/DexField.java b/src/main/java/com/android/tools/r8/graph/DexField.java
index bd110a3..3fd37ec 100644
--- a/src/main/java/com/android/tools/r8/graph/DexField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexField.java
@@ -22,6 +22,8 @@
 
 public class DexField extends DexMember<DexEncodedField, DexField> {
 
+  public static DexField[] EMPTY_ARRAY = new DexField[0];
+
   @SuppressWarnings("ReferenceEquality")
   public static boolean identical(DexField t1, DexField t2) {
     return t1 == t2;
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 6f5c0fe..68bc137 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -272,6 +272,11 @@
     forEachStaticField(field -> consumer.accept(new ProgramField(this, field)));
   }
 
+  public void forEachProgramStaticFieldMatching(
+      Predicate<? super DexEncodedField> predicate, Consumer<? super ProgramField> consumer) {
+    forEachStaticFieldMatching(predicate, field -> consumer.accept(new ProgramField(this, field)));
+  }
+
   public void forEachProgramStaticMethod(Consumer<? super ProgramMethod> consumer) {
     forEachProgramDirectMethodMatching(DexEncodedMethod::isStatic, consumer);
   }
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
index 1c8cdc9..18f1d1a 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.conversion.LirConverter;
 import com.android.tools.r8.ir.conversion.MethodConversionOptions;
 import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
+import com.android.tools.r8.naming.IdentifierMinifier;
 import com.android.tools.r8.profile.art.ArtProfileCompletenessChecker;
 import com.android.tools.r8.profile.rewriting.ProfileCollectionAdditions;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -183,24 +184,24 @@
     DexApplication newApplication = getNewApplication(mergedClasses);
     if (appView.enableWholeProgramOptimizations()) {
       // Prune keep info.
+      AppView<AppInfoWithClassHierarchy> appViewWithClassHierarchy = appView.withClassHierarchy();
       KeepInfoCollection keepInfo = appView.getKeepInfo();
       keepInfo.mutate(mutator -> mutator.removeKeepInfoForMergedClasses(prunedItems));
-      assert appView.hasClassHierarchy();
       if (mode.isInitial()) {
         appView.rewriteWithLensAndApplication(
             horizontalClassMergerGraphLens, newApplication.toDirect(), executorService, timing);
       } else {
         appView.rewriteWithLens(horizontalClassMergerGraphLens, executorService, timing);
-        LirConverter.rewriteLirWithLens(appView.withClassHierarchy(), timing, executorService);
+        LirConverter.rewriteLirWithLens(appViewWithClassHierarchy, timing, executorService);
+        new IdentifierMinifier(appViewWithClassHierarchy)
+            .rewriteDexItemBasedConstStringInStaticFields(executorService);
         if (appView.hasLiveness()) {
-          appView
-              .withLiveness()
-              .setAppInfo(appView.appInfoWithLiveness().rebuildWithLiveness(newApplication));
+          AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
+          appViewWithLiveness.setAppInfo(
+              appViewWithLiveness.appInfo().rebuildWithLiveness(newApplication));
         } else {
-          appView
-              .withClassHierarchy()
-              .setAppInfo(
-                  appView.appInfoWithClassHierarchy().rebuildWithClassHierarchy(newApplication));
+          appViewWithClassHierarchy.setAppInfo(
+              appViewWithClassHierarchy.appInfo().rebuildWithClassHierarchy(newApplication));
         }
         appView.clearCodeRewritings(executorService, timing);
       }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index 72e5dac..b4dbe9f 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -11,6 +11,7 @@
 import static com.android.tools.r8.ir.code.Opcodes.CONST_CLASS;
 import static com.android.tools.r8.ir.code.Opcodes.CONST_METHOD_HANDLE;
 import static com.android.tools.r8.ir.code.Opcodes.CONST_METHOD_TYPE;
+import static com.android.tools.r8.ir.code.Opcodes.DEX_ITEM_BASED_CONST_STRING;
 import static com.android.tools.r8.ir.code.Opcodes.INIT_CLASS;
 import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_GET;
 import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_OF;
@@ -74,6 +75,7 @@
 import com.android.tools.r8.ir.code.ConstClass;
 import com.android.tools.r8.ir.code.ConstMethodHandle;
 import com.android.tools.r8.ir.code.ConstMethodType;
+import com.android.tools.r8.ir.code.DexItemBasedConstString;
 import com.android.tools.r8.ir.code.FieldInstruction;
 import com.android.tools.r8.ir.code.FieldPut;
 import com.android.tools.r8.ir.code.IRCode;
@@ -281,6 +283,19 @@
       while (iterator.hasNext()) {
         Instruction current = iterator.next();
         switch (current.opcode()) {
+          case DEX_ITEM_BASED_CONST_STRING:
+            {
+              DexItemBasedConstString dexItemBasedConstString = current.asDexItemBasedConstString();
+              iterator.replaceCurrentInstruction(
+                  new DexItemBasedConstString(
+                      dexItemBasedConstString.outValue(),
+                      graphLens.getRenamedReference(dexItemBasedConstString.getItem(), codeLens),
+                      dexItemBasedConstString
+                          .getNameComputationInfo()
+                          .rewrittenWithLens(graphLens, codeLens)));
+            }
+            break;
+
           case INVOKE_CUSTOM:
             {
               InvokeCustom invokeCustom = current.asInvokeCustom();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryR8IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryR8IRConverter.java
index 436969d..663f27f 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryR8IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryR8IRConverter.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.ir.analysis.fieldaccess.TrivialFieldAccessReprocessor;
 import com.android.tools.r8.ir.optimize.info.MethodResolutionOptimizationInfoAnalysis;
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackDelayed;
+import com.android.tools.r8.naming.IdentifierMinifier;
 import com.android.tools.r8.optimize.argumentpropagation.ArgumentPropagator;
 import com.android.tools.r8.optimize.compose.ComposableOptimizationPass;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -108,6 +109,9 @@
       timing.end();
     }
 
+    // Rewrite DexItemBasedConstString static field values before updating code lens.
+    new IdentifierMinifier(appView).rewriteDexItemBasedConstStringInStaticFields(executorService);
+
     // The field access info collection is not maintained during IR processing.
     appView.appInfo().withLiveness().getFieldAccessInfoCollection().destroyAccessContexts();
 
diff --git a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
index 7fbec5b..6f68845 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.bytecodemetadata.BytecodeInstructionMetadata;
+import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.CatchHandlers;
@@ -248,6 +249,14 @@
 
     @Override
     public void internalLirConstantAcceptHashing(HashingVisitor visitor) {}
+
+    public NameComputationPayload rewrittenWithLens(GraphLens graphLens, GraphLens codeLens) {
+      NameComputationInfo<?> rewrittenNameComputationInfo =
+          nameComputationInfo.rewrittenWithLens(graphLens, codeLens);
+      return rewrittenNameComputationInfo != nameComputationInfo
+          ? new NameComputationPayload(rewrittenNameComputationInfo)
+          : this;
+    }
   }
 
   public static class RecordFieldValuesPayload extends InstructionPayload {
diff --git a/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java b/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java
index 3746ba5..26a4261 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java
@@ -15,6 +15,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexMethodHandle;
 import com.android.tools.r8.graph.DexProto;
+import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadataProvider;
@@ -32,8 +33,10 @@
 import com.android.tools.r8.ir.conversion.MethodProcessor;
 import com.android.tools.r8.ir.optimize.AffectedValues;
 import com.android.tools.r8.ir.optimize.DeadCodeRemover;
+import com.android.tools.r8.lightir.LirBuilder.NameComputationPayload;
 import com.android.tools.r8.lightir.LirBuilder.RecordFieldValuesPayload;
 import com.android.tools.r8.lightir.LirCode.TryCatchTable;
+import com.android.tools.r8.naming.dexitembasedstring.NameComputationInfo;
 import com.android.tools.r8.utils.ArrayUtils;
 import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.verticalclassmerging.VerticalClassMergerGraphLens;
@@ -93,6 +96,11 @@
     addRewrittenMapping(callSite, helper.rewriteCallSite(callSite, context));
   }
 
+  public void onNameComputationPayload(NameComputationPayload nameComputationPayload) {
+    addRewrittenMapping(
+        nameComputationPayload, nameComputationPayload.rewrittenWithLens(graphLens, codeLens));
+  }
+
   public void onMethodHandleReference(DexMethodHandle methodHandle) {
     addRewrittenMapping(
         methodHandle,
@@ -174,6 +182,12 @@
   }
 
   @Override
+  public void onDexItemBasedConstString(
+      DexReference item, NameComputationInfo<?> nameComputationInfo) {
+    addRewrittenMapping(item, graphLens.getRenamedReference(item, codeLens));
+  }
+
+  @Override
   public void onInstanceGet(DexField field, EV object) {
     onFieldGet(field);
   }
@@ -379,6 +393,7 @@
     // The code may need to be rewritten by the lens.
     // First pass scans just the constant pool to see if any types change or if there are any
     // fields/methods that need to be examined.
+    boolean hasDexItemBasedConstString = false;
     boolean hasFieldReference = false;
     boolean hasPotentialRewrittenMethod = false;
     for (LirConstant constant : code.getConstantPool()) {
@@ -391,6 +406,9 @@
         hasFieldReference = true;
       } else if (constant instanceof DexCallSite) {
         onCallSiteReference((DexCallSite) constant);
+      } else if (constant instanceof NameComputationPayload) {
+        onNameComputationPayload((NameComputationPayload) constant);
+        hasDexItemBasedConstString = true;
       } else if (constant instanceof DexMethodHandle) {
         onMethodHandleReference((DexMethodHandle) constant);
       } else if (constant instanceof DexProto) {
@@ -406,7 +424,9 @@
     // rewriting is instruction-sensitive (i.e., may be dependent on the invoke type).
     boolean hasPotentialNonTrivialFieldAccessRewriting =
         hasFieldReference && graphLens.isClassMergerLens();
-    if (hasPotentialNonTrivialFieldAccessRewriting || hasPotentialRewrittenMethod) {
+    if (hasDexItemBasedConstString
+        || hasPotentialNonTrivialFieldAccessRewriting
+        || hasPotentialRewrittenMethod) {
       for (LirInstructionView view : code) {
         view.accept(this);
         if (hasNonTrivialRewritings) {
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
index c425c1b..3986e50 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
@@ -10,10 +10,13 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexValue.DexItemBasedValueString;
 import com.android.tools.r8.graph.DexValue.DexValueString;
+import com.android.tools.r8.graph.ProgramField;
+import com.android.tools.r8.naming.dexitembasedstring.NameComputationInfo;
 import com.android.tools.r8.shaking.ProguardClassFilter;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.ThreadUtils;
@@ -25,12 +28,10 @@
 
   private final AppView<? extends AppInfoWithClassHierarchy> appView;
   private final ProguardClassFilter adaptClassStrings;
-  private final NamingLens lens;
 
   public IdentifierMinifier(AppView<? extends AppInfoWithClassHierarchy> appView) {
     this.appView = appView;
     this.adaptClassStrings = appView.options().getProguardConfiguration().getAdaptClassStrings();
-    this.lens = appView.getNamingLens();
   }
 
   public void run(ExecutorService executorService) throws ExecutionException {
@@ -93,25 +94,50 @@
       throws ExecutionException {
     ThreadUtils.processItems(
         appView.appInfo().classes(),
-        clazz -> {
-          // Some const strings could be moved to field's static value (from <clinit>).
-          for (DexEncodedField field : clazz.staticFields()) {
-            replaceDexItemBasedConstStringInStaticField(field);
-          }
-        },
+        clazz ->
+            clazz.forEachProgramStaticFieldMatching(
+                IdentifierMinifier::hasExplicitStaticDexItemBasedValueString,
+                this::replaceDexItemBasedConstStringInStaticField),
         appView.options().getThreadingModule(),
         executorService);
   }
 
-  private void replaceDexItemBasedConstStringInStaticField(DexEncodedField field) {
-    assert field.isStatic();
-    DexItemBasedValueString staticValue = field.getStaticValue().asDexItemBasedValueString();
-    if (staticValue != null) {
-      DexString replacement =
-          staticValue
-              .getNameComputationInfo()
-              .computeNameFor(staticValue.getValue(), appView, appView.graphLens(), lens);
-      field.setStaticValue(new DexValueString(replacement));
-    }
+  private void replaceDexItemBasedConstStringInStaticField(ProgramField field) {
+    DexItemBasedValueString staticValue =
+        field.getDefinition().getStaticValue().asDexItemBasedValueString();
+    DexString replacement =
+        staticValue.getNameComputationInfo().computeNameFor(staticValue.getValue(), appView);
+    field.getDefinition().setStaticValue(new DexValueString(replacement));
+  }
+
+  public void rewriteDexItemBasedConstStringInStaticFields(ExecutorService executorService)
+      throws ExecutionException {
+    ThreadUtils.processItems(
+        appView.appInfo().classes(),
+        clazz ->
+            clazz.forEachProgramStaticFieldMatching(
+                IdentifierMinifier::hasExplicitStaticDexItemBasedValueString,
+                this::rewriteDexItemBasedConstStringInStaticFields),
+        appView.options().getThreadingModule(),
+        executorService);
+  }
+
+  private void rewriteDexItemBasedConstStringInStaticFields(ProgramField field) {
+    DexItemBasedValueString staticValue =
+        field.getDefinition().getStaticValue().asDexItemBasedValueString();
+    DexReference rewrittenReference =
+        appView.graphLens().getRenamedReference(staticValue.getValue(), appView.codeLens());
+    NameComputationInfo<?> rewrittenNameComputationInfo =
+        staticValue
+            .getNameComputationInfo()
+            .rewrittenWithLens(appView.graphLens(), appView.codeLens());
+    field
+        .getDefinition()
+        .setStaticValue(
+            new DexItemBasedValueString(rewrittenReference, rewrittenNameComputationInfo));
+  }
+
+  private static boolean hasExplicitStaticDexItemBasedValueString(DexEncodedField field) {
+    return field.hasExplicitStaticValue() && field.getStaticValue().isDexItemBasedValueString();
   }
 }
diff --git a/src/main/java/com/android/tools/r8/naming/RecordInvokeDynamicInvokeCustomRewriter.java b/src/main/java/com/android/tools/r8/naming/RecordInvokeDynamicInvokeCustomRewriter.java
index 6ff9638..389f9d9 100644
--- a/src/main/java/com/android/tools/r8/naming/RecordInvokeDynamicInvokeCustomRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/RecordInvokeDynamicInvokeCustomRewriter.java
@@ -85,7 +85,6 @@
             .internalComputeNameFor(
                 recordInvokeDynamic.getRecordType(),
                 appView,
-                appView.graphLens(),
                 appView.getNamingLens());
     DexField[] newFields =
         recordRewriter.computePresentFields(appView.graphLens(), recordInvokeDynamic);
diff --git a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/ClassNameComputationInfo.java b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/ClassNameComputationInfo.java
index 000e8d3..23b0f29 100644
--- a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/ClassNameComputationInfo.java
+++ b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/ClassNameComputationInfo.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import com.android.tools.r8.utils.structural.HashingVisitor;
@@ -204,6 +205,11 @@
   }
 
   @Override
+  public NameComputationInfo<DexType> rewrittenWithLens(GraphLens graphLens, GraphLens codeLens) {
+    return this;
+  }
+
+  @Override
   @SuppressWarnings("EqualsGetClass")
   public boolean equals(Object other) {
     if (getClass() != other.getClass()) {
diff --git a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/FieldNameComputationInfo.java b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/FieldNameComputationInfo.java
index a99056e..594dfb6 100644
--- a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/FieldNameComputationInfo.java
+++ b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/FieldNameComputationInfo.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import com.android.tools.r8.utils.structural.HashingVisitor;
@@ -65,4 +66,9 @@
   public FieldNameComputationInfo asFieldNameComputationInfo() {
     return this;
   }
+
+  @Override
+  public NameComputationInfo<DexField> rewrittenWithLens(GraphLens graphLens, GraphLens codeLens) {
+    return this;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/NameComputationInfo.java b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/NameComputationInfo.java
index a6fdb57..9e30fef 100644
--- a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/NameComputationInfo.java
+++ b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/NameComputationInfo.java
@@ -25,34 +25,29 @@
 
   public final DexString computeNameFor(
       DexReference reference, AppView<? extends AppInfoWithClassHierarchy> appView) {
-    return computeNameFor(reference, appView, appView.graphLens(), appView.getNamingLens());
+    return computeNameFor(reference, appView, appView.getNamingLens());
   }
 
-  public final DexString computeNameFor(
-      DexReference reference,
-      DexDefinitionSupplier definitions,
-      GraphLens graphLens,
-      NamingLens namingLens) {
-    GraphLens nameLens = GraphLens.getIdentityLens();
-    DexReference rewritten = graphLens.getRenamedReference(reference, nameLens);
+  private DexString computeNameFor(
+      DexReference reference, DexDefinitionSupplier definitions, NamingLens namingLens) {
     if (needsToComputeName()) {
       if (isFieldNameComputationInfo()) {
         return asFieldNameComputationInfo()
-            .internalComputeNameFor(rewritten.asDexField(), definitions, namingLens);
+            .internalComputeNameFor(reference.asDexField(), definitions, namingLens);
       }
       if (isClassNameComputationInfo()) {
         return asClassNameComputationInfo()
-            .internalComputeNameFor(rewritten.asDexType(), definitions, namingLens);
+            .internalComputeNameFor(reference.asDexType(), definitions, namingLens);
       }
       if (isRecordFieldNamesComputationInfo()) {
         return asRecordFieldNamesComputationInfo()
-            .internalComputeNameFor(rewritten.asDexType(), definitions, graphLens, namingLens);
+            .internalComputeNameFor(reference.asDexType(), definitions, namingLens);
       }
     }
-    return namingLens.lookupName(rewritten, definitions.dexItemFactory());
+    return namingLens.lookupName(reference, definitions.dexItemFactory());
   }
 
-  abstract DexString internalComputeNameFor(
+  public abstract DexString internalComputeNameFor(
       T reference, DexDefinitionSupplier definitions, NamingLens namingLens);
 
   abstract Order getOrder();
@@ -101,4 +96,6 @@
   public RecordFieldNamesComputationInfo asRecordFieldNamesComputationInfo() {
     return null;
   }
+
+  public abstract NameComputationInfo<T> rewrittenWithLens(GraphLens graphLens, GraphLens codeLens);
 }
diff --git a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/RecordFieldNamesComputationInfo.java b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/RecordFieldNamesComputationInfo.java
index 4fc282f..9eabb5f 100644
--- a/src/main/java/com/android/tools/r8/naming/dexitembasedstring/RecordFieldNamesComputationInfo.java
+++ b/src/main/java/com/android/tools/r8/naming/dexitembasedstring/RecordFieldNamesComputationInfo.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.naming.dexitembasedstring;
 
-import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedField;
@@ -14,6 +13,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.utils.ArrayUtils;
 import com.android.tools.r8.utils.ComparatorUtils;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
@@ -85,9 +85,8 @@
     public DexString internalComputeNameFor(
         DexType type,
         DexDefinitionSupplier definitions,
-        GraphLens graphLens,
         NamingLens namingLens) {
-      return internalComputeNameFor(type, definitions, graphLens, i -> fieldNames[i]);
+      return internalComputeNameFor(type, definitions, i -> fieldNames[i]);
     }
 
     @Override
@@ -115,6 +114,16 @@
     void internalAcceptHashing(HashingVisitor visitor) {
       StructuralItem.super.acceptHashing(visitor);
     }
+
+    @Override
+    public NameComputationInfo<DexType> rewrittenWithLens(GraphLens graphLens, GraphLens codeLens) {
+      DexField[] rewrittenFields =
+          ArrayUtils.map(
+              fields, field -> graphLens.lookupField(field, codeLens), DexField.EMPTY_ARRAY);
+      return rewrittenFields != fields
+          ? new MissMatchingRecordFieldNamesComputationInfo(fieldNames, rewrittenFields)
+          : this;
+    }
   }
 
   private static class MatchingRecordFieldNamesComputationInfo
@@ -134,18 +143,11 @@
     public DexString internalComputeNameFor(
         DexType type,
         DexDefinitionSupplier definitions,
-        GraphLens graphLens,
         NamingLens namingLens) {
       return internalComputeNameFor(
           type,
           definitions,
-          graphLens,
-          i ->
-              namingLens
-                  .lookupField(
-                      graphLens.getRenamedFieldSignature(fields[i]), definitions.dexItemFactory())
-                  .name
-                  .toString());
+          i -> namingLens.lookupField(fields[i], definitions.dexItemFactory()).name.toString());
     }
 
     @Override
@@ -173,6 +175,16 @@
     void internalAcceptHashing(HashingVisitor visitor) {
       StructuralItem.super.acceptHashing(visitor);
     }
+
+    @Override
+    public NameComputationInfo<DexType> rewrittenWithLens(GraphLens graphLens, GraphLens codeLens) {
+      DexField[] rewrittenFields =
+          ArrayUtils.map(
+              fields, field -> graphLens.lookupField(field, codeLens), DexField.EMPTY_ARRAY);
+      return rewrittenFields != fields
+          ? new MatchingRecordFieldNamesComputationInfo(rewrittenFields)
+          : this;
+    }
   }
 
   static DexString dexStringFromFieldNames(List<String> fieldNames, DexItemFactory factory) {
@@ -204,14 +216,12 @@
   public DexString internalComputeNameFor(
       DexType type,
       DexDefinitionSupplier definitions,
-      GraphLens graphLens,
       IntFunction<String> nameSupplier) {
     DexClass recordClass = definitions.contextIndependentDefinitionFor(type);
     assert recordClass != null;
     List<String> names = new ArrayList<>(fields.length);
     for (int i = 0; i < fields.length; i++) {
-      DexEncodedField recordField =
-          recordClass.lookupInstanceField(graphLens.getRenamedFieldSignature(fields[i]));
+      DexEncodedField recordField = recordClass.lookupInstanceField(fields[i]);
       if (recordField != null) {
         names.add(nameSupplier.apply(i));
       }
@@ -220,15 +230,6 @@
   }
 
   @Override
-  DexString internalComputeNameFor(
-      DexType reference, DexDefinitionSupplier definitions, NamingLens namingLens) {
-    throw new Unreachable();
-  }
-
-  public abstract DexString internalComputeNameFor(
-      DexType type, DexDefinitionSupplier definitions, GraphLens graphLens, NamingLens namingLens);
-
-  @Override
   public boolean needsToComputeName() {
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/repackaging/Repackaging.java b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
index d6bc517..2334808 100644
--- a/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
+++ b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
@@ -21,6 +21,7 @@
 import com.android.tools.r8.graph.ProgramPackageCollection;
 import com.android.tools.r8.graph.SortedProgramPackageCollection;
 import com.android.tools.r8.graph.fixup.TreeFixerBase;
+import com.android.tools.r8.naming.IdentifierMinifier;
 import com.android.tools.r8.naming.Minifier.MinificationPackageNamingStrategy;
 import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
 import com.android.tools.r8.repackaging.RepackagingLens.Builder;
@@ -78,6 +79,7 @@
       appView.rewriteWithLensAndApplication(lens, appBuilder.build(), executorService, timing);
       appView.testing().repackagingLensConsumer.accept(appView.dexItemFactory(), lens);
       new GenericSignatureRewriter(appView).run(appView.appInfo().classes(), executorService);
+      new IdentifierMinifier(appView).rewriteDexItemBasedConstStringInStaticFields(executorService);
     }
     appView.notifyOptimizationFinishedForTesting();
     timing.end();
@@ -125,14 +127,12 @@
     return true;
   }
 
-  @SuppressWarnings("ReferenceEquality")
   private RepackagingLens repackageClasses(
       DirectMappedDexApplication.Builder appBuilder, ExecutorService executorService)
       throws ExecutionException {
     if (proguardConfiguration.getPackageObfuscationMode().isNone()) {
       return null;
     }
-
     BiMap<DexType, DexType> mappings = HashBiMap.create();
     Map<String, String> packageMappings = new HashMap<>();
     Set<String> seenPackageDescriptors = new HashSet<>();
@@ -141,7 +141,7 @@
     processPackagesInDesiredLocation(packages, mappings, packageMappings, seenPackageDescriptors);
     processRemainingPackages(
         packages, mappings, packageMappings, seenPackageDescriptors, executorService);
-    mappings.entrySet().removeIf(entry -> entry.getKey() == entry.getValue());
+    mappings.entrySet().removeIf(entry -> entry.getKey().isIdenticalTo(entry.getValue()));
     if (mappings.isEmpty()) {
       return null;
     }
diff --git a/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMerger.java
index 5d13246..67bc83a 100644
--- a/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMerger.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.ir.conversion.LirConverter;
+import com.android.tools.r8.naming.IdentifierMinifier;
 import com.android.tools.r8.optimize.argumentpropagation.utils.ProgramClassesBidirectedGraph;
 import com.android.tools.r8.profile.art.ArtProfileCompletenessChecker;
 import com.android.tools.r8.profile.rewriting.ProfileCollectionAdditions;
@@ -237,6 +238,7 @@
       return;
     }
     LirConverter.rewriteLirWithLens(appView, timing, executorService);
+    new IdentifierMinifier(appView).rewriteDexItemBasedConstStringInStaticFields(executorService);
   }
 
   private void updateArtProfiles(