Revert "Use definition values where possible when accessing keep info."

This reverts commit dc57639d4b195805f102df1c7a4021c37bd02708.

Reason for revert: test failures

Change-Id: I9a3743b16c8cbbb09affa8caf09fdcc930b2da13
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index 38bf4ee..82e4b48 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -392,7 +392,8 @@
       return false;
     }
     // If tree shaking, only keep annotations on kept methods.
-    if (appView.appInfo().hasLiveness() && !appView.appInfo().withLiveness().isPinned(method)) {
+    if (appView.appInfo().hasLiveness()
+        && !appView.appInfo().withLiveness().isPinned(method.getReference())) {
       return false;
     }
     return true;
@@ -773,7 +774,7 @@
     // The enqueuer might build IR to trace reflective behaviour. At that point liveness is not
     // known, so be conservative with collection parameter name information.
     if (appView.appInfo().hasLiveness()
-        && !appView.appInfo().withLiveness().isPinned(encodedMethod)) {
+        && !appView.appInfo().withLiveness().isPinned(encodedMethod.getReference())) {
       return DexEncodedMethod.NO_PARAMETER_INFO;
     }
 
diff --git a/src/main/java/com/android/tools/r8/graph/EnclosingMethodAttribute.java b/src/main/java/com/android/tools/r8/graph/EnclosingMethodAttribute.java
index 7d6b3a2..4062f96 100644
--- a/src/main/java/com/android/tools/r8/graph/EnclosingMethodAttribute.java
+++ b/src/main/java/com/android/tools/r8/graph/EnclosingMethodAttribute.java
@@ -101,10 +101,10 @@
 
   public boolean isEnclosingPinned(AppView<AppInfoWithLiveness> appView) {
     if (enclosingMethod != null) {
-      return appView.appInfo().isPinnedWithDefinitionLookup(enclosingMethod);
+      return appView.appInfo().isPinned(enclosingMethod);
     }
     if (enclosingClass != null) {
-      return appView.appInfo().isPinnedWithDefinitionLookup(enclosingClass);
+      return appView.appInfo().isPinned(enclosingClass);
     }
     return false;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java b/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java
index d849002..0d19daa 100644
--- a/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java
@@ -35,7 +35,7 @@
       // If `subject` is kept, then it is instantiated by reflection, which means that the analysis
       // has not seen all allocation sites. In that case, we conservatively return false.
       AppInfoWithClassHierarchy appInfo = appView.appInfo();
-      if (appInfo.hasLiveness() && appInfo.withLiveness().isPinned(subject)) {
+      if (appInfo.hasLiveness() && appInfo.withLiveness().isPinned(subject.type)) {
         return false;
       }
 
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java
index 33ab115..9af0407 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java
@@ -275,8 +275,7 @@
     return root.isDefinedByInstructionSatisfying(Instruction::isConstClass)
         && !appView
             .getKeepInfo()
-            .isPinnedWithDefinitionLookup(
-                root.getDefinition().asConstClass().getType(), options, appView);
+            .isPinned(root.getDefinition().asConstClass().getType(), appView, options);
   }
 
   private boolean addLogicalBinopValueToValueGraph(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
index 66ef64e..ef1b959 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
@@ -332,7 +332,7 @@
     }
 
     if (appView.enableWholeProgramOptimizations()
-        && appView.withLiveness().appInfo().isMinificationAllowed(clazz)) {
+        && appView.withLiveness().appInfo().isMinificationAllowed(holder)) {
       if (invokedMethod == dexItemFactory.classMethods.getName) {
         return new DexItemBasedValueString(holder, ClassNameComputationInfo.getInstance(NAME));
       }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
index 12030bf..753b6ce 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
@@ -113,7 +113,7 @@
       ConstClass constClass = argument.getConstInstruction().asConstClass();
 
       // Check that the service is not kept.
-      if (appView.appInfo().isPinnedWithDefinitionLookup(constClass.getValue())) {
+      if (appView.appInfo().isPinned(constClass.getValue())) {
         continue;
       }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index ed89e93..c02b953 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -235,7 +235,7 @@
       IRCode code,
       OptimizationFeedback feedback,
       InstanceFieldInitializationInfoCollection instanceFieldInitializationInfos) {
-    assert !appView.appInfo().isPinned(method);
+    assert !appView.appInfo().isPinned(method.getReference());
 
     if (!method.isInstanceInitializer()) {
       return;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
index 09c8163..1d0e301 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
@@ -350,7 +350,7 @@
       }
       boolean mayBeRenamed =
           appView.enableWholeProgramOptimizations()
-              && appView.withLiveness().appInfo().isMinificationAllowed(holder);
+              && appView.withLiveness().appInfo().isMinificationAllowed(holder.type);
       // b/120138731: Filter out escaping uses. In such case, the result of this optimization will
       // be stored somewhere, which can lead to a regression if the corresponding class is in a deep
       // package hierarchy. For local cases, it is likely a one-time computation, but make sure the
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/typechecks/CheckCastAndInstanceOfMethodSpecialization.java b/src/main/java/com/android/tools/r8/ir/optimize/typechecks/CheckCastAndInstanceOfMethodSpecialization.java
index 4d3075c..d2ec4d6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/typechecks/CheckCastAndInstanceOfMethodSpecialization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/typechecks/CheckCastAndInstanceOfMethodSpecialization.java
@@ -119,8 +119,8 @@
 
     // Verify that the methods are not pinned. They shouldn't be, since we've computed an abstract
     // return value for both.
-    assert !appView.appInfo().isPinned(method);
-    assert !appView.appInfo().isPinned(parentMethod);
+    assert !appView.appInfo().isPinned(method.getReference());
+    assert !appView.appInfo().isPinned(parentMethod.getReference());
 
     if (appView
         .appInfo()
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
index c06aea8..415995e 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
@@ -110,7 +110,7 @@
           if (oldMeta == null
               || kotlinInfo == getNoKotlinInfo()
               || (appView.appInfo().hasLiveness()
-                  && !appView.withLiveness().appInfo().isPinned(clazz))) {
+                  && !appView.withLiveness().appInfo().isPinned(clazz.type))) {
             // Remove @Metadata in DexAnnotation when there is no kotlin info and the type is not
             // missing.
             if (oldMeta != null) {
diff --git a/src/main/java/com/android/tools/r8/naming/Minifier.java b/src/main/java/com/android/tools/r8/naming/Minifier.java
index 52fee79..00c0d9f 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -312,7 +312,7 @@
       if (!allowMemberRenaming(holder)
           || holder.accessFlags.isAnnotation()
           || method.accessFlags.isConstructor()
-          || !appView.appInfo().isMinificationAllowed(method)) {
+          || !appView.appInfo().isMinificationAllowed(method.getReference())) {
         return method.getReference().name;
       }
       if (desugaredLibraryRenaming
@@ -327,7 +327,8 @@
 
     @Override
     public DexString getReservedName(DexEncodedField field, DexClass holder) {
-      if (holder.isLibraryClass() || !appView.appInfo().isMinificationAllowed(field)) {
+      if (holder.isLibraryClass()
+          || !appView.appInfo().isMinificationAllowed(field.getReference())) {
         return field.getReference().name;
       }
       return null;
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
index 3c128fb..6637177 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
@@ -408,7 +408,7 @@
         return mappings.get(type);
       }
       if (clazz.isProgramClass()) {
-        if (appView.appInfo().isMinificationAllowed(clazz.asProgramClass())) {
+        if (appView.appInfo().isMinificationAllowed(type)) {
           return mappings.get(type);
         }
         // TODO(b/136694827): Report a warning here if in the mapping since the user may find this
@@ -454,7 +454,7 @@
         nextName = reservedName;
       } else {
         assert !mappedNames.containsKey(reference);
-        assert appView.appInfo().isMinificationAllowed(method);
+        assert appView.appInfo().isMinificationAllowed(reference);
         nextName = super.next(method, internalState, isAvailable);
       }
       assert nextName == reference.name || !method.isInitializer();
@@ -477,7 +477,7 @@
         return reservedName;
       }
       assert !mappedNames.containsKey(reference);
-      assert appView.appInfo().isMinificationAllowed(field);
+      assert appView.appInfo().isMinificationAllowed(reference);
       return super.next(field, internalState, isAvailable);
     }
 
diff --git a/src/main/java/com/android/tools/r8/optimize/AccessModifier.java b/src/main/java/com/android/tools/r8/optimize/AccessModifier.java
index b2d577c..c1ee380 100644
--- a/src/main/java/com/android/tools/r8/optimize/AccessModifier.java
+++ b/src/main/java/com/android/tools/r8/optimize/AccessModifier.java
@@ -223,7 +223,7 @@
     boolean wasSeen = methodPoolCollection.markIfNotSeen(method.getHolder(), method.getReference());
     if (wasSeen) {
       // We can't do anything further because even renaming is not allowed due to the keep rule.
-      if (!appView.appInfo().isMinificationAllowed(method)) {
+      if (!appView.appInfo().isMinificationAllowed(method.getReference())) {
         return false;
       }
       // TODO(b/111118390): Renaming will enable more private instance methods to be publicized.
diff --git a/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java b/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java
index 7c07af0..e6df4a0 100644
--- a/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java
+++ b/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java
@@ -154,8 +154,7 @@
     // If the method is defined on the parent class, we cannot hoist the bridge.
     // TODO(b/153147967): If the declared method is abstract, we could replace it by the bridge.
     //  Add a test.
-    ProgramMethod programMethod = clazz.lookupProgramMethod(method);
-    if (programMethod != null) {
+    if (clazz.lookupMethod(method) != null) {
       return;
     }
 
@@ -280,7 +279,7 @@
 
     // Remove all of the bridges in the eligible subclasses.
     for (DexProgramClass subclass : eligibleSubclasses) {
-      assert !appView.appInfo().isPinned(programMethod);
+      assert !appView.appInfo().isPinned(method);
       DexEncodedMethod removed = subclass.removeMethod(method);
       assert removed != null;
     }
diff --git a/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java b/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java
index edfa788..e0c7f83 100644
--- a/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java
@@ -6,14 +6,13 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.SubtypingInfo;
 import com.android.tools.r8.logging.Log;
 import com.android.tools.r8.shaking.ScopedDexMethodSet.AddMethodIfMoreVisibleResult;
-import java.util.HashSet;
-import java.util.Set;
+import com.android.tools.r8.utils.IterableUtils;
+import com.android.tools.r8.utils.ListUtils;
+import java.util.List;
 
 /**
  * Removes abstract methods if they only shadow methods of the same signature in a superclass.
@@ -44,38 +43,39 @@
     DexClass holder = appView.definitionFor(type);
     scope = scope.newNestedScope();
     if (holder != null && holder.isProgramClass()) {
-      processMethods(holder.asProgramClass());
+      DexEncodedMethod[] newVirtualMethods =
+          processMethods(IterableUtils.ensureUnmodifiableList(holder.virtualMethods()));
+      if (newVirtualMethods != null) {
+        holder.setVirtualMethods(newVirtualMethods);
+      }
     }
     // TODO(b/154881041): Does this need the full subtype hierarchy of referenced types!?
     subtypingInfo.forAllImmediateExtendsSubtypes(type, this::processClass);
     scope = scope.getParent();
   }
 
-  private void processMethods(DexProgramClass clazz) {
-    Set<DexEncodedMethod> toRemove = null;
-    for (ProgramMethod method : clazz.virtualProgramMethods()) {
-      if (!isNonAbstractPinnedOrWideningVisibility(method)) {
-        if (toRemove == null) {
-          toRemove = new HashSet<>();
-        }
-        toRemove.add(method.getDefinition());
-      }
+  private DexEncodedMethod[] processMethods(List<DexEncodedMethod> virtualMethods) {
+    if (virtualMethods == null) {
+      return null;
     }
-    if (toRemove != null) {
-      clazz.getMethodCollection().removeMethods(toRemove);
-    }
+    // Removal of abstract methods is rare, ListUtils.filterOrElse does no copying if nothing is
+    // filtered out.
+    List<DexEncodedMethod> filteredMethods =
+        ListUtils.filterOrElse(virtualMethods, this::isNonAbstractPinnedOrWideningVisibility);
+    return filteredMethods == virtualMethods
+        ? null
+        : filteredMethods.toArray(DexEncodedMethod.EMPTY_ARRAY);
   }
 
-  private boolean isNonAbstractPinnedOrWideningVisibility(ProgramMethod method) {
-    if (!method.getAccessFlags().isAbstract()) {
+  private boolean isNonAbstractPinnedOrWideningVisibility(DexEncodedMethod method) {
+    if (!method.accessFlags.isAbstract()) {
       return true;
     }
     // Check if the method widens visibility. Adding to the scope mutates it.
-    if (scope.addMethodIfMoreVisible(method.getDefinition())
-        != AddMethodIfMoreVisibleResult.NOT_ADDED) {
+    if (scope.addMethodIfMoreVisible(method) != AddMethodIfMoreVisibleResult.NOT_ADDED) {
       return true;
     }
-    if (appView.appInfo().isPinned(method)) {
+    if (appView.appInfo().isPinned(method.getReference())) {
       return true;
     }
     // We will filter the method out since it is not pinned.
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 6bb528e..387186f 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -918,7 +918,7 @@
       assert info.isRead() || info.isWritten();
       return true;
     }
-    assert getKeepInfo().getFieldInfo(field, this).isShrinkingAllowed(options());
+    assert getKeepInfo().getFieldInfo(reference, this).isShrinkingAllowed(options());
     return false;
   }
 
@@ -929,7 +929,7 @@
     if (info != null && info.isRead()) {
       return true;
     }
-    if (isPinned(encodedField)) {
+    if (isPinned(field)) {
       return true;
     }
     // For library classes we don't know whether a field is read.
@@ -938,7 +938,8 @@
 
   public boolean isFieldWritten(DexEncodedField encodedField) {
     assert checkIfObsolete();
-    return isFieldWrittenByFieldPutInstruction(encodedField) || isPinned(encodedField);
+    return isFieldWrittenByFieldPutInstruction(encodedField)
+        || isPinned(encodedField.getReference());
   }
 
   public boolean isFieldWrittenByFieldPutInstruction(DexEncodedField encodedField) {
@@ -956,7 +957,7 @@
   public boolean isFieldOnlyWrittenInMethod(DexEncodedField field, DexEncodedMethod method) {
     assert checkIfObsolete();
     assert isFieldWritten(field) : "Expected field `" + field.toSourceString() + "` to be written";
-    if (isPinned(field)) {
+    if (isPinned(field.getReference())) {
       return false;
     }
     return isFieldOnlyWrittenInMethodIgnoringPinning(field, method);
@@ -979,7 +980,7 @@
   public boolean isInstanceFieldWrittenOnlyInInstanceInitializers(DexEncodedField field) {
     assert checkIfObsolete();
     assert isFieldWritten(field) : "Expected field `" + field.toSourceString() + "` to be written";
-    if (isPinned(field)) {
+    if (isPinned(field.getReference())) {
       return false;
     }
     FieldAccessInfo fieldAccessInfo = getFieldAccessInfoCollection().get(field.getReference());
@@ -1026,7 +1027,7 @@
     if (neverPropagateValue.contains(field)) {
       return false;
     }
-    if (isPinnedWithDefinitionLookup(field) && !field.getType().isAlwaysNull(appView)) {
+    if (isPinned(field) && !field.getType().isAlwaysNull(appView)) {
       return false;
     }
     return true;
@@ -1038,7 +1039,7 @@
       return false;
     }
     if (!method.getReturnType().isAlwaysNull(appView)
-        && !getKeepInfo().getMethodInfoSlow(method, this).isOptimizationAllowed(options())) {
+        && !getKeepInfo().getMethodInfo(method, this).isOptimizationAllowed(options())) {
       return false;
     }
     return true;
@@ -1070,29 +1071,18 @@
     return !isPinned(clazz) && !neverClassInline.contains(clazz.getType());
   }
 
-  public boolean isMinificationAllowed(DexProgramClass clazz) {
+  public boolean isMinificationAllowed(DexReference reference) {
     return options().isMinificationEnabled()
-        && keepInfo.getInfo(clazz).isMinificationAllowed(options());
-  }
-
-  public boolean isMinificationAllowed(ProgramDefinition definition) {
-    return options().isMinificationEnabled()
-        && keepInfo.getInfo(definition).isMinificationAllowed(options());
-  }
-
-  public boolean isMinificationAllowed(DexDefinition definition) {
-    return options().isMinificationEnabled()
-        && keepInfo.getInfo(definition, this).isMinificationAllowed(options());
-  }
-
-  public boolean isMinificationAllowed(DexType reference) {
-    return options().isMinificationEnabled()
-        && keepInfo.getClassInfo(reference, this).isMinificationAllowed(options());
+        && keepInfo.getInfo(reference, this).isMinificationAllowed(options());
   }
 
   public boolean isAccessModificationAllowed(ProgramDefinition definition) {
+    return isAccessModificationAllowed(definition.getReference());
+  }
+
+  public boolean isAccessModificationAllowed(DexReference reference) {
     assert options().getProguardConfiguration().isAccessModificationAllowed();
-    return keepInfo.getInfo(definition).isAccessModificationAllowed(options());
+    return keepInfo.getInfo(reference, this).isAccessModificationAllowed(options());
   }
 
   public boolean isRepackagingAllowed(DexProgramClass clazz, AppView<?> appView) {
@@ -1109,30 +1099,27 @@
     return applyMappingSeedMapper == null || !applyMappingSeedMapper.hasMapping(clazz.type);
   }
 
-  public boolean isPinnedWithDefinitionLookup(DexReference reference) {
+  public boolean isPinned(DexReference reference) {
     assert checkIfObsolete();
-    return keepInfo.isPinnedWithDefinitionLookup(reference, options(), this);
+    return keepInfo.isPinned(reference, this, options());
   }
 
   public boolean isPinned(DexDefinition definition) {
-    return keepInfo.isPinned(definition, options(), this);
-  }
-
-  public boolean isPinned(DexProgramClass clazz) {
-    return keepInfo.isPinned(clazz, options());
-  }
-
-  public boolean isPinned(ProgramDefinition definition) {
     assert definition != null;
-    return keepInfo.isPinned(definition, options());
+    return isPinned(definition.getReference());
+  }
+
+  public boolean isPinned(DexClassAndMember<?, ?> member) {
+    assert member != null;
+    return isPinned(member.getReference());
   }
 
   public boolean hasPinnedInstanceInitializer(DexType type) {
     assert type.isClassType();
     DexProgramClass clazz = asProgramClassOrNull(definitionFor(type));
     if (clazz != null) {
-      for (ProgramMethod method : clazz.directProgramMethods()) {
-        if (method.getDefinition().isInstanceInitializer() && isPinned(method)) {
+      for (DexEncodedMethod method : clazz.directMethods()) {
+        if (method.isInstanceInitializer() && isPinned(method.getReference())) {
           return true;
         }
       }
@@ -1508,11 +1495,11 @@
   }
 
   private boolean isInstantiatedOrPinned(DexProgramClass clazz) {
-    return isInstantiatedDirectly(clazz) || isPinned(clazz) || isInstantiatedInterface(clazz);
+    return isInstantiatedDirectly(clazz) || isPinned(clazz.type) || isInstantiatedInterface(clazz);
   }
 
   public boolean isPinnedNotProgramOrLibraryOverride(DexDefinition definition) {
-    if (isPinned(definition)) {
+    if (isPinned(definition.getReference())) {
       return true;
     }
     if (definition.isDexEncodedMethod()) {
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 8684cb4..59b7ae3 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -2918,7 +2918,8 @@
                                         instantiation.apply(subTypeConsumer, lambdaConsumer);
                                       },
                                       definition ->
-                                          keepInfo.isPinned(definition, options, appInfo));
+                                          keepInfo.isPinned(
+                                              definition.getReference(), appInfo, options));
                               lookupResult.forEach(
                                   target ->
                                       markVirtualDispatchTargetAsLive(
@@ -3421,7 +3422,7 @@
                       (type, subTypeConsumer, lambdaConsumer) ->
                           objectAllocationInfoCollection.forEachInstantiatedSubType(
                               type, subTypeConsumer, lambdaConsumer, appInfo),
-                      definition -> keepInfo.isPinned(definition, options, appInfo))
+                      definition -> keepInfo.isPinned(definition.getReference(), appInfo, options))
                   .forEach(
                       target ->
                           markVirtualDispatchTargetAsLive(
@@ -4327,7 +4328,7 @@
         (methodReference, companionReference) -> {
           ProgramMethod companion = appView.definitionFor(companionReference).asProgramMethod();
           KeepMethodInfo.Joiner minimumKeepInfoForCompanion =
-              keepInfo.getMethodInfoSlow(methodReference, appInfo).joiner();
+              keepInfo.getMethodInfo(methodReference, appInfo).joiner();
           KeepMethodInfo.Joiner extraMinimumKeepInfoForCompanion =
               dependentMinimumKeepInfo
                   .getUnconditionalMinimumKeepInfoOrDefault(MinimumKeepInfoCollection.empty())
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
index 8a60e7a..c78e39a 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
@@ -9,8 +9,6 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexDefinition;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMember;
@@ -94,14 +92,9 @@
     return getMethodInfo(member.asDexEncodedMethod(), holder);
   }
 
-  public final KeepClassInfo getClassInfo(DexClass clazz) {
-    return clazz.isProgramClass()
-        ? getClassInfo(clazz.asProgramClass())
-        : keepInfoForNonProgramClass();
-  }
-
   public final KeepClassInfo getClassInfo(DexType type, DexDefinitionSupplier definitions) {
-    return getClassInfo(definitions.contextIndependentDefinitionFor(type));
+    DexProgramClass clazz = asProgramClassOrNull(definitions.definitionFor(type));
+    return clazz == null ? keepInfoForNonProgramClass() : getClassInfo(clazz);
   }
 
   public final KeepMemberInfo<?, ?> getMemberInfo(ProgramMember<?, ?> member) {
@@ -112,21 +105,8 @@
     return getMethodInfo(method.getDefinition(), method.getHolder());
   }
 
-  public final KeepMethodInfo getMethodInfo(
-      DexEncodedMethod method, DexDefinitionSupplier definitions) {
-    DexProgramClass holder =
-        asProgramClassOrNull(definitions.contextIndependentDefinitionFor(method.getHolderType()));
-    if (holder == null) {
-      return keepInfoForNonProgramMethod();
-    }
-    assert method == holder.lookupMethod(method.getReference());
-    return getMethodInfo(method, holder);
-  }
-
-  public final KeepMethodInfo getMethodInfoSlow(
-      DexMethod method, DexDefinitionSupplier definitions) {
-    DexProgramClass holder =
-        asProgramClassOrNull(definitions.contextIndependentDefinitionFor(method.holder));
+  public final KeepMethodInfo getMethodInfo(DexMethod method, DexDefinitionSupplier definitions) {
+    DexProgramClass holder = asProgramClassOrNull(definitions.definitionFor(method.holder));
     if (holder == null) {
       return keepInfoForNonProgramMethod();
     }
@@ -138,18 +118,7 @@
     return getFieldInfo(field.getDefinition(), field.getHolder());
   }
 
-  public final KeepFieldInfo getFieldInfo(
-      DexEncodedField field, DexDefinitionSupplier definitions) {
-    DexProgramClass holder =
-        asProgramClassOrNull(definitions.contextIndependentDefinitionFor(field.getHolderType()));
-    if (holder == null) {
-      return keepInfoForNonProgramField();
-    }
-    assert holder.lookupField(field.getReference()) == field;
-    return getFieldInfo(field, holder);
-  }
-
-  private KeepFieldInfo getFieldInfoSlow(DexField field, DexDefinitionSupplier definitions) {
+  public final KeepFieldInfo getFieldInfo(DexField field, DexDefinitionSupplier definitions) {
     DexProgramClass holder = asProgramClassOrNull(definitions.definitionFor(field.holder));
     if (holder == null) {
       return keepInfoForNonProgramField();
@@ -158,29 +127,15 @@
     return definition == null ? KeepFieldInfo.bottom() : getFieldInfo(definition, holder);
   }
 
-  private KeepInfo<?, ?> getInfoWithDefinitionLookup(
-      DexReference reference, DexDefinitionSupplier definitions) {
+  public final KeepInfo<?, ?> getInfo(DexReference reference, DexDefinitionSupplier definitions) {
     if (reference.isDexType()) {
       return getClassInfo(reference.asDexType(), definitions);
     }
     if (reference.isDexMethod()) {
-      return getMethodInfoSlow(reference.asDexMethod(), definitions);
+      return getMethodInfo(reference.asDexMethod(), definitions);
     }
     if (reference.isDexField()) {
-      return getFieldInfoSlow(reference.asDexField(), definitions);
-    }
-    throw new Unreachable();
-  }
-
-  public final KeepInfo<?, ?> getInfo(DexDefinition definition, DexDefinitionSupplier definitions) {
-    if (definition.isDexClass()) {
-      return getClassInfo(definition.asDexClass());
-    }
-    if (definition.isDexEncodedMethod()) {
-      return getMethodInfo(definition.asDexEncodedMethod(), definitions);
-    }
-    if (definition.isDexEncodedField()) {
-      return getFieldInfo(definition.asDexEncodedField(), definitions);
+      return getFieldInfo(reference.asDexField(), definitions);
     }
     throw new Unreachable();
   }
@@ -203,28 +158,37 @@
   }
 
   public final boolean isPinned(
-      ProgramDefinition definition, GlobalKeepInfoConfiguration configuration) {
-    return getInfo(definition).isPinned(configuration);
+      DexReference reference,
+      DexDefinitionSupplier definitions,
+      GlobalKeepInfoConfiguration configuration) {
+    return getInfo(reference, definitions).isPinned(configuration);
   }
 
   public final boolean isPinned(
-      DexDefinition definition,
-      GlobalKeepInfoConfiguration configuration,
-      DexDefinitionSupplier definitions) {
-    return getInfo(definition, definitions).isPinned(configuration);
+      DexType type, DexDefinitionSupplier definitions, GlobalKeepInfoConfiguration configuration) {
+    return getClassInfo(type, definitions).isPinned(configuration);
   }
 
-  public final boolean isPinnedWithDefinitionLookup(
-      DexReference reference,
-      GlobalKeepInfoConfiguration configuration,
-      DexDefinitionSupplier definitions) {
-    return getInfoWithDefinitionLookup(reference, definitions).isPinned(configuration);
+  public final boolean isPinned(
+      DexMethod method,
+      DexDefinitionSupplier definitions,
+      GlobalKeepInfoConfiguration configuration) {
+    return getMethodInfo(method, definitions).isPinned(configuration);
+  }
+
+  public final boolean isPinned(
+      DexField field,
+      DexDefinitionSupplier definitions,
+      GlobalKeepInfoConfiguration configuration) {
+    return getFieldInfo(field, definitions).isPinned(configuration);
   }
 
   public final boolean isMinificationAllowed(
-      ProgramDefinition definition, GlobalKeepInfoConfiguration configuration) {
+      DexReference reference,
+      DexDefinitionSupplier definitions,
+      GlobalKeepInfoConfiguration configuration) {
     return configuration.isMinificationEnabled()
-        && getInfo(definition).isMinificationAllowed(configuration);
+        && getInfo(reference, definitions).isMinificationAllowed(configuration);
   }
 
   public abstract boolean verifyPinnedTypesAreLive(Set<DexType> liveTypes, InternalOptions options);
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 7d8610b..a728063 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -2083,14 +2083,12 @@
               (reference, minimumKeepInfo) -> {
                 if (reference.isDexType()) {
                   DexType type = reference.asDexType();
-                  assert !appInfo.hasLiveness()
-                          || appInfo.withLiveness().isPinnedWithDefinitionLookup(type)
+                  assert !appInfo.hasLiveness() || appInfo.withLiveness().isPinned(type)
                       : "Expected reference `" + type.toSourceString() + "` to be pinned";
                   requiredMembersPerType.computeIfAbsent(type, key -> Sets.newIdentityHashSet());
                 } else {
                   DexMember<?, ?> member = reference.asDexMember();
-                  assert !appInfo.hasLiveness()
-                          || appInfo.withLiveness().isPinnedWithDefinitionLookup(member)
+                  assert !appInfo.hasLiveness() || appInfo.withLiveness().isPinned(member)
                       : "Expected reference `" + member.toSourceString() + "` to be pinned";
                   requiredMembersPerType
                       .computeIfAbsent(member.holder, key -> Sets.newIdentityHashSet())
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 4819d4d..32878da 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -359,7 +359,7 @@
 
   private void markTypeAsPinned(DexType type, AbortReason reason) {
     DexType baseType = type.toBaseType(appView.dexItemFactory());
-    if (!baseType.isClassType() || appInfo.isPinnedWithDefinitionLookup(baseType)) {
+    if (!baseType.isClassType() || appInfo.isPinned(baseType)) {
       // We check for the case where the type is pinned according to appInfo.isPinned,
       // so we only need to add it here if it is not the case.
       return;
@@ -380,13 +380,14 @@
     if (allocationInfo.isInstantiatedDirectly(sourceClass)
         || allocationInfo.isInterfaceWithUnknownSubtypeHierarchy(sourceClass)
         || allocationInfo.isImmediateInterfaceOfInstantiatedLambda(sourceClass)
-        || appInfo.isPinned(sourceClass)
+        || appInfo.isPinned(sourceClass.type)
         || pinnedTypes.contains(sourceClass.type)
         || appInfo.isNoVerticalClassMergingOfType(sourceClass.type)) {
       return false;
     }
 
     assert Streams.stream(Iterables.concat(sourceClass.fields(), sourceClass.methods()))
+        .map(DexEncodedMember::getReference)
         .noneMatch(appInfo::isPinned);
 
     if (!FeatureSplitBoundaryOptimizationUtils.isSafeForVerticalClassMerging(
@@ -394,7 +395,7 @@
       return false;
     }
     if (appView.appServices().allServiceTypes().contains(sourceClass.type)
-        && appInfo.isPinned(targetClass)) {
+        && appInfo.isPinned(targetClass.type)) {
       if (Log.ENABLED) {
         AbortReason.SERVICE_LOADER.printLogMessageForClass(sourceClass);
       }
diff --git a/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
index 11f01d2..c1e6850 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
@@ -170,7 +170,7 @@
       }
       allSeenAreInstanceInitializers = false;
       // If the method is pinned, we cannot minify it.
-      if (!keepInfo.isMinificationAllowed(method, appView.options())) {
+      if (!keepInfo.isMinificationAllowed(method.getReference(), appView, appView.options())) {
         continue;
       }
       // With desugared library, call-backs names are reserved here.