Global lock levels for the LLVM side.

Change-Id: Id2807c8775686bc38f79e13c097fadda2d96d042
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 635fde3..e52478b 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -21,7 +21,6 @@
 #include "compilation_unit.h"
 #include "compiled_method.h"
 #include "compiler.h"
-#include "dex_cache.h"
 #include "ir_builder.h"
 #include "jni_compiler.h"
 #include "method_compiler.h"
@@ -193,14 +192,13 @@
 extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
                                                  const art::DexFile::CodeItem* code_item,
                                                  uint32_t access_flags, uint32_t method_idx,
-                                                 art::ClassLoader* class_loader,
+                                                 jobject class_loader,
                                                  const art::DexFile& dex_file)
 {
   art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
-  art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
 
   art::OatCompilationUnit oat_compilation_unit(
-    class_loader, class_linker, dex_file, *dex_cache, code_item,
+    class_loader, class_linker, dex_file, code_item,
     method_idx, access_flags);
   art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
   art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit);
@@ -211,10 +209,9 @@
                                                     uint32_t access_flags, uint32_t method_idx,
                                                     const art::DexFile& dex_file) {
   art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
-  art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
 
   art::OatCompilationUnit oat_compilation_unit(
-    NULL, class_linker, dex_file, *dex_cache, NULL,
+    NULL, class_linker, dex_file, NULL,
     method_idx, access_flags);
 
   art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index b96e0be..1f687f6 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -47,14 +47,7 @@
   oat_compilation_unit_(oat_compilation_unit),
   access_flags_(oat_compilation_unit->access_flags_),
   method_idx_(oat_compilation_unit->method_idx_),
-  class_linker_(oat_compilation_unit->class_linker_),
-  class_loader_(oat_compilation_unit->class_loader_),
-  dex_cache_(oat_compilation_unit->dex_cache_),
-  dex_file_(oat_compilation_unit->dex_file_),
-  method_(dex_cache_->GetResolvedMethod(method_idx_)) {
-
-  // Check: Ensure that the method is resolved
-  CHECK_NE(method_, static_cast<art::Method*>(NULL));
+  dex_file_(oat_compilation_unit->dex_file_) {
 
   // Check: Ensure that JNI compiler will only get "native" method
   CHECK((access_flags_ & kAccNative) != 0);
@@ -272,9 +265,11 @@
   // LLVM function name
   std::string func_name(ElfFuncName(cunit_->GetIndex()));
 
+  const bool is_static = (access_flags_ & kAccStatic) != 0;
+
   // Get function type
   llvm::FunctionType* func_type =
-    GetFunctionType(method_idx_, method_->IsStatic(), false);
+    GetFunctionType(method_idx_, is_static, false);
 
   // Create function
   func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
diff --git a/src/compiler_llvm/jni_compiler.h b/src/compiler_llvm/jni_compiler.h
index 15c9810..80494b6 100644
--- a/src/compiler_llvm/jni_compiler.h
+++ b/src/compiler_llvm/jni_compiler.h
@@ -73,11 +73,7 @@
 
   uint32_t access_flags_;
   uint32_t method_idx_;
-  ClassLinker * class_linker_;
-  const ClassLoader* class_loader_;
-  const DexCache* dex_cache_;
   const DexFile* dex_file_;
-  Method* method_;
 
   llvm::Function* func_;
   uint16_t elf_func_idx_;
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 58d5c33..9990b19 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -50,10 +50,7 @@
                                Compiler* compiler,
                                OatCompilationUnit* oat_compilation_unit)
   : cunit_(cunit), compiler_(compiler),
-    class_linker_(oat_compilation_unit->class_linker_),
-    class_loader_(oat_compilation_unit->class_loader_),
     dex_file_(oat_compilation_unit->dex_file_),
-    dex_cache_(oat_compilation_unit->dex_cache_),
     code_item_(oat_compilation_unit->code_item_),
     oat_compilation_unit_(oat_compilation_unit),
     method_idx_(oat_compilation_unit->method_idx_),
@@ -70,7 +67,7 @@
     basic_block_reg_arg_init_(NULL),
     basic_blocks_(code_item_->insns_size_in_code_units_),
     basic_block_landing_pads_(code_item_->tries_size_, NULL),
-    basic_block_unwind_(NULL), basic_block_unreachable_(NULL),
+    basic_block_unwind_(NULL),
     shadow_frame_(NULL), old_shadow_frame_(NULL),
     already_pushed_shadow_frame_(NULL), shadow_frame_size_(0) {
 }
@@ -1409,7 +1406,7 @@
 
   llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAAJRuntime);
 
-  if (!compiler_->CanAssumeStringIsPresentInDexCache(dex_cache_, string_idx)) {
+  if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) {
     llvm::BasicBlock* block_str_exist =
       CreateBasicBlockWithDexPC(dex_pc, "str_exist");
 
@@ -1452,8 +1449,7 @@
 
 llvm::Value* MethodCompiler::EmitLoadConstantClass(uint32_t dex_pc,
                                                    uint32_t type_idx) {
-  if (!compiler_->CanAccessTypeWithoutChecks(method_idx_, dex_cache_,
-                                             *dex_file_, type_idx)) {
+  if (!compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) {
     llvm::Value* type_idx_value = irb_.getInt32(type_idx);
 
     llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
@@ -1479,7 +1475,7 @@
 
     llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAAJRuntime);
 
-    if (compiler_->CanAssumeTypeIsPresentInDexCache(dex_cache_, type_idx)) {
+    if (compiler_->CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) {
       return type_object_addr;
     }
 
@@ -1742,7 +1738,7 @@
 
   llvm::Function* runtime_func;
   if (compiler_->CanAccessInstantiableTypeWithoutChecks(
-        method_idx_, dex_cache_, *dex_file_, dec_insn.vB)) {
+        method_idx_, *dex_file_, dec_insn.vB)) {
     runtime_func = irb_.GetRuntime(AllocObject);
   } else {
     runtime_func = irb_.GetRuntime(AllocObjectWithAccessCheck);
@@ -1774,8 +1770,7 @@
   llvm::Function* runtime_func;
 
   bool skip_access_check =
-    compiler_->CanAccessTypeWithoutChecks(method_idx_, dex_cache_,
-                                          *dex_file_, type_idx);
+    compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx);
 
   llvm::Value* array_length_value;
 
@@ -4208,7 +4203,7 @@
     case Instruction::CONST_STRING:
     case Instruction::CONST_STRING_JUMBO:
       // TODO: Will the ResolveString throw exception?
-      if (!compiler_->CanAssumeStringIsPresentInDexCache(dex_cache_, dec_insn.vB)) {
+      if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, dec_insn.vB)) {
         may_throw_exception = true;
       }
       set_to_another_object[dec_insn.vA] = true;
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index dbdcb52..9b207c3 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -441,11 +441,7 @@
   CompilationUnit* cunit_;
   Compiler* compiler_;
 
-  ClassLinker* class_linker_;
-  const ClassLoader* class_loader_;
-
   const DexFile* dex_file_;
-  DexCache* dex_cache_;
   const DexFile::CodeItem* code_item_;
 
   OatCompilationUnit* oat_compilation_unit_;
@@ -470,7 +466,6 @@
 
   std::vector<llvm::BasicBlock*> basic_block_landing_pads_;
   llvm::BasicBlock* basic_block_unwind_;
-  llvm::BasicBlock* basic_block_unreachable_;
 
   llvm::AllocaInst* shadow_frame_;
   llvm::Value* old_shadow_frame_;
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index 7f3467b..e0fefd5 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -68,7 +68,8 @@
   return NULL;
 }
 
-void art_lock_object_from_code(Object* obj, Thread* thread) {
+void art_lock_object_from_code(Object* obj, Thread* thread)
+    EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) {
   DCHECK(obj != NULL);        // Assumed to have been checked before entry
   obj->MonitorEnter(thread);  // May block
   DCHECK(thread->HoldsLock(obj));
@@ -76,13 +77,15 @@
   DCHECK(!thread->IsExceptionPending());
 }
 
-void art_unlock_object_from_code(Object* obj, Thread* thread) {
+void art_unlock_object_from_code(Object* obj, Thread* thread)
+    UNLOCK_FUNCTION(monitor_lock_) {
   DCHECK(obj != NULL);  // Assumed to have been checked before entry
   // MonitorExit may throw exception
   obj->MonitorExit(thread);
 }
 
-void art_test_suspend_from_code(Thread* thread) {
+void art_test_suspend_from_code(Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   thread->FullSuspendCheck();
 }
 
@@ -111,19 +114,22 @@
   return false;
 }
 
-void art_throw_div_zero_from_code() {
+void art_throw_div_zero_from_code()
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Thread* thread = art_get_current_thread_from_code();
   thread->ThrowNewException("Ljava/lang/ArithmeticException;",
                             "divide by zero");
 }
 
-void art_throw_array_bounds_from_code(int32_t index, int32_t length) {
+void art_throw_array_bounds_from_code(int32_t index, int32_t length)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Thread* thread = art_get_current_thread_from_code();
   thread->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
                              "length=%d; index=%d", length, index);
 }
 
-void art_throw_no_such_method_from_code(int32_t method_idx) {
+void art_throw_no_such_method_from_code(int32_t method_idx)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Thread* thread = art_get_current_thread_from_code();
   // We need the calling method as context for the method_idx
   Method* method = thread->GetCurrentMethod();
@@ -134,7 +140,8 @@
                                                 false).c_str());
 }
 
