Move to newer clang annotations

Also enable -Wthread-safety-negative.

Changes:
Switch to capabilities and negative capabilities.

Future work:
Use capabilities to implement uninterruptible annotations to work
with AssertNoThreadSuspension.

Bug: 20072211

Change-Id: I42fcbe0300d98a831c89d1eff3ecd5a7e99ebf33
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index d215662..dc2bc5c 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -46,12 +46,12 @@
   // Create an OatMethod based on pointers (for unit tests).
   OatFile::OatMethod CreateOatMethod(const void* code);
 
-  void MakeExecutable(ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void MakeExecutable(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_);
 
   static void MakeExecutable(const void* code_start, size_t code_length);
 
   void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
  protected:
   virtual void SetUp();
@@ -76,17 +76,17 @@
   virtual void TearDown();
 
   void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
-  void CompileMethod(ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void CompileMethod(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_);
 
   void CompileDirectMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name,
                            const char* method_name, const char* signature)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   void CompileVirtualMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name,
                             const char* method_name, const char* signature)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   void ReserveImageSpace();
 
diff --git a/compiler/compiler.h b/compiler/compiler.h
index e5d1aff..fcd3434 100644
--- a/compiler/compiler.h
+++ b/compiler/compiler.h
@@ -58,7 +58,7 @@
                                      const DexFile& dex_file) const = 0;
 
   virtual uintptr_t GetEntryPointOf(ArtMethod* method) const
-     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0;
+     SHARED_REQUIRES(Locks::mutator_lock_) = 0;
 
   uint64_t GetMaximumCompilationTimeBeforeWarning() const {
     return maximum_compilation_time_before_warning_;
diff --git a/compiler/dex/mir_field_info.h b/compiler/dex/mir_field_info.h
index e4570fd..04c58ac 100644
--- a/compiler/dex/mir_field_info.h
+++ b/compiler/dex/mir_field_info.h
@@ -135,7 +135,7 @@
   // with IGET/IPUT. For fast path fields, retrieve the field offset.
   static void Resolve(CompilerDriver* compiler_driver, const DexCompilationUnit* mUnit,
                       MirIFieldLoweringInfo* field_infos, size_t count)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   // Construct an unresolved instance field lowering info.
   explicit MirIFieldLoweringInfo(uint16_t field_idx, DexMemAccessType type, bool is_quickened)
@@ -192,7 +192,7 @@
   // and the type index of the declaring class in the compiled method's dex file.
   static void Resolve(CompilerDriver* compiler_driver, const DexCompilationUnit* mUnit,
                       MirSFieldLoweringInfo* field_infos, size_t count)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   // Construct an unresolved static field lowering info.
   explicit MirSFieldLoweringInfo(uint16_t field_idx, DexMemAccessType type)
diff --git a/compiler/dex/mir_method_info.h b/compiler/dex/mir_method_info.h
index 946c74b..4512f35 100644
--- a/compiler/dex/mir_method_info.h
+++ b/compiler/dex/mir_method_info.h
@@ -99,7 +99,7 @@
   // path methods, retrieve the method's vtable index and direct code and method when applicable.
   static void Resolve(CompilerDriver* compiler_driver, const DexCompilationUnit* mUnit,
                       MirMethodLoweringInfo* method_infos, size_t count)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   MirMethodLoweringInfo(uint16_t method_idx, InvokeType type, bool is_quickened)
       : MirMethodInfo(method_idx,
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index 26b41bf..a8cb9f0 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -62,49 +62,49 @@
      * @return true if the method is a candidate for inlining, false otherwise.
      */
     bool AnalyseMethodCode(verifier::MethodVerifier* verifier)
-        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(lock_);
+        SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!lock_);
 
     /**
      * Check whether a particular method index corresponds to an intrinsic or special function.
      */
-    InlineMethodFlags IsIntrinsicOrSpecial(uint32_t method_index) LOCKS_EXCLUDED(lock_);
+    InlineMethodFlags IsIntrinsicOrSpecial(uint32_t method_index) REQUIRES(!lock_);
 
     /**
      * Check whether a particular method index corresponds to an intrinsic function.
      */
-    bool IsIntrinsic(uint32_t method_index, InlineMethod* intrinsic) LOCKS_EXCLUDED(lock_);
+    bool IsIntrinsic(uint32_t method_index, InlineMethod* intrinsic) REQUIRES(!lock_);
 
     /**
      * Generate code for an intrinsic function invocation.
      */
-    bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) LOCKS_EXCLUDED(lock_);
+    bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) REQUIRES(!lock_);
 
     /**
      * Check whether a particular method index corresponds to a special function.
      */
-    bool IsSpecial(uint32_t method_index) LOCKS_EXCLUDED(lock_);
+    bool IsSpecial(uint32_t method_index) REQUIRES(!lock_);
 
     /**
      * Generate code for a special function.
      */
-    bool GenSpecial(Mir2Lir* backend, uint32_t method_idx) LOCKS_EXCLUDED(lock_);
+    bool GenSpecial(Mir2Lir* backend, uint32_t method_idx) REQUIRES(!lock_);
 
     /**
      * Try to inline an invoke.
      */
     bool GenInline(MIRGraph* mir_graph, BasicBlock* bb, MIR* invoke, uint32_t method_idx)
-        LOCKS_EXCLUDED(lock_);
+        REQUIRES(!lock_);
 
     /**
      * Gets the thread pointer entrypoint offset for a string init method index and pointer size.
      */
     uint32_t GetOffsetForStringInit(uint32_t method_index, size_t pointer_size)
-        LOCKS_EXCLUDED(lock_);
+        REQUIRES(!lock_);
 
     /**
      * Check whether a particular method index is a string init.
      */
-    bool IsStringInitMethodIndex(uint32_t method_index) LOCKS_EXCLUDED(lock_);
+    bool IsStringInitMethodIndex(uint32_t method_index) REQUIRES(!lock_);
 
     /**
      * To avoid multiple lookups of a class by its descriptor, we cache its
@@ -351,11 +351,11 @@
      *
      * Only DexFileToMethodInlinerMap may call this function to initialize the inliner.
      */
-    void FindIntrinsics(const DexFile* dex_file) EXCLUSIVE_LOCKS_REQUIRED(lock_);
+    void FindIntrinsics(const DexFile* dex_file) REQUIRES(lock_);
 
     friend class DexFileToMethodInlinerMap;
 
-    bool AddInlineMethod(int32_t method_idx, const InlineMethod& method) LOCKS_EXCLUDED(lock_);
+    bool AddInlineMethod(int32_t method_idx, const InlineMethod& method) REQUIRES(!lock_);
 
     static bool GenInlineConst(MIRGraph* mir_graph, BasicBlock* bb, MIR* invoke,
                                MIR* move_result, const InlineMethod& method);
diff --git a/compiler/dex/quick/quick_compiler.h b/compiler/dex/quick/quick_compiler.h
index 43dd578..4a39ab3 100644
--- a/compiler/dex/quick/quick_compiler.h
+++ b/compiler/dex/quick/quick_compiler.h
@@ -50,7 +50,7 @@
                              const DexFile& dex_file) const OVERRIDE;
 
   uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   static Mir2Lir* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit);
 
diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h
index d692d26..03bf57b 100644
--- a/compiler/dex/quick_compiler_callbacks.h
+++ b/compiler/dex/quick_compiler_callbacks.h
@@ -38,7 +38,7 @@
     ~QuickCompilerCallbacks() { }
 
     bool MethodVerified(verifier::MethodVerifier* verifier)
-        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
+        SHARED_REQUIRES(Locks::mutator_lock_) OVERRIDE;
 
     void ClassRejected(ClassReference ref) OVERRIDE;
 
diff --git a/compiler/dex/verification_results.h b/compiler/dex/verification_results.h
index 7fc2a23..9934f6b 100644
--- a/compiler/dex/verification_results.h
+++ b/compiler/dex/verification_results.h
@@ -43,15 +43,15 @@
     ~VerificationResults();
 
     bool ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier)
-        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-        LOCKS_EXCLUDED(verified_methods_lock_);
+        SHARED_REQUIRES(Locks::mutator_lock_)
+        REQUIRES(!verified_methods_lock_);
 
     const VerifiedMethod* GetVerifiedMethod(MethodReference ref)
-        LOCKS_EXCLUDED(verified_methods_lock_);
-    void RemoveVerifiedMethod(MethodReference ref) LOCKS_EXCLUDED(verified_methods_lock_);
+        REQUIRES(!verified_methods_lock_);
+    void RemoveVerifiedMethod(MethodReference ref) REQUIRES(!verified_methods_lock_);
 
-    void AddRejectedClass(ClassReference ref) LOCKS_EXCLUDED(rejected_classes_lock_);
-    bool IsClassRejected(ClassReference ref) LOCKS_EXCLUDED(rejected_classes_lock_);
+    void AddRejectedClass(ClassReference ref) REQUIRES(!rejected_classes_lock_);
+    bool IsClassRejected(ClassReference ref) REQUIRES(!rejected_classes_lock_);
 
     bool IsCandidateForCompilation(MethodReference& method_ref,
                                    const uint32_t access_flags);
