Add additional synthetics to profiles

Bug: b/265729283
Change-Id: I547c13c11ed7731f60c091c13cca4fe65f50fa8e
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 97467f1..be6f9d0 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -473,7 +473,7 @@
       // should therefore be run after the publicizer.
       new NestReducer(appViewWithLiveness).run(executorService, timing);
 
-      appView.setGraphLens(new MemberRebindingAnalysis(appViewWithLiveness).run(executorService));
+      new MemberRebindingAnalysis(appViewWithLiveness).run(executorService);
       appView.appInfo().withLiveness().getFieldAccessInfoCollection().restrictToProgram(appView);
 
       boolean isKotlinLibraryCompilationWithInlinePassThrough =
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 6d6edbf..e607b66 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -633,7 +633,7 @@
     if (serviceLoaderRewriter != null) {
       assert appView.appInfo().hasLiveness();
       timing.begin("Rewrite service loaders");
-      serviceLoaderRewriter.rewrite(code, methodProcessingContext);
+      serviceLoaderRewriter.rewrite(code, methodProcessor, methodProcessingContext);
       timing.end();
     }
 
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java b/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java
index d002cd5..ff9c34c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessorEventConsumer.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.ir.conversion;
 
 import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.optimize.ServiceLoaderRewriterEventConsumer;
 import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizationsEventConsumer;
 import com.android.tools.r8.ir.optimize.api.InstanceInitializerOutlinerEventConsumer;
 import com.android.tools.r8.ir.optimize.enums.EnumUnboxerMethodProcessorEventConsumer;
@@ -14,6 +15,7 @@
 public abstract class MethodProcessorEventConsumer
     implements EnumUnboxerMethodProcessorEventConsumer,
         InstanceInitializerOutlinerEventConsumer,
+        ServiceLoaderRewriterEventConsumer,
         UtilityMethodsForCodeOptimizationsEventConsumer {
 
   public static MethodProcessorEventConsumer create(
@@ -60,6 +62,11 @@
     }
 
     @Override
+    public void acceptServiceLoaderLoadUtilityMethod(ProgramMethod method, ProgramMethod context) {
+      // Intentionally empty.
+    }
+
+    @Override
     public void acceptUtilityToStringIfNotNullMethod(ProgramMethod method, ProgramMethod context) {
       // Intentionally empty.
     }
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 29cb618..33ff0b4 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
@@ -143,8 +143,9 @@
     }
 
     @Override
-    public void acceptAPIConversionCallback(ProgramMethod method) {
-      addMethodToReprocess(method);
+    public void acceptAPIConversionCallback(
+        ProgramMethod callbackMethod, ProgramMethod convertedMethod) {
+      addMethodToReprocess(callbackMethod);
     }
 
     @Override
@@ -241,9 +242,10 @@
     }
 
     @Override
-    public void acceptAPIConversionCallback(ProgramMethod method) {
-      assert !desugaring.needsDesugaring(method);
-      additions.addLiveMethod(method);
+    public void acceptAPIConversionCallback(
+        ProgramMethod callbackMethod, ProgramMethod convertedMethod) {
+      assert !desugaring.needsDesugaring(callbackMethod);
+      additions.addLiveMethod(callbackMethod);
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
index 7907037..c4ce708 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
@@ -213,9 +213,9 @@
     if (method.getDefinition().isLibraryMethodOverride().isTrue()) {
       newMethod.setLibraryMethodOverride(OptionalBool.TRUE);
     }
-    ProgramMethod callback = new ProgramMethod(clazz, newMethod);
+    ProgramMethod callback = newMethod.asProgramMethod(clazz);
     assert eventConsumer != null;
-    eventConsumer.acceptAPIConversionCallback(callback);
+    eventConsumer.acceptAPIConversionCallback(callback, method);
     return callback;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java
index 4adc11f..161247c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizerEventConsumer.java
@@ -39,6 +39,6 @@
   interface DesugaredLibraryAPICallbackSynthesizorEventConsumer
       extends DesugaredLibraryClasspathWrapperSynthesizeEventConsumer {
 
-    void acceptAPIConversionCallback(ProgramMethod method);
+    void acceptAPIConversionCallback(ProgramMethod callbackMethod, ProgramMethod convertedMethod);
   }
 }
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..534b5a9 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
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.code.InvokeStatic;
 import com.android.tools.r8.ir.code.InvokeVirtual;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.conversion.MethodProcessor;
 import com.android.tools.r8.ir.desugar.ServiceLoaderSourceCode;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.BooleanBox;
@@ -75,7 +76,10 @@
     return serviceLoadMethods;
   }
 