-void art_throw_null_pointer_exception_from_code(uint32_t dex_pc) {
+void art_throw_null_pointer_exception_from_code(uint32_t dex_pc)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Thread* thread = art_get_current_thread_from_code();
   NthCallerVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack(), 0);
   visitor.WalkStack();
@@ -142,7 +149,8 @@
   ThrowNullPointerExceptionFromDexPC(thread, throw_method, dex_pc);
 }
 
-void art_throw_stack_overflow_from_code() {
+void art_throw_stack_overflow_from_code()
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Thread* thread = art_get_current_thread_from_code();
   if (Runtime::Current()->IsMethodTracingActive()) {
     TraceMethodUnwindFromCode(thread);
@@ -153,7 +161,8 @@
   thread->ResetDefaultStackEnd();  // Return to default stack size.
 }
 
-void art_throw_exception_from_code(Object* exception) {
+void art_throw_exception_from_code(Object* exception)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Thread* thread = art_get_current_thread_from_code();
   if (exception == NULL) {
     thread->ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
@@ -164,12 +173,14 @@
 
 void art_throw_verification_error_from_code(Method* current_method,
                                             int32_t kind,
-                                            int32_t ref) {
+                                            int32_t ref)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ThrowVerificationError(art_get_current_thread_from_code(), current_method, kind, ref);
 }
 
 int32_t art_find_catch_block_from_code(Method* current_method,
-                                       uint32_t ti_offset) {
+                                       uint32_t ti_offset)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Thread* thread = art_get_current_thread_from_code();
   Class* exception_type = thread->GetException()->GetClass();
   MethodHelper mh(current_method);
@@ -207,46 +218,53 @@
 
 Object* art_alloc_object_from_code(uint32_t type_idx,
                                    Method* referrer,
-                                   Thread* thread) {
+                                   Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return AllocObjectFromCode(type_idx, referrer, thread, false);
 }
 
 Object* art_alloc_object_from_code_with_access_check(uint32_t type_idx,
                                                      Method* referrer,
-                                                     Thread* thread) {
+                                                     Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return AllocObjectFromCode(type_idx, referrer, thread, true);
 }
 
 Object* art_alloc_array_from_code(uint32_t type_idx,
                                   Method* referrer,
                                   uint32_t length,
-                                  Thread* thread) {
+                                  Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return AllocArrayFromCode(type_idx, referrer, length, thread, false);
 }
 
 Object* art_alloc_array_from_code_with_access_check(uint32_t type_idx,
                                                     Method* referrer,
                                                     uint32_t length,
-                                                    Thread* thread) {
+                                                    Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return AllocArrayFromCode(type_idx, referrer, length, thread, true);
 }
 
 Object* art_check_and_alloc_array_from_code(uint32_t type_idx,
                                             Method* referrer,
                                             uint32_t length,
-                                            Thread* thread) {
+                                            Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return CheckAndAllocArrayFromCode(type_idx, referrer, length, thread, false);
 }
 
 Object* art_check_and_alloc_array_from_code_with_access_check(uint32_t type_idx,
                                                               Method* referrer,
                                                               uint32_t length,
-                                                              Thread* thread) {
+                                                              Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return CheckAndAllocArrayFromCode(type_idx, referrer, length, thread, true);
 }
 
 static Method* FindMethodHelper(uint32_t method_idx, Object* this_object, Method* caller_method,
-                                bool access_check, InvokeType type, Thread* thread) {
+                                bool access_check, InvokeType type, Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Method* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type);
   if (UNLIKELY(method == NULL)) {
     method = FindMethodFromCode(method_idx, this_object, caller_method,
@@ -263,28 +281,32 @@
 Object* art_find_static_method_from_code_with_access_check(uint32_t method_idx,
                                                            Object* this_object,
                                                            Method* referrer,
-                                                           Thread* thread) {
+                                                           Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return FindMethodHelper(method_idx, this_object, referrer, true, kStatic, thread);
 }
 
 Object* art_find_direct_method_from_code_with_access_check(uint32_t method_idx,
                                                            Object* this_object,
                                                            Method* referrer,
-                                                           Thread* thread) {
+                                                           Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return FindMethodHelper(method_idx, this_object, referrer, true, kDirect, thread);
 }
 
 Object* art_find_virtual_method_from_code_with_access_check(uint32_t method_idx,
                                                             Object* this_object,
                                                             Method* referrer,
-                                                            Thread* thread) {
+                                                            Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return FindMethodHelper(method_idx, this_object, referrer, true, kVirtual, thread);
 }
 
 Object* art_find_super_method_from_code_with_access_check(uint32_t method_idx,
                                                           Object* this_object,
                                                           Method* referrer,
-                                                          Thread* thread) {
+                                                          Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return FindMethodHelper(method_idx, this_object, referrer, true, kSuper, thread);
 }
 
@@ -292,42 +314,49 @@
 art_find_interface_method_from_code_with_access_check(uint32_t method_idx,
                                                       Object* this_object,
                                                       Method* referrer,
-                                                      Thread* thread) {
+                                                      Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return FindMethodHelper(method_idx, this_object, referrer, true, kInterface, thread);
 }
 
 Object* art_find_interface_method_from_code(uint32_t method_idx,
                                             Object* this_object,
                                             Method* referrer,
-                                            Thread* thread) {
+                                            Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return FindMethodHelper(method_idx, this_object, referrer, false, kInterface, thread);
 }
 
 Object* art_initialize_static_storage_from_code(uint32_t type_idx,
                                                 Method* referrer,
-                                                Thread* thread) {
+                                                Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return ResolveVerifyAndClinit(type_idx, referrer, thread, true, false);
 }
 
 Object* art_initialize_type_from_code(uint32_t type_idx,
                                       Method* referrer,
-                                      Thread* thread) {
+                                      Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return ResolveVerifyAndClinit(type_idx, referrer, thread, false, false);
 }
 
 Object* art_initialize_type_and_verify_access_from_code(uint32_t type_idx,
                                                         Method* referrer,
-                                                        Thread* thread) {
+                                                        Thread* thread)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   // Called when caller isn't guaranteed to have access to a type and the dex cache may be
   // unpopulated
   return ResolveVerifyAndClinit(type_idx, referrer, thread, false, true);
 }
 
-Object* art_resolve_string_from_code(Method* referrer, uint32_t string_idx) {
+Object* art_resolve_string_from_code(Method* referrer, uint32_t string_idx)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return ResolveStringFromCode(referrer, string_idx);
 }
 
-int32_t art_set32_static_from_code(uint32_t field_idx, Method* referrer, int32_t new_value) {
+int32_t art_set32_static_from_code(uint32_t field_idx, Method* referrer, int32_t new_value)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, true, sizeof(uint32_t));
   if (LIKELY(field != NULL)) {
     field->Set32(NULL, new_value);
@@ -342,7 +371,8 @@
   return -1;
 }
 
-int32_t art_set64_static_from_code(uint32_t field_idx, Method* referrer, int64_t new_value) {
+int32_t art_set64_static_from_code(uint32_t field_idx, Method* referrer, int64_t new_value)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, true, sizeof(uint64_t));
   if (LIKELY(field != NULL)) {
     field->Set64(NULL, new_value);
@@ -357,7 +387,8 @@
   return -1;
 }
 
-int32_t art_set_obj_static_from_code(uint32_t field_idx, Method* referrer, Object* new_value) {
+int32_t art_set_obj_static_from_code(uint32_t field_idx, Method* referrer, Object* new_value)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, false, true, sizeof(Object*));
   if (LIKELY(field != NULL)) {
     field->SetObj(NULL, new_value);
@@ -372,7 +403,8 @@
   return -1;
 }
 
-int32_t art_get32_static_from_code(uint32_t field_idx, Method* referrer) {
+int32_t art_get32_static_from_code(uint32_t field_idx, Method* referrer)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, false, sizeof(uint32_t));
   if (LIKELY(field != NULL)) {
     return field->Get32(NULL);
@@ -385,7 +417,8 @@
   return 0;
 }
 
-int64_t art_get64_static_from_code(uint32_t field_idx, Method* referrer) {
+int64_t art_get64_static_from_code(uint32_t field_idx, Method* referrer)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, false, sizeof(uint64_t));
   if (LIKELY(field != NULL)) {
     return field->Get64(NULL);
@@ -398,7 +431,8 @@
   return 0;
 }
 
-Object* art_get_obj_static_from_code(uint32_t field_idx, Method* referrer) {
+Object* art_get_obj_static_from_code(uint32_t field_idx, Method* referrer)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, false, false, sizeof(Object*));
   if (LIKELY(field != NULL)) {
     return field->GetObj(NULL);
@@ -412,7 +446,8 @@
 }
 
 int32_t art_set32_instance_from_code(uint32_t field_idx, Method* referrer,
-                                     Object* obj, uint32_t new_value) {
+                                     Object* obj, uint32_t new_value)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, true, sizeof(uint32_t));
   if (LIKELY(field != NULL)) {
     field->Set32(obj, new_value);
@@ -428,7 +463,8 @@
 }
 
 int32_t art_set64_instance_from_code(uint32_t field_idx, Method* referrer,
-                                     Object* obj, int64_t new_value) {
+                                     Object* obj, int64_t new_value)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, true, sizeof(uint64_t));
   if (LIKELY(field != NULL)) {
     field->Set64(obj, new_value);
@@ -444,7 +480,8 @@
 }
 
 int32_t art_set_obj_instance_from_code(uint32_t field_idx, Method* referrer,
-                                       Object* obj, Object* new_value) {
+                                       Object* obj, Object* new_value)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, false, true, sizeof(Object*));
   if (LIKELY(field != NULL)) {
     field->SetObj(obj, new_value);
@@ -459,7 +496,8 @@
   return -1;
 }
 