diff --git a/compiler/dex/verified_method.h b/compiler/dex/verified_method.h
index bf11839..f7d6d67 100644
--- a/compiler/dex/verified_method.h
+++ b/compiler/dex/verified_method.h
@@ -44,7 +44,7 @@
   typedef SafeMap<uint32_t, DexFileReference> DequickenMap;
 
   static const VerifiedMethod* Create(verifier::MethodVerifier* method_verifier, bool compile)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   ~VerifiedMethod() = default;
 
   const std::vector<uint8_t>& GetDexGcMap() const {
@@ -107,15 +107,15 @@
 
   // Generate devirtualizaion map into devirt_map_.
   void GenerateDevirtMap(verifier::MethodVerifier* method_verifier)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Generate dequickening map into dequicken_map_. Returns false if there is an error.
   bool GenerateDequickenMap(verifier::MethodVerifier* method_verifier)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Generate safe case set into safe_cast_set_.
   void GenerateSafeCastSet(verifier::MethodVerifier* method_verifier)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   std::vector<uint8_t> dex_gc_map_;
   DevirtualizationMap devirt_map_;
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index a52bfae..05705a2 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -167,69 +167,69 @@
 #define STATS_LOCK()
 #endif
 
-  void TypeInDexCache() {
+  void TypeInDexCache() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     types_in_dex_cache_++;
   }
 
-  void TypeNotInDexCache() {
+  void TypeNotInDexCache() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     types_not_in_dex_cache_++;
   }
 
-  void StringInDexCache() {
+  void StringInDexCache() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     strings_in_dex_cache_++;
   }
 
-  void StringNotInDexCache() {
+  void StringNotInDexCache() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     strings_not_in_dex_cache_++;
   }
 
-  void TypeDoesntNeedAccessCheck() {
+  void TypeDoesntNeedAccessCheck() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     resolved_types_++;
   }
 
-  void TypeNeedsAccessCheck() {
+  void TypeNeedsAccessCheck() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     unresolved_types_++;
   }
 
-  void ResolvedInstanceField() {
+  void ResolvedInstanceField() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     resolved_instance_fields_++;
   }
 
-  void UnresolvedInstanceField() {
+  void UnresolvedInstanceField() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     unresolved_instance_fields_++;
   }
 
-  void ResolvedLocalStaticField() {
+  void ResolvedLocalStaticField() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     resolved_local_static_fields_++;
   }
 
-  void ResolvedStaticField() {
+  void ResolvedStaticField() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     resolved_static_fields_++;
   }
 
-  void UnresolvedStaticField() {
+  void UnresolvedStaticField() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     unresolved_static_fields_++;
   }
 
   // Indicate that type information from the verifier led to devirtualization.
-  void PreciseTypeDevirtualization() {
+  void PreciseTypeDevirtualization() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     type_based_devirtualization_++;
   }
 
   // Indicate that a method of the given type was resolved at compile time.
-  void ResolvedMethod(InvokeType type) {
+  void ResolvedMethod(InvokeType type) REQUIRES(!stats_lock_) {
     DCHECK_LE(type, kMaxInvokeType);
     STATS_LOCK();
     resolved_methods_[type]++;
@@ -237,7 +237,7 @@
 
   // Indicate that a method of the given type was unresolved at compile time as it was in an
   // unknown dex file.
-  void UnresolvedMethod(InvokeType type) {
+  void UnresolvedMethod(InvokeType type) REQUIRES(!stats_lock_) {
     DCHECK_LE(type, kMaxInvokeType);
     STATS_LOCK();
     unresolved_methods_[type]++;
@@ -245,27 +245,27 @@
 
   // Indicate that a type of virtual method dispatch has been converted into a direct method
   // dispatch.
-  void VirtualMadeDirect(InvokeType type) {
+  void VirtualMadeDirect(InvokeType type) REQUIRES(!stats_lock_) {
     DCHECK(type == kVirtual || type == kInterface || type == kSuper);
     STATS_LOCK();
     virtual_made_direct_[type]++;
   }
 
   // Indicate that a method of the given type was able to call directly into boot.
-  void DirectCallsToBoot(InvokeType type) {
+  void DirectCallsToBoot(InvokeType type) REQUIRES(!stats_lock_) {
     DCHECK_LE(type, kMaxInvokeType);
     STATS_LOCK();
     direct_calls_to_boot_[type]++;
   }
 
   // Indicate that a method of the given type was able to be resolved directly from boot.
-  void DirectMethodsToBoot(InvokeType type) {
+  void DirectMethodsToBoot(InvokeType type) REQUIRES(!stats_lock_) {
     DCHECK_LE(type, kMaxInvokeType);
     STATS_LOCK();
     direct_methods_to_boot_[type]++;
   }
 
-  void ProcessedInvoke(InvokeType type, int flags) {
+  void ProcessedInvoke(InvokeType type, int flags) REQUIRES(!stats_lock_) {
     STATS_LOCK();
     if (flags == 0) {
       unresolved_methods_[type]++;
@@ -290,13 +290,13 @@
   }
 
   // A check-cast could be eliminated due to verifier type analysis.
-  void SafeCast() {
+  void SafeCast() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     safe_casts_++;
   }
 
   // A check-cast couldn't be eliminated due to verifier type analysis.
-  void NotASafeCast() {
+  void NotASafeCast() REQUIRES(!stats_lock_) {
     STATS_LOCK();
     not_safe_casts_++;
   }
@@ -692,7 +692,7 @@
 
 static void ResolveExceptionsForMethod(
     ArtMethod* method_handle, std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   const DexFile::CodeItem* code_item = method_handle->GetCodeItem();
   if (code_item == nullptr) {
     return;  // native or abstract method
@@ -729,7 +729,7 @@
 }
 
 static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   auto* exceptions_to_resolve =
       reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*>>*>(arg);
   const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
@@ -743,7 +743,7 @@
 }
 
 static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   std::unordered_set<std::string>* image_classes =
       reinterpret_cast<std::unordered_set<std::string>*>(arg);
   std::string temp;
@@ -752,8 +752,7 @@
 }
 
 // Make a list of descriptors for classes to include in the image
-void CompilerDriver::LoadImageClasses(TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_) {
+void CompilerDriver::LoadImageClasses(TimingLogger* timings) {
   CHECK(timings != nullptr);
   if (!IsImage()) {
     return;
@@ -819,7 +818,7 @@
 
 static void MaybeAddToImageClasses(Handle<mirror::Class> c,
                                    std::unordered_set<std::string>* image_classes)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   Thread* self = Thread::Current();
   StackHandleScope<1> hs(self);
   // Make a copy of the handle so that we don't clobber it doing Assign.
@@ -876,7 +875,7 @@
 
   // Visitor for VisitReferences.
   void operator()(mirror::Object* object, MemberOffset field_offset, bool /* is_static */) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     mirror::Object* ref = object->GetFieldObject<mirror::Object>(field_offset);
     if (ref != nullptr) {
       VisitClinitClassesObject(ref);
@@ -887,7 +886,7 @@
   void operator()(mirror::Class* /* klass */, mirror::Reference* /* ref */) const {
   }
 
-  void Walk() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  void Walk() SHARED_REQUIRES(Locks::mutator_lock_) {
     // Use the initial classes as roots for a search.
     for (mirror::Class* klass_root : image_classes_) {
       VisitClinitClassesObject(klass_root);
@@ -897,7 +896,7 @@
  private:
   ClinitImageUpdate(std::unordered_set<std::string>* image_class_descriptors, Thread* self,
                     ClassLinker* linker)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) :
+      SHARED_REQUIRES(Locks::mutator_lock_) :
       image_class_descriptors_(image_class_descriptors), self_(self) {
     CHECK(linker != nullptr);
     CHECK(image_class_descriptors != nullptr);
@@ -915,7 +914,7 @@
   }
 
   static bool FindImageClasses(mirror::Class* klass, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     ClinitImageUpdate* data = reinterpret_cast<ClinitImageUpdate*>(arg);
     std::string temp;
     const char* name = klass->GetDescriptor(&temp);
@@ -933,7 +932,7 @@
   }
 
   void VisitClinitClassesObject(mirror::Object* object) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     DCHECK(object != nullptr);
     if (marked_objects_.find(object) != marked_objects_.end()) {
       // Already processed.
@@ -1569,10 +1568,14 @@
   return result;
 }
 
+class CompilationVisitor {
+ public:
+  virtual ~CompilationVisitor() {}
+  virtual void Visit(size_t index) = 0;
+};
+
 class ParallelCompilationManager {
  public:
-  typedef void Callback(const ParallelCompilationManager* manager, size_t index);
-
   ParallelCompilationManager(ClassLinker* class_linker,
                              jobject class_loader,
                              CompilerDriver* compiler,
@@ -1610,14 +1613,15 @@
     return dex_files_;
   }
 
-  void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) {
+  void ForAll(size_t begin, size_t end, CompilationVisitor* visitor, size_t work_units)
+      REQUIRES(!*Locks::mutator_lock_) {
     Thread* self = Thread::Current();
     self->AssertNoPendingException();
     CHECK_GT(work_units, 0U);
 
     index_.StoreRelaxed(begin);
     for (size_t i = 0; i < work_units; ++i) {
-      thread_pool_->AddTask(self, new ForAllClosure(this, end, callback));
+      thread_pool_->AddTask(self, new ForAllClosure(this, end, visitor));
     }
     thread_pool_->StartWorkers(self);
 
@@ -1636,10 +1640,10 @@
  private:
   class ForAllClosure : public Task {
    public:
-    ForAllClosure(ParallelCompilationManager* manager, size_t end, Callback* callback)
+    ForAllClosure(ParallelCompilationManager* manager, size_t end, CompilationVisitor* visitor)
         : manager_(manager),
           end_(end),
-          callback_(callback) {}
+          visitor_(visitor) {}
 
     virtual void Run(Thread* self) {
       while (true) {
@@ -1647,7 +1651,7 @@
         if (UNLIKELY(index >= end_)) {
           break;
         }
-        callback_(manager_, index);
+        visitor_->Visit(index);
         self->AssertNoPendingException();
       }
     }
@@ -1659,7 +1663,7 @@
    private:
     ParallelCompilationManager* const manager_;
     const size_t end_;
-    Callback* const callback_;
+    CompilationVisitor* const visitor_;
   };
 
   AtomicInteger index_;
@@ -1676,7 +1680,7 @@
 // A fast version of SkipClass above if the class pointer is available
 // that avoids the expensive FindInClassPath search.
 static bool SkipClass(jobject class_loader, const DexFile& dex_file, mirror::Class* klass)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   DCHECK(klass != nullptr);
   const DexFile& original_dex_file = *klass->GetDexCache()->GetDexFile();
   if (&dex_file != &original_dex_file) {
@@ -1691,7 +1695,7 @@
 }
 
 static void CheckAndClearResolveException(Thread* self)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   CHECK(self->IsExceptionPending());
   mirror::Throwable* exception = self->GetException();
   std::string temp;
@@ -1717,134 +1721,148 @@
   self->ClearException();
 }
 
-static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager,
-                                         size_t class_def_index)
-    LOCKS_EXCLUDED(Locks::mutator_lock_) {
-  ATRACE_CALL();
-  Thread* self = Thread::Current();
-  jobject jclass_loader = manager->GetClassLoader();
-  const DexFile& dex_file = *manager->GetDexFile();
-  ClassLinker* class_linker = manager->GetClassLinker();
+class ResolveClassFieldsAndMethodsVisitor : public CompilationVisitor {
+ public:
+  explicit ResolveClassFieldsAndMethodsVisitor(const ParallelCompilationManager* manager)
+      : manager_(manager) {}
 
-  // If an instance field is final then we need to have a barrier on the return, static final
-  // fields are assigned within the lock held for class initialization. Conservatively assume
-  // constructor barriers are always required.
-  bool requires_constructor_barrier = true;
+  virtual void Visit(size_t class_def_index) OVERRIDE REQUIRES(!Locks::mutator_lock_) {
+    ATRACE_CALL();
+    Thread* const self = Thread::Current();
+    jobject jclass_loader = manager_->GetClassLoader();
+    const DexFile& dex_file = *manager_->GetDexFile();
+    ClassLinker* class_linker = manager_->GetClassLinker();
 
-  // Method and Field are the worst. We can't resolve without either
-  // context from the code use (to disambiguate virtual vs direct
-  // method and instance vs static field) or from class
-  // definitions. While the compiler will resolve what it can as it
-  // needs it, here we try to resolve fields and methods used in class
-  // definitions, since many of them many never be referenced by
-  // generated code.
-  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  ScopedObjectAccess soa(self);
-  StackHandleScope<2> hs(soa.Self());
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-  Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
-  // Resolve the class.
-  mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache,
-                                                   class_loader);
-  bool resolve_fields_and_methods;
-  if (klass == nullptr) {
-    // Class couldn't be resolved, for example, super-class is in a different dex file. Don't
-    // attempt to resolve methods and fields when there is no declaring class.
-    CheckAndClearResolveException(soa.Self());
-    resolve_fields_and_methods = false;
-  } else {
-    // We successfully resolved a class, should we skip it?
-    if (SkipClass(jclass_loader, dex_file, klass)) {
-      return;
-    }
-    // We want to resolve the methods and fields eagerly.
-    resolve_fields_and_methods = true;
-  }
-  // Note the class_data pointer advances through the headers,
-  // static fields, instance fields, direct methods, and virtual
-  // methods.
-  const uint8_t* class_data = dex_file.GetClassData(class_def);
-  if (class_data == nullptr) {
-    // Empty class such as a marker interface.
-    requires_constructor_barrier = false;
-  } else {
-    ClassDataItemIterator it(dex_file, class_data);
-    while (it.HasNextStaticField()) {
-      if (resolve_fields_and_methods) {
-        ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
-                                                             dex_cache, class_loader, true);
-        if (field == nullptr) {
-          CheckAndClearResolveException(soa.Self());
-        }
+    // If an instance field is final then we need to have a barrier on the return, static final
+    // fields are assigned within the lock held for class initialization. Conservatively assume
+    // constructor barriers are always required.
+    bool requires_constructor_barrier = true;
+
+    // Method and Field are the worst. We can't resolve without either
+    // context from the code use (to disambiguate virtual vs direct
+    // method and instance vs static field) or from class
+    // definitions. While the compiler will resolve what it can as it
+    // needs it, here we try to resolve fields and methods used in class
+    // definitions, since many of them many never be referenced by
+    // generated code.
+    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
+    ScopedObjectAccess soa(self);
+    StackHandleScope<2> hs(soa.Self());
+    Handle<mirror::ClassLoader> class_loader(
+        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+    Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
+    // Resolve the class.
+    mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache,
+                                                     class_loader);
+    bool resolve_fields_and_methods;
+    if (klass == nullptr) {
+      // Class couldn't be resolved, for example, super-class is in a different dex file. Don't
+      // attempt to resolve methods and fields when there is no declaring class.
+      CheckAndClearResolveException(soa.Self());
+      resolve_fields_and_methods = false;
+    } else {
+      // We successfully resolved a class, should we skip it?
+      if (SkipClass(jclass_loader, dex_file, klass)) {
+        return;
       }
-      it.Next();
+      // We want to resolve the methods and fields eagerly.
+      resolve_fields_and_methods = true;
     }
-    // We require a constructor barrier if there are final instance fields.
-    requires_constructor_barrier = false;
-    while (it.HasNextInstanceField()) {
-      if (it.MemberIsFinal()) {
-        requires_constructor_barrier = true;
-      }
-      if (resolve_fields_and_methods) {
-        ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
-                                                             dex_cache, class_loader, false);
-        if (field == nullptr) {
-          CheckAndClearResolveException(soa.Self());
-        }
-      }
-      it.Next();
-    }
-    if (resolve_fields_and_methods) {
-      while (it.HasNextDirectMethod()) {
-        ArtMethod* method = class_linker->ResolveMethod(
-            dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
-            it.GetMethodInvokeType(class_def));
-        if (method == nullptr) {
-          CheckAndClearResolveException(soa.Self());
+    // Note the class_data pointer advances through the headers,
+    // static fields, instance fields, direct methods, and virtual
+    // methods.
+    const uint8_t* class_data = dex_file.GetClassData(class_def);
+    if (class_data == nullptr) {
+      // Empty class such as a marker interface.
+      requires_constructor_barrier = false;
+    } else {
+      ClassDataItemIterator it(dex_file, class_data);
+      while (it.HasNextStaticField()) {
+        if (resolve_fields_and_methods) {
+          ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
+                                                               dex_cache, class_loader, true);
+          if (field == nullptr) {
+            CheckAndClearResolveException(soa.Self());
+          }
         }
         it.Next();
       }
-      while (it.HasNextVirtualMethod()) {
-        ArtMethod* method = class_linker->ResolveMethod(
-            dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
-            it.GetMethodInvokeType(class_def));
-        if (method == nullptr) {
-          CheckAndClearResolveException(soa.Self());
+      // We require a constructor barrier if there are final instance fields.
+      requires_constructor_barrier = false;
+      while (it.HasNextInstanceField()) {
+        if (it.MemberIsFinal()) {
+          requires_constructor_barrier = true;
+        }
+        if (resolve_fields_and_methods) {
+          ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
+                                                               dex_cache, class_loader, false);
+          if (field == nullptr) {
+            CheckAndClearResolveException(soa.Self());
+          }
         }
         it.Next();
       }
-      DCHECK(!it.HasNext());
+      if (resolve_fields_and_methods) {
+        while (it.HasNextDirectMethod()) {
+          ArtMethod* method = class_linker->ResolveMethod(
+              dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
+              it.GetMethodInvokeType(class_def));
+          if (method == nullptr) {
+            CheckAndClearResolveException(soa.Self());
+          }
+          it.Next();
+        }
+        while (it.HasNextVirtualMethod()) {
+          ArtMethod* method = class_linker->ResolveMethod(
+              dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
+              it.GetMethodInvokeType(class_def));
+          if (method == nullptr) {
+            CheckAndClearResolveException(soa.Self());
+          }
+          it.Next();
+        }
+        DCHECK(!it.HasNext());
+      }
+    }
+    if (requires_constructor_barrier) {
+      manager_->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index);
     }
   }
-  if (requires_constructor_barrier) {
-    manager->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index);
-  }
-}
 
-static void ResolveType(const ParallelCompilationManager* manager, size_t type_idx)
-    LOCKS_EXCLUDED(Locks::mutator_lock_) {
+ private:
+  const ParallelCompilationManager* const manager_;
+};
+
+class ResolveTypeVisitor : public CompilationVisitor {
+ public:
+  explicit ResolveTypeVisitor(const ParallelCompilationManager* manager) : manager_(manager) {
+  }
+  virtual void Visit(size_t type_idx) OVERRIDE REQUIRES(!Locks::mutator_lock_) {
   // Class derived values are more complicated, they require the linker and loader.
-  ScopedObjectAccess soa(Thread::Current());
-  ClassLinker* class_linker = manager->GetClassLinker();
-  const DexFile& dex_file = *manager->GetDexFile();
-  StackHandleScope<2> hs(soa.Self());
-  Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader())));
-  mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
+    ScopedObjectAccess soa(Thread::Current());
+    ClassLinker* class_linker = manager_->GetClassLinker();
+    const DexFile& dex_file = *manager_->GetDexFile();
+    StackHandleScope<2> hs(soa.Self());
+    Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
+    Handle<mirror::ClassLoader> class_loader(
+        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(manager_->GetClassLoader())));
+    mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
 
-  if (klass == nullptr) {
-    CHECK(soa.Self()->IsExceptionPending());
-    mirror::Throwable* exception = soa.Self()->GetException();
-    VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
-    if (exception->GetClass()->DescriptorEquals("Ljava/lang/OutOfMemoryError;")) {
-      // There's little point continuing compilation if the heap is exhausted.
-      LOG(FATAL) << "Out of memory during type resolution for compilation";
+    if (klass == nullptr) {
+      soa.Self()->AssertPendingException();
+      mirror::Throwable* exception = soa.Self()->GetException();
+      VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
+      if (exception->GetClass()->DescriptorEquals("Ljava/lang/OutOfMemoryError;")) {
+        // There's little point continuing compilation if the heap is exhausted.
+        LOG(FATAL) << "Out of memory during type resolution for compilation";
+      }
+      soa.Self()->ClearException();
     }
-    soa.Self()->ClearException();
   }
-}
+
+ private:
+  const ParallelCompilationManager* const manager_;
+};
 
 void CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file,
                                     const std::vector<const DexFile*>& dex_files,
@@ -1860,17 +1878,18 @@
     // For images we resolve all types, such as array, whereas for applications just those with
     // classdefs are resolved by ResolveClassFieldsAndMethods.
     TimingLogger::ScopedTiming t("Resolve Types", timings);
-    context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
+    ResolveTypeVisitor visitor(&context);
+    context.ForAll(0, dex_file.NumTypeIds(), &visitor, thread_count_);
   }
 
   TimingLogger::ScopedTiming t("Resolve MethodsAndFields", timings);
-  context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
+  ResolveClassFieldsAndMethodsVisitor visitor(&context);
+  context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count_);
 }
 
 void CompilerDriver::SetVerified(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                                  ThreadPool* thread_pool, TimingLogger* timings) {
-  for (size_t i = 0; i != dex_files.size(); ++i) {
-    const DexFile* dex_file = dex_files[i];
+  for (const DexFile* dex_file : dex_files) {
     CHECK(dex_file != nullptr);
     SetVerifiedDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
   }
@@ -1878,67 +1897,73 @@
 
 void CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                             ThreadPool* thread_pool, TimingLogger* timings) {
-  for (size_t i = 0; i != dex_files.size(); ++i) {
-    const DexFile* dex_file = dex_files[i];
+  for (const DexFile* dex_file : dex_files) {
     CHECK(dex_file != nullptr);
     VerifyDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
   }
 }
 
-static void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index)
-    LOCKS_EXCLUDED(Locks::mutator_lock_) {
-  ATRACE_CALL();
-  ScopedObjectAccess soa(Thread::Current());
-  const DexFile& dex_file = *manager->GetDexFile();
-  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  const char* descriptor = dex_file.GetClassDescriptor(class_def);
-  ClassLinker* class_linker = manager->GetClassLinker();
-  jobject jclass_loader = manager->GetClassLoader();
-  StackHandleScope<3> hs(soa.Self());
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-  Handle<mirror::Class> klass(
-      hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
-  if (klass.Get() == nullptr) {
-    CHECK(soa.Self()->IsExceptionPending());
-    soa.Self()->ClearException();
+class VerifyClassVisitor : public CompilationVisitor {
+ public:
+  explicit VerifyClassVisitor(const ParallelCompilationManager* manager) : manager_(manager) {}
 
-    /*
-     * At compile time, we can still structurally verify the class even if FindClass fails.
-     * This is to ensure the class is structurally sound for compilation. An unsound class
-     * will be rejected by the verifier and later skipped during compilation in the compiler.
-     */
-    Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
-    std::string error_msg;
-    if (verifier::MethodVerifier::VerifyClass(soa.Self(), &dex_file, dex_cache, class_loader,
-                                              &class_def, true, &error_msg) ==
-                                                  verifier::MethodVerifier::kHardFailure) {
-      LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor)
-                 << " because: " << error_msg;
-      manager->GetCompiler()->SetHadHardVerifierFailure();
-    }
-  } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) {
-    CHECK(klass->IsResolved()) << PrettyClass(klass.Get());
-    class_linker->VerifyClass(soa.Self(), klass);
-
-    if (klass->IsErroneous()) {
-      // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
+  virtual void Visit(size_t class_def_index) REQUIRES(!Locks::mutator_lock_) OVERRIDE {
+    ATRACE_CALL();
+    ScopedObjectAccess soa(Thread::Current());
+    const DexFile& dex_file = *manager_->GetDexFile();
+    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
+    const char* descriptor = dex_file.GetClassDescriptor(class_def);
+    ClassLinker* class_linker = manager_->GetClassLinker();
+    jobject jclass_loader = manager_->GetClassLoader();
+    StackHandleScope<3> hs(soa.Self());
+    Handle<mirror::ClassLoader> class_loader(
+        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+    Handle<mirror::Class> klass(
+        hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
+    if (klass.Get() == nullptr) {
       CHECK(soa.Self()->IsExceptionPending());
       soa.Self()->ClearException();
-      manager->GetCompiler()->SetHadHardVerifierFailure();
+
+      /*
+       * At compile time, we can still structurally verify the class even if FindClass fails.
+       * This is to ensure the class is structurally sound for compilation. An unsound class
+       * will be rejected by the verifier and later skipped during compilation in the compiler.
+       */
+      Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
+      std::string error_msg;
+      if (verifier::MethodVerifier::VerifyClass(soa.Self(), &dex_file, dex_cache, class_loader,
+                                                &class_def, true, &error_msg) ==
+                                                    verifier::MethodVerifier::kHardFailure) {
+        LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor)
+                   << " because: " << error_msg;
+        manager_->GetCompiler()->SetHadHardVerifierFailure();
+      }
+    } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) {
+      CHECK(klass->IsResolved()) << PrettyClass(klass.Get());
+      class_linker->VerifyClass(soa.Self(), klass);
+
+      if (klass->IsErroneous()) {
+        // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
+        CHECK(soa.Self()->IsExceptionPending());
+        soa.Self()->ClearException();
+        manager_->GetCompiler()->SetHadHardVerifierFailure();
+      }
+
+      CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
+          << PrettyDescriptor(klass.Get()) << ": state=" << klass->GetStatus();
+
+      // It is *very* problematic if there are verification errors in the boot classpath. For example,
+      // we rely on things working OK without verification when the decryption dialog is brought up.
+      // So abort in a debug build if we find this violated.
+      DCHECK(!manager_->GetCompiler()->IsImage() || klass->IsVerified()) << "Boot classpath class "
+          << PrettyClass(klass.Get()) << " failed to fully verify.";
     }
-
-    CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
-        << PrettyDescriptor(klass.Get()) << ": state=" << klass->GetStatus();
-
-    // It is *very* problematic if there are verification errors in the boot classpath. For example,
-    // we rely on things working OK without verification when the decryption dialog is brought up.
-    // So abort in a debug build if we find this violated.
-    DCHECK(!manager->GetCompiler()->IsImage() || klass->IsVerified()) << "Boot classpath class " <<
-        PrettyClass(klass.Get()) << " failed to fully verify.";
+    soa.Self()->AssertNoPendingException();
   }
-  soa.Self()->AssertNoPendingException();
-}
+
+ private:
+  const ParallelCompilationManager* const manager_;
+};
 
 void CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
                                    const std::vector<const DexFile*>& dex_files,
@@ -1947,48 +1972,56 @@
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
                                      thread_pool);
-  context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
+  VerifyClassVisitor visitor(&context);
+  context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count_);
 }
 
-static void SetVerifiedClass(const ParallelCompilationManager* manager, size_t class_def_index)
-    LOCKS_EXCLUDED(Locks::mutator_lock_) {
-  ATRACE_CALL();
-  ScopedObjectAccess soa(Thread::Current());
-  const DexFile& dex_file = *manager->GetDexFile();
-  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  const char* descriptor = dex_file.GetClassDescriptor(class_def);
-  ClassLinker* class_linker = manager->GetClassLinker();
-  jobject jclass_loader = manager->GetClassLoader();
-  StackHandleScope<3> hs(soa.Self());
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-  Handle<mirror::Class> klass(
-      hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
-  // Class might have failed resolution. Then don't set it to verified.
-  if (klass.Get() != nullptr) {
-    // Only do this if the class is resolved. If even resolution fails, quickening will go very,
-    // very wrong.
-    if (klass->IsResolved()) {
-      if (klass->GetStatus() < mirror::Class::kStatusVerified) {
-        ObjectLock<mirror::Class> lock(soa.Self(), klass);
-        // Set class status to verified.
-        mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, soa.Self());
-        // Mark methods as pre-verified. If we don't do this, the interpreter will run with
-        // access checks.
-        klass->SetPreverifiedFlagOnAllMethods(
-            GetInstructionSetPointerSize(manager->GetCompiler()->GetInstructionSet()));
-        klass->SetPreverified();
+class SetVerifiedClassVisitor : public CompilationVisitor {
+ public:
+  explicit SetVerifiedClassVisitor(const ParallelCompilationManager* manager) : manager_(manager) {}
+
+  virtual void Visit(size_t class_def_index) REQUIRES(!Locks::mutator_lock_) OVERRIDE {
+    ATRACE_CALL();
+    ScopedObjectAccess soa(Thread::Current());
+    const DexFile& dex_file = *manager_->GetDexFile();
+    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
+    const char* descriptor = dex_file.GetClassDescriptor(class_def);
+    ClassLinker* class_linker = manager_->GetClassLinker();
+    jobject jclass_loader = manager_->GetClassLoader();
+    StackHandleScope<3> hs(soa.Self());
+    Handle<mirror::ClassLoader> class_loader(
+        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+    Handle<mirror::Class> klass(
+        hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
+    // Class might have failed resolution. Then don't set it to verified.
+    if (klass.Get() != nullptr) {
+      // Only do this if the class is resolved. If even resolution fails, quickening will go very,
+      // very wrong.
+      if (klass->IsResolved()) {
+        if (klass->GetStatus() < mirror::Class::kStatusVerified) {
+          ObjectLock<mirror::Class> lock(soa.Self(), klass);
+          // Set class status to verified.
+          mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, soa.Self());
+          // Mark methods as pre-verified. If we don't do this, the interpreter will run with
+          // access checks.
+          klass->SetPreverifiedFlagOnAllMethods(
+              GetInstructionSetPointerSize(manager_->GetCompiler()->GetInstructionSet()));
+          klass->SetPreverified();
+        }
+        // Record the final class status if necessary.
+        ClassReference ref(manager_->GetDexFile(), class_def_index);
+        manager_->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
       }
-      // Record the final class status if necessary.
-      ClassReference ref(manager->GetDexFile(), class_def_index);
-      manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
+    } else {
+      Thread* self = soa.Self();
+      DCHECK(self->IsExceptionPending());
+      self->ClearException();
     }
-  } else {
-    Thread* self = soa.Self();
-    DCHECK(self->IsExceptionPending());
-    self->ClearException();
   }
-}
+
+ private:
+  const ParallelCompilationManager* const manager_;
+};
 
 void CompilerDriver::SetVerifiedDexFile(jobject class_loader, const DexFile& dex_file,
                                         const std::vector<const DexFile*>& dex_files,
@@ -1997,99 +2030,107 @@
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
                                      thread_pool);
-  context.ForAll(0, dex_file.NumClassDefs(), SetVerifiedClass, thread_count_);
+  SetVerifiedClassVisitor visitor(&context);
+  context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count_);
 }
 
-static void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index)
-    LOCKS_EXCLUDED(Locks::mutator_lock_) {
-  ATRACE_CALL();
-  jobject jclass_loader = manager->GetClassLoader();
-  const DexFile& dex_file = *manager->GetDexFile();
-  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  const DexFile::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
-  const char* descriptor = dex_file.StringDataByIdx(class_type_id.descriptor_idx_);
+class InitializeClassVisitor : public CompilationVisitor {
+ public:
+  explicit InitializeClassVisitor(const ParallelCompilationManager* manager) : manager_(manager) {}
 
-  ScopedObjectAccess soa(Thread::Current());
-  StackHandleScope<3> hs(soa.Self());
-  Handle<mirror::ClassLoader> class_loader(
-      hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-  Handle<mirror::Class> klass(
-      hs.NewHandle(manager->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader)));
+  virtual void Visit(size_t class_def_index) REQUIRES(!Locks::mutator_lock_) OVERRIDE {
+    ATRACE_CALL();
+    jobject jclass_loader = manager_->GetClassLoader();
+    const DexFile& dex_file = *manager_->GetDexFile();
+    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
+    const DexFile::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
+    const char* descriptor = dex_file.StringDataByIdx(class_type_id.descriptor_idx_);
 
-  if (klass.Get() != nullptr && !SkipClass(jclass_loader, dex_file, klass.Get())) {
-    // Only try to initialize classes that were successfully verified.
-    if (klass->IsVerified()) {
-      // Attempt to initialize the class but bail if we either need to initialize the super-class
-      // or static fields.
-      manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, false);
-      if (!klass->IsInitialized()) {
-        // We don't want non-trivial class initialization occurring on multiple threads due to
-        // deadlock problems. For example, a parent class is initialized (holding its lock) that
-        // refers to a sub-class in its static/class initializer causing it to try to acquire the
-        // sub-class' lock. While on a second thread the sub-class is initialized (holding its lock)
-        // after first initializing its parents, whose locks are acquired. This leads to a
-        // parent-to-child and a child-to-parent lock ordering and consequent potential deadlock.
-        // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
-        // than use a special Object for the purpose we use the Class of java.lang.Class.
-        Handle<mirror::Class> h_klass(hs.NewHandle(klass->GetClass()));
-        ObjectLock<mirror::Class> lock(soa.Self(), h_klass);
-        // Attempt to initialize allowing initialization of parent classes but still not static
-        // fields.
-        manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true);
+    ScopedObjectAccess soa(Thread::Current());
+    StackHandleScope<3> hs(soa.Self());
+    Handle<mirror::ClassLoader> class_loader(
+        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+    Handle<mirror::Class> klass(
+        hs.NewHandle(manager_->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader)));
+
+    if (klass.Get() != nullptr && !SkipClass(jclass_loader, dex_file, klass.Get())) {
+      // Only try to initialize classes that were successfully verified.
+      if (klass->IsVerified()) {
+        // Attempt to initialize the class but bail if we either need to initialize the super-class
+        // or static fields.
+        manager_->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, false);
         if (!klass->IsInitialized()) {
-          // We need to initialize static fields, we only do this for image classes that aren't
-          // marked with the $NoPreloadHolder (which implies this should not be initialized early).
-          bool can_init_static_fields = manager->GetCompiler()->IsImage() &&
-              manager->GetCompiler()->IsImageClass(descriptor) &&
-              !StringPiece(descriptor).ends_with("$NoPreloadHolder;");
-          if (can_init_static_fields) {
-            VLOG(compiler) << "Initializing: " << descriptor;
-            // TODO multithreading support. We should ensure the current compilation thread has
-            // exclusive access to the runtime and the transaction. To achieve this, we could use
-            // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity
-            // checks in Thread::AssertThreadSuspensionIsAllowable.
-            Runtime* const runtime = Runtime::Current();
-            Transaction transaction;
+          // We don't want non-trivial class initialization occurring on multiple threads due to
+          // deadlock problems. For example, a parent class is initialized (holding its lock) that
+          // refers to a sub-class in its static/class initializer causing it to try to acquire the
+          // sub-class' lock. While on a second thread the sub-class is initialized (holding its lock)
+          // after first initializing its parents, whose locks are acquired. This leads to a
+          // parent-to-child and a child-to-parent lock ordering and consequent potential deadlock.
+          // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
+          // than use a special Object for the purpose we use the Class of java.lang.Class.
+          Handle<mirror::Class> h_klass(hs.NewHandle(klass->GetClass()));
+          ObjectLock<mirror::Class> lock(soa.Self(), h_klass);
+          // Attempt to initialize allowing initialization of parent classes but still not static
+          // fields.
+          manager_->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true);
+          if (!klass->IsInitialized()) {
+            // We need to initialize static fields, we only do this for image classes that aren't
+            // marked with the $NoPreloadHolder (which implies this should not be initialized early).
+            bool can_init_static_fields = manager_->GetCompiler()->IsImage() &&
+                manager_->GetCompiler()->IsImageClass(descriptor) &&
+                !StringPiece(descriptor).ends_with("$NoPreloadHolder;");
+            if (can_init_static_fields) {
+              VLOG(compiler) << "Initializing: " << descriptor;
+              // TODO multithreading support. We should ensure the current compilation thread has
+              // exclusive access to the runtime and the transaction. To achieve this, we could use
+              // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity
+              // checks in Thread::AssertThreadSuspensionIsAllowable.
+              Runtime* const runtime = Runtime::Current();
+              Transaction transaction;
 
-            // Run the class initializer in transaction mode.
-            runtime->EnterTransactionMode(&transaction);
-            const mirror::Class::Status old_status = klass->GetStatus();
-            bool success = manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, true,
-                                                                        true);
-            // TODO we detach transaction from runtime to indicate we quit the transactional
-            // mode which prevents the GC from visiting objects modified during the transaction.
-            // Ensure GC is not run so don't access freed objects when aborting transaction.
+              // Run the class initializer in transaction mode.
+              runtime->EnterTransactionMode(&transaction);
+              const mirror::Class::Status old_status = klass->GetStatus();
+              bool success = manager_->GetClassLinker()->EnsureInitialized(soa.Self(), klass, true,
+                                                                           true);
+              // TODO we detach transaction from runtime to indicate we quit the transactional
+              // mode which prevents the GC from visiting objects modified during the transaction.
+              // Ensure GC is not run so don't access freed objects when aborting transaction.
 
-            ScopedAssertNoThreadSuspension ants(soa.Self(), "Transaction end");
-            runtime->ExitTransactionMode();
+              ScopedAssertNoThreadSuspension ants(soa.Self(), "Transaction end");
+              runtime->ExitTransactionMode();
 
-            if (!success) {
-              CHECK(soa.Self()->IsExceptionPending());
-              mirror::Throwable* exception = soa.Self()->GetException();
-              VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
-                  << exception->Dump();
-              std::ostream* file_log = manager->GetCompiler()->
-                  GetCompilerOptions().GetInitFailureOutput();
-              if (file_log != nullptr) {
-                *file_log << descriptor << "\n";
-                *file_log << exception->Dump() << "\n";
+              if (!success) {
+                CHECK(soa.Self()->IsExceptionPending());
+                mirror::Throwable* exception = soa.Self()->GetException();
+                VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
+                    << exception->Dump();
+                std::ostream* file_log = manager_->GetCompiler()->
+                    GetCompilerOptions().GetInitFailureOutput();
+                if (file_log != nullptr) {
+                  *file_log << descriptor << "\n";
+                  *file_log << exception->Dump() << "\n";
+                }
+                soa.Self()->ClearException();
+                transaction.Rollback();
+                CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
               }
-              soa.Self()->ClearException();
-              transaction.Rollback();
-              CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
             }
           }
+          soa.Self()->AssertNoPendingException();
         }
-        soa.Self()->AssertNoPendingException();
       }
+      // Record the final class status if necessary.
+      ClassReference ref(manager_->GetDexFile(), class_def_index);
+      manager_->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
     }
-    // Record the final class status if necessary.
-    ClassReference ref(manager->GetDexFile(), class_def_index);
-    manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
+    // Clear any class not found or verification exceptions.
+    soa.Self()->ClearException();
   }
-  // Clear any class not found or verification exceptions.
-  soa.Self()->ClearException();
-}
+
+ private:
+  const ParallelCompilationManager* const manager_;
+};
 
 void CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
                                        const std::vector<const DexFile*>& dex_files,
@@ -2105,7 +2146,8 @@
   } else {
     thread_count = thread_count_;
   }
-  context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count);
+  InitializeClassVisitor visitor(&context);
+  context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count);
 }
 
 void CompilerDriver::InitializeClasses(jobject class_loader,
@@ -2132,101 +2174,108 @@
   VLOG(compiler) << "Compile: " << GetMemoryUsageString(false);
 }
 
-void CompilerDriver::CompileClass(const ParallelCompilationManager* manager,
-                                  size_t class_def_index) {
-  ATRACE_CALL();
-  const DexFile& dex_file = *manager->GetDexFile();
-  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  ClassLinker* class_linker = manager->GetClassLinker();
-  jobject jclass_loader = manager->GetClassLoader();
-  Thread* self = Thread::Current();
-  {
-    // Use a scoped object access to perform to the quick SkipClass check.
-    const char* descriptor = dex_file.GetClassDescriptor(class_def);
-    ScopedObjectAccess soa(self);
-    StackHandleScope<3> hs(soa.Self());
-    Handle<mirror::ClassLoader> class_loader(
-        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-    Handle<mirror::Class> klass(
-        hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
-    if (klass.Get() == nullptr) {
-      CHECK(soa.Self()->IsExceptionPending());
-      soa.Self()->ClearException();
-    } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
+class CompileClassVisitor : public CompilationVisitor {
+ public:
+  explicit CompileClassVisitor(const ParallelCompilationManager* manager) : manager_(manager) {}
+
+  virtual void Visit(size_t class_def_index) REQUIRES(!Locks::mutator_lock_) OVERRIDE {
+    ATRACE_CALL();
+    const DexFile& dex_file = *manager_->GetDexFile();
+    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
+    ClassLinker* class_linker = manager_->GetClassLinker();
+    jobject jclass_loader = manager_->GetClassLoader();
+    Thread* self = Thread::Current();
+    {
+      // Use a scoped object access to perform to the quick SkipClass check.
+      const char* descriptor = dex_file.GetClassDescriptor(class_def);
+      ScopedObjectAccess soa(self);
+      StackHandleScope<3> hs(soa.Self());
+      Handle<mirror::ClassLoader> class_loader(
+          hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+      Handle<mirror::Class> klass(
+          hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
+      if (klass.Get() == nullptr) {
+        CHECK(soa.Self()->IsExceptionPending());
+        soa.Self()->ClearException();
+      } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
+        return;
+      }
+    }
+    ClassReference ref(&dex_file, class_def_index);
+    // Skip compiling classes with generic verifier failures since they will still fail at runtime
+    if (manager_->GetCompiler()->verification_results_->IsClassRejected(ref)) {
       return;
     }
-  }
-  ClassReference ref(&dex_file, class_def_index);
-  // Skip compiling classes with generic verifier failures since they will still fail at runtime
-  if (manager->GetCompiler()->verification_results_->IsClassRejected(ref)) {
-    return;
-  }
-  const uint8_t* class_data = dex_file.GetClassData(class_def);
-  if (class_data == nullptr) {
-    // empty class, probably a marker interface
-    return;
-  }
-
-  CompilerDriver* const driver = manager->GetCompiler();
-
-  // Can we run DEX-to-DEX compiler on this class ?
-  DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
-  {
-    ScopedObjectAccess soa(self);
-    StackHandleScope<1> hs(soa.Self());
-    Handle<mirror::ClassLoader> class_loader(
-        hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
-    dex_to_dex_compilation_level = driver->GetDexToDexCompilationlevel(
-        soa.Self(), class_loader, dex_file, class_def);
-  }
-  ClassDataItemIterator it(dex_file, class_data);
-  // Skip fields
-  while (it.HasNextStaticField()) {
-    it.Next();
-  }
-  while (it.HasNextInstanceField()) {
-    it.Next();
-  }
-
-  bool compilation_enabled = driver->IsClassToCompile(
-      dex_file.StringByTypeIdx(class_def.class_idx_));
-
-  // Compile direct methods
-  int64_t previous_direct_method_idx = -1;
-  while (it.HasNextDirectMethod()) {
-    uint32_t method_idx = it.GetMemberIndex();
-    if (method_idx == previous_direct_method_idx) {
-      // smali can create dex files with two encoded_methods sharing the same method_idx
-      // http://code.google.com/p/smali/issues/detail?id=119
-      it.Next();
-      continue;
+    const uint8_t* class_data = dex_file.GetClassData(class_def);
+    if (class_data == nullptr) {
+      // empty class, probably a marker interface
+      return;
     }
-    previous_direct_method_idx = method_idx;
-    driver->CompileMethod(self, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
-                          it.GetMethodInvokeType(class_def), class_def_index,
-                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
-                          compilation_enabled);
-    it.Next();
-  }
-  // Compile virtual methods
-  int64_t previous_virtual_method_idx = -1;
-  while (it.HasNextVirtualMethod()) {
-    uint32_t method_idx = it.GetMemberIndex();
-    if (method_idx == previous_virtual_method_idx) {
-      // smali can create dex files with two encoded_methods sharing the same method_idx
-      // http://code.google.com/p/smali/issues/detail?id=119
-      it.Next();
-      continue;
+
+    CompilerDriver* const driver = manager_->GetCompiler();
+
+    // Can we run DEX-to-DEX compiler on this class ?
+    DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
+    {
+      ScopedObjectAccess soa(self);
+      StackHandleScope<1> hs(soa.Self());
+      Handle<mirror::ClassLoader> class_loader(
+          hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+      dex_to_dex_compilation_level = driver->GetDexToDexCompilationlevel(
+          soa.Self(), class_loader, dex_file, class_def);
     }
-    previous_virtual_method_idx = method_idx;
-    driver->CompileMethod(self, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
-                          it.GetMethodInvokeType(class_def), class_def_index,
-                          method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
-                          compilation_enabled);
-    it.Next();
+    ClassDataItemIterator it(dex_file, class_data);
+    // Skip fields
+    while (it.HasNextStaticField()) {
+      it.Next();
+    }
+    while (it.HasNextInstanceField()) {
+      it.Next();
+    }
+
+    bool compilation_enabled = driver->IsClassToCompile(
+        dex_file.StringByTypeIdx(class_def.class_idx_));
+
+    // Compile direct methods
+    int64_t previous_direct_method_idx = -1;
+    while (it.HasNextDirectMethod()) {
+      uint32_t method_idx = it.GetMemberIndex();
+      if (method_idx == previous_direct_method_idx) {
+        // smali can create dex files with two encoded_methods sharing the same method_idx
+        // http://code.google.com/p/smali/issues/detail?id=119
+        it.Next();
+        continue;
+      }
+      previous_direct_method_idx = method_idx;
+      driver->CompileMethod(self, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
+                            it.GetMethodInvokeType(class_def), class_def_index,
+                            method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+                            compilation_enabled);
+      it.Next();
+    }
+    // Compile virtual methods
+    int64_t previous_virtual_method_idx = -1;
+    while (it.HasNextVirtualMethod()) {
+      uint32_t method_idx = it.GetMemberIndex();
+      if (method_idx == previous_virtual_method_idx) {
+        // smali can create dex files with two encoded_methods sharing the same method_idx
+        // http://code.google.com/p/smali/issues/detail?id=119
+        it.Next();
+        continue;
+      }
+      previous_virtual_method_idx = method_idx;
+      driver->CompileMethod(self, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
+                            it.GetMethodInvokeType(class_def), class_def_index,
+                            method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+                            compilation_enabled);
+      it.Next();
+    }
+    DCHECK(!it.HasNext());
   }
-  DCHECK(!it.HasNext());
-}
+
+ private:
+  const ParallelCompilationManager* const manager_;
+};
 
 void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,
                                     const std::vector<const DexFile*>& dex_files,
@@ -2234,7 +2283,8 @@
   TimingLogger::ScopedTiming t("Compile Dex File", timings);
   ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this,
                                      &dex_file, dex_files, thread_pool);
-  context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);
+  CompileClassVisitor visitor(&context);
+  context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count_);
 }
 
 // Does the runtime for the InstructionSet provide an implementation returned by
@@ -2453,7 +2503,7 @@
                               const std::vector<const art::DexFile*>& dex_files,
                               OatWriter* oat_writer,
                               art::File* file)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   if (kProduce64BitELFFiles && Is64BitInstructionSet(GetInstructionSet())) {
     return art::ElfWriterQuick64::Create(file, oat_writer, dex_files, android_root, is_host, *this);
   } else {
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 5cf4044..88e03a2 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -114,14 +114,15 @@
 
   void CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                   TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
 
   CompiledMethod* CompileMethod(Thread* self, ArtMethod*)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) WARN_UNUSED;
+      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!compiled_methods_lock_) WARN_UNUSED;
 
   // Compile a single Method.
   void CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_)
+      REQUIRES(!compiled_methods_lock_, !compiled_classes_lock_);
 
   VerificationResults* GetVerificationResults() const {
     return verification_results_;
@@ -162,54 +163,56 @@
 
   // Generate the trampolines that are invoked by unresolved direct methods.
   const std::vector<uint8_t>* CreateInterpreterToInterpreterBridge() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateInterpreterToCompiledCodeBridge() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateJniDlsymLookup() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateQuickGenericJniTrampoline() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateQuickImtConflictTrampoline() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateQuickResolutionTrampoline() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateQuickToInterpreterBridge() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   CompiledClass* GetCompiledClass(ClassReference ref) const
-      LOCKS_EXCLUDED(compiled_classes_lock_);
+      REQUIRES(!compiled_classes_lock_);
 
   CompiledMethod* GetCompiledMethod(MethodReference ref) const
-      LOCKS_EXCLUDED(compiled_methods_lock_);
+      REQUIRES(!compiled_methods_lock_);
   size_t GetNonRelativeLinkerPatchCount() const
-      LOCKS_EXCLUDED(compiled_methods_lock_);
+      REQUIRES(!compiled_methods_lock_);
 
   // Remove and delete a compiled method.
-  void RemoveCompiledMethod(const MethodReference& method_ref);
+  void RemoveCompiledMethod(const MethodReference& method_ref) REQUIRES(!compiled_methods_lock_);
 
   void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
-                                     uint16_t class_def_index);
+                                     uint16_t class_def_index)
+      REQUIRES(!freezing_constructor_lock_);
   bool RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
-                                  uint16_t class_def_index) const;
+                                  uint16_t class_def_index) const
+      REQUIRES(!freezing_constructor_lock_);
 
   // Callbacks from compiler to see what runtime checks must be generated.
 
   bool CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx);
 
   bool CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, uint32_t string_idx)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   // Are runtime access checks necessary in the compiled code?
   bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
                                   uint32_t type_idx, bool* type_known_final = nullptr,
                                   bool* type_known_abstract = nullptr,
                                   bool* equals_referrers_class = nullptr)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   // Are runtime access and instantiable checks necessary in the code?
   bool CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
                                               uint32_t type_idx)
-     LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   bool CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
                           bool* is_type_initialized, bool* use_direct_type_ptr,
@@ -223,22 +226,22 @@
 
   // Get the DexCache for the
   mirror::DexCache* GetDexCache(const DexCompilationUnit* mUnit)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+    SHARED_REQUIRES(Locks::mutator_lock_);
 
   mirror::ClassLoader* GetClassLoader(ScopedObjectAccess& soa, const DexCompilationUnit* mUnit)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+    SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Resolve compiling method's class. Returns null on failure.
   mirror::Class* ResolveCompilingMethodsClass(
       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
       Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   mirror::Class* ResolveClass(
       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
       Handle<mirror::ClassLoader> class_loader, uint16_t type_index,
       const DexCompilationUnit* mUnit)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Resolve a field. Returns null on failure, including incompatible class change.
   // NOTE: Unlike ClassLinker's ResolveField(), this method enforces is_static.
@@ -246,40 +249,40 @@
       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
       Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
       uint32_t field_idx, bool is_static)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Resolve a field with a given dex file.
   ArtField* ResolveFieldWithDexFile(
       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
       Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file,
       uint32_t field_idx, bool is_static)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Get declaration location of a resolved field.
   void GetResolvedFieldDexFileLocation(
       ArtField* resolved_field, const DexFile** declaring_dex_file,
       uint16_t* declaring_class_idx, uint16_t* declaring_field_idx)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
-  bool IsFieldVolatile(ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  MemberOffset GetFieldOffset(ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool IsFieldVolatile(ArtField* field) SHARED_REQUIRES(Locks::mutator_lock_);
+  MemberOffset GetFieldOffset(ArtField* field) SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Find a dex cache for a dex file.
   inline mirror::DexCache* FindDexCache(const DexFile* dex_file)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset.
   std::pair<bool, bool> IsFastInstanceField(
       mirror::DexCache* dex_cache, mirror::Class* referrer_class,
       ArtField* resolved_field, uint16_t field_idx)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Can we fast-path an SGET/SPUT access to a static field? If yes, compute the type index
   // of the declaring class in the referrer's dex file.
   std::pair<bool, bool> IsFastStaticField(
       mirror::DexCache* dex_cache, mirror::Class* referrer_class,
       ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Return whether the declaring class of `resolved_method` is
   // available to `referrer_class`. If this is true, compute the type
@@ -291,34 +294,34 @@
                                                 ArtMethod* resolved_method,
                                                 uint16_t method_idx,
                                                 uint32_t* storage_index)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Is static field's in referrer's class?
   bool IsStaticFieldInReferrerClass(mirror::Class* referrer_class, ArtField* resolved_field)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Is static field's class initialized?
   bool IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
                                       ArtField* resolved_field)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Resolve a method. Returns null on failure, including incompatible class change.
   ArtMethod* ResolveMethod(
       ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
       Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
       uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change = true)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Get declaration location of a resolved field.
   void GetResolvedMethodDexFileLocation(
       ArtMethod* resolved_method, const DexFile** declaring_dex_file,
       uint16_t* declaring_class_idx, uint16_t* declaring_method_idx)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Get the index in the vtable of the method.
   uint16_t GetResolvedMethodVTableIndex(
       ArtMethod* resolved_method, InvokeType type)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Can we fast-path an INVOKE? If no, returns 0. If yes, returns a non-zero opaque flags value
   // for ProcessedInvoke() and computes the necessary lowering info.
@@ -328,13 +331,13 @@
       mirror::Class* referrer_class, ArtMethod* resolved_method, InvokeType* invoke_type,
       MethodReference* target_method, const MethodReference* devirt_target,
       uintptr_t* direct_code, uintptr_t* direct_method)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Is method's class initialized for an invoke?
   // For static invokes to determine whether we need to consider potential call to <clinit>().
   // For non-static invokes, assuming a non-null reference, the class is always initialized.
   bool IsMethodsClassInitialized(mirror::Class* referrer_class, ArtMethod* resolved_method)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Get the layout of dex cache arrays for a dex file. Returns invalid layout if the
   // dex cache arrays don't have a fixed layout.
@@ -349,18 +352,18 @@
                         ArtField** resolved_field,
                         mirror::Class** referrer_class,
                         mirror::DexCache** dex_cache)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Can we fast path instance field access? Computes field's offset and volatility.
   bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
                                 MemberOffset* field_offset, bool* is_volatile)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   ArtField* ComputeInstanceFieldInfo(uint32_t field_idx,
                                              const DexCompilationUnit* mUnit,
                                              bool is_put,
                                              const ScopedObjectAccess& soa)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
 
   // Can we fastpath static field access? Computes field's offset, volatility and whether the