-  public void rewrite(IRCode code, MethodProcessingContext methodProcessingContext) {
+  public void rewrite(
+      IRCode code,
+      MethodProcessor methodProcessor,
+      MethodProcessingContext methodProcessingContext) {
     DexItemFactory factory = appView.dexItemFactory();
     InstructionListIterator instructionIterator = code.instructionListIterator();
     // Create a map from service type to loader methods local to this context since two
@@ -175,7 +179,8 @@
               constClass.getValue(),
               service -> {
                 DexEncodedMethod addedMethod =
-                    createSynthesizedMethod(service, classes, methodProcessingContext);
+                    createSynthesizedMethod(
+                        service, classes, methodProcessor, methodProcessingContext);
                 if (appView.options().isGeneratingClassFiles()) {
                   addedMethod.upgradeClassFileVersion(
                       code.context().getDefinition().getClassFileVersion());
@@ -191,6 +196,7 @@
   private DexEncodedMethod createSynthesizedMethod(
       DexType serviceType,
       List<DexClass> classes,
+      MethodProcessor methodProcessor,
       MethodProcessingContext methodProcessingContext) {
     DexProto proto = appView.dexItemFactory().createProto(appView.dexItemFactory().iteratorType);
     ProgramMethod method =
@@ -215,6 +221,9 @@
     synchronized (serviceLoadMethods) {
       serviceLoadMethods.add(method);
     }
+    methodProcessor
+        .getEventConsumer()
+        .acceptServiceLoaderLoadUtilityMethod(method, methodProcessingContext.getMethodContext());
     return method.getDefinition();
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriterEventConsumer.java b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriterEventConsumer.java
new file mode 100644
index 0000000..379021b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriterEventConsumer.java
@@ -0,0 +1,12 @@
+// 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.ir.optimize;
+
+import com.android.tools.r8.graph.ProgramMethod;
+
+public interface ServiceLoaderRewriterEventConsumer {
+
+  void acceptServiceLoaderLoadUtilityMethod(ProgramMethod method, ProgramMethod context);
+}
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index 2ac83b2..b6abede 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -50,6 +50,7 @@
 
   private final AndroidApiLevelCompute androidApiLevelCompute;
   private final AppView<AppInfoWithLiveness> appView;
+  private final MemberRebindingEventConsumer eventConsumer;
   private final InternalOptions options;
 
   private final MemberRebindingLens.Builder lensBuilder;
@@ -58,6 +59,7 @@
     assert appView.graphLens().isContextFreeForMethods();
     this.androidApiLevelCompute = appView.apiLevelCompute();
     this.appView = appView;
+    this.eventConsumer = MemberRebindingEventConsumer.create(appView);
     this.options = appView.options();
     this.lensBuilder = MemberRebindingLens.builder(appView);
   }
@@ -383,6 +385,8 @@
                             target.isLibraryMethod(), OptionalBool.TRUE);
                       });
               bridgeHolder.addMethod(bridgeMethodDefinition);
+              eventConsumer.acceptMemberRebindingBridgeMethod(
+                  bridgeMethodDefinition.asProgramMethod(bridgeHolder), target);
             }
             assert resolver.apply(method).getResolvedMethod().getReference() == bridgeMethod;
           }
@@ -507,12 +511,14 @@
     fieldAccessInfoCollection.forEach(lensBuilder::recordNonReboundFieldAccesses);
   }
 
