Add program class witness to enqueuer mark kept methods.

Change-Id: Ie7b61e021f271c7d76cb55acca83beacf8095b22
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 9f49f34..246dfa1 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -434,6 +434,7 @@
           DexEncodedMethod defaultInitializer = clazz.getDefaultInitializer();
           if (forceProguardCompatibility) {
             workList.enqueueMarkMethodKeptAction(
+                clazz,
                 defaultInitializer,
                 graphReporter.reportCompatKeepDefaultInitializer(clazz, defaultInitializer));
           }
@@ -443,13 +444,23 @@
         }
       }
     } else if (item.isDexEncodedField()) {
-      KeepReasonWitness witness =
-          graphReporter.reportKeepField(precondition, rules, item.asDexEncodedField());
-      workList.enqueueMarkFieldKeptAction(item.asDexEncodedField(), witness);
+      DexEncodedField dexEncodedField = item.asDexEncodedField();
+      DexProgramClass holder = getProgramClassOrNull(dexEncodedField.field.holder);
+      if (holder != null) {
+        workList.enqueueMarkFieldKeptAction(
+            holder,
+            dexEncodedField,
+            graphReporter.reportKeepField(precondition, rules, dexEncodedField));
+      }
     } else if (item.isDexEncodedMethod()) {
-      KeepReasonWitness witness =
-          graphReporter.reportKeepMethod(precondition, rules, item.asDexEncodedMethod());
-      workList.enqueueMarkMethodKeptAction(item.asDexEncodedMethod(), witness);
+      DexEncodedMethod encodedMethod = item.asDexEncodedMethod();
+      DexProgramClass holder = getProgramClassOrNull(encodedMethod.method.holder);
+      if (holder != null) {
+        workList.enqueueMarkMethodKeptAction(
+            holder,
+            encodedMethod,
+            graphReporter.reportKeepMethod(precondition, rules, encodedMethod));
+      }
     } else {
       throw new IllegalArgumentException(item.toString());
     }
@@ -2077,7 +2088,7 @@
     if (valuesMethod != null) {
       // TODO(sgjesse): Does this have to be enqueued as a root item? Right now it is done as the
       // marking for not renaming it is in the root set.
-      workList.enqueueMarkMethodKeptAction(valuesMethod, reason);
+      workList.enqueueMarkMethodKeptAction(clazz, valuesMethod, reason);
       pinnedItems.add(valuesMethod.toReference());
       rootSet.shouldNotBeMinified(valuesMethod.toReference());
     }
@@ -2371,12 +2382,8 @@
   }
 
   // Package protected due to entry point from worklist.
-  void markMethodAsKept(DexEncodedMethod target, KeepReason reason) {
+  void markMethodAsKept(DexProgramClass holder, DexEncodedMethod target, KeepReason reason) {
     DexMethod method = target.method;
-    DexProgramClass holder = getProgramClassOrNull(method.holder);
-    if (holder == null) {
-      return;
-    }
     if (target.isVirtualMethod()) {
       // A virtual method. Mark it as reachable so that subclasses, if instantiated, keep
       // their overrides. However, we don't mark it live, as a keep rule might not imply that
@@ -2411,11 +2418,8 @@
   }
 
   // Package protected due to entry point from worklist.
-  void markFieldAsKept(DexEncodedField target, KeepReason reason) {
-    DexProgramClass clazz = getProgramClassOrNull(target.field.holder);
-    if (clazz == null) {
-      return;
-    }
+  void markFieldAsKept(DexProgramClass holder, DexEncodedField target, KeepReason reason) {
+    assert holder.type == target.field.holder;
     if (target.accessFlags.isStatic()) {
       markStaticFieldAsLive(target, reason);
     } else {
@@ -2624,7 +2628,7 @@
       if (keepClass) {
         markInstantiated(clazz, null, KeepReason.reflectiveUseIn(method));
       }
-      markFieldAsKept(encodedField, KeepReason.reflectiveUseIn(method));
+      markFieldAsKept(clazz, encodedField, KeepReason.reflectiveUseIn(method));
       // Fields accessed by reflection is marked as both read and written.
       registerFieldRead(encodedField.field, method);
       registerFieldWrite(encodedField.field, method);
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
index 275e5a7..24f72ab 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.shaking.GraphReporter.KeepReasonWitness;
 import java.util.ArrayDeque;
 import java.util.Queue;
 
@@ -127,32 +128,38 @@
   }
 
   static class MarkMethodKeptAction extends Action {
+    final DexProgramClass holder;
     final DexEncodedMethod target;
     final KeepReason reason;
 
-    public MarkMethodKeptAction(DexEncodedMethod target, KeepReason reason) {
+    public MarkMethodKeptAction(
+        DexProgramClass holder, DexEncodedMethod target, KeepReason reason) {
+      this.holder = holder;
       this.target = target;
       this.reason = reason;
     }
 
     @Override
     public void run(Enqueuer enqueuer) {
-      enqueuer.markMethodAsKept(target, reason);
+      enqueuer.markMethodAsKept(holder, target, reason);
     }
   }
 
   static class MarkFieldKeptAction extends Action {
+    final DexProgramClass holder;
     final DexEncodedField target;
-    final KeepReason reason;
+    final KeepReasonWitness witness;
 
-    public MarkFieldKeptAction(DexEncodedField target, KeepReason reason) {
+    public MarkFieldKeptAction(
+        DexProgramClass holder, DexEncodedField target, KeepReasonWitness witness) {
+      this.holder = holder;
       this.target = target;
-      this.reason = reason;
+      this.witness = witness;
     }
 
     @Override
     public void run(Enqueuer enqueuer) {
-      enqueuer.markFieldAsKept(target, reason);
+      enqueuer.markFieldAsKept(holder, target, witness);
     }
   }
 
@@ -211,13 +218,15 @@
     queue.add(new MarkMethodLiveAction(method, reason));
   }
 
-  void enqueueMarkMethodKeptAction(DexEncodedMethod method, KeepReason reason) {
-    assert method.isProgramMethod(appView);
-    queue.add(new MarkMethodKeptAction(method, reason));
+  void enqueueMarkMethodKeptAction(
+      DexProgramClass clazz, DexEncodedMethod method, KeepReason reason) {
+    assert method.method.holder == clazz.type;
+    queue.add(new MarkMethodKeptAction(clazz, method, reason));
   }
 
-  void enqueueMarkFieldKeptAction(DexEncodedField field, KeepReason reason) {
+  void enqueueMarkFieldKeptAction(
+      DexProgramClass holder, DexEncodedField field, KeepReasonWitness witness) {
     assert field.isProgramField(appView);
-    queue.add(new MarkFieldKeptAction(field, reason));
+    queue.add(new MarkFieldKeptAction(holder, field, witness));
   }
 }