@@ -369,7 +372,7 @@
                               MemberOffset* field_offset, uint32_t* storage_index,
                               bool* is_referrers_class, bool* is_volatile, bool* is_initialized,
                               Primitive::Type* type)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   // Can we fastpath a interface, super class or virtual method call? Computes method's vtable
   // index.
@@ -377,7 +380,7 @@
                          bool update_stats, bool enable_devirtualization,
                          InvokeType* type, MethodReference* target_method, int* vtable_idx,
                          uintptr_t* direct_code, uintptr_t* direct_method)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const;
   bool IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc);
@@ -445,7 +448,7 @@
   bool IsMethodToCompile(const MethodReference& method_ref) const;
 
   void RecordClassStatus(ClassReference ref, mirror::Class::Status status)
-      LOCKS_EXCLUDED(compiled_classes_lock_);
+      REQUIRES(!compiled_classes_lock_);
 
   // Checks if the specified method has been verified without failures. Returns
   // false if the method is not in the verification results (GetVerificationResults).
@@ -487,7 +490,7 @@
                                                                  ArtMember* resolved_member,
                                                                  uint16_t member_idx,
                                                                  uint32_t* storage_index)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Can `referrer_class` access the resolved `member`?
   // Dispatch call to mirror::Class::CanAccessResolvedField or