-int32_t art_get32_instance_from_code(uint32_t field_idx, Method* referrer, Object* obj) {
+int32_t art_get32_instance_from_code(uint32_t field_idx, Method* referrer, Object* obj)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, false, sizeof(uint32_t));
   if (LIKELY(field != NULL)) {
     return field->Get32(obj);
@@ -472,7 +510,8 @@
   return 0;
 }
 
-int64_t art_get64_instance_from_code(uint32_t field_idx, Method* referrer, Object* obj) {
+int64_t art_get64_instance_from_code(uint32_t field_idx, Method* referrer, Object* obj)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, true, false, sizeof(uint64_t));
   if (LIKELY(field != NULL)) {
     return field->Get64(obj);
@@ -485,7 +524,8 @@
   return 0;
 }
 
-Object* art_get_obj_instance_from_code(uint32_t field_idx, Method* referrer, Object* obj) {
+Object* art_get_obj_instance_from_code(uint32_t field_idx, Method* referrer, Object* obj)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Field* field = FindFieldFast(field_idx, referrer, false, false, sizeof(Object*));
   if (LIKELY(field != NULL)) {
     return field->GetObj(obj);
@@ -498,7 +538,8 @@
   return 0;
 }
 
-Object* art_decode_jobject_in_thread(Thread* self, jobject java_object) {
+Object* art_decode_jobject_in_thread(Thread* self, jobject java_object)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   if (self->IsExceptionPending()) {
     return NULL;
   }
@@ -527,7 +568,8 @@
 }
 
 void art_fill_array_data_from_code(Method* method, uint32_t dex_pc,
-                                   Array* array, uint32_t payload_offset) {
+                                   Array* array, uint32_t payload_offset)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   // Test: Is array equal to null? (Guard NullPointerException)
   if (UNLIKELY(array == NULL)) {
     art_throw_null_pointer_exception_from_code(dex_pc);
@@ -566,13 +608,15 @@
 // Type checking, in the nature of casting
 //----------------------------------------------------------------------------
 
-int32_t art_is_assignable_from_code(const Class* dest_type, const Class* src_type) {
+int32_t art_is_assignable_from_code(const Class* dest_type, const Class* src_type)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   DCHECK(dest_type != NULL);
   DCHECK(src_type != NULL);
   return dest_type->IsAssignableFrom(src_type) ? 1 : 0;
 }
 
-void art_check_cast_from_code(const Class* dest_type, const Class* src_type) {
+void art_check_cast_from_code(const Class* dest_type, const Class* src_type)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   DCHECK(dest_type->IsClass()) << PrettyClass(dest_type);
   DCHECK(src_type->IsClass()) << PrettyClass(src_type);
   if (UNLIKELY(!dest_type->IsAssignableFrom(src_type))) {
@@ -584,7 +628,8 @@
   }
 }
 
-void art_check_put_array_element_from_code(const Object* element, const Object* array) {
+void art_check_put_array_element_from_code(const Object* element, const Object* array)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   if (element == NULL) {
     return;
   }
@@ -645,7 +690,8 @@
 
 // Handler for invocation on proxy methods. We create a boxed argument array. And we invoke
 // the invocation handler which is a field within the proxy object receiver.
-void art_proxy_invoke_handler_from_code(Method* proxy_method, ...) {
+void art_proxy_invoke_handler_from_code(Method* proxy_method, ...)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   va_list ap;
   va_start(ap, proxy_method);
 
@@ -656,7 +702,7 @@
 
   // Start new JNI local reference state
   JNIEnvExt* env = thread->GetJniEnv();
-  ScopedObjectAccess soa(env);
+  ScopedObjectAccessUnchecked soa(env);
   ScopedJniEnvLocalRefState env_state(env);
 
   // Create local ref. copies of the receiver
diff --git a/src/oat/runtime/support_stubs.cc b/src/oat/runtime/support_stubs.cc
index 013f885..8b12973 100644
--- a/src/oat/runtime/support_stubs.cc
+++ b/src/oat/runtime/support_stubs.cc
@@ -223,7 +223,8 @@
 }
 #else // ART_USE_LLVM_COMPILER
 const void* UnresolvedDirectMethodTrampolineFromCode(Method* called, Method** called_addr,
-                                                     Thread* thread, Runtime::TrampolineType type) {
+                                                     Thread* thread, Runtime::TrampolineType type)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   uint32_t dex_pc;
   Method* caller = thread->GetCurrentMethod(&dex_pc);
 
@@ -317,7 +318,8 @@
   thread->DeliverException();
 }
 #else // ART_USE_LLVM_COMPILER
-extern void ThrowAbstractMethodErrorFromCode(Method* method, Thread* thread, Method**) {
+extern void ThrowAbstractMethodErrorFromCode(Method* method, Thread* thread, Method**)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   thread->ThrowNewExceptionF("Ljava/lang/AbstractMethodError;",
                              "abstract method \"%s\"", PrettyMethod(method).c_str());
 }
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 167e1e5..c6c61b9 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -3474,16 +3474,16 @@
 
 void MethodVerifier::SetInferredRegCategoryMap(Compiler::MethodReference ref,
                                           const InferredRegCategoryMap& inferred_reg_category_map) {
-  MutexLock mu(*inferred_reg_category_maps_lock_);
-  const InferredRegCategoryMap* existing_inferred_reg_category_map = GetInferredRegCategoryMap(ref);
-
-  if (existing_inferred_reg_category_map == NULL) {
-    inferred_reg_category_maps_->Put(ref, &inferred_reg_category_map);
-  } else {
-    CHECK(*existing_inferred_reg_category_map == inferred_reg_category_map);
-    delete &inferred_reg_category_map;
+  {
+    MutexLock mu(*inferred_reg_category_maps_lock_);
+    InferredRegCategoryMapTable::iterator it = inferred_reg_category_maps_->find(ref);
+    if (it == inferred_reg_category_maps_->end()) {
+      inferred_reg_category_maps_->Put(ref, &inferred_reg_category_map);
+    } else {
+      CHECK(*(it->second) == inferred_reg_category_map);
+      delete &inferred_reg_category_map;
+    }
   }
-
   CHECK(GetInferredRegCategoryMap(ref) != NULL);
 }
 
diff --git a/src/verifier/method_verifier.h b/src/verifier/method_verifier.h
index a67366f..80f70e1 100644
--- a/src/verifier/method_verifier.h
+++ b/src/verifier/method_verifier.h
@@ -208,7 +208,8 @@
   static void Shutdown();
 
 #if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
-  static const InferredRegCategoryMap* GetInferredRegCategoryMap(Compiler::MethodReference ref);
+  static const InferredRegCategoryMap* GetInferredRegCategoryMap(Compiler::MethodReference ref)
+      LOCKS_EXCLUDED(inferred_reg_category_maps_lock_);
 #endif
 
   static bool IsClassRejected(Compiler::ClassReference ref)
@@ -605,9 +606,10 @@
   typedef SafeMap<const Compiler::MethodReference,
                   const InferredRegCategoryMap*> InferredRegCategoryMapTable;
   static Mutex* inferred_reg_category_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
-  static InferredRegCategoryMapTable* inferred_reg_category_maps_;
+  static InferredRegCategoryMapTable* inferred_reg_category_maps_ GUARDED_BY(inferred_reg_category_maps_lock_);
   static void SetInferredRegCategoryMap(Compiler::MethodReference ref,
-                                        const InferredRegCategoryMap& m);
+                                        const InferredRegCategoryMap& m)
+      LOCKS_EXCLUDED(inferred_reg_category_maps_lock_);
 #endif
 
   static void AddRejectedClass(Compiler::ClassReference ref)