Global lock levels.

Introduce the notion of the mutators/GC being a shared-exclusive (aka
reader-writer) lock. Introduce globally ordered locks, analysable by
annotalysis, statically at compile time. Add locking attributes to
methods.

More subtly, remove the heap_lock_ and split between various locks that
are held for smaller periods (where work doesn't get blocked). Remove
buggy Dalvik style thread transitions. Make GC use CMS in all cases when
concurrent is enabled. Fix bug where suspend counts rather than debug
suspend counts were sent to JDWP. Move the PathClassLoader to
WellKnownClasses. In debugger refactor calls to send request and
possibly suspend. Break apart different VmWait thread states. Move
identity hash code to a shared method.

Change-Id: Icdbfc3ce3fcccd14341860ac7305d8e97b51f5c6
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index 36fbaf1..fbe9192 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -91,13 +91,16 @@
  */
 static JdwpError FinishInvoke(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
                               ObjectId thread_id, ObjectId object_id,
-                              RefTypeId class_id, MethodId method_id, bool is_constructor) {
+                              RefTypeId class_id, MethodId method_id, bool is_constructor)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   CHECK(!is_constructor || object_id != 0);
 
   uint32_t arg_count = Read4BE(&buf);
 
   VLOG(jdwp) << StringPrintf("    --> thread_id=%#llx object_id=%#llx", thread_id, object_id);
-  VLOG(jdwp) << StringPrintf("        class_id=%#llx method_id=%x %s.%s", class_id, method_id, Dbg::GetClassName(class_id).c_str(), Dbg::GetMethodName(class_id, method_id).c_str());
+  VLOG(jdwp) << StringPrintf("        class_id=%#llx method_id=%x %s.%s", class_id,
+                             method_id, Dbg::GetClassName(class_id).c_str(),
+                             Dbg::GetMethodName(class_id, method_id).c_str());
   VLOG(jdwp) << StringPrintf("        %d args:", arg_count);
 
   UniquePtr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : NULL);
@@ -110,7 +113,9 @@
   }
 
   uint32_t options = Read4BE(&buf);  /* enum InvokeOptions bit flags */