@@ -499,17 +502,17 @@
                                       ArtMember* member,
                                       mirror::DexCache* dex_cache,
                                       uint32_t field_idx)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Can we assume that the klass is initialized?
   bool CanAssumeClassIsInitialized(mirror::Class* klass)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   bool CanReferrerAssumeClassIsInitialized(mirror::Class* referrer_class, mirror::Class* klass)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Can we assume that the klass is loaded?
   bool CanAssumeClassIsLoaded(mirror::Class* klass)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // These flags are internal to CompilerDriver for collecting INVOKE resolution statistics.
   // The only external contract is that unresolved method has flags 0 and resolved non-0.
@@ -540,71 +543,68 @@
                                      /*out*/int* stats_flags,
                                      MethodReference* target_method,
                                      uintptr_t* direct_code, uintptr_t* direct_method)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
  private:
   DexToDexCompilationLevel GetDexToDexCompilationlevel(
       Thread* self, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file,
-      const DexFile::ClassDef& class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      const DexFile::ClassDef& class_def) SHARED_REQUIRES(Locks::mutator_lock_);
 
   void PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                   ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
 
-  void LoadImageClasses(TimingLogger* timings);
+  void LoadImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_);
 
   // Attempt to resolve all type, methods, fields, and strings
   // referenced from code in the dex file following PathClassLoader
   // ordering semantics.
   void Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
   void ResolveDexFile(jobject class_loader, const DexFile& dex_file,
                       const std::vector<const DexFile*>& dex_files,
                       ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   void Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
               ThreadPool* thread_pool, TimingLogger* timings);
   void VerifyDexFile(jobject class_loader, const DexFile& dex_file,
                      const std::vector<const DexFile*>& dex_files,
                      ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   void SetVerified(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                    ThreadPool* thread_pool, TimingLogger* timings);
   void SetVerifiedDexFile(jobject class_loader, const DexFile& dex_file,
                           const std::vector<const DexFile*>& dex_files,
                           ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   void InitializeClasses(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                          ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
   void InitializeClasses(jobject class_loader, const DexFile& dex_file,
                          const std::vector<const DexFile*>& dex_files,
                          ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_, compiled_classes_lock_);
+      REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
 
-  void UpdateImageClasses(TimingLogger* timings) LOCKS_EXCLUDED(Locks::mutator_lock_);
+  void UpdateImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_);
   static void FindClinitImageClassesCallback(mirror::Object* object, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   void Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                ThreadPool* thread_pool, TimingLogger* timings);
   void CompileDexFile(jobject class_loader, const DexFile& dex_file,
                       const std::vector<const DexFile*>& dex_files,
                       ThreadPool* thread_pool, TimingLogger* timings)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
   void CompileMethod(Thread* self, const DexFile::CodeItem* code_item, uint32_t access_flags,
                      InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx,
                      jobject class_loader, const DexFile& dex_file,
                      DexToDexCompilationLevel dex_to_dex_compilation_level,
                      bool compilation_enabled)
-      LOCKS_EXCLUDED(compiled_methods_lock_);
-
-  static void CompileClass(const ParallelCompilationManager* context, size_t class_def_index)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!compiled_methods_lock_);
 
   // Swap pool and allocator used for native allocations. May be file-backed. Needs to be first
   // as other fields rely on this.
@@ -776,6 +776,7 @@
   DedupeSet<ArrayRef<const uint8_t>,
             SwapVector<uint8_t>, size_t, DedupeHashFunc<const uint8_t>, 4> dedupe_cfi_info_;
 
+  friend class CompileClassVisitor;
   DISALLOW_COPY_AND_ASSIGN(CompilerDriver);
 };
 
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index b358f4f..e35d07d 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -37,7 +37,7 @@
 
 class CompilerDriverTest : public CommonCompilerTest {
  protected:
-  void CompileAll(jobject class_loader) LOCKS_EXCLUDED(Locks::mutator_lock_) {
+  void CompileAll(jobject class_loader) REQUIRES(!Locks::mutator_lock_) {
     TimingLogger timings("CompilerDriverTest::CompileAll", false, false);
     TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
     compiler_driver_->CompileAll(class_loader,
@@ -49,7 +49,7 @@
 
   void EnsureCompiled(jobject class_loader, const char* class_name, const char* method,
                       const char* signature, bool is_virtual)
-      LOCKS_EXCLUDED(Locks::mutator_lock_) {
+      REQUIRES(!Locks::mutator_lock_) {
     CompileAll(class_loader);
     Thread::Current()->TransitionFromSuspendedToRunnable();
     bool started = runtime_->Start();
diff --git a/compiler/elf_writer.h b/compiler/elf_writer.h
index 8e13b51..03f8ceb 100644
--- a/compiler/elf_writer.h
+++ b/compiler/elf_writer.h
@@ -57,7 +57,7 @@
                      const std::vector<const DexFile*>& dex_files,
                      const std::string& android_root,
                      bool is_host)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0;
+      SHARED_REQUIRES(Locks::mutator_lock_) = 0;
 
   const CompilerDriver* const compiler_driver_;
   File* const elf_file_;
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h
index fd202ee..83781ab 100644
--- a/compiler/elf_writer_quick.h
+++ b/compiler/elf_writer_quick.h
@@ -33,7 +33,7 @@
                      const std::string& android_root,
                      bool is_host,
                      const CompilerDriver& driver)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   static void EncodeOatPatches(const std::vector<uintptr_t>& locations,
                                std::vector<uint8_t>* buffer);
@@ -44,7 +44,7 @@
              const std::string& android_root,
              bool is_host)
       OVERRIDE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
  private:
   ElfWriterQuick(const CompilerDriver& driver, File* elf_file)
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 2b65aa9..3ba1415 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -73,7 +73,7 @@
 static constexpr bool kComputeEagerResolvedStrings = false;
 
 static void CheckNoDexObjectsCallback(Object* obj, void* arg ATTRIBUTE_UNUSED)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   Class* klass = obj->GetClass();
   CHECK_NE(PrettyClass(klass), "com.android.dex.Dex");
 }
@@ -1035,7 +1035,7 @@
   }
 
   void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info ATTRIBUTE_UNUSED)
