Split rewriting of record invokedynamic from DexItemBasedXXXString
Bug: b/293592205
Change-Id: I8c0136b093874d77602624454e3bb8bf005696b5
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 91a8318..5f11e97 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -59,9 +59,12 @@
import com.android.tools.r8.jar.CfApplicationWriter;
import com.android.tools.r8.kotlin.KotlinMetadataRewriter;
import com.android.tools.r8.kotlin.KotlinMetadataUtils;
+import com.android.tools.r8.naming.IdentifierMinifier;
import com.android.tools.r8.naming.Minifier;
+import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.PrefixRewritingNamingLens;
import com.android.tools.r8.naming.ProguardMapMinifier;
+import com.android.tools.r8.naming.RecordInvokeDynamicRewriter;
import com.android.tools.r8.naming.RecordRewritingNamingLens;
import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.optimize.LegacyAccessModifier;
@@ -767,8 +770,12 @@
appView.setNamingLens(new Minifier(appView.withLiveness()).run(executorService, timing));
timing.end();
} else {
- new Minifier(appView.withLiveness())
- .replaceDexItemBasedConstString(executorService, timing);
+ timing.begin("MinifyIdentifiers");
+ new IdentifierMinifier(appView, NamingLens.getIdentityLens()).run(executorService);
+ timing.end();
+ timing.begin("RecordInvokeDynamicRewrite");
+ new RecordInvokeDynamicRewriter(appView, NamingLens.getIdentityLens()).run(executorService);
+ timing.end();
}
appView.appInfo().notifyMinifierFinished();
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
index 8b4970f..ba443fe 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
@@ -22,7 +22,6 @@
import com.android.tools.r8.graph.DexValue.DexItemBasedValueString;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.desugar.records.RecordCfToCfRewriter;
import com.android.tools.r8.shaking.ProguardClassFilter;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.DescriptorUtils;
@@ -36,21 +35,19 @@
* Replaces all instances of DexItemBasedConstString by ConstString, and all instances of
* DexItemBasedValueString by DexValueString.
*/
-class IdentifierMinifier {
+public class IdentifierMinifier {
private final AppView<?> appView;
private final ProguardClassFilter adaptClassStrings;
- private final RecordCfToCfRewriter recordCfToCfRewriter;
private final NamingLens lens;
- IdentifierMinifier(AppView<?> appView, NamingLens lens) {
+ public IdentifierMinifier(AppView<?> appView, NamingLens lens) {
this.appView = appView;
this.adaptClassStrings = appView.options().getProguardConfiguration().getAdaptClassStrings();
- this.recordCfToCfRewriter = RecordCfToCfRewriter.create(appView);
this.lens = lens;
}
- void run(ExecutorService executorService) throws ExecutionException {
+ public void run(ExecutorService executorService) throws ExecutionException {
if (!adaptClassStrings.isEmpty()) {
adaptClassStrings(executorService);
}
@@ -211,9 +208,6 @@
return new CfConstString(
cnst.getNameComputationInfo()
.computeNameFor(cnst.getItem(), appView, appView.graphLens(), lens));
- } else if (recordCfToCfRewriter != null && instruction.isInvokeDynamic()) {
- return recordCfToCfRewriter.rewriteRecordInvokeDynamic(
- instruction.asInvokeDynamic(), programMethod, lens);
}
return instruction;
},
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 229de6a..40490d4 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -86,18 +86,14 @@
new IdentifierMinifier(appView, lens).run(executorService);
timing.end();
+ timing.begin("RecordInvokeDynamicRewrite");
+ new RecordInvokeDynamicRewriter(appView, lens).run(executorService);
+ timing.end();
+
appView.notifyOptimizationFinishedForTesting();
return lens;
}
- public void replaceDexItemBasedConstString(ExecutorService executorService, Timing timing)
- throws ExecutionException {
- timing.begin("ReplaceDexItemBasedConstString");
- new IdentifierMinifier(appView, NamingLens.getIdentityLens())
- .replaceDexItemBasedConstString(executorService);
- timing.end();
- }
-
abstract static class BaseMinificationNamingStrategy {
// We have to ensure that the names proposed by the minifier is not used in the obfuscation
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 f08df03..423978d 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
@@ -156,6 +156,10 @@
new IdentifierMinifier(appView, lens).run(executorService);
timing.end();
+ timing.begin("RecordInvokeDynamicRewrite");
+ new RecordInvokeDynamicRewriter(appView, lens).run(executorService);
+ timing.begin("MinifyIdentifiers");
+
appView.notifyOptimizationFinishedForTesting();
return lens;
}
diff --git a/src/main/java/com/android/tools/r8/naming/RecordInvokeDynamicRewriter.java b/src/main/java/com/android/tools/r8/naming/RecordInvokeDynamicRewriter.java
new file mode 100644
index 0000000..c59aaf0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/naming/RecordInvokeDynamicRewriter.java
@@ -0,0 +1,67 @@
+// 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.naming;
+
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Code;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.desugar.records.RecordCfToCfRewriter;
+import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.ThreadUtils;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+
+/** Rewrites the record invokedynamic in hashCode, equals and toString. */
+public class RecordInvokeDynamicRewriter {
+
+ private final AppView<?> appView;
+ private final RecordCfToCfRewriter recordCfToCfRewriter;
+ private final NamingLens lens;
+
+ public RecordInvokeDynamicRewriter(AppView<?> appView, NamingLens lens) {
+ this.appView = appView;
+ this.recordCfToCfRewriter = RecordCfToCfRewriter.create(appView);
+ this.lens = lens;
+ }
+
+ public void run(ExecutorService executorService) throws ExecutionException {
+ ThreadUtils.processItems(
+ appView.appInfo().classes(),
+ clazz -> {
+ clazz.forEachProgramMethodMatching(
+ DexEncodedMethod::hasCode, this::rewriteRecordInvokeDynamicInMethod);
+ },
+ executorService);
+ }
+
+ private void rewriteRecordInvokeDynamicInMethod(ProgramMethod programMethod) {
+ if (recordCfToCfRewriter == null) {
+ return;
+ }
+ if (!programMethod.getHolder().isRecord()) {
+ return;
+ }
+ Code code = programMethod.getDefinition().getCode();
+ assert code != null;
+ if (code.isDexCode()) {
+ return;
+ }
+ List<CfInstruction> instructions = code.asCfCode().getInstructions();
+ List<CfInstruction> newInstructions =
+ ListUtils.mapOrElse(
+ instructions,
+ (int index, CfInstruction instruction) -> {
+ if (instruction.isInvokeDynamic()) {
+ return recordCfToCfRewriter.rewriteRecordInvokeDynamic(
+ instruction.asInvokeDynamic(), programMethod, lens);
+ }
+ return instruction;
+ },
+ instructions);
+ code.asCfCode().setInstructions(newInstructions);
+ }
+}