-  public MemberRebindingLens run(ExecutorService executorService) throws ExecutionException {
+  public void run(ExecutorService executorService) throws ExecutionException {
     AppInfoWithLiveness appInfo = appView.appInfo();
     computeMethodRebinding(appInfo.getMethodAccessInfoCollection());
     recordNonReboundFieldAccesses(executorService);
     appInfo.getFieldAccessInfoCollection().flattenAccessContexts();
-    return lensBuilder.build();
+    MemberRebindingLens memberRebindingLens = lensBuilder.build();
+    appView.setGraphLens(memberRebindingLens);
+    eventConsumer.finished(appView, memberRebindingLens);
   }
 
   private boolean verifyFieldAccessCollectionContainsAllNonReboundFieldReferences(
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingEventConsumer.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingEventConsumer.java
new file mode 100644
index 0000000..dff6597
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingEventConsumer.java
@@ -0,0 +1,46 @@
+// 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.optimize;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingMemberRebindingEventConsumer;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
+public interface MemberRebindingEventConsumer {
+
+  void acceptMemberRebindingBridgeMethod(
+      ProgramMethod bridgeMethod, DexClassAndMethod targetMethod);
+
+  default void finished(
+      AppView<AppInfoWithLiveness> appView, MemberRebindingLens memberRebindingLens) {}
+
+  static MemberRebindingEventConsumer create(AppView<AppInfoWithLiveness> appView) {
+    return ArtProfileRewritingMemberRebindingEventConsumer.attach(appView, empty());
+  }
+
+  static EmptyMemberRebindingEventConsumer empty() {
+    return EmptyMemberRebindingEventConsumer.getInstance();
+  }
+
+  class EmptyMemberRebindingEventConsumer implements MemberRebindingEventConsumer {
+
+    private static final EmptyMemberRebindingEventConsumer INSTANCE =
+        new EmptyMemberRebindingEventConsumer();
+
+    private EmptyMemberRebindingEventConsumer() {}
+
+    static EmptyMemberRebindingEventConsumer getInstance() {
+      return INSTANCE;
+    }
+
+    @Override
+    public void acceptMemberRebindingBridgeMethod(
+        ProgramMethod bridgeMethod, DexClassAndMethod targetMethod) {
+      // Intentionally empty.
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
index d7c3f12..eb21c54 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
@@ -6,6 +6,7 @@
 
 import static com.android.tools.r8.utils.SystemPropertyUtils.parseSystemPropertyOrDefault;
 
+import com.android.tools.r8.utils.InternalOptions;
 import java.util.Collection;
 import java.util.Collections;
 
@@ -16,14 +17,18 @@
       parseSystemPropertyOrDefault(
           "com.android.tools.r8.artprofilerewritingcompletenesscheck", false);
 
-  public ArtProfileOptions() {}
+  private final InternalOptions options;
+
+  public ArtProfileOptions(InternalOptions options) {
+    this.options = options;
+  }
 
   public Collection<ArtProfileForRewriting> getArtProfilesForRewriting() {
     return artProfilesForRewriting;
   }
 
   public boolean isCompletenessCheckForTestingEnabled() {
-    return enableCompletenessCheckForTesting;
+    return enableCompletenessCheckForTesting && !options.isDesugaredLibraryCompilation();
   }
 
   public boolean isIncludingApiReferenceStubs() {
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java
index 36d235f..49d99c4 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileCollectionAdditions.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.profile.art.ArtProfileCollection;
 import com.android.tools.r8.profile.art.rewriting.ArtProfileAdditions.ArtProfileAdditionsBuilder;
 import java.util.function.Consumer;
@@ -34,6 +35,8 @@
     return NopArtProfileCollectionAdditions.getInstance();
   }
 
+  public abstract void addMethodIfContextIsInProfile(ProgramMethod method, ProgramMethod context);
+
   public abstract void applyIfContextIsInProfile(
       DexMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer);
 
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 811b1f5..973dec5 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
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.profile.art.rewriting;
 
+import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
+
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexClasspathClass;
@@ -56,10 +58,7 @@
 
   @Override
   public void acceptBackportedMethod(ProgramMethod backportedMethod, ProgramMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context,
-        additionsBuilder ->
-            additionsBuilder.addRule(backportedMethod).addRule(backportedMethod.getHolder()));
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(backportedMethod, context);
     parent.acceptBackportedMethod(backportedMethod, context);
   }
 
@@ -90,10 +89,7 @@
 
   @Override
   public void acceptDefaultAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
-    additionsCollection.applyIfContextIsInProfile(
-        method,
-        additionsBuilder ->
-            additionsBuilder.addRule(companionMethod).addRule(companionMethod.getHolder()));
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(companionMethod, method);
     parent.acceptDefaultAsCompanionMethod(method, companionMethod);
   }
 
@@ -114,9 +110,8 @@
 
   @Override
   public void acceptInvokeSpecialBridgeInfo(InvokeSpecialBridgeInfo info) {
-    additionsCollection.applyIfContextIsInProfile(
-        info.getVirtualMethod(),
-        additionsBuilder -> additionsBuilder.addRule(info.getNewDirectMethod()));
+    additionsCollection.addMethodIfContextIsInProfile(
+        info.getVirtualMethod(), info.getNewDirectMethod());
     parent.acceptInvokeSpecialBridgeInfo(info);
   }
 
@@ -149,15 +144,19 @@
 
   private void addLambdaVirtualMethodsIfLambdaImplementationIsInProfile(
       LambdaClass lambdaClass, ProgramMethod context) {
+    Target target = lambdaClass.getTarget();
     if (shouldConservativelyAddLambdaVirtualMethodsIfLambdaInstantiated(lambdaClass, context)) {
       additionsCollection.applyIfContextIsInProfile(
           context,
-          additionsBuilder ->
-              lambdaClass
-                  .getLambdaProgramClass()
-                  .forEachProgramVirtualMethod(additionsBuilder::addRule));
+          additionsBuilder -> {
+            lambdaClass
+                .getLambdaProgramClass()
+                .forEachProgramVirtualMethod(additionsBuilder::addRule);
+            if (target.getCallTarget() != target.getImplementationMethod()) {
+              additionsBuilder.addRule(target.getCallTarget());
+            }
+          });
     } else {
-      Target target = lambdaClass.getTarget();
       additionsCollection.applyIfContextIsInProfile(
           target.getImplementationMethod(),
           additionsBuilder -> {
@@ -207,41 +206,42 @@
       ProgramMethod bridge,
       DexProgramClass argumentClass,
       DexClassAndMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(argumentClass).addRule(bridge));
+    if (context.isProgramMethod()) {
+      additionsCollection.applyIfContextIsInProfile(
+          context.asProgramMethod(),
+          additionsBuilder -> additionsBuilder.addRule(argumentClass).addRule(bridge));
+    } else {
+      additionsCollection.apply(
+          additions ->
+              additions.addClassRule(argumentClass).addMethodRule(bridge, emptyConsumer()));
+    }
     parent.acceptNestConstructorBridge(target, bridge, argumentClass, context);
   }
 
   @Override
   public void acceptNestFieldGetBridge(
       ProgramField target, ProgramMethod bridge, DexClassAndMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(bridge));
+    additionsCollection.addMethodIfContextIsInProfile(bridge, context, emptyConsumer());
     parent.acceptNestFieldGetBridge(target, bridge, context);
   }
 
   @Override
   public void acceptNestFieldPutBridge(
       ProgramField target, ProgramMethod bridge, DexClassAndMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(bridge));
+    additionsCollection.addMethodIfContextIsInProfile(bridge, context, emptyConsumer());
     parent.acceptNestFieldPutBridge(target, bridge, context);
   }
 
   @Override
   public void acceptNestMethodBridge(
       ProgramMethod target, ProgramMethod bridge, DexClassAndMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(bridge));
+    additionsCollection.addMethodIfContextIsInProfile(bridge, context, emptyConsumer());
     parent.acceptNestMethodBridge(target, bridge, context);
   }
 
   @Override
   public void acceptOutlinedMethod(ProgramMethod outlinedMethod, ProgramMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context,
-        additionsBuilder ->
-            additionsBuilder.addRule(outlinedMethod).addRule(outlinedMethod.getHolder()));
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(outlinedMethod, context);
     parent.acceptOutlinedMethod(outlinedMethod, context);
   }
 
