Extend profile rewriting to default interface method desugaring

Bug: b/265729283
Change-Id: I2eb2795acab72f9e1cfd4519d70f0511d45b5142
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 761298d..d7a47a1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -1224,12 +1224,11 @@
   }
 
   public static DexEncodedMethod createDesugaringForwardingMethod(
-      DexEncodedMethod target, DexClass clazz, DexMethod forwardMethod, DexItemFactory factory) {
-    DexMethod method = target.getReference();
+      DexClassAndMethod target, DexClass clazz, DexMethod forwardMethod, DexItemFactory factory) {
     assert forwardMethod != null;
     // New method will have the same name, proto, and also all the flags of the
     // default method, including bridge flag.
-    DexMethod newMethod = factory.createMethod(clazz.type, method.proto, method.name);
+    DexMethod newMethod = target.getReference().withHolder(clazz, factory);
     MethodAccessFlags newFlags = target.getAccessFlags().copy();
     // Some debuggers (like IntelliJ) automatically skip synthetic methods on single step.
     newFlags.setSynthetic();
@@ -1246,8 +1245,8 @@
                 .setNonStaticSource(newMethod)
                 .setStaticTarget(forwardMethod, isInterfaceMethodReference)
                 .build())
-        .setApiLevelForDefinition(target.getApiLevelForDefinition())
-        .setApiLevelForCode(target.getApiLevelForCode())
+        .setApiLevelForDefinition(target.getDefinition().getApiLevelForDefinition())
+        .setApiLevelForCode(target.getDefinition().getApiLevelForCode())
         .build();
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
index f96680f..0d37795 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8.ir.desugar;
 
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
@@ -13,6 +14,8 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterPostProcessingEventConsumer;
 import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
 import com.android.tools.r8.ir.desugar.itf.InterfaceProcessingDesugaringEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingCfPostProcessingDesugaringEventConsumer;
 import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
 import com.android.tools.r8.utils.collections.ProgramMethodSet;
 import java.util.concurrent.ExecutionException;
@@ -33,11 +36,15 @@
     return new D8CfPostProcessingDesugaringEventConsumer(methodProcessor, instructionDesugaring);
   }
 
-  public static R8PostProcessingDesugaringEventConsumer createForR8(
+  public static CfPostProcessingDesugaringEventConsumer createForR8(
       SyntheticAdditions additions,
+      ArtProfileCollectionAdditions artProfileCollectionAdditions,
       CfInstructionDesugaringCollection desugaring,
       BiConsumer<DexProgramClass, DexType> missingClassConsumer) {
-    return new R8PostProcessingDesugaringEventConsumer(additions, desugaring, missingClassConsumer);
+    CfPostProcessingDesugaringEventConsumer eventConsumer =
+        new R8PostProcessingDesugaringEventConsumer(additions, desugaring, missingClassConsumer);
+    return ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.attach(
+        artProfileCollectionAdditions, eventConsumer);
   }
 
   public abstract void finalizeDesugaring() throws ExecutionException;
@@ -92,7 +99,18 @@
     }
 
     @Override
-    public void acceptForwardingMethod(ProgramMethod method) {
+    public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+      addMethodToReprocess(method);
+    }
+
+    @Override
+    public void acceptInterfaceMethodDesugaringForwardingMethod(
+        ProgramMethod method, DexClassAndMethod baseMethod) {
+      addMethodToReprocess(method);
+    }
+
+    @Override
+    public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
       addMethodToReprocess(method);
     }
 
@@ -180,7 +198,18 @@
     }
 
     @Override
-    public void acceptForwardingMethod(ProgramMethod method) {
+    public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+      additions.addLiveMethod(method);
+    }
+
+    @Override
+    public void acceptInterfaceMethodDesugaringForwardingMethod(
+        ProgramMethod method, DexClassAndMethod baseMethod) {
+      additions.addLiveMethod(method);
+    }
+
+    @Override
+    public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
       additions.addLiveMethod(method);
     }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
index 53b8207..cc5abfd 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
@@ -5,6 +5,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexLibraryClass;
 import com.android.tools.r8.graph.DexMethod;
