Delay dex-to-dex compilation until Optimizing is done.

This fixes a race between inlining in the Optimizing
backend and dex-to-dex quickening where the Optimizing can
read the non-quickened opcode and then the quickened field
index or vtable index and look up the wrong field or method.
Even if we such tearing of the dex instruction does not
happen, the possible reordering of dex-to-dex and Optimizing
compilation makes the final oat file non-deterministic.

Also, remove VerificationResults::RemoveVerifiedMethod() as
we have only the Optimizing backend now and as such it was
dead code and would have interfered with this change.

Bug: 29043547
Bug: 29089975
Change-Id: I8389927d35dcacaf2f99c2153f055857036c8129
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 19a1ecc..2dd4651 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -52,6 +52,7 @@
 class MethodVerifier;
 }  // namespace verifier
 
+class BitVector;
 class CompiledClass;
 class CompiledMethod;
 class CompilerOptions;
@@ -120,12 +121,12 @@
   void CompileAll(jobject class_loader,
                   const std::vector<const DexFile*>& dex_files,
                   TimingLogger* timings)
-      REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
+      REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_);
 
   // Compile a single Method.
   void CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings)
       SHARED_REQUIRES(Locks::mutator_lock_)
-      REQUIRES(!compiled_methods_lock_, !compiled_classes_lock_);
+      REQUIRES(!compiled_methods_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_);
 
   VerificationResults* GetVerificationResults() const {
     DCHECK(Runtime::Current()->IsAotCompiler());
@@ -475,6 +476,13 @@
     return true;
   }
 
+  void MarkForDexToDexCompilation(Thread* self, const MethodReference& method_ref)
+      REQUIRES(!dex_to_dex_references_lock_);
+
+  const BitVector* GetCurrentDexToDexMethods() const {
+    return current_dex_to_dex_methods_;
+  }
+
  private:
   // Return whether the declaring class of `resolved_member` is
   // available to `referrer_class` for read or write access using two
@@ -601,7 +609,7 @@
 
   void Compile(jobject class_loader,
                const std::vector<const DexFile*>& dex_files,
-               TimingLogger* timings);
+               TimingLogger* timings) REQUIRES(!dex_to_dex_references_lock_);
   void CompileDexFile(jobject class_loader,
                       const DexFile& dex_file,
                       const std::vector<const DexFile*>& dex_files,
@@ -702,6 +710,16 @@
   const ProfileCompilationInfo* const profile_compilation_info_;
 
   size_t max_arena_alloc_;
+
+  // Data for delaying dex-to-dex compilation.
+  Mutex dex_to_dex_references_lock_;
+  // In the first phase, dex_to_dex_references_ collects methods for dex-to-dex compilation.
+  class DexFileMethodSet;
+  std::vector<DexFileMethodSet> dex_to_dex_references_ GUARDED_BY(dex_to_dex_references_lock_);
+  // In the second phase, current_dex_to_dex_methods_ points to the BitVector with method
+  // indexes for dex-to-dex compilation in the current dex file.
+  const BitVector* current_dex_to_dex_methods_;
+
   friend class CompileClassVisitor;
   DISALLOW_COPY_AND_ASSIGN(CompilerDriver);
 };