Fix cf-to-cf handling of record call sites
Fixes: b/381812767
Change-Id: Ibdbf5ccd40d8322eb4953343efb923434e396e22
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
index 2bdebd2..94a7584 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorMethodReprocessingEnqueuer.java
@@ -11,7 +11,9 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.FieldResolutionResult;
import com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult;
import com.android.tools.r8.graph.ProgramField;
@@ -27,6 +29,7 @@
import com.android.tools.r8.ir.conversion.IRToLirFinalizer;
import com.android.tools.r8.ir.conversion.PostMethodProcessor;
import com.android.tools.r8.ir.desugar.LambdaDescriptor;
+import com.android.tools.r8.ir.desugar.records.RecordRewriterHelper;
import com.android.tools.r8.ir.optimize.AffectedValues;
import com.android.tools.r8.ir.optimize.info.CallSiteOptimizationInfo;
import com.android.tools.r8.lightir.LirCode;
@@ -323,9 +326,15 @@
public void registerCallSite(DexCallSite callSite) {
LambdaDescriptor descriptor =
LambdaDescriptor.tryInfer(callSite, appView, appViewWithLiveness.appInfo(), getContext());
- if (descriptor == null || descriptor.interfaces.isEmpty()) {
- return;
+ if (descriptor != null) {
+ registerLambdaCallSite(descriptor);
+ } else if (RecordRewriterHelper.isInvokeDynamicOnRecord(callSite, appView, getContext())) {
+ registerRecordCallSite(callSite);
}
+ }
+
+ private void registerLambdaCallSite(LambdaDescriptor descriptor) {
+ assert !descriptor.interfaces.isEmpty();
ProgramMethod resolvedMainMethod =
appViewWithLiveness
.appInfo()
@@ -343,6 +352,18 @@
}
}
+ private void registerRecordCallSite(DexCallSite callSite) {
+ for (DexValue bootstrapArg : callSite.getBootstrapArgs()) {
+ if (bootstrapArg.isDexValueMethodHandle()) {
+ DexMethodHandle handle = bootstrapArg.asDexValueMethodHandle().getValue();
+ assert handle.isFieldHandle();
+ if (registerFieldAccess(handle.asField())) {
+ break;
+ }
+ }
+ }
+ }
+
@Override
public void registerInstanceFieldRead(DexField field) {
registerFieldAccess(field);
@@ -363,19 +384,20 @@
registerFieldAccess(field);
}
- @SuppressWarnings("ReferenceEquality")
- private void registerFieldAccess(DexField field) {
+ private boolean registerFieldAccess(DexField field) {
FieldResolutionResult resolutionResult = appViewWithLiveness.appInfo().resolveField(field);
if (resolutionResult.getSingleProgramField() == null) {
- return;
+ return false;
}
ProgramField resolvedField = resolutionResult.getSingleProgramField();
DexField rewrittenFieldReference =
graphLens.getNextFieldSignature(resolvedField.getReference());
- if (rewrittenFieldReference != resolvedField.getReference()) {
+ if (rewrittenFieldReference.isNotIdenticalTo(resolvedField.getReference())) {
markAffected();
+ return true;
}
+ return false;
}
}
}
diff --git a/src/test/examplesJava17/records/RecordComponentSignatureTest.java b/src/test/examplesJava17/records/RecordComponentSignatureTest.java
index c4a5d63..d2d530b 100644
--- a/src/test/examplesJava17/records/RecordComponentSignatureTest.java
+++ b/src/test/examplesJava17/records/RecordComponentSignatureTest.java
@@ -133,8 +133,6 @@
@Test
public void testR8() throws Exception {
parameters.assumeR8TestParameters();
- // TODO(b/381812767): Fix for Class file
- assumeTrue(parameters.isDexRuntime());
testForR8(parameters.getBackend())
.addInnerClassesAndStrippedOuter(getClass())
.addLibraryFiles(ToolHelper.getAndroidJar(35))