NestConstructor synchronization

NestConstructor creation was not synchronized,
leading to multiple nestConstructor classes when
multiple threads get into ensureConstructorClass()
at the same time. Resulting code was working correctly
for some reason but I guess we should still try to
get a single class.

Change-Id: Ief1459ad57d28e90d6e611857d0c7b95823f1201
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
index cdd925a..2ece201 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
@@ -55,14 +55,17 @@
   // if come classes are on the classpath and not the program path.
   final Map<DexEncodedMethod, DexProgramClass> deferredBridgesToAdd = new ConcurrentHashMap<>();
   // Common single empty class for nest based private constructors
-  private DexProgramClass nestConstructor;
+  private final DexProgramClass nestConstructor;
+  private boolean nestConstructorUsed = false;
 
   NestBasedAccessDesugaring(AppView<?> appView) {
     this.appView = appView;
+    this.nestConstructor = createNestAccessConstructor();
   }
 
   DexType getNestConstructorType() {
-    return nestConstructor == null ? null : nestConstructor.type;
+    assert nestConstructor != null;
+    return nestConstructor.type;
   }
 
   // Extract the list of types in the programClass' nest, of host hostClass
@@ -202,36 +205,36 @@
     return appView.dexItemFactory().createString(fullName);
   }
 
+  private DexProgramClass createNestAccessConstructor() {
+    return new DexProgramClass(
+        appView.dexItemFactory().createType(FULL_NEST_CONTRUCTOR_NAME),
+        null,
+        new SynthesizedOrigin("Nest based access desugaring", getClass()),
+        // Make the synthesized class public since shared in the whole program.
+        ClassAccessFlags.fromDexAccessFlags(
+            Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PUBLIC),
+        appView.dexItemFactory().objectType,
+        DexTypeList.empty(),
+        appView.dexItemFactory().createString("nest"),
+        null,
+        Collections.emptyList(),
+        null,
+        Collections.emptyList(),
+        DexAnnotationSet.empty(),
+        DexEncodedField.EMPTY_ARRAY,
+        DexEncodedField.EMPTY_ARRAY,
+        DexEncodedMethod.EMPTY_ARRAY,
+        DexEncodedMethod.EMPTY_ARRAY,
+        appView.dexItemFactory().getSkipNameValidationForTesting());
+  }
+
   private DexProgramClass ensureNestConstructorClass() {
-    if (nestConstructor != null) {
-      return nestConstructor;
-    }
-    nestConstructor =
-        new DexProgramClass(
-            appView.dexItemFactory().createType(FULL_NEST_CONTRUCTOR_NAME),
-            null,
-            new SynthesizedOrigin("Nest based access desugaring", getClass()),
-            // Make the synthesized class public since shared in the whole program.
-            ClassAccessFlags.fromDexAccessFlags(
-                Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PUBLIC),
-            appView.dexItemFactory().objectType,
-            DexTypeList.empty(),
-            appView.dexItemFactory().createString("nest"),
-            null,
-            Collections.emptyList(),
-            null,
-            Collections.emptyList(),
-            DexAnnotationSet.empty(),
-            DexEncodedField.EMPTY_ARRAY,
-            DexEncodedField.EMPTY_ARRAY,
-            DexEncodedMethod.EMPTY_ARRAY,
-            DexEncodedMethod.EMPTY_ARRAY,
-            appView.dexItemFactory().getSkipNameValidationForTesting());
+    nestConstructorUsed = true;
     return nestConstructor;
   }
 
   void synthetizeNestConstructor(DexApplication.Builder<?> builder) {
-    if (nestConstructor != null) {
+    if (nestConstructorUsed) {
       appView.appInfo().addSynthesizedClass(nestConstructor);
       builder.addSynthesizedClass(nestConstructor, true);
     }