@@ -269,30 +269,26 @@
 
   @Override
   public void acceptRecordEqualsHelperMethod(ProgramMethod method, ProgramMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(method));
+    additionsCollection.addMethodIfContextIsInProfile(method, context);
     parent.acceptRecordEqualsHelperMethod(method, context);
   }
 
   @Override
   public void acceptRecordGetFieldsAsObjectsHelperMethod(
       ProgramMethod method, ProgramMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(method));
+    additionsCollection.addMethodIfContextIsInProfile(method, context);
     parent.acceptRecordGetFieldsAsObjectsHelperMethod(method, context);
   }
 
   @Override
   public void acceptRecordHashCodeHelperMethod(ProgramMethod method, ProgramMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(method).addRule(method.getHolder()));
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
     parent.acceptRecordHashCodeHelperMethod(method, context);
   }
 
   @Override
   public void acceptRecordToStringHelperMethod(ProgramMethod method, ProgramMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context, additionsBuilder -> additionsBuilder.addRule(method).addRule(method.getHolder()));
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
     parent.acceptRecordToStringHelperMethod(method, context);
   }
 
@@ -310,44 +306,48 @@
 
   @Override
   public void acceptTwrCloseResourceMethod(ProgramMethod closeMethod, ProgramMethod context) {
-    additionsCollection.applyIfContextIsInProfile(
-        context,
-        additionsBuilder -> additionsBuilder.addRule(closeMethod).addRule(closeMethod.getHolder()));
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(closeMethod, context);
     parent.acceptTwrCloseResourceMethod(closeMethod, context);
   }
 
   @Override
   public void acceptUtilityToStringIfNotNullMethod(ProgramMethod method, ProgramMethod context) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(context, method);
     parent.acceptUtilityToStringIfNotNullMethod(method, context);
   }
 
   @Override
   public void acceptUtilityThrowClassCastExceptionIfNotNullMethod(
       ProgramMethod method, ProgramMethod context) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
     parent.acceptUtilityThrowClassCastExceptionIfNotNullMethod(method, context);
   }
 
   @Override
   public void acceptUtilityThrowIllegalAccessErrorMethod(
       ProgramMethod method, ProgramMethod context) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
     parent.acceptUtilityThrowIllegalAccessErrorMethod(method, context);
   }
 
   @Override
   public void acceptUtilityThrowIncompatibleClassChangeErrorMethod(
       ProgramMethod method, ProgramMethod context) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
     parent.acceptUtilityThrowIncompatibleClassChangeErrorMethod(method, context);
   }
 
   @Override
   public void acceptUtilityThrowNoSuchMethodErrorMethod(
       ProgramMethod method, ProgramMethod context) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
     parent.acceptUtilityThrowNoSuchMethodErrorMethod(method, context);
   }
 
   @Override
   public void acceptUtilityThrowRuntimeExceptionWithMessageMethod(
       ProgramMethod method, ProgramMethod context) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
     parent.acceptUtilityThrowRuntimeExceptionWithMessageMethod(method, context);
   }
 
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
index 6843852..a317c8d 100644
--- 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
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.profile.art.rewriting;
 
