Version 1.6.89 Cherry pick: Update ServiceLoaderRewriter to synchronize on synthetic clazz creation CL: https://r8-review.googlesource.com/50340 Bug: 153127674 Bug: 155106999 Change-Id: I32e197581956d65374c7d6e2b0a7fcc7cfce5f55
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java index 1427a23..a705522 100644 --- a/src/main/java/com/android/tools/r8/Version.java +++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@ // This field is accessed from release scripts using simple pattern matching. // Therefore, changing this field could break our release scripts. - public static final String LABEL = "1.6.88"; + public static final String LABEL = "1.6.89"; private Version() { }
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java index c99cf51..b33eef1 100644 --- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java +++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -4,6 +4,7 @@ package com.android.tools.r8.graph; import static com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement.computeLeastUpperBoundOfInterfaces; +import static com.android.tools.r8.ir.optimize.ServiceLoaderRewriter.SERVICE_LOADER_CLASS_NAME; import static com.google.common.base.Predicates.alwaysTrue; import com.android.tools.r8.dex.Constants; @@ -301,6 +302,8 @@ public final DexType invocationHandlerType = createType(invocationHandlerDescriptor); public final DexType proxyType = createType(proxyDescriptor); public final DexType serviceLoaderType = createType(serviceLoaderDescriptor); + public final DexType serviceLoaderRewrittenClassType = + createType("L" + SERVICE_LOADER_CLASS_NAME + ";"); public final DexType serviceLoaderConfigurationErrorType = createType(serviceLoaderConfigurationErrorDescriptor); public final DexType listType = createType(listDescriptor);
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 db13388..c590a21 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
@@ -36,6 +36,7 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; /** * ServiceLoaderRewriter will attempt to rewrite calls on the form of: ServiceLoader.load(X.class, @@ -69,7 +70,7 @@ public static final String SERVICE_LOADER_CLASS_NAME = "$$ServiceLoaderMethods"; private static final String SERVICE_LOADER_METHOD_PREFIX_NAME = "$load"; - private DexProgramClass synthesizedClass; + private AtomicReference<DexProgramClass> synthesizedClass = new AtomicReference<>(); private ConcurrentHashMap<DexType, DexEncodedMethod> synthesizedServiceLoaders = new ConcurrentHashMap<>(); @@ -82,7 +83,7 @@ } public DexProgramClass getSynthesizedClass() { - return synthesizedClass; + return synthesizedClass.get(); } public void rewrite(IRCode code) { @@ -185,40 +186,12 @@ } private DexEncodedMethod createSynthesizedMethod(DexType serviceType, List<DexClass> classes) { - DexType serviceLoaderType = - appView.dexItemFactory().createType("L" + SERVICE_LOADER_CLASS_NAME + ";"); - if (synthesizedClass == null) { - assert !appView.options().encodeChecksums; - ChecksumSupplier checksumSupplier = DexProgramClass::invalidChecksumRequest; - synthesizedClass = - new DexProgramClass( - serviceLoaderType, - null, - new SynthesizedOrigin("Service Loader desugaring", getClass()), - ClassAccessFlags.fromDexAccessFlags( - Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PUBLIC), - appView.dexItemFactory().objectType, - DexTypeList.empty(), - appView.dexItemFactory().createString("ServiceLoader"), - null, - Collections.emptyList(), - null, - Collections.emptyList(), - DexAnnotationSet.empty(), - DexEncodedField.EMPTY_ARRAY, // Static fields. - DexEncodedField.EMPTY_ARRAY, // Instance fields. - DexEncodedMethod.EMPTY_ARRAY, - DexEncodedMethod.EMPTY_ARRAY, // Virtual methods. - appView.dexItemFactory().getSkipNameValidationForTesting(), - checksumSupplier); - appView.appInfo().addSynthesizedClass(synthesizedClass); - } DexProto proto = appView.dexItemFactory().createProto(appView.dexItemFactory().iteratorType); DexMethod method = appView .dexItemFactory() .createMethod( - serviceLoaderType, + appView.dexItemFactory().serviceLoaderRewrittenClassType, proto, SERVICE_LOADER_METHOD_PREFIX_NAME + atomicInteger.incrementAndGet()); MethodAccessFlags methodAccess = @@ -230,10 +203,48 @@ DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), ServiceLoaderSourceCode.generate(serviceType, classes, appView.dexItemFactory())); - synthesizedClass.addDirectMethod(encodedMethod); + getOrSetSynthesizedClass().addDirectMethod(encodedMethod); return encodedMethod; } + private DexProgramClass getOrSetSynthesizedClass() { + if (synthesizedClass.get() != null) { + return synthesizedClass.get(); + } + assert !appView.options().encodeChecksums; + ChecksumSupplier checksumSupplier = DexProgramClass::invalidChecksumRequest; + DexProgramClass clazz = + synthesizedClass.updateAndGet( + existingClazz -> { + if (existingClazz != null) { + return existingClazz; + } + return new DexProgramClass( + appView.dexItemFactory().serviceLoaderRewrittenClassType, + null, + new SynthesizedOrigin("Service Loader desugaring", getClass()), + ClassAccessFlags.fromDexAccessFlags( + Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PUBLIC), + appView.dexItemFactory().objectType, + DexTypeList.empty(), + appView.dexItemFactory().createString("ServiceLoader"), + null, + Collections.emptyList(), + null, + Collections.emptyList(), + DexAnnotationSet.empty(), + DexEncodedField.EMPTY_ARRAY, // Static fields. + DexEncodedField.EMPTY_ARRAY, // Instance fields. + DexEncodedMethod.EMPTY_ARRAY, + DexEncodedMethod.EMPTY_ARRAY, // Virtual methods. + appView.dexItemFactory().getSkipNameValidationForTesting(), + checksumSupplier); + }); + assert clazz != null; + appView.appInfo().addSynthesizedClass(clazz); + return clazz; + } + /** * Rewriter assumes that the code is of the form: *