-      OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
     for (size_t i = 0; i < count; ++i) {
       *roots[i] = ImageAddress(*roots[i]);
     }
@@ -1043,7 +1043,7 @@
 
   void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count,
                   const RootInfo& info ATTRIBUTE_UNUSED)
-      OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
     for (size_t i = 0; i < count; ++i) {
       roots[i]->Assign(ImageAddress(roots[i]->AsMirrorPtr()));
     }
@@ -1052,7 +1052,7 @@
  private:
   ImageWriter* const image_writer_;
 
-  mirror::Object* ImageAddress(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  mirror::Object* ImageAddress(mirror::Object* obj) SHARED_REQUIRES(Locks::mutator_lock_) {
     const size_t offset = image_writer_->GetImageOffset(obj);
     auto* const dest = reinterpret_cast<Object*>(image_writer_->image_begin_ + offset);
     VLOG(compiler) << "Update root from " << obj << " to " << dest;
@@ -1190,7 +1190,7 @@
   }
 
   void operator()(Object* obj, MemberOffset offset, bool is_static ATTRIBUTE_UNUSED) const
-      EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
+      REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
     Object* ref = obj->GetFieldObject<Object, kVerifyNone>(offset);
     // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
     // image.
@@ -1200,8 +1200,8 @@
 
   // java.lang.ref.Reference visitor.
   void operator()(mirror::Class* klass ATTRIBUTE_UNUSED, mirror::Reference* ref) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_)