+import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
+
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexClasspathClass;
@@ -40,8 +42,10 @@
   }
 
   @Override
-  public void acceptAPIConversionCallback(ProgramMethod method) {
-    parent.acceptAPIConversionCallback(method);
+  public void acceptAPIConversionCallback(
+      ProgramMethod callbackMethod, ProgramMethod convertedMethod) {
+    additionsCollection.addMethodIfContextIsInProfile(callbackMethod, convertedMethod);
+    parent.acceptAPIConversionCallback(callbackMethod, convertedMethod);
   }
 
   @Override
@@ -88,8 +92,7 @@
   @Override
   public void acceptInterfaceMethodDesugaringForwardingMethod(
       ProgramMethod method, DexClassAndMethod baseMethod) {
-    additionsCollection.applyIfContextIsInProfile(
-        baseMethod, additionsBuilder -> additionsBuilder.addRule(method));
+    additionsCollection.addMethodIfContextIsInProfile(method, baseMethod, emptyConsumer());
     parent.acceptInterfaceMethodDesugaringForwardingMethod(method, baseMethod);
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMemberRebindingEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMemberRebindingEventConsumer.java
new file mode 100644
index 0000000..df87170
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMemberRebindingEventConsumer.java
@@ -0,0 +1,53 @@
+// 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 static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.optimize.MemberRebindingEventConsumer;
+import com.android.tools.r8.optimize.MemberRebindingLens;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
+public class ArtProfileRewritingMemberRebindingEventConsumer
+    implements MemberRebindingEventConsumer {
+
+  private final ConcreteArtProfileCollectionAdditions additionsCollection;
+  private final MemberRebindingEventConsumer parent;
+
+  private ArtProfileRewritingMemberRebindingEventConsumer(
+      ConcreteArtProfileCollectionAdditions additionsCollection,
+      MemberRebindingEventConsumer parent) {
+    this.additionsCollection = additionsCollection;
+    this.parent = parent;
+  }
+
+  public static MemberRebindingEventConsumer attach(
+      AppView<AppInfoWithLiveness> appView, MemberRebindingEventConsumer eventConsumer) {
+    ArtProfileCollectionAdditions additionsCollection =
+        ArtProfileCollectionAdditions.create(appView);
+    if (additionsCollection.isNop()) {
+      return eventConsumer;
+    }
+    return new ArtProfileRewritingMemberRebindingEventConsumer(
+        additionsCollection.asConcrete(), eventConsumer);
+  }
+
+  @Override
+  public void acceptMemberRebindingBridgeMethod(
+      ProgramMethod bridgeMethod, DexClassAndMethod targetMethod) {
+    additionsCollection.addMethodIfContextIsInProfile(bridgeMethod, targetMethod, emptyConsumer());
+    parent.acceptMemberRebindingBridgeMethod(bridgeMethod, targetMethod);
+  }
+
+  @Override
+  public void finished(
+      AppView<AppInfoWithLiveness> appView, MemberRebindingLens memberRebindingLens) {
+    additionsCollection.commit(appView);
+    parent.finished(appView, memberRebindingLens);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java
index 325422e..b359bf5 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingMethodProcessorEventConsumer.java
@@ -64,6 +64,12 @@
   }
 
   @Override
+  public void acceptServiceLoaderLoadUtilityMethod(ProgramMethod method, ProgramMethod context) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(method, context);
+    parent.acceptServiceLoaderLoadUtilityMethod(method, context);
+  }
+
+  @Override
   public void acceptUtilityToStringIfNotNullMethod(ProgramMethod method, ProgramMethod context) {
     additionsCollection.applyIfContextIsInProfile(
         context, additionsBuilder -> additionsBuilder.addRule(method).addRule(method.getHolder()));
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java
new file mode 100644
index 0000000..9a61ea9
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingRootSetBuilderEventConsumer.java
@@ -0,0 +1,76 @@
+// 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.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.shaking.RootSetBuilderEventConsumer;
+import com.android.tools.r8.shaking.RootSetUtils.RootSet;
+
+public class ArtProfileRewritingRootSetBuilderEventConsumer implements RootSetBuilderEventConsumer {
+
+  private final ConcreteArtProfileCollectionAdditions additionsCollection;
+  private final RootSetBuilderEventConsumer parent;
+
+  private ArtProfileRewritingRootSetBuilderEventConsumer(
+      ConcreteArtProfileCollectionAdditions additionsCollection,
+      RootSetBuilderEventConsumer parent) {
+    this.additionsCollection = additionsCollection;
+    this.parent = parent;
+  }
+
+  public static RootSetBuilderEventConsumer attach(
+      AppView<? extends AppInfoWithClassHierarchy> appView,
+      RootSetBuilderEventConsumer eventConsumer) {
+    ArtProfileCollectionAdditions additionsCollection =
+        ArtProfileCollectionAdditions.create(appView);
+    if (additionsCollection.isNop()) {
+      return eventConsumer;
+    }
+    return new ArtProfileRewritingRootSetBuilderEventConsumer(
+        additionsCollection.asConcrete(), eventConsumer);
+  }
+
+  @Override
+  public void acceptCompanionClassClinit(ProgramMethod method) {
+    parent.acceptCompanionClassClinit(method);
+  }
+
+  @Override
+  public void acceptDefaultAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
+    additionsCollection.addMethodAndHolderIfContextIsInProfile(companionMethod, method);
+    parent.acceptDefaultAsCompanionMethod(method, companionMethod);
+  }
+
+  @Override
+  public void acceptPrivateAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
+    additionsCollection.applyIfContextIsInProfile(
+        method,
+        additionsBuilder ->
+            additionsBuilder
+                .addRule(companionMethod)
+                .addRule(companionMethod.getHolder())
+                .removeMovedMethodRule(method, companionMethod));
+    parent.acceptPrivateAsCompanionMethod(method, companionMethod);
+  }
+
+  @Override
+  public void acceptStaticAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
+    additionsCollection.applyIfContextIsInProfile(
+        method,
+        additionsBuilder ->
+            additionsBuilder
+                .addRule(companionMethod)
+                .addRule(companionMethod.getHolder())
+                .removeMovedMethodRule(method, companionMethod));
+    parent.acceptStaticAsCompanionMethod(method, companionMethod);
+  }
+
+  @Override
+  public void finished(AppView<? extends AppInfoWithClassHierarchy> appView, RootSet rootSet) {
+    additionsCollection.commit(appView);
+  }
+}
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 85c54e1..6dd6a31 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,12 +5,14 @@
 package com.android.tools.r8.profile.art.rewriting;
 
 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.DexMethod;