-  VLOG(jdwp) << StringPrintf("        options=0x%04x%s%s", options, (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "", (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
+  VLOG(jdwp) << StringPrintf("        options=0x%04x%s%s", options,
+                             (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "",
+                             (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
 
   JdwpTag resultTag;
   uint64_t resultValue;
@@ -155,7 +160,8 @@
 /*
  * Request for version info.
  */
-static JdwpError VM_Version(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_Version(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   /* text information on runtime version */
   std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
   expandBufAddUtf8String(pReply, version);
@@ -175,7 +181,8 @@
  * referenceTypeID.  We need to send back more than one if the class has
  * been loaded by multiple class loaders.
  */
-static JdwpError VM_ClassesBySignature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError VM_ClassesBySignature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   std::string classDescriptor(ReadNewUtf8String(&buf));
   VLOG(jdwp) << "  Req for class by signature '" << classDescriptor << "'";
 
@@ -207,7 +214,8 @@
  * We exclude ourselves from the list, because we don't allow ourselves
  * to be suspended, and that violates some JDWP expectations.
  */
-static JdwpError VM_AllThreads(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_AllThreads(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   std::vector<ObjectId> thread_ids;
   Dbg::GetThreads(0, thread_ids);
 
@@ -222,7 +230,8 @@
 /*
  * List all thread groups that do not have a parent.
  */
-static JdwpError VM_TopLevelThreadGroups(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_TopLevelThreadGroups(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   /*
    * TODO: maintain a list of parentless thread groups in the VM.
    *
@@ -244,7 +253,8 @@
  *
  * All IDs are 8 bytes.
  */
-static JdwpError VM_IDSizes(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_IDSizes(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   expandBufAdd4BE(pReply, sizeof(FieldId));
   expandBufAdd4BE(pReply, sizeof(MethodId));
   expandBufAdd4BE(pReply, sizeof(ObjectId));
@@ -253,7 +263,8 @@
   return ERR_NONE;
 }
 
-static JdwpError VM_Dispose(JdwpState*, const uint8_t*, int, ExpandBuf*) {
+static JdwpError VM_Dispose(JdwpState*, const uint8_t*, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Dbg::Disposed();
   return ERR_NONE;
 }
@@ -264,7 +275,8 @@
  *
  * This needs to increment the "suspend count" on all threads.
  */
-static JdwpError VM_Suspend(JdwpState*, const uint8_t*, int, ExpandBuf*) {
+static JdwpError VM_Suspend(JdwpState*, const uint8_t*, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Dbg::SuspendVM();
   return ERR_NONE;
 }
@@ -272,7 +284,8 @@
 /*
  * Resume execution.  Decrements the "suspend count" of all threads.
  */
-static JdwpError VM_Resume(JdwpState*, const uint8_t*, int, ExpandBuf*) {
+static JdwpError VM_Resume(JdwpState*, const uint8_t*, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   Dbg::ResumeVM();
   return ERR_NONE;
 }
@@ -280,7 +293,8 @@
 /*
  * The debugger wants the entire VM to exit.
  */
-static JdwpError VM_Exit(JdwpState*, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError VM_Exit(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   uint32_t exitCode = Get4BE(buf);
 
   LOG(WARNING) << "Debugger is telling the VM to exit with code=" << exitCode;
@@ -295,7 +309,8 @@
  * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
  * string "java.util.Arrays".)
  */
-static JdwpError VM_CreateString(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError VM_CreateString(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   std::string str(ReadNewUtf8String(&buf));
   VLOG(jdwp) << "  Req to create string '" << str << "'";
   ObjectId stringId = Dbg::CreateString(str);
@@ -309,7 +324,8 @@
 /*
  * Tell the debugger what we are capable of.
  */
-static JdwpError VM_Capabilities(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_Capabilities(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   expandBufAdd1(pReply, false);   /* canWatchFieldModification */
   expandBufAdd1(pReply, false);   /* canWatchFieldAccess */
   expandBufAdd1(pReply, false);   /* canGetBytecodes */
@@ -320,7 +336,8 @@
   return ERR_NONE;
 }
 
-static JdwpError VM_ClassPaths(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_ClassPaths(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   expandBufAddUtf8String(pReply, "/");
 
   std::vector<std::string> class_path;
@@ -345,14 +362,16 @@
  *
  * Currently does nothing.
  */
-static JdwpError VM_DisposeObjects(JdwpState*, const uint8_t*, int, ExpandBuf*) {
+static JdwpError VM_DisposeObjects(JdwpState*, const uint8_t*, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return ERR_NONE;
 }
 
 /*
  * Tell the debugger what we are capable of.
  */
-static JdwpError VM_CapabilitiesNew(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_CapabilitiesNew(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   expandBufAdd1(pReply, false);   /* canWatchFieldModification */
   expandBufAdd1(pReply, false);   /* canWatchFieldAccess */
   expandBufAdd1(pReply, false);   /* canGetBytecodes */
@@ -382,7 +401,8 @@
   return ERR_NONE;
 }
 
-static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic) {
+static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   std::vector<JDWP::RefTypeId> classes;
   Dbg::GetClassList(classes);
 
@@ -412,15 +432,18 @@
   return ERR_NONE;
 }
 
-static JdwpError VM_AllClasses(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_AllClasses(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return VM_AllClassesImpl(pReply, true, false);
 }
 
-static JdwpError VM_AllClassesWithGeneric(JdwpState*, const uint8_t*, int, ExpandBuf* pReply) {
+static JdwpError VM_AllClassesWithGeneric(JdwpState*, const uint8_t*, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return VM_AllClassesImpl(pReply, true, true);
 }
 
-static JdwpError RT_Modifiers(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_Modifiers(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   return Dbg::GetModifiers(refTypeId, pReply);
 }
@@ -428,7 +451,8 @@
 /*
  * Get values from static fields in a reference type.
  */
-static JdwpError RT_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   uint32_t field_count = Read4BE(&buf);
   expandBufAdd4BE(pReply, field_count);
@@ -445,7 +469,8 @@
 /*
  * Get the name of the source file in which a reference type was declared.
  */
-static JdwpError RT_SourceFile(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_SourceFile(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   std::string source_file;
   JdwpError status = Dbg::GetSourceFile(refTypeId, source_file);
@@ -459,7 +484,8 @@
 /*
  * Return the current status of the reference type.
  */
-static JdwpError RT_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   JDWP::JdwpTypeTag type_tag;
   uint32_t class_status;
@@ -474,7 +500,8 @@
 /*
  * Return interfaces implemented directly by this class.
  */
-static JdwpError RT_Interfaces(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_Interfaces(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   VLOG(jdwp) << StringPrintf("  Req for interfaces in %#llx (%s)", refTypeId, Dbg::GetClassName(refTypeId).c_str());
   return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
@@ -483,7 +510,8 @@
 /*
  * Return the class object corresponding to this type.
  */
-static JdwpError RT_ClassObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_ClassObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   ObjectId classObjectId;
   JdwpError status = Dbg::GetClassObject(refTypeId, classObjectId);
@@ -500,12 +528,15 @@
  *
  * JDB seems interested, but DEX files don't currently support this.
  */
-static JdwpError RT_SourceDebugExtension(JdwpState*, const uint8_t*, int, ExpandBuf*) {
+static JdwpError RT_SourceDebugExtension(JdwpState*, const uint8_t*, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   /* referenceTypeId in, string out */
   return ERR_ABSENT_INFORMATION;
 }
 
-static JdwpError RT_Signature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply, bool with_generic) {
+static JdwpError RT_Signature(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
+                              bool with_generic)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
 
   VLOG(jdwp) << StringPrintf("  Req for signature of refTypeId=%#llx", refTypeId);
@@ -522,11 +553,14 @@
   return ERR_NONE;
 }
 
-static JdwpError RT_Signature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError RT_Signature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return RT_Signature(state, buf, dataLen, pReply, false);
 }
 
-static JdwpError RT_SignatureWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError RT_SignatureWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen,
+                                         ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return RT_Signature(state, buf, dataLen, pReply, true);
 }
 
@@ -534,12 +568,14 @@
  * Return the instance of java.lang.ClassLoader that loaded the specified
  * reference type, or null if it was loaded by the system loader.
  */
-static JdwpError RT_ClassLoader(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_ClassLoader(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   return Dbg::GetClassLoader(refTypeId, pReply);
 }
 
-static std::string Describe(const RefTypeId& refTypeId) {
+static std::string Describe(const RefTypeId& refTypeId)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   std::string signature("unknown");
   Dbg::GetSignature(refTypeId, signature);
   return StringPrintf("refTypeId=%#llx (%s)", refTypeId, signature.c_str());
@@ -549,14 +585,16 @@
  * Given a referenceTypeId, return a block of stuff that describes the
  * fields declared by a class.
  */
-static JdwpError RT_FieldsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_FieldsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   VLOG(jdwp) << "  Req for fields in " << Describe(refTypeId);
   return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
 }
 
 // Obsolete equivalent of FieldsWithGeneric, without the generic type information.
-static JdwpError RT_Fields(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_Fields(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   VLOG(jdwp) << "  Req for fields in " << Describe(refTypeId);
   return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
@@ -566,14 +604,16 @@
  * Given a referenceTypeID, return a block of goodies describing the
  * methods declared by a class.
  */
-static JdwpError RT_MethodsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_MethodsWithGeneric(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   VLOG(jdwp) << "  Req for methods in " << Describe(refTypeId);
   return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
 }
 
 // Obsolete equivalent of MethodsWithGeneric, without the generic type information.
-static JdwpError RT_Methods(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError RT_Methods(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   VLOG(jdwp) << "  Req for methods in " << Describe(refTypeId);
   return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
@@ -582,7 +622,8 @@
 /*
  * Return the immediate superclass of a class.
  */
-static JdwpError CT_Superclass(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError CT_Superclass(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId class_id = ReadRefTypeId(&buf);
   RefTypeId superClassId;
   JdwpError status = Dbg::GetSuperclass(class_id, superClassId);
@@ -596,7 +637,8 @@
 /*
  * Set static class values.
  */
-static JdwpError CT_SetValues(JdwpState* , const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError CT_SetValues(JdwpState* , const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId class_id = ReadRefTypeId(&buf);
   uint32_t values = Read4BE(&buf);
 
@@ -624,7 +666,9 @@
  * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
  * values in the "variables" display.
  */
-static JdwpError CT_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError CT_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen,
+                                 ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId class_id = ReadRefTypeId(&buf);
   ObjectId thread_id = ReadObjectId(&buf);
   MethodId method_id = ReadMethodId(&buf);
@@ -639,7 +683,9 @@
  * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
  * see the contents of a byte[] as a string.
  */
-static JdwpError CT_NewInstance(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError CT_NewInstance(JdwpState* state, const uint8_t* buf, int dataLen,
+                                ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId class_id = ReadRefTypeId(&buf);
   ObjectId thread_id = ReadObjectId(&buf);
   MethodId method_id = ReadMethodId(&buf);
@@ -659,7 +705,8 @@
 /*
  * Create a new array object of the requested type and length.
  */
-static JdwpError AT_newInstance(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError AT_newInstance(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId arrayTypeId = ReadRefTypeId(&buf);
   uint32_t length = Read4BE(&buf);
 
@@ -680,7 +727,8 @@
 /*
  * Return line number information for the method, if present.
  */
-static JdwpError M_LineTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError M_LineTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId refTypeId = ReadRefTypeId(&buf);
   MethodId method_id = ReadMethodId(&buf);
 
@@ -691,11 +739,15 @@
   return ERR_NONE;
 }
 
-static JdwpError M_VariableTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply, bool generic) {
+static JdwpError M_VariableTable(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply,
+                                 bool generic)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId class_id = ReadRefTypeId(&buf);
   MethodId method_id = ReadMethodId(&buf);
 
-  VLOG(jdwp) << StringPrintf("  Req for LocalVarTab in class=%s method=%s", Dbg::GetClassName(class_id).c_str(), Dbg::GetMethodName(class_id, method_id).c_str());
+  VLOG(jdwp) << StringPrintf("  Req for LocalVarTab in class=%s method=%s",
+                             Dbg::GetClassName(class_id).c_str(),
+                             Dbg::GetMethodName(class_id, method_id).c_str());
 
   // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
   // information. That will cause Eclipse to make a best-effort attempt at displaying local
@@ -705,11 +757,15 @@
   return ERR_NONE;
 }
 
-static JdwpError M_VariableTable(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError M_VariableTable(JdwpState* state, const uint8_t* buf, int dataLen,
+                                 ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return M_VariableTable(state, buf, dataLen, pReply, false);
 }
 
-static JdwpError M_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError M_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen,
+                                            ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   return M_VariableTable(state, buf, dataLen, pReply, true);
 }
 
@@ -720,7 +776,8 @@
  * This can get called on different things, e.g. thread_id gets
  * passed in here.
  */
-static JdwpError OR_ReferenceType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError OR_ReferenceType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId object_id = ReadObjectId(&buf);
   VLOG(jdwp) << StringPrintf("  Req for type of object_id=%#llx", object_id);
   return Dbg::GetReferenceType(object_id, pReply);
@@ -729,7 +786,8 @@
 /*
  * Get values from the fields of an object.
  */
-static JdwpError OR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError OR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId object_id = ReadObjectId(&buf);
   uint32_t field_count = Read4BE(&buf);
 
@@ -751,7 +809,8 @@
 /*
  * Set values in the fields of an object.
  */
-static JdwpError OR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError OR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId object_id = ReadObjectId(&buf);
   uint32_t field_count = Read4BE(&buf);
 
@@ -785,7 +844,9 @@
  * object), it will try to invoke the object's toString() function.  This
  * feature becomes crucial when examining ArrayLists with Eclipse.
  */
-static JdwpError OR_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError OR_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen,
+                                 ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId object_id = ReadObjectId(&buf);
   ObjectId thread_id = ReadObjectId(&buf);
   RefTypeId class_id = ReadRefTypeId(&buf);
@@ -797,7 +858,8 @@
 /*
  * Disable garbage collection of the specified object.
  */
-static JdwpError OR_DisableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*) {
+static JdwpError OR_DisableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   // this is currently a no-op
   return ERR_NONE;
 }
@@ -805,7 +867,8 @@
 /*
  * Enable garbage collection of the specified object.
  */
-static JdwpError OR_EnableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*) {
+static JdwpError OR_EnableCollection(JdwpState*, const uint8_t*, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   // this is currently a no-op
   return ERR_NONE;
 }
@@ -813,7 +876,8 @@
 /*
  * Determine whether an object has been garbage collected.
  */
-static JdwpError OR_IsCollected(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError OR_IsCollected(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId object_id;
 
   object_id = ReadObjectId(&buf);
@@ -828,7 +892,8 @@
 /*
  * Return the string value in a string object.
  */
-static JdwpError SR_Value(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError SR_Value(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId stringObject = ReadObjectId(&buf);
   std::string str(Dbg::StringToUtf8(stringObject));
 
@@ -842,7 +907,8 @@
 /*
  * Return a thread's name.
  */
-static JdwpError TR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
 
   VLOG(jdwp) << StringPrintf("  Req for name of thread %#llx", thread_id);
@@ -862,7 +928,8 @@
  * It's supposed to remain suspended even if interpreted code wants to
  * resume it; only the JDI is allowed to resume it.
  */
-static JdwpError TR_Suspend(JdwpState*, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError TR_Suspend(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
 
   if (thread_id == Dbg::GetThreadSelfId()) {
@@ -870,14 +937,18 @@
     return ERR_THREAD_NOT_SUSPENDED;
   }
   VLOG(jdwp) << StringPrintf("  Req to suspend thread %#llx", thread_id);
-  Dbg::SuspendThread(thread_id);
-  return ERR_NONE;
+  Thread* self = Thread::Current();
+  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
+  JdwpError result = Dbg::SuspendThread(thread_id);
+  self->TransitionFromSuspendedToRunnable();
+  return result;
 }
 
 /*
  * Resume the specified thread.
  */
-static JdwpError TR_Resume(JdwpState*, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError TR_Resume(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
 
   if (thread_id == Dbg::GetThreadSelfId()) {
@@ -892,7 +963,8 @@
 /*
  * Return status of specified thread.
  */
-static JdwpError TR_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TR_Status(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
 
   VLOG(jdwp) << StringPrintf("  Req for status of thread %#llx", thread_id);
@@ -914,7 +986,8 @@
 /*
  * Return the thread group that the specified thread is a member of.
  */
-static JdwpError TR_ThreadGroup(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TR_ThreadGroup(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
   return Dbg::GetThreadGroup(thread_id, pReply);
 }
@@ -925,7 +998,8 @@
  * If the thread isn't suspended, the error code isn't defined, but should
  * be THREAD_NOT_SUSPENDED.
  */
-static JdwpError TR_Frames(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TR_Frames(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
   uint32_t start_frame = Read4BE(&buf);
   uint32_t length = Read4BE(&buf);
@@ -961,7 +1035,8 @@
 /*
  * Returns the #of frames on the specified thread, which must be suspended.
  */
-static JdwpError TR_FrameCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TR_FrameCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
 
   if (!Dbg::ThreadExists(thread_id)) {
@@ -984,7 +1059,8 @@
 /*
  * Get the monitor that the thread is waiting on.
  */
-static JdwpError TR_CurrentContendedMonitor(JdwpState*, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError TR_CurrentContendedMonitor(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ReadObjectId(&buf);  // thread_id
 
   // TODO: create an Object to represent the monitor (we're currently
@@ -994,14 +1070,15 @@
 }
 
 /*
- * Return the suspend count for the specified thread.
+ * Return the debug suspend count for the specified thread.
  *
  * (The thread *might* still be running -- it might not have examined
  * its suspend count recently.)
  */
-static JdwpError TR_SuspendCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TR_DebugSuspendCount(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
-  return Dbg::GetThreadSuspendCount(thread_id, pReply);
+  return Dbg::GetThreadDebugSuspendCount(thread_id, pReply);
 }
 
 /*
@@ -1009,7 +1086,8 @@
  *
  * The Eclipse debugger recognizes "main" and "system" as special.
  */
-static JdwpError TGR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TGR_Name(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_group_id = ReadObjectId(&buf);
   VLOG(jdwp) << StringPrintf("  Req for name of thread_group_id=%#llx", thread_group_id);
 
@@ -1022,7 +1100,8 @@
  * Returns the thread group -- if any -- that contains the specified
  * thread group.
  */
-static JdwpError TGR_Parent(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TGR_Parent(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_group_id = ReadObjectId(&buf);
 
   ObjectId parentGroup = Dbg::GetThreadGroupParent(thread_group_id);
@@ -1035,7 +1114,8 @@
  * Return the active threads and thread groups that are part of the
  * specified thread group.
  */
-static JdwpError TGR_Children(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError TGR_Children(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_group_id = ReadObjectId(&buf);
   VLOG(jdwp) << StringPrintf("  Req for threads in thread_group_id=%#llx", thread_group_id);
 
@@ -1059,7 +1139,8 @@
 /*
  * Return the #of components in the array.
  */
-static JdwpError AR_Length(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError AR_Length(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId arrayId = ReadObjectId(&buf);
   VLOG(jdwp) << StringPrintf("  Req for length of array %#llx", arrayId);
 
@@ -1078,7 +1159,8 @@
 /*
  * Return the values from an array.
  */
-static JdwpError AR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError AR_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId arrayId = ReadObjectId(&buf);
   uint32_t firstIndex = Read4BE(&buf);
   uint32_t length = Read4BE(&buf);
@@ -1090,17 +1172,20 @@
 /*
  * Set values in an array.
  */
-static JdwpError AR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError AR_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId arrayId = ReadObjectId(&buf);
   uint32_t firstIndex = Read4BE(&buf);
   uint32_t values = Read4BE(&buf);
 
-  VLOG(jdwp) << StringPrintf("  Req to set array values %#llx first=%d count=%d", arrayId, firstIndex, values);
+  VLOG(jdwp) << StringPrintf("  Req to set array values %#llx first=%d count=%d", arrayId,
+                             firstIndex, values);
 
   return Dbg::SetArrayElements(arrayId, firstIndex, values, buf);
 }
 
-static JdwpError CLR_VisibleClasses(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError CLR_VisibleClasses(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ReadObjectId(&buf);  // classLoaderObject
   // TODO: we should only return classes which have the given class loader as a defining or
   // initiating loader. The former would be easy; the latter is hard, because we don't have
@@ -1113,7 +1198,8 @@
  *
  * Reply with a requestID.
  */
-static JdwpError ER_Set(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError ER_Set(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   const uint8_t* origBuf = buf;
 
   uint8_t eventKind = Read1(&buf);
@@ -1282,7 +1368,8 @@
  * Clear an event.  Failure to find an event with a matching ID is a no-op
  * and does not return an error.
  */
-static JdwpError ER_Clear(JdwpState* state, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError ER_Clear(JdwpState* state, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   uint8_t eventKind;
   eventKind = Read1(&buf);
   uint32_t requestId = Read4BE(&buf);
@@ -1297,7 +1384,8 @@
 /*
  * Return the values of arguments and local variables.
  */
-static JdwpError SF_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError SF_GetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
   FrameId frame_id = ReadFrameId(&buf);
   uint32_t slots = Read4BE(&buf);
@@ -1322,7 +1410,8 @@
 /*
  * Set the values of arguments and local variables.
  */
-static JdwpError SF_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*) {
+static JdwpError SF_SetValues(JdwpState*, const uint8_t* buf, int, ExpandBuf*)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
   FrameId frame_id = ReadFrameId(&buf);
   uint32_t slots = Read4BE(&buf);
@@ -1345,7 +1434,8 @@
 /*
  * Returns the value of "this" for the specified frame.
  */
-static JdwpError SF_ThisObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError SF_ThisObject(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   ObjectId thread_id = ReadObjectId(&buf);
   FrameId frame_id = ReadFrameId(&buf);
 
@@ -1361,7 +1451,8 @@
     return rc;
   }
 
-  VLOG(jdwp) << StringPrintf("  Req for 'this' in thread_id=%#llx frame=%lld --> %#llx '%c'", thread_id, frame_id, id, static_cast<char>(tag));
+  VLOG(jdwp) << StringPrintf("  Req for 'this' in thread_id=%#llx frame=%lld --> %#llx '%c'",
+                             thread_id, frame_id, id, static_cast<char>(tag));
   expandBufAdd1(pReply, tag);
   expandBufAddObjectId(pReply, id);
 
@@ -1375,16 +1466,19 @@
  * reused, whereas ClassIds can be recycled like any other object.  (Either
  * that, or I have no idea what this is for.)
  */
-static JdwpError COR_ReflectedType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply) {
+static JdwpError COR_ReflectedType(JdwpState*, const uint8_t* buf, int, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   RefTypeId classObjectId = ReadRefTypeId(&buf);
-  VLOG(jdwp) << StringPrintf("  Req for refTypeId for class=%#llx (%s)", classObjectId, Dbg::GetClassName(classObjectId).c_str());
+  VLOG(jdwp) << StringPrintf("  Req for refTypeId for class=%#llx (%s)", classObjectId,
+                             Dbg::GetClassName(classObjectId).c_str());
   return Dbg::GetReflectedType(classObjectId, pReply);
 }
 
 /*
  * Handle a DDM packet with a single chunk in it.
  */
-static JdwpError DDM_Chunk(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+static JdwpError DDM_Chunk(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply)
+    SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
   uint8_t* replyBuf = NULL;
   int replyLen = -1;
 
@@ -1518,7 +1612,7 @@
   { 11,   9,  TR_CurrentContendedMonitor, "ThreadReference.CurrentContendedMonitor" },
   { 11,   10, NULL, "ThreadReference.Stop" },
   { 11,   11, NULL, "ThreadReference.Interrupt" },
-  { 11,   12, TR_SuspendCount,  "ThreadReference.SuspendCount" },
+  { 11,   12, TR_DebugSuspendCount, "ThreadReference.SuspendCount" },
   { 11,   13, NULL, "ThreadReference.OwnedMonitorsStackDepthInfo" },
   { 11,   14, NULL, "ThreadReference.ForceEarlyReturn" },
 
@@ -1612,7 +1706,8 @@
    * Tell the VM that we're running and shouldn't be interrupted by GC.
    * Do this after anything that can stall indefinitely.
    */
-  Dbg::ThreadRunning();
+  Thread* self = Thread::Current();
+  ThreadState old_state = self->TransitionFromSuspendedToRunnable();
 
   expandBufAddSpace(pReply, kJDWPHeaderLen);
 
@@ -1660,7 +1755,8 @@
   }
 
   /* tell the VM that GC is okay again */
-  Dbg::ThreadWaiting();
+  self->TransitionFromRunnableToSuspended(old_state);
+
 }
 
 }  // namespace JDWP