+      REQUIRES(Locks::heap_bitmap_lock_) {
     copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
         mirror::Reference::ReferentOffset(), image_writer_->GetImageAddress(ref->GetReferent()));
   }
@@ -1217,15 +1217,15 @@
   }
 
   void operator()(Object* obj, MemberOffset offset, bool is_static ATTRIBUTE_UNUSED) const
-      EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
+      REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
     DCHECK(obj->IsClass());
     FixupVisitor::operator()(obj, offset, /*is_static*/false);
   }
 
   void operator()(mirror::Class* klass ATTRIBUTE_UNUSED,
                   mirror::Reference* ref ATTRIBUTE_UNUSED) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_)
+      REQUIRES(Locks::heap_bitmap_lock_) {
     LOG(FATAL) << "Reference not expected here.";
   }
 };
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index 1523383..42b1cbf 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -69,15 +69,15 @@
   }
 
   template <typename T>
-  T* GetImageAddress(T* object) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  T* GetImageAddress(T* object) const SHARED_REQUIRES(Locks::mutator_lock_) {
     return object == nullptr ? nullptr :
         reinterpret_cast<T*>(image_begin_ + GetImageOffset(object));
   }
 
-  ArtMethod* GetImageMethodAddress(ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  ArtMethod* GetImageMethodAddress(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_);
 
   mirror::HeapReference<mirror::Object>* GetDexCacheArrayElementImageAddress(
-      const DexFile* dex_file, uint32_t offset) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      const DexFile* dex_file, uint32_t offset) const SHARED_REQUIRES(Locks::mutator_lock_) {
     auto it = dex_cache_array_starts_.find(dex_file);
     DCHECK(it != dex_cache_array_starts_.end());
     return reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
@@ -88,7 +88,7 @@
 
   bool Write(const std::string& image_filename, const std::string& oat_filename,
              const std::string& oat_location)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
+      REQUIRES(!Locks::mutator_lock_);
 
   uintptr_t GetOatDataBegin() {
     return reinterpret_cast<uintptr_t>(oat_data_begin_);
@@ -98,7 +98,7 @@
   bool AllocMemory();
 
   // Mark the objects defined in this space in the given live bitmap.
-  void RecordImageAllocations() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void RecordImageAllocations() SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Classify different kinds of bins that objects end up getting packed into during image writing.
   enum Bin {
@@ -165,32 +165,32 @@
 
   // We use the lock word to store the offset of the object in the image.
   void AssignImageOffset(mirror::Object* object, BinSlot bin_slot)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void SetImageOffset(mirror::Object* object, size_t offset)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   bool IsImageOffsetAssigned(mirror::Object* object) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  size_t GetImageOffset(mirror::Object* object) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
+  size_t GetImageOffset(mirror::Object* object) const SHARED_REQUIRES(Locks::mutator_lock_);
   void UpdateImageOffset(mirror::Object* obj, uintptr_t offset)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
-  void PrepareDexCacheArraySlots() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  void AssignImageBinSlot(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void PrepareDexCacheArraySlots() SHARED_REQUIRES(Locks::mutator_lock_);
+  void AssignImageBinSlot(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_);
   void SetImageBinSlot(mirror::Object* object, BinSlot bin_slot)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   bool IsImageBinSlotAssigned(mirror::Object* object) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  BinSlot GetImageBinSlot(mirror::Object* object) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
+  BinSlot GetImageBinSlot(mirror::Object* object) const SHARED_REQUIRES(Locks::mutator_lock_);
 
-  void AddMethodPointerArray(mirror::PointerArray* arr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void AddMethodPointerArray(mirror::PointerArray* arr) SHARED_REQUIRES(Locks::mutator_lock_);
 
   static void* GetImageAddressCallback(void* writer, mirror::Object* obj)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     return reinterpret_cast<ImageWriter*>(writer)->GetImageAddress(obj);
   }
 
   mirror::Object* GetLocalAddress(mirror::Object* object) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     size_t offset = GetImageOffset(object);
     uint8_t* dst = image_->Begin() + offset;
     return reinterpret_cast<mirror::Object*>(dst);
@@ -209,74 +209,74 @@
   }
 
   // Returns true if the class was in the original requested image classes list.
-  bool IsImageClass(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool IsImageClass(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Debug aid that list of requested image classes.
   void DumpImageClasses();
 
   // Preinitializes some otherwise lazy fields (such as Class name) to avoid runtime image dirtying.
   void ComputeLazyFieldsForImageClasses()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   static bool ComputeLazyFieldsForClassesVisitor(mirror::Class* klass, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Wire dex cache resolved strings to strings in the image to avoid runtime resolution.
-  void ComputeEagerResolvedStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void ComputeEagerResolvedStrings() SHARED_REQUIRES(Locks::mutator_lock_);
   static void ComputeEagerResolvedStringsCallback(mirror::Object* obj, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Remove unwanted classes from various roots.
-  void PruneNonImageClasses() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void PruneNonImageClasses() SHARED_REQUIRES(Locks::mutator_lock_);
   static bool NonImageClassesVisitor(mirror::Class* c, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Verify unwanted classes removed.
-  void CheckNonImageClassesRemoved() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void CheckNonImageClassesRemoved() SHARED_REQUIRES(Locks::mutator_lock_);
   static void CheckNonImageClassesRemovedCallback(mirror::Object* obj, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Lays out where the image objects will be at runtime.
   void CalculateNewObjectOffsets()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void CreateHeader(size_t oat_loaded_size, size_t oat_data_offset)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   mirror::ObjectArray<mirror::Object>* CreateImageRoots() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void CalculateObjectBinSlots(mirror::Object* obj)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void UnbinObjectsIntoOffset(mirror::Object* obj)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   void WalkInstanceFields(mirror::Object* obj, mirror::Class* klass)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void WalkFieldsInOrder(mirror::Object* obj)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   static void WalkFieldsCallback(mirror::Object* obj, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   static void UnbinObjectsIntoOffsetCallback(mirror::Object* obj, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Creates the contiguous image in memory and adjusts pointers.
-  void CopyAndFixupNativeData() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  void CopyAndFixupObjects() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void CopyAndFixupNativeData() SHARED_REQUIRES(Locks::mutator_lock_);
+  void CopyAndFixupObjects() SHARED_REQUIRES(Locks::mutator_lock_);
   static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  void CopyAndFixupObject(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
+  void CopyAndFixupObject(mirror::Object* obj) SHARED_REQUIRES(Locks::mutator_lock_);
   void CopyAndFixupMethod(ArtMethod* orig, ArtMethod* copy)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void FixupClass(mirror::Class* orig, mirror::Class* copy)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void FixupObject(mirror::Object* orig, mirror::Object* copy)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   void FixupPointerArray(mirror::Object* dst, mirror::PointerArray* arr, mirror::Class* klass,
-                         Bin array_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+                         Bin array_type) SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Get quick code for non-resolution/imt_conflict/abstract method.
   const uint8_t* GetQuickCode(ArtMethod* method, bool* quick_is_interpreted)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   const uint8_t* GetQuickEntryPoint(ArtMethod* method)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Patches references in OatFile to expect runtime addresses.
   void SetOatChecksumFromElfFile(File* elf_file);
@@ -285,10 +285,10 @@
   size_t GetBinSizeSum(Bin up_to = kBinSize) const;
 
   // Return true if a method is likely to be dirtied at runtime.
-  bool WillMethodBeDirty(ArtMethod* m) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool WillMethodBeDirty(ArtMethod* m) const SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Assign the offset for an ArtMethod.
-  void AssignMethodOffset(ArtMethod* method, Bin bin) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void AssignMethodOffset(ArtMethod* method, Bin bin) SHARED_REQUIRES(Locks::mutator_lock_);
 
   const CompilerDriver& compiler_driver_;
 
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index a122ceb..d70211f 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -55,7 +55,7 @@
 }
 
 extern "C" bool jit_compile_method(void* handle, ArtMethod* method, Thread* self)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   auto* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
   DCHECK(jit_compiler != nullptr);
   return jit_compiler->CompileMethod(self, method);
diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h
index b0010e0..ef68caa 100644
--- a/compiler/jit/jit_compiler.h
+++ b/compiler/jit/jit_compiler.h
@@ -38,11 +38,11 @@
   static JitCompiler* Create();
   virtual ~JitCompiler();
   bool CompileMethod(Thread* self, ArtMethod* method)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   // This is in the compiler since the runtime doesn't have access to the compiled method
   // structures.
   bool AddToCodeCache(ArtMethod* method, const CompiledMethod* compiled_method,
-                      OatFile::OatMethod* out_method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+                      OatFile::OatMethod* out_method) SHARED_REQUIRES(Locks::mutator_lock_);
   CompilerCallbacks* GetCompilerCallbacks() const;
   size_t GetTotalCompileTime() const {
     return total_time_;
@@ -63,7 +63,7 @@
       const CompiledMethod* compiled_method, uint8_t* reserve_begin, uint8_t* reserve_end,
       const uint8_t* mapping_table, const uint8_t* vmap_table, const uint8_t* gc_map);
   bool MakeExecutable(CompiledMethod* compiled_method, ArtMethod* method)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   DISALLOW_COPY_AND_ASSIGN(JitCompiler);
 };
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 0747756..c98a5f8 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -44,7 +44,7 @@
   void CheckMethod(ArtMethod* method,
                    const OatFile::OatMethod& oat_method,
                    const DexFile& dex_file)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     const CompiledMethod* compiled_method =
         compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
                                                             method->GetDexMethodIndex()));
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 4318ea5..64e7487 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -365,7 +365,7 @@
   }
 
   bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     OatClass* oat_class = writer_->oat_classes_[oat_class_index_];
     CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index);
 
@@ -560,7 +560,7 @@
   }
 
   bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it ATTRIBUTE_UNUSED)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     OatClass* oat_class = writer_->oat_classes_[oat_class_index_];
     CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index);
 
@@ -601,7 +601,7 @@
   }
 
   bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     OatClass* oat_class = writer_->oat_classes_[oat_class_index_];
     CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index);
 
@@ -665,7 +665,7 @@
   }
 
   bool StartClass(const DexFile* dex_file, size_t class_def_index)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     OatDexMethodVisitor::StartClass(dex_file, class_def_index);
     if (dex_cache_ == nullptr || dex_cache_->GetDexFile() != dex_file) {
       dex_cache_ = class_linker_->FindDexCache(*dex_file);
@@ -673,7 +673,7 @@
     return true;
   }
 