+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.profile.art.ArtProfile;
 import com.android.tools.r8.profile.art.ArtProfileCollection;
+import com.android.tools.r8.profile.art.ArtProfileMethodRuleInfoImpl;
 import com.android.tools.r8.profile.art.NonEmptyArtProfileCollection;
 import com.android.tools.r8.profile.art.rewriting.ArtProfileAdditions.ArtProfileAdditionsBuilder;
 import com.google.common.collect.Iterables;
@@ -36,8 +38,37 @@
     assert !additionsCollection.isEmpty();
   }
 
+  public void addMethodIfContextIsInProfile(ProgramMethod method, ProgramMethod context) {
+    applyIfContextIsInProfile(context, additionsBuilder -> additionsBuilder.addRule(method));
+  }
+
+  public void addMethodIfContextIsInProfile(
+      ProgramMethod method,
+      DexClassAndMethod context,
+      Consumer<ArtProfileMethodRuleInfoImpl.Builder> methodRuleInfoBuilderConsumer) {
+    if (context.isProgramMethod()) {
+      applyIfContextIsInProfile(
+          context.asProgramMethod(), additionsBuilder -> additionsBuilder.addRule(method));
+    } else {
+      apply(
+          artProfileAdditions ->
+              artProfileAdditions.addMethodRule(method, methodRuleInfoBuilderConsumer));
+    }
+  }
+
+  public void addMethodAndHolderIfContextIsInProfile(ProgramMethod method, ProgramMethod context) {
+    applyIfContextIsInProfile(
+        context, additionsBuilder -> additionsBuilder.addRule(method).addRule(method.getHolder()));
+  }
+
+  void apply(Consumer<ArtProfileAdditions> additionsConsumer) {
+    for (ArtProfileAdditions artProfileAdditions : additionsCollection) {
+      additionsConsumer.accept(artProfileAdditions);
+    }
+  }
+
   void applyIfContextIsInProfile(
-      DexClass context, Consumer<ArtProfileAdditions> additionsConsumer) {
+      DexProgramClass context, Consumer<ArtProfileAdditions> additionsConsumer) {
     applyIfContextIsInProfile(context.getType(), additionsConsumer);
   }
 
@@ -48,7 +79,7 @@
   }
 
   public void applyIfContextIsInProfile(
-      DexClassAndMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
+      ProgramMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
     applyIfContextIsInProfile(context.getReference(), builderConsumer);
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java
index a0c6925..fe61aaa 100644
--- a/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/NopArtProfileCollectionAdditions.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.profile.art.ArtProfileCollection;
 import com.android.tools.r8.profile.art.rewriting.ArtProfileAdditions.ArtProfileAdditionsBuilder;
 import java.util.function.Consumer;
@@ -23,6 +24,11 @@
   }
 
   @Override
