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:
    *