-  bool EndClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  bool EndClass() SHARED_REQUIRES(Locks::mutator_lock_) {
     bool result = OatDexMethodVisitor::EndClass();
     if (oat_class_index_ == writer_->oat_classes_.size()) {
       DCHECK(result);  // OatDexMethodVisitor::EndClass() never fails.
@@ -687,7 +687,7 @@
   }
 
   bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     OatClass* oat_class = writer_->oat_classes_[oat_class_index_];
     const CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index);
 
@@ -793,7 +793,7 @@
   }
 
   ArtMethod* GetTargetMethod(const LinkerPatch& patch)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     MethodReference ref = patch.TargetMethod();
     mirror::DexCache* dex_cache =
         (dex_file_ == ref.dex_file) ? dex_cache_ : class_linker_->FindDexCache(*ref.dex_file);
@@ -803,7 +803,7 @@
     return method;
   }
 
-  uint32_t GetTargetOffset(const LinkerPatch& patch) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  uint32_t GetTargetOffset(const LinkerPatch& patch) SHARED_REQUIRES(Locks::mutator_lock_) {
     auto target_it = writer_->method_offset_map_.map.find(patch.TargetMethod());
     uint32_t target_offset =
         (target_it != writer_->method_offset_map_.map.end()) ? target_it->second : 0u;
@@ -828,7 +828,7 @@
   }
 
   mirror::Class* GetTargetType(const LinkerPatch& patch)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     mirror::DexCache* dex_cache = (dex_file_ == patch.TargetTypeDexFile())
         ? dex_cache_ : class_linker_->FindDexCache(*patch.TargetTypeDexFile());
     mirror::Class* type = dex_cache->GetResolvedType(patch.TargetTypeIndex());