+  public void addMethodIfContextIsInProfile(ProgramMethod method, ProgramMethod context) {
+    // Intentionally empty.
+  }
+
+  @Override
   public void applyIfContextIsInProfile(
       DexMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
     // Intentionally empty.
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 bbdb059..13e0528 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -4010,7 +4010,7 @@
     // registered first and no dependencies may exist among them.
     SyntheticAdditions additions = new SyntheticAdditions(appView.createProcessorContext());
     desugar(additions);
-    synthesizeInterfaceMethodBridges(additions);
+    synthesizeInterfaceMethodBridges();
     if (additions.isEmpty()) {
       return;
     }
@@ -4164,11 +4164,13 @@
     }
   }
 
-  private void synthesizeInterfaceMethodBridges(SyntheticAdditions additions) {
-    for (ProgramMethod bridge : syntheticInterfaceMethodBridges.values()) {
+  private void synthesizeInterfaceMethodBridges() {
+    for (InterfaceMethodSyntheticBridgeAction action : syntheticInterfaceMethodBridges.values()) {
+      ProgramMethod bridge = action.getMethodToKeep();
       DexProgramClass holder = bridge.getHolder();
       DexEncodedMethod method = bridge.getDefinition();
       holder.addVirtualMethod(method);
+      artProfileCollectionAdditions.addMethodIfContextIsInProfile(bridge, action.getSingleTarget());
     }
     syntheticInterfaceMethodBridges.clear();
   }
@@ -4643,8 +4645,8 @@
     return builder.buildConsequentRootSet();
   }
 
-  private final Map<DexMethod, ProgramMethod> syntheticInterfaceMethodBridges =
-      new LinkedHashMap<>();
+  private final Map<DexMethod, InterfaceMethodSyntheticBridgeAction>
+      syntheticInterfaceMethodBridges = new LinkedHashMap<>();
 
   private void identifySyntheticInterfaceMethodBridges(
       InterfaceMethodSyntheticBridgeAction action) {
@@ -4656,8 +4658,7 @@
     if (methodToKeep != singleTarget
         && !syntheticInterfaceMethodBridges.containsKey(
             methodToKeep.getDefinition().getReference())) {
-      syntheticInterfaceMethodBridges.put(
-          methodToKeep.getDefinition().getReference(), methodToKeep);
+      syntheticInterfaceMethodBridges.put(methodToKeep.getDefinition().getReference(), action);
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java
new file mode 100644
index 0000000..b49a15d
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilderEventConsumer.java
@@ -0,0 +1,59 @@
+// 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.shaking;
+
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.desugar.itf.InterfaceMethodDesugaringBaseEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingRootSetBuilderEventConsumer;
+import com.android.tools.r8.shaking.RootSetUtils.RootSet;
+
+public interface RootSetBuilderEventConsumer extends InterfaceMethodDesugaringBaseEventConsumer {
+
+  static RootSetBuilderEventConsumer create(AppView<? extends AppInfoWithClassHierarchy> appView) {
+    return ArtProfileRewritingRootSetBuilderEventConsumer.attach(appView, empty());
+  }
+
+  static EmptyRootSetBuilderEventConsumer empty() {
+    return EmptyRootSetBuilderEventConsumer.getInstance();
+  }
+
+  default void finished(AppView<? extends AppInfoWithClassHierarchy> appView, RootSet rootSet) {}
+
+  class EmptyRootSetBuilderEventConsumer implements RootSetBuilderEventConsumer {
+
+    private static final EmptyRootSetBuilderEventConsumer INSTANCE =
+        new EmptyRootSetBuilderEventConsumer();
+
+    private EmptyRootSetBuilderEventConsumer() {}
+
+    static EmptyRootSetBuilderEventConsumer getInstance() {
+      return INSTANCE;
+    }
+
+    @Override
+    public void acceptCompanionClassClinit(ProgramMethod method) {
+      // Intentionally empty.
+    }
+
+    @Override
+    public void acceptDefaultAsCompanionMethod(
+        ProgramMethod method, ProgramMethod companionMethod) {
+      // Intentionally empty.
+    }
+
+    @Override
+    public void acceptPrivateAsCompanionMethod(
+        ProgramMethod method, ProgramMethod companionMethod) {
+      // Intentionally empty.
+    }
+
+    @Override
+    public void acceptStaticAsCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
+      // Intentionally empty.
+    }
+  }
+}
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 149201d..bda1564 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -50,7 +50,6 @@
 import com.android.tools.r8.ir.analysis.type.DynamicType;
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
 import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper;
-import com.android.tools.r8.ir.desugar.itf.InterfaceMethodDesugaringBaseEventConsumer;
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
 import com.android.tools.r8.ir.optimize.membervaluepropagation.assume.AssumeInfo;
 import com.android.tools.r8.logging.Log;
@@ -113,6 +112,7 @@
 
     private final AppView<? extends AppInfoWithClassHierarchy> appView;
     private AssumeInfoCollection.Builder assumeInfoCollectionBuilder;
+    private final RootSetBuilderEventConsumer eventConsumer;
     private final SubtypingInfo subtypingInfo;
     private final DirectMappedDexApplication application;
     private final Iterable<? extends ProguardConfigurationRule> rules;
@@ -159,6 +159,7 @@
         SubtypingInfo subtypingInfo,
         Iterable<? extends ProguardConfigurationRule> rules) {
       this.appView = appView;
+      this.eventConsumer = RootSetBuilderEventConsumer.create(appView);
       this.subtypingInfo = subtypingInfo;
       this.application = appView.appInfo().app().asDirect();
       this.rules = rules;
@@ -385,27 +386,30 @@
             alwaysInline,
             bypassClinitforInlining);
       }