@@ -136,7 +137,8 @@
       if (clazz.lookupVirtualMethod(method) == null) {
         DexEncodedMethod newMethod = createForwardingMethod(itfMethod, descriptor, clazz);
         clazz.addVirtualMethod(newMethod);
-        eventConsumer.acceptForwardingMethod(new ProgramMethod(clazz, newMethod));
+        eventConsumer.acceptDesugaredLibraryRetargeterForwardingMethod(
+            new ProgramMethod(clazz, newMethod));
       }
     }
   }
@@ -148,8 +150,8 @@
     // In desugared library, emulated interface methods can be overridden by retarget lib members.
     DexMethod forwardMethod = syntheticHelper.forwardingMethod(descriptor);
     assert forwardMethod != null && forwardMethod != target;
-    DexEncodedMethod resolvedMethod =
-        appView.appInfoForDesugaring().resolveMethodLegacy(target, true).getResolvedMethod();
+    DexClassAndMethod resolvedMethod =
+        appView.appInfoForDesugaring().resolveMethodLegacy(target, true).getResolutionPair();
     assert resolvedMethod != null;
     DexEncodedMethod desugaringForwardingMethod =
         DexEncodedMethod.createDesugaringForwardingMethod(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
index 7e86c5b..63dcba2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
@@ -25,6 +25,6 @@
       extends DesugaredLibraryRetargeterInstructionEventConsumer {
     void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface);
 
-    void acceptForwardingMethod(ProgramMethod method);
+    void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
index 3f3d045..0c5ed70 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMember;
 import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexEncodedMember;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexLibraryClass;
@@ -39,8 +40,8 @@
 import com.android.tools.r8.utils.IterableUtils;
 import com.android.tools.r8.utils.MethodSignatureEquivalence;
 import com.android.tools.r8.utils.OptionalBool;
+import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.WorkList;
-import com.android.tools.r8.utils.collections.ProgramMethodSet;
 import com.google.common.base.Equivalence.Wrapper;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList.Builder;
@@ -55,6 +56,8 @@
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
 import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -71,6 +74,74 @@
  */
 final class ClassProcessor {
 
+  private abstract static class SyntheticMethodInfo {
+
+    private final ProgramMethod method;
+
+    SyntheticMethodInfo(ProgramMethod method) {
+      this.method = method;
+    }
+
+    ProgramMethod getMethod() {
+      return method;
+    }
+
+    boolean isForwardingMethodInfo() {
+      return false;
+    }
+
+    SyntheticForwardingMethodInfo asForwardingMethodInfo() {
+      return null;
+    }
+
+    SyntheticThrowingMethodInfo asThrowingMethodInfo() {
+      return null;
+    }
+  }
+
+  private static class SyntheticForwardingMethodInfo extends SyntheticMethodInfo {
+
+    private final DexClassAndMethod baseMethod;
+
+    SyntheticForwardingMethodInfo(ProgramMethod method, DexClassAndMethod baseMethod) {
+      super(method);
+      this.baseMethod = baseMethod;
+    }
+
+    DexClassAndMethod getBaseMethod() {
+      return baseMethod;
+    }
+
+    @Override
+    boolean isForwardingMethodInfo() {
+      return true;
+    }
+
+    @Override
+    SyntheticForwardingMethodInfo asForwardingMethodInfo() {
+      return this;
+    }
+  }
+
+  private static class SyntheticThrowingMethodInfo extends SyntheticMethodInfo {
+
+    private final DexType errorType;
+
+    SyntheticThrowingMethodInfo(ProgramMethod method, DexType errorType) {
+      super(method);
+      this.errorType = errorType;
+    }
+
+    DexType getErrorType() {
+      return errorType;
+    }
+
+    @Override
+    SyntheticThrowingMethodInfo asThrowingMethodInfo() {
+      return this;
+    }
+  }
+
   // Collection for method signatures that may cause forwarding methods to be created.
   private static class MethodSignatures {
 
@@ -370,7 +441,7 @@
   private final Map<DexClass, SignaturesInfo> interfaceInfo = new ConcurrentHashMap<>();
 
   // Mapping from actual program classes to the synthesized forwarding methods to be created.
-  private final Map<DexProgramClass, ProgramMethodSet> newSyntheticMethods =
+  private final Map<DexProgramClass, Map<DexMethod, SyntheticMethodInfo>> newSyntheticMethods =
       new ConcurrentHashMap<>();
 
   // Mapping from actual program classes to the extra interfaces needed for emulated dispatch.
@@ -422,16 +493,30 @@
 
   // We introduce forwarding methods only once all desugaring has been performed to avoid
   // confusing the look-up with inserted forwarding methods.
-  public void finalizeProcessing(InterfaceProcessingDesugaringEventConsumer eventConsumer) {
-    newSyntheticMethods.forEach(
-        (clazz, newForwardingMethods) -> {
-          List<ProgramMethod> sorted = new ArrayList<>(newForwardingMethods.toCollection());
-          sorted.sort(Comparator.comparing(ProgramMethod::getReference));
-          for (ProgramMethod method : sorted) {
-            clazz.addVirtualMethod(method.getDefinition());
-            eventConsumer.acceptForwardingMethod(method);
+  public void finalizeProcessing(
+      InterfaceProcessingDesugaringEventConsumer eventConsumer, ExecutorService executorService)
+      throws ExecutionException {
+    ThreadUtils.processMap(
+        newSyntheticMethods,
+        (clazz, infos) -> {
+          List<DexEncodedMethod> sortedDefinitions = new ArrayList<>(infos.size());
+          for (SyntheticMethodInfo info : infos.values()) {
+            sortedDefinitions.add(info.getMethod().getDefinition());
           }
-        });
+          sortedDefinitions.sort(Comparator.comparing(DexEncodedMember::getReference));
+          clazz.addVirtualMethods(sortedDefinitions);
+          for (DexEncodedMethod definition : sortedDefinitions) {
+            SyntheticMethodInfo info = infos.get(definition.getReference());
+            if (info.isForwardingMethodInfo()) {
+              eventConsumer.acceptInterfaceMethodDesugaringForwardingMethod(
+                  info.getMethod(), info.asForwardingMethodInfo().getBaseMethod());
+            } else {
+              eventConsumer.acceptThrowingMethod(
+                  info.getMethod(), info.asThrowingMethodInfo().getErrorType());
+            }
+          }
+        },
+        executorService);
     newExtraInterfaceSignatures.forEach(
         (clazz, extraInterfaceSignatures) -> {
           if (!extraInterfaceSignatures.isEmpty()) {
@@ -826,11 +911,20 @@
     }
   }
 
-  // Construction of actual forwarding methods.
-  private void addSyntheticMethod(DexProgramClass clazz, DexEncodedMethod method) {
-    newSyntheticMethods
-        .computeIfAbsent(clazz, key -> ProgramMethodSet.create())
-        .createAndAdd(clazz, method);
+  private void addSyntheticForwardingMethod(ProgramMethod method, DexClassAndMethod baseMethod) {
+    SyntheticMethodInfo existingMethodInfo =
+        newSyntheticMethods
+            .computeIfAbsent(method.getHolder(), key -> new ConcurrentHashMap<>())
+            .put(method.getReference(), new SyntheticForwardingMethodInfo(method, baseMethod));
+    assert existingMethodInfo == null;
+  }
+
+  private void addSyntheticThrowingMethod(ProgramMethod method, DexType errorType) {
+    SyntheticMethodInfo existingMethodInfo =
+        newSyntheticMethods
+            .computeIfAbsent(method.getHolder(), key -> new ConcurrentHashMap<>())
+            .put(method.getReference(), new SyntheticThrowingMethodInfo(method, errorType));
+    assert existingMethodInfo == null;
   }
 
   private void addICCEThrowingMethod(DexMethod method, DexClass clazz) {
@@ -859,7 +953,7 @@
                 createExceptionThrowingCfCode(newMethod, accessFlags, errorType, dexItemFactory))
             .disableAndroidApiLevelCheck()
             .build();
-    addSyntheticMethod(clazz.asProgramClass(), newEncodedMethod);
+    addSyntheticThrowingMethod(newEncodedMethod.asProgramMethod(clazz.asProgramClass()), errorType);
   }
 
   private static CfCode createExceptionThrowingCfCode(
@@ -907,12 +1001,12 @@
     // In desugared library, emulated interface methods can be overridden by retarget lib members.
     DexEncodedMethod desugaringForwardingMethod =
         DexEncodedMethod.createDesugaringForwardingMethod(
-            target.getDefinition(), clazz, forwardMethod, dexItemFactory);
-    if (!target.isProgramDefinition()
-        || target.getDefinition().isLibraryMethodOverride().isTrue()) {
+            target, clazz, forwardMethod, dexItemFactory);
+    if (!target.isProgramMethod() || target.getDefinition().isLibraryMethodOverride().isTrue()) {
       desugaringForwardingMethod.setLibraryMethodOverride(OptionalBool.TRUE);
     }
-    addSyntheticMethod(clazz.asProgramClass(), desugaringForwardingMethod);
+    addSyntheticForwardingMethod(
+        desugaringForwardingMethod.asProgramMethod(clazz.asProgramClass()), target);
   }
 
   // Topological order traversal and its helpers.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
index a5ec16a..c92c9ce 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodProcessorFacade.java
@@ -54,7 +54,7 @@
         Iterables.filter(programClasses, (DexProgramClass clazz) -> shouldProcess(clazz, flavour)),
         clazz -> classProcessor.process(clazz, eventConsumer),
         executorService);
-    classProcessor.finalizeProcessing(eventConsumer);
+    classProcessor.finalizeProcessing(eventConsumer, executorService);
     interfaceProcessor.finalizeProcessing();
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
index 8115626..dde1382 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessingDesugaringEventConsumer.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.desugar.itf;
 
+import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
@@ -11,11 +12,14 @@
 
 public interface InterfaceProcessingDesugaringEventConsumer {
 
-  void acceptForwardingMethod(ProgramMethod method);
+  void acceptInterfaceMethodDesugaringForwardingMethod(
+      ProgramMethod method, DexClassAndMethod baseMethod);
 
   void acceptEmulatedInterfaceMarkerInterface(
       DexProgramClass clazz, DexClasspathClass newInterface);
 
+  void acceptThrowingMethod(ProgramMethod method, DexType errorType);
+
   void warnMissingInterface(
       DexProgramClass context, DexType missing, InterfaceDesugaringSyntheticHelper helper);
 }
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java
index 297e443..428f970 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileAdditions.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.profile.art.rewriting;
 
+import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
@@ -32,7 +33,7 @@
     this.artProfile = artProfile;
   }
 
-  void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition... definitions) {
+  void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition... definitions) {
     ArtProfileMethodRule contextMethodRule = artProfile.getMethodRule(context.getReference());
     if (contextMethodRule != null) {
       for (ProgramDefinition definition : definitions) {
@@ -42,7 +43,7 @@
   }
 
   // Specialization of the above method to avoid redundant varargs array creation.
-  void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition definition) {
+  void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition definition) {
     ArtProfileMethodRule contextMethodRule = artProfile.getMethodRule(context.getReference());
     if (contextMethodRule != null) {
       addRuleFromContext(definition, contextMethodRule, MethodRuleAdditionConfig.getDefault());
@@ -82,9 +83,11 @@
             methodReference -> ArtProfileMethodRule.builder().setMethod(method.getReference()));
 
     // Setup the rule.
-    methodRuleBuilder.acceptMethodRuleInfoBuilder(
-        methodRuleInfoBuilder ->
-            config.configureMethodRuleInfo(methodRuleInfoBuilder, contextMethodRule));
+    synchronized (methodRuleBuilder) {
+      methodRuleBuilder.acceptMethodRuleInfoBuilder(
+          methodRuleInfoBuilder ->
+              config.configureMethodRuleInfo(methodRuleInfoBuilder, contextMethodRule));
+    }
   }
 
   ArtProfile createNewArtProfile() {
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
index 5c9ffa5..3f04e4c 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
@@ -82,6 +82,8 @@
 
   @Override
   public void acceptDefaultAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
+    additionsCollection.addRulesIfContextIsInProfile(
+        method, companionMethod, companionMethod.getHolder());
     parent.acceptDefaultAsCompanionMethod(method, companionMethod);
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
new file mode 100644
index 0000000..cc234c8
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfPostProcessingDesugaringEventConsumer.java
@@ -0,0 +1,113 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.profile.art.rewriting;
+
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexClasspathClass;
+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.ir.desugar.CfPostProcessingDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
+import java.util.concurrent.ExecutionException;
+
+public class ArtProfileRewritingCfPostProcessingDesugaringEventConsumer
+    extends CfPostProcessingDesugaringEventConsumer {
+
+  private final ConcreteArtProfileCollectionAdditions additionsCollection;
+  private final CfPostProcessingDesugaringEventConsumer parent;
+
+  private ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
+      ConcreteArtProfileCollectionAdditions additionsCollection,
+      CfPostProcessingDesugaringEventConsumer parent) {
+    this.additionsCollection = additionsCollection;
+    this.parent = parent;
+  }
+
+  public static CfPostProcessingDesugaringEventConsumer attach(
+      ArtProfileCollectionAdditions artProfileCollectionAdditions,
+      CfPostProcessingDesugaringEventConsumer eventConsumer) {
+    if (artProfileCollectionAdditions.isNop()) {
+      return eventConsumer;
+    }
+    return new ArtProfileRewritingCfPostProcessingDesugaringEventConsumer(
+        artProfileCollectionAdditions.asConcrete(), eventConsumer);
+  }
+
+  @Override
+  public void acceptAPIConversionCallback(ProgramMethod method) {
+    parent.acceptAPIConversionCallback(method);
+  }
+
+  @Override
+  public void acceptCollectionConversion(ProgramMethod arrayConversion) {
+    parent.acceptCollectionConversion(arrayConversion);
+  }
+
+  @Override
+  public void acceptCovariantRetargetMethod(ProgramMethod method) {
+    parent.acceptCovariantRetargetMethod(method);
+  }
+
+  @Override
+  public void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz) {
+    parent.acceptDesugaredLibraryRetargeterDispatchClasspathClass(clazz);
+  }
+
+  @Override
+  public void acceptDesugaredLibraryRetargeterForwardingMethod(ProgramMethod method) {
+    parent.acceptDesugaredLibraryRetargeterForwardingMethod(method);
+  }
+
+  @Override
+  public void acceptEmulatedInterfaceMarkerInterface(
+      DexProgramClass clazz, DexClasspathClass newInterface) {
+    parent.acceptEmulatedInterfaceMarkerInterface(clazz, newInterface);
+  }
+
+  @Override
+  public void acceptEnumConversionClasspathClass(DexClasspathClass clazz) {
+    parent.acceptEnumConversionClasspathClass(clazz);
+  }
+
+  @Override
+  public void acceptGenericApiConversionStub(DexClasspathClass dexClasspathClass) {
+    parent.acceptGenericApiConversionStub(dexClasspathClass);
+  }
+
+  @Override
+  public void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface) {
+    parent.acceptInterfaceInjection(clazz, newInterface);
+  }
+
+  @Override
+  public void acceptInterfaceMethodDesugaringForwardingMethod(
+      ProgramMethod method, DexClassAndMethod baseMethod) {
+    additionsCollection.addRulesIfContextIsInProfile(baseMethod, method);
+    parent.acceptInterfaceMethodDesugaringForwardingMethod(method, baseMethod);
+  }
+
+  @Override
+  public void acceptThrowingMethod(ProgramMethod method, DexType errorType) {
+    parent.acceptThrowingMethod(method, errorType);
+  }
+
+  @Override
+  public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
+    parent.acceptWrapperClasspathClass(clazz);
+  }
+
+  @Override
+  public void finalizeDesugaring() throws ExecutionException {
+    parent.finalizeDesugaring();
+  }
+
+  @Override
+  public void warnMissingInterface(
+      DexProgramClass context, DexType missing, InterfaceDesugaringSyntheticHelper helper) {
+    parent.warnMissingInterface(context, missing, helper);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
index b66c5f1..1d0c199 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ConcreteArtProfileCollectionAdditions.java
@@ -5,8 +5,8 @@
 package com.android.tools.r8.profile.art.rewriting;
 
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.ProgramDefinition;
-import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.profile.art.ArtProfile;
 import com.android.tools.r8.profile.art.ArtProfileCollection;
 import com.android.tools.r8.profile.art.NonEmptyArtProfileCollection;
@@ -25,14 +25,14 @@
     assert !additionsCollection.isEmpty();
   }
 
-  void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition... definitions) {
+  void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition... definitions) {
     for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
       artProfileAdditions.addRulesIfContextIsInProfile(context, definitions);
     }
   }
 
   // Specialization of the above method to avoid redundant varargs array creation.
-  void addRulesIfContextIsInProfile(ProgramMethod context, ProgramDefinition definition) {
+  void addRulesIfContextIsInProfile(DexClassAndMethod context, ProgramDefinition definition) {
     for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
       artProfileAdditions.addRulesIfContextIsInProfile(context, definition);
     }
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 ca0f9b5..06db3b7 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -113,7 +113,6 @@
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringCollection;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer.R8PostProcessingDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.LambdaClass;
 import com.android.tools.r8.ir.desugar.LambdaDescriptor;
 import com.android.tools.r8.ir.desugar.ProgramAdditions;
@@ -4562,9 +4561,10 @@
 
     assert workList.isEmpty();
 
-    R8PostProcessingDesugaringEventConsumer eventConsumer =
+    CfPostProcessingDesugaringEventConsumer eventConsumer =
         CfPostProcessingDesugaringEventConsumer.createForR8(
             syntheticAdditions,
+            artProfileCollectionAdditions,
             desugaring,
             (context, missing) ->
                 missingClassesBuilder.addNewMissingClassWithDesugarDiagnostic(
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java
index 4e59b75..211d4bb 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/completeness/DefaultInterfaceMethodProfileRewritingTest.java
@@ -73,6 +73,9 @@
       ClassSubject aClassSubject = inspector.clazz(A.class);
       assertThat(aClassSubject, isPresent());
 
+      ClassSubject bClassSubject = inspector.clazz(B.class);
+      assertThat(bClassSubject, isPresent());
+
       ClassSubject companionClassSubject =
           inspector.clazz(SyntheticItemsTestUtils.syntheticCompanionClass(I.class));
       assertThat(companionClassSubject, isPresent());
@@ -80,15 +83,24 @@
       MethodSubject interfaceMethodSubject = iClassSubject.uniqueMethodWithOriginalName("m");
       assertThat(interfaceMethodSubject, isPresent());
 
-      MethodSubject implementationMethodSubject =
+      MethodSubject aForwardingMethodSubject =
           aClassSubject.method(interfaceMethodSubject.getFinalReference());
-      assertThat(implementationMethodSubject, isPresent());
+      assertThat(aForwardingMethodSubject, isPresent());
+
+      MethodSubject bForwardingMethodSubject =
+          bClassSubject.method(interfaceMethodSubject.getFinalReference());
+      assertThat(bForwardingMethodSubject, isPresent());
 
       MethodSubject movedMethodSubject = companionClassSubject.uniqueMethod();
       assertThat(movedMethodSubject, isPresent());
 
-      // TODO(b/265729283): Should also include the two methods from desugaring.
-      profileInspector.assertContainsMethodRule(interfaceMethodSubject);
+      profileInspector
+          .assertContainsClassRule(companionClassSubject)
+          .assertContainsMethodRules(
+              interfaceMethodSubject,
+              aForwardingMethodSubject,
+              bForwardingMethodSubject,
+              movedMethodSubject);
     }
 
     profileInspector.assertContainsNoOtherRules();