@@ -836,7 +836,7 @@
     return type;
   }
 
-  uint32_t GetDexCacheOffset(const LinkerPatch& patch) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  uint32_t GetDexCacheOffset(const LinkerPatch& patch) SHARED_REQUIRES(Locks::mutator_lock_) {
     if (writer_->image_writer_ != nullptr) {
       auto* element = writer_->image_writer_->GetDexCacheArrayElementImageAddress(
               patch.TargetDexCacheDexFile(), patch.TargetDexCacheElementOffset());
@@ -849,7 +849,7 @@
   }
 
   void PatchObjectAddress(std::vector<uint8_t>* code, uint32_t offset, mirror::Object* object)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     // NOTE: Direct method pointers across oat files don't use linker patches. However, direct
     // type pointers across oat files do. (TODO: Investigate why.)
     if (writer_->image_writer_ != nullptr) {
@@ -865,7 +865,7 @@
   }
 
   void PatchMethodAddress(std::vector<uint8_t>* code, uint32_t offset, ArtMethod* method)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     // NOTE: Direct method pointers across oat files don't use linker patches. However, direct
     // type pointers across oat files do. (TODO: Investigate why.)
     if (writer_->image_writer_ != nullptr) {
@@ -882,7 +882,7 @@
   }
 
   void PatchCodeAddress(std::vector<uint8_t>* code, uint32_t offset, uint32_t target_offset)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     uint32_t address = writer_->image_writer_ == nullptr ? target_offset :
         PointerToLowMemUInt32(writer_->image_writer_->GetOatFileBegin() +
                               writer_->oat_data_offset_ + target_offset);
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 82b9377..3baf438 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -165,9 +165,9 @@
   size_t InitOatClasses(size_t offset);
   size_t InitOatMaps(size_t offset);
   size_t InitOatCode(size_t offset)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
   size_t InitOatCodeDexFiles(size_t offset)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   bool WriteTables(OutputStream* out, const size_t file_offset);
   size_t WriteMaps(OutputStream* out, const size_t file_offset, size_t relative_offset);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index cea7dd9..c185b58 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -86,7 +86,7 @@
 }
 
 static bool IsMethodOrDeclaringClassFinal(ArtMethod* method)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   return method->IsFinal() || method->GetDeclaringClass()->IsFinal();
 }
 
@@ -96,7 +96,7 @@
  * Return nullptr if the runtime target cannot be proven.
  */
 static ArtMethod* FindVirtualOrInterfaceTarget(HInvoke* invoke, ArtMethod* resolved_method)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   if (IsMethodOrDeclaringClassFinal(resolved_method)) {
     // No need to lookup further, the resolved method will be the target.
     return resolved_method;
@@ -164,7 +164,7 @@
 static uint32_t FindMethodIndexIn(ArtMethod* method,
                                   const DexFile& dex_file,
                                   uint32_t referrer_index)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    SHARED_REQUIRES(Locks::mutator_lock_) {
   if (method->GetDexFile()->GetLocation().compare(dex_file.GetLocation()) == 0) {
     return method->GetDexMethodIndex();
   } else {
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index f7a8486..7f446d4 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1461,7 +1461,7 @@
   typedef Handle<mirror::Class> TypeHandle;
 
   static ReferenceTypeInfo Create(TypeHandle type_handle, bool is_exact)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     if (type_handle->IsObjectClass()) {
       // Override the type handle to be consistent with the case when we get to
       // Top but don't have the Object class available. It avoids having to guess
@@ -1478,13 +1478,13 @@
 
   bool IsExact() const { return is_exact_; }
   bool IsTop() const { return is_top_; }
-  bool IsInterface() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  bool IsInterface() const SHARED_REQUIRES(Locks::mutator_lock_) {
     return !IsTop() && GetTypeHandle()->IsInterface();
   }
 
   Handle<mirror::Class> GetTypeHandle() const { return type_handle_; }
 
-  bool IsSupertypeOf(ReferenceTypeInfo rti) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  bool IsSupertypeOf(ReferenceTypeInfo rti) const SHARED_REQUIRES(Locks::mutator_lock_) {
     if (IsTop()) {
       // Top (equivalent for java.lang.Object) is supertype of anything.
       return true;
@@ -1499,7 +1499,7 @@
   // Returns true if the type information provide the same amount of details.
   // Note that it does not mean that the instructions have the same actual type
   // (e.g. tops are equal but they can be the result of a merge).
-  bool IsEqual(ReferenceTypeInfo rti) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  bool IsEqual(ReferenceTypeInfo rti) SHARED_REQUIRES(Locks::mutator_lock_) {
     if (IsExact() != rti.IsExact()) {
       return false;
     }
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index b8ce04e..1c0123e 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -256,7 +256,7 @@
   }
 
   uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+      SHARED_REQUIRES(Locks::mutator_lock_) {
     return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
         InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
   }
diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h
index 17cfed4..11f5ac9 100644
--- a/compiler/optimizing/reference_type_propagation.h
+++ b/compiler/optimizing/reference_type_propagation.h
@@ -42,8 +42,8 @@
  private:
   void VisitPhi(HPhi* phi);
   void VisitBasicBlock(HBasicBlock* block);
-  void UpdateBoundType(HBoundType* bound_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  void UpdatePhi(HPhi* phi) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void UpdateBoundType(HBoundType* bound_type) SHARED_REQUIRES(Locks::mutator_lock_);
+  void UpdatePhi(HPhi* phi) SHARED_REQUIRES(Locks::mutator_lock_);
   void BoundTypeForIfNotNull(HBasicBlock* block);
   void BoundTypeForIfInstanceOf(HBasicBlock* block);
   void ProcessWorklist();
@@ -54,7 +54,7 @@
   bool UpdateReferenceTypeInfo(HInstruction* instr);
 
   ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, const ReferenceTypeInfo& b)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_REQUIRES(Locks::mutator_lock_);
 
   StackHandleScopeCollection* handles_;
 
diff --git a/compiler/trampolines/trampoline_compiler.h b/compiler/trampolines/trampoline_compiler.h
index bdab279..9fb2245 100644
--- a/compiler/trampolines/trampoline_compiler.h
+++ b/compiler/trampolines/trampoline_compiler.h
@@ -27,10 +27,10 @@
 // Create code that will invoke the function held in thread local storage.
 const std::vector<uint8_t>* CreateTrampoline32(InstructionSet isa, EntryPointCallingConvention abi,
                                                ThreadOffset<4> entry_point_offset)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+    SHARED_REQUIRES(Locks::mutator_lock_);
 const std::vector<uint8_t>* CreateTrampoline64(InstructionSet isa, EntryPointCallingConvention abi,
                                                ThreadOffset<8> entry_point_offset)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+    SHARED_REQUIRES(Locks::mutator_lock_);
 
 }  // namespace art
 
diff --git a/compiler/utils/swap_space.cc b/compiler/utils/swap_space.cc
index 325ee4f..42ed881 100644
--- a/compiler/utils/swap_space.cc
+++ b/compiler/utils/swap_space.cc
@@ -143,7 +143,6 @@
     LOG(ERROR) << "Unable to mmap new swap file chunk.";
     LOG(ERROR) << "Current size: " << size_ << " requested: " << next_part << "/" << min_size;
     LOG(ERROR) << "Free list:";
-    MutexLock lock(Thread::Current(), lock_);
     DumpFreeMap(free_by_size_);
     LOG(ERROR) << "In free list: " << CollectFree(free_by_start_, free_by_size_);
     LOG(FATAL) << "Aborting...";
diff --git a/compiler/utils/swap_space.h b/compiler/utils/swap_space.h
index 691df4a..f7c772d 100644
--- a/compiler/utils/swap_space.h
+++ b/compiler/utils/swap_space.h
@@ -60,15 +60,15 @@
  public:
   SwapSpace(int fd, size_t initial_size);
   ~SwapSpace();
-  void* Alloc(size_t size) LOCKS_EXCLUDED(lock_);
-  void Free(void* ptr, size_t size) LOCKS_EXCLUDED(lock_);
+  void* Alloc(size_t size) REQUIRES(!lock_);
+  void Free(void* ptr, size_t size) REQUIRES(!lock_);
 
   size_t GetSize() {
     return size_;
   }
 
  private:
-  SpaceChunk NewFileChunk(size_t min_size);
+  SpaceChunk NewFileChunk(size_t min_size) REQUIRES(lock_);
 
   int fd_;
   size_t size_;