-      return new RootSet(
-          dependentMinimumKeepInfo,
-          ImmutableList.copyOf(reasonAsked.values()),
-          alwaysInline,
-          neverInlineDueToSingleCaller,
-          bypassClinitforInlining,
-          whyAreYouNotInlining,
-          reprocess,
-          neverReprocess,
-          alwaysClassInline,
-          neverClassInline,
-          noUnusedInterfaceRemoval,
-          noVerticalClassMerging,
-          noHorizontalClassMerging,
-          neverPropagateValue,
-          mayHaveSideEffects,
-          dependentKeepClassCompatRule,
-          identifierNameStrings,
-          ifRules,
-          Lists.newArrayList(delayedRootSetActionItems),
-          pendingMethodMoveInverse);
+      RootSet rootSet =
+          new RootSet(
+              dependentMinimumKeepInfo,
+              ImmutableList.copyOf(reasonAsked.values()),
+              alwaysInline,
+              neverInlineDueToSingleCaller,
+              bypassClinitforInlining,
+              whyAreYouNotInlining,
+              reprocess,
+              neverReprocess,
+              alwaysClassInline,
+              neverClassInline,
+              noUnusedInterfaceRemoval,
+              noVerticalClassMerging,
+              noHorizontalClassMerging,
+              neverPropagateValue,
+              mayHaveSideEffects,
+              dependentKeepClassCompatRule,
+              identifierNameStrings,
+              ifRules,
+              Lists.newArrayList(delayedRootSetActionItems),
+              pendingMethodMoveInverse);
+      eventConsumer.finished(appView, rootSet);
+      return rootSet;
     }
 
     private void propagateAssumeRules(DexClass clazz) {
@@ -1582,32 +1586,7 @@
         ProgramMethod method = item.asMethod();
         ProgramMethod companion =
             interfaceDesugaringSyntheticHelper.ensureMethodOfProgramCompanionClassStub(
-                method,
-                new InterfaceMethodDesugaringBaseEventConsumer() {
-
-                  @Override
-                  public void acceptCompanionClassClinit(ProgramMethod method) {
-                    // No processing of synthesized CC.<clinit>. They will be picked up by tracing.
-                  }
-
-                  @Override
-                  public void acceptDefaultAsCompanionMethod(
-                      ProgramMethod method, ProgramMethod companionMethod) {
-                    // The move will be included in the pending-inverse map below.
-                  }
-
-                  @Override
-                  public void acceptPrivateAsCompanionMethod(
-                      ProgramMethod method, ProgramMethod companion) {
-                    // The move will be included in the pending-inverse map below.
-                  }
-
-                  @Override
-                  public void acceptStaticAsCompanionMethod(
-                      ProgramMethod method, ProgramMethod companion) {
-                    // The move will be included in the pending-inverse map below.
-                  }
-                });
+                method, eventConsumer);
         // Add the method to the inverse map as tracing will now directly target the CC method.
         pendingMethodMoveInverse.put(companion, method);
         // Only shrinking and optimization are transferred for interface companion methods.
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index ce1acd6..7480fc8 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -839,7 +839,7 @@
   private final ApiModelTestingOptions apiModelTestingOptions = new ApiModelTestingOptions();
   private final DesugarSpecificOptions desugarSpecificOptions = new DesugarSpecificOptions();
   private final MappingComposeOptions mappingComposeOptions = new MappingComposeOptions();
-  private final ArtProfileOptions artProfileOptions = new ArtProfileOptions();
+  private final ArtProfileOptions artProfileOptions = new ArtProfileOptions(this);
   private final StartupOptions startupOptions = new StartupOptions();
   private final StartupInstrumentationOptions startupInstrumentationOptions =
       new StartupInstrumentationOptions();