[GlobalSynthetics] Add var-handle desugared class to output
Bug: b/280016114
Change-Id: I4ba3402aad7014f17ec79814782b8a2c518d99a3
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
index 827931b..b0d984f 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsGenerator.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.androidapi.ComputedApiLevel.KnownApiLevel;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
+import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
@@ -30,16 +31,20 @@
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodCollection.MethodCollectionFactory;
import com.android.tools.r8.graph.NestHostClassAttribute;
+import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ThrowExceptionCode;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.desugar.TypeRewriter;
import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
-import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaring;
+import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaringEventConsumer;
import com.android.tools.r8.naming.RecordRewritingNamingLens;
+import com.android.tools.r8.naming.VarHandleDesugaringRewritingNamingLens;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.MainDexInfo;
+import com.android.tools.r8.synthesis.SyntheticFinalization;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
import com.android.tools.r8.synthesis.SyntheticNaming;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
@@ -116,13 +121,15 @@
AppView<AppInfo> appView = readApp(app, options, executorService, timing);
timing.end();
- timing.time(
- "Create global synthetics",
- () -> createGlobalSynthetics(appView, executorService));
+ timing.begin("Create global synthetics");
+ createGlobalSynthetics(appView, timing, executorService);
+ timing.end();
ApplicationWriter.create(appView, options.getMarker()).write(executorService, app);
} catch (ExecutionException e) {
throw unwrapExecutionException(e);
+ } catch (IOException e) {
+ throw new CompilationError(e.getMessage(), e);
} finally {
options.signalFinishedToConsumers();
// Dump timings.
@@ -156,7 +163,8 @@
}
private static void createGlobalSynthetics(
- AppView<AppInfo> appView, ExecutorService executorService) throws ExecutionException {
+ AppView<AppInfo> appView, Timing timing, ExecutorService executorService)
+ throws ExecutionException, IOException {
assert ensureAllGlobalSyntheticsModeled(appView.getSyntheticItems().getNaming());
Set<DexProgramClass> synthesizingContext =
ImmutableSet.of(createSynthesizingContext(appView.dexItemFactory()));
@@ -166,14 +174,20 @@
appView,
synthesizingContext,
recordTagClass -> recordTagClass.programMethods().forEach(methodsToProcess::add));
- NamingLens namingLens = RecordRewritingNamingLens.createRecordRewritingNamingLens(appView);
+ VarHandleDesugaring.ensureVarHandleClass(
+ appView,
+ new VarHandleDesugaringEventConsumer() {
+ @Override
+ public void acceptVarHandleDesugaringClass(DexProgramClass clazz) {
+ clazz.programMethods().forEach(methodsToProcess::add);
+ }
- // TODO(b/280016114): Create Var Handle
- // TODO(b/280016114): Create MethodHandlesLookup
+ @Override
+ public void acceptVarHandleDesugaringClassContext(
+ DexProgramClass clazz, ProgramDefinition context) {}
+ },
+ synthesizingContext);
- createAllApiStubs(appView, synthesizingContext, executorService);
-
- appView.setNamingLens(namingLens);
IRConverter converter = new IRConverter(appView);
converter.processSimpleSynthesizeMethods(methodsToProcess, executorService);
@@ -183,6 +197,24 @@
new AppInfo(
appView.appInfo().getSyntheticItems().commit(appView.app()),
appView.appInfo().getMainDexInfo()));
+
+ timing.time(
+ "Finalize synthetics",
+ () -> SyntheticFinalization.finalize(appView, timing, executorService));
+
+ appView.setNamingLens(RecordRewritingNamingLens.createRecordRewritingNamingLens(appView));
+ appView.setNamingLens(
+ VarHandleDesugaringRewritingNamingLens.createVarHandleDesugaringRewritingNamingLens(
+ appView));
+
+ createAllApiStubs(appView, synthesizingContext, executorService);
+
+ appView
+ .withoutClassHierarchy()
+ .setAppInfo(
+ new AppInfo(
+ appView.appInfo().getSyntheticItems().commit(appView.app()),
+ appView.appInfo().getMainDexInfo()));
}
private static DexProgramClass createSynthesizingContext(DexItemFactory factory) {
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java
index bc5e1c0..54cf918 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsGeneratorCommand.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.InternalOptions.DesugarState;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
import java.nio.file.Path;
@@ -137,6 +138,8 @@
assert !internal.passthroughDexCode;
internal.tool = Tool.GlobalSyntheticsGenerator;
+ internal.desugarState = DesugarState.ON;
+ internal.enableVarHandleDesugaring = true;
return internal;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
index 063286c..a77261e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
@@ -210,17 +210,20 @@
ensureMethodHandlesLookupClass(eventConsumer, ImmutableList.of(context));
}
- private void ensureVarHandleClass(
+ @SuppressWarnings("InconsistentOverloads")
+ public static void ensureVarHandleClass(
+ AppView<?> appView,
VarHandleDesugaringEventConsumer eventConsumer,
Collection<? extends ProgramDefinition> contexts) {
- assert contexts.stream().allMatch(context -> context.getContextType() != factory.varHandleType);
+ assert contexts.stream()
+ .allMatch(context -> context.getContextType() != appView.dexItemFactory().varHandleType);
DexProgramClass clazz =
appView
.getSyntheticItems()
.ensureGlobalClass(
() -> new MissingGlobalSyntheticsConsumerDiagnostic("VarHandle desugaring"),
kinds -> kinds.VAR_HANDLE,
- factory.varHandleType,
+ appView.dexItemFactory().varHandleType,
contexts,
appView,
builder ->
@@ -235,7 +238,7 @@
private void ensureVarHandleClass(
VarHandleDesugaringEventConsumer eventConsumer, ProgramDefinition context) {
if (context.getContextType() != factory.varHandleType) {
- ensureVarHandleClass(eventConsumer, ImmutableList.of(context));
+ ensureVarHandleClass(appView, eventConsumer, ImmutableList.of(context));
}
}
@@ -595,7 +598,7 @@
flags,
DexApplicationReadFlags::hasReadVarHandleReferenceFromProgramClass,
DexApplicationReadFlags::getVarHandleWitnesses,
- classes -> ensureVarHandleClass(eventConsumer, classes));
+ classes -> ensureVarHandleClass(appView, eventConsumer, classes));
}
private void synthesizeClassIfReferenced(
diff --git a/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java b/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java
index 13e2f29..47a78fe 100644
--- a/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java
+++ b/src/test/java/com/android/tools/r8/globalsynthetics/GlobalSyntheticsEnsureClassesOutputTest.java
@@ -13,6 +13,8 @@
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
@@ -48,7 +50,7 @@
.setProgramConsumer(new DexIndexedConsumer.ArchiveConsumer(output))
.build());
CodeInspector inspector = new CodeInspector(output);
- assertEquals(1024, inspector.allClasses().size());
+ assertEquals(1025, inspector.allClasses().size());
}
@Test
@@ -64,6 +66,7 @@
// The output contains a RecordTag type that is mapped back to the original java.lang.Record by
// our codeinspector.
expectedInOutput.add("Ljava/lang/Record;");
+ expectedInOutput.add("Ljava/lang/invoke/VarHandle;");
assertEquals(
expectedInOutput,
new CodeInspector(output)
@@ -84,7 +87,21 @@
.build(),
options ->
options.testing.globalSyntheticCreatedCallback =
- programClass -> generatedGlobalSynthetics.add(programClass.getTypeName()));
+ programClass -> {
+ if (programClass
+ .getClassReference()
+ .getDescriptor()
+ .equals(DexItemFactory.varHandleDescriptorString)) {
+ // We emit a desugared var handle. Rewrite it here to allow checking for final
+ // type names.
+ generatedGlobalSynthetics.add(
+ Reference.classFromDescriptor(
+ DexItemFactory.desugarVarHandleDescriptorString)
+ .getTypeName());
+ } else {
+ generatedGlobalSynthetics.add(programClass.getTypeName());
+ }
+ });
Set<String> readGlobalSynthetics =
new CodeInspector(output)
.allClasses().stream().map(FoundClassSubject::getFinalName).collect(Collectors.toSet());