Revert "Enable constructor inlining for final fields in tests"

This reverts commit e21e87abe6aaf23444f2a9fb65dad866bd3955f7.

Reason for revert: Test failures on Android 13+

Change-Id: Iefa843c9d1eefea51cdd85ed5f69b64d0bb98420
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessor.java
index e26ea21..9c8b286 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/MethodProcessor.java
@@ -8,10 +8,6 @@
 
 public abstract class MethodProcessor {
 
-  public boolean hasWaves() {
-    return false;
-  }
-
   public boolean isD8MethodProcessor() {
     return false;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
index f625c8e..d31a884 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
@@ -85,11 +85,6 @@
   }
 
   @Override
-  public boolean hasWaves() {
-    return true;
-  }
-
-  @Override
   public boolean isPostMethodProcessor() {
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java
index 788bfcb..4e3f618 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java
@@ -71,11 +71,6 @@
   }
 
   @Override
-  public boolean hasWaves() {
-    return true;
-  }
-
-  @Override
   public boolean isPrimaryMethodProcessor() {
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index e811b72..f5c745d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -18,7 +18,8 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.Code;
 import com.android.tools.r8.graph.DefaultUseRegistryWithResult;
-import com.android.tools.r8.graph.DexClassAndField;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexItemFactory.BoxUnboxPrimitiveMethodRoundtrip;
 import com.android.tools.r8.graph.DexMethod;
@@ -725,19 +726,20 @@
       } else if (instruction.isInstancePut()) {
         // Final fields may not be initialized outside of a constructor in the enclosing class.
         InstancePut instancePut = instruction.asInstancePut();
-        DexClassAndField target =
-            instancePut.resolveField(appView, singleTarget).getResolutionPair();
+        DexField field = instancePut.getField();
+        DexEncodedField target = appView.appInfo().lookupInstanceTarget(field);
         if (target == null) {
           whyAreYouNotInliningReporter.reportUnsafeConstructorInliningDueToMissingFieldAssignment(
               instancePut);
           return false;
         }
-        if (target.getAccessFlags().isFinal()) {
+        if (target.isFinal()) {
+          // TODO(b/278964529): We should unset the final flag for good measure. Find a way to do
+          //  this in a thread safe manner.
           if (inlinerOptions.enableConstructorInliningWithFinalFields
-              && options.canUseJavaLangVarHandleStoreStoreFence(appView)
-              && methodProcessor.hasWaves()
-              && target.isProgramField()) {
-            actionBuilder.setShouldEnsureStoreStoreFence(target.asProgramField());
+              && options.canAssignFinalInstanceFieldOutsideConstructor()
+              && options.canUseJavaLangVarHandleStoreStoreFence(appView)) {
+            actionBuilder.setShouldEnsureStoreStoreBarrier();
           } else {
             whyAreYouNotInliningReporter.reportUnsafeConstructorInliningDueToFinalFieldAssignment(
                 instancePut);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index af554ca..b58048e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -21,7 +21,6 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult;
 import com.android.tools.r8.graph.NestMemberClassAttribute;
-import com.android.tools.r8.graph.ProgramField;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
 import com.android.tools.r8.ir.analysis.proto.ProtoInliningReasonStrategy;
@@ -70,7 +69,6 @@
 import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.collections.LongLivedProgramMethodSetBuilder;
-import com.android.tools.r8.utils.collections.ProgramFieldSet;
 import com.android.tools.r8.utils.collections.ProgramMethodMap;
 import com.android.tools.r8.utils.collections.ProgramMethodSet;
 import com.google.common.collect.ImmutableList;
@@ -86,7 +84,6 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
@@ -103,10 +100,6 @@
 
   private final MultiCallerInliner multiCallerInliner;
 
-  // The set of final fields that have been assigned by a constructor that has been inlined in the
-  // current wave.
-  private final ProgramFieldSet inlinedFinalFieldsInWave = ProgramFieldSet.createConcurrent();
-
   // The set of methods that have been single caller inlined in the current wave. These need to be
   // pruned when the wave ends.
   private final Map<DexProgramClass, ProgramMethodMap<ProgramMethod>>
@@ -116,8 +109,6 @@
 
   private final AvailableApiExceptions availableApiExceptions;
 
-  private final AtomicBoolean waveDoneScheduled = new AtomicBoolean();
-
   public Inliner(AppView<AppInfoWithLiveness> appView) {
     this(appView, null);
   }
@@ -574,7 +565,7 @@
     final Reason reason;
 
     private boolean shouldEnsureStaticInitialization;
-    private ProgramFieldSet shouldEnsureStoreStoreFenceCauses;
+    private boolean shouldEnsureStoreStoreBarrier;
 
     private DexProgramClass downcastClass;
 
@@ -605,8 +596,8 @@
       shouldEnsureStaticInitialization = true;
     }
 
-    void setShouldEnsureStoreStoreFenceCauses(ProgramFieldSet shouldEnsureStoreStoreFenceCauses) {
-      this.shouldEnsureStoreStoreFenceCauses = shouldEnsureStoreStoreFenceCauses;
+    void setShouldEnsureStoreStoreBarrier() {
+      shouldEnsureStoreStoreBarrier = true;
     }
 
     boolean mustBeInlined() {
@@ -635,9 +626,9 @@
             failingBlock -> synthesizeInitClass(code, failingBlock));
       }
 
-      // Insert a store-store fence at the end of the method.
-      if (shouldEnsureStoreStoreFenceCauses != null) {
-        synthesizeStoreStoreFence(appView, code);
+      // Insert a store-store barrier at the end of the method.
+      if (shouldEnsureStoreStoreBarrier) {
+        synthesizeStoreStoreBarrier(appView, code);
       }
 
       // Insert a null check if this is needed to preserve the implicit null check for the receiver.
@@ -834,7 +825,7 @@
       }
     }
 
-    private void synthesizeStoreStoreFence(AppView<AppInfoWithLiveness> appView, IRCode code) {
+    private void synthesizeStoreStoreBarrier(AppView<AppInfoWithLiveness> appView, IRCode code) {
       assert target.getDefinition().isInstanceInitializer();
       BasicBlockIterator blockIterator = code.listIterator();
       while (blockIterator.hasNext()) {
@@ -842,23 +833,10 @@
         if (!block.isReturnBlock()) {
           continue;
         }
-        InstructionListIterator instructionIterator;
-        if (block.hasCatchHandlers()) {
-          instructionIterator = block.listIterator();
-          Instruction throwingInstruction =
-              instructionIterator.nextUntil(Instruction::instructionTypeCanThrow);
-          if (throwingInstruction != null) {
-            instructionIterator =
-                instructionIterator
-                    .splitCopyCatchHandlers(code, blockIterator, appView.options())
-                    .listIterator();
-          } else {
-            Instruction previousInstruction = instructionIterator.previous();
-            assert previousInstruction.isReturn();
-          }
-        } else {
-          instructionIterator = block.listIterator(block.getInstructions().size() - 1);
-        }
+        // It is an invariant that return blocks do not have catch handlers.
+        assert !block.hasCatchHandlers();
+        InstructionListIterator instructionIterator =
+            block.listIterator(block.getInstructions().size() - 1);
         DexMethod storeStoreFenceMethod =
             appView.dexItemFactory().javaLangInvokeVarHandleMembers.storeStoreFence;
         assert appView.definitionFor(storeStoreFenceMethod) != null;
@@ -889,7 +867,7 @@
       private InvokeMethod invoke;
       private Reason reason;
       private boolean shouldEnsureStaticInitialization;
-      private ProgramFieldSet shouldEnsureStoreStoreFenceCauses;
+      private boolean shouldEnsureStoreStoreBarrier;
       private ProgramMethod target;
 
       Builder setDowncastClass(DexProgramClass downcastClass) {
@@ -912,11 +890,8 @@
         return this;
       }
 
-      Builder setShouldEnsureStoreStoreFence(ProgramField finalFieldCause) {
-        if (shouldEnsureStoreStoreFenceCauses == null) {
-          shouldEnsureStoreStoreFenceCauses = ProgramFieldSet.create();
-        }
-        shouldEnsureStoreStoreFenceCauses.add(finalFieldCause);
+      Builder setShouldEnsureStoreStoreBarrier() {
+        this.shouldEnsureStoreStoreBarrier = true;
         return this;
       }
 
@@ -933,8 +908,8 @@
         if (shouldEnsureStaticInitialization) {
           action.setShouldEnsureStaticInitialization();
         }
-        if (shouldEnsureStoreStoreFenceCauses != null) {
-          action.setShouldEnsureStoreStoreFenceCauses(shouldEnsureStoreStoreFenceCauses);
+        if (shouldEnsureStoreStoreBarrier) {
+          action.setShouldEnsureStoreStoreBarrier();
         }
         return action;
       }
@@ -1174,13 +1149,6 @@
           iterator.inlineInvoke(
               appView, code, inlinee, blockIterator, blocksToRemove, action.getDowncastClass());
 
-          if (action.shouldEnsureStoreStoreFenceCauses != null) {
-            assert !action.shouldEnsureStoreStoreFenceCauses.isEmpty();
-            assert converter.isInWave();
-            inlinedFinalFieldsInWave.addAll(action.shouldEnsureStoreStoreFenceCauses);
-            scheduleWaveDone();
-          }
-
           if (methodProcessor.getCallSiteInformation().hasSingleCallSite(singleTarget, context)) {
             feedback.markInlinedIntoSingleCallSite(singleTargetMethod);
             appView.withArgumentPropagator(
@@ -1189,7 +1157,9 @@
                         singleTarget, context, methodProcessor));
             if (!(methodProcessor instanceof OneTimeMethodProcessor)) {
               assert converter.isInWave();
-              scheduleWaveDone();
+              if (singleCallerInlinedMethodsInWave.isEmpty()) {
+                converter.addWaveDoneAction(this::onWaveDone);
+              }
               singleCallerInlinedMethodsInWave
                   .computeIfAbsent(
                       singleTarget.getHolder(), ignoreKey(ProgramMethodMap::createConcurrent))
@@ -1369,7 +1339,6 @@
   }
 
   private void onWaveDone() {
-    inlinedFinalFieldsInWave.forEach(field -> field.getAccessFlags().demoteFromFinal());
     singleCallerInlinedMethodsInWave.forEach(
         (clazz, singleCallerInlinedMethodsForClass) -> {
           // Convert and remove virtual single caller inlined methods to abstract or throw null.
@@ -1415,15 +1384,7 @@
                 });
           }
         });
-    inlinedFinalFieldsInWave.clear();
     singleCallerInlinedMethodsInWave.clear();
-    waveDoneScheduled.set(false);
-  }
-
-  private void scheduleWaveDone() {
-    if (!waveDoneScheduled.getAndSet(true)) {
-      converter.addWaveDoneAction(this::onWaveDone);
-    }
   }
 
   public void onLastWaveDone(
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index db25078..6709446 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -2681,6 +2681,11 @@
     return !appView.enableWholeProgramOptimizations();
   }
 
+  public boolean canAssignFinalInstanceFieldOutsideConstructor() {
+    // ART does not check this property.
+    return isGeneratingDex();
+  }
+
   /**
    * Dex2Oat issues a warning for abstract methods on non-abstract classes, so we never allow this.
    *
@@ -2882,7 +2887,7 @@
   }
 
   public boolean canUseJavaLangVarHandleStoreStoreFence(DexDefinitionSupplier definitions) {
-    if (isGeneratingDex() && hasMinApi(AndroidApiLevel.T)) {
+    if (isGeneratingDex() && hasMinApi(AndroidApiLevel.P)) {
       DexItemFactory factory = definitions.dexItemFactory();
       return definitions.hasDefinitionFor(factory.javaLangInvokeVarHandleMembers.storeStoreFence);
     }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineConstructorWithFinalFieldsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineConstructorWithFinalFieldsTest.java
index 6e8e2f9..e5cca20 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineConstructorWithFinalFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineConstructorWithFinalFieldsTest.java
@@ -5,10 +5,9 @@
 
 import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsentIf;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isFinal;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
 
 import com.android.tools.r8.AlwaysInline;
 import com.android.tools.r8.TestBase;
@@ -16,9 +15,9 @@
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.FieldSubject;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,6 +45,11 @@
             parameters.isDexRuntime(),
             testBuilder -> testBuilder.addLibraryFiles(ToolHelper.getMostRecentAndroidJar()))
         .addKeepMainRule(Main.class)
+        .addOptionsModification(
+            options -> {
+              assertFalse(options.inlinerOptions().enableConstructorInliningWithFinalFields);
+              options.inlinerOptions().enableConstructorInliningWithFinalFields = true;
+            })
         .enableAlwaysInliningAnnotations()
         .setMinApi(parameters)
         .compile()
@@ -54,24 +58,17 @@
               ClassSubject mainClassSubject = inspector.clazz(Main.class);
               assertThat(mainClassSubject, isPresent());
 
-              FieldSubject xFieldSubject = mainClassSubject.uniqueFieldWithOriginalName("x");
-              assertThat(xFieldSubject, isPresent());
-
-              FieldSubject yFieldSubject = mainClassSubject.uniqueFieldWithOriginalName("y");
-              assertThat(yFieldSubject, isPresent());
-
               MethodSubject initMethodSubject = mainClassSubject.init("int", "int");
               assertThat(
                   initMethodSubject,
-                  isAbsentIf(parameters.canUseJavaLangInvokeVarHandleStoreStoreFence()));
+                  isAbsentIf(
+                      parameters.isDexRuntime()
+                          && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.P)));
 
               MethodSubject mainMethodSubject = mainClassSubject.mainMethod();
               assertThat(mainMethodSubject, isPresent());
-
               if (initMethodSubject.isPresent()) {
                 assertThat(mainMethodSubject, invokesMethod(initMethodSubject));
-                assertThat(xFieldSubject, isFinal());
-                assertThat(yFieldSubject, isFinal());
               } else {
                 assertThat(
                     mainMethodSubject,
@@ -81,8 +78,6 @@
                     invokesMethod(
                         Reference.methodFromDescriptor(
                             "Ljava/lang/invoke/VarHandle;", "storeStoreFence", "()V")));
-                assertThat(xFieldSubject, not(isFinal()));
-                assertThat(yFieldSubject, not(isFinal()));
               }
             })
         .run(parameters.getRuntime(), Main.class, "20", "22")
diff --git a/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java
index f4f0034..2a9697a 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -67,7 +67,6 @@
         options.testing.listIterationRewritingEnabled = true;
         options.horizontalClassMergerOptions().enable();
         options.horizontalClassMergerOptions().setEnableInterfaceMerging();
-        options.inlinerOptions().enableConstructorInliningWithFinalFields = true;
         options
             .getCfCodeAnalysisOptions()
             .setAllowUnreachableCfBlocks(false)
diff --git a/src/test/testbase/java/com/android/tools/r8/TestParameters.java b/src/test/testbase/java/com/android/tools/r8/TestParameters.java
index ab3077c..fc90c26 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestParameters.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestParameters.java
@@ -85,10 +85,6 @@
         .isGreaterThanOrEqualTo(TestBase.apiLevelWithDefaultInterfaceMethodsSupport());
   }
 
-  public boolean canUseJavaLangInvokeVarHandleStoreStoreFence() {
-    return isDexRuntime() && getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.T);
-  }
-
   public boolean canUseNativeDexPC() {
     assert isCfRuntime() || isDexRuntime();
     return isDexRuntime() && getDexRuntimeVersion().isNewerThanOrEqual(DexVm.Version.V8_1_0);