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/debugger.h b/src/debugger.h
index 4c0c1b6..4db9bd7 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -38,7 +38,10 @@
  */
 struct DebugInvokeReq {
   DebugInvokeReq()
-      : invoke_needed_(false),
+      : ready(false), invoke_needed_(false),
+        receiver_(NULL), thread_(NULL), class_(NULL), method_(NULL),
+        arg_count_(0), arg_values_(NULL), options_(0), error(JDWP::ERR_NONE),
+        result_tag(JDWP::JT_VOID), exception(0),
         lock_("a DebugInvokeReq lock"),
         cond_("a DebugInvokeReq condition variable") {
   }
@@ -78,7 +81,7 @@
   static void StopJdwp();
 
   // Invoked by the GC in case we need to keep DDMS informed.
-  static void GcDidFinish();
+  static void GcDidFinish() LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_);
 
   // Return the DebugInvokeReq for the current thread.
   static DebugInvokeReq* GetInvokeReq();
@@ -111,15 +114,6 @@
    */
   static int64_t LastDebuggerActivity();
 
-  /*
-   * Block/allow GC depending on what we're doing.  These return the old
-   * status, which can be fed to ThreadContinuing() to restore the previous
-   * mode.
-   */
-  static int ThreadRunning();
-  static int ThreadWaiting();
-  static int ThreadContinuing(int status);
-
   static void UndoDebuggerSuspensions();
 
   static void Exit(int status);
@@ -129,84 +123,154 @@
   /*
    * Class, Object, Array
    */
-  static std::string GetClassName(JDWP::RefTypeId id);
-  static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId);
-  static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId);
-  static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId classId, JDWP::ExpandBuf* pReply);
-  static void GetClassList(std::vector<JDWP::RefTypeId>& classes);
-  static JDWP::JdwpError GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor);
-  static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids);
+  static std::string GetClassName(JDWP::RefTypeId id)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId classId, JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void GetClassList(std::vector<JDWP::RefTypeId>& classes)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag,
+                                      uint32_t* pStatus, std::string* pDescriptor)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static JDWP::JdwpError GetReferenceType(JDWP::ObjectId objectId, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError GetSignature(JDWP::RefTypeId refTypeId, std::string& signature);
-  static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId refTypeId, std::string& source_file);
-  static JDWP::JdwpError GetObjectTag(JDWP::ObjectId objectId, uint8_t& tag);
+  static JDWP::JdwpError GetSignature(JDWP::RefTypeId refTypeId, std::string& signature)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId refTypeId, std::string& source_file)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetObjectTag(JDWP::ObjectId objectId, uint8_t& tag)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static size_t GetTagWidth(JDWP::JdwpTag tag);
 
-  static JDWP::JdwpError GetArrayLength(JDWP::ObjectId arrayId, int& length);
-  static JDWP::JdwpError OutputArray(JDWP::ObjectId arrayId, int firstIndex, int count, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError SetArrayElements(JDWP::ObjectId arrayId, int firstIndex, int count, const uint8_t* buf);
+  static JDWP::JdwpError GetArrayLength(JDWP::ObjectId arrayId, int& length)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError OutputArray(JDWP::ObjectId arrayId, int firstIndex, int count,
+                                     JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError SetArrayElements(JDWP::ObjectId arrayId, int firstIndex, int count,
+                                          const uint8_t* buf)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
-  static JDWP::ObjectId CreateString(const std::string& str);
-  static JDWP::JdwpError CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object);
-  static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length, JDWP::ObjectId& new_array);
+  static JDWP::ObjectId CreateString(const std::string& str)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length,
+                                           JDWP::ObjectId& new_array)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
-  static bool MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId);
+  static bool MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
   /*
    * Method and Field
    */
-  static std::string GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId id);
-  static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply);
-  static void OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply);
-  static void OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId id, bool withGeneric, JDWP::ExpandBuf* pReply);
+  static std::string GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId id)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric,
+                                              JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric,
+                                               JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId,
+                                                  JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId,
+                              JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId id, bool withGeneric,
+                                  JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
-  static JDWP::JdwpTag GetFieldBasicTag(JDWP::FieldId fieldId);
-  static JDWP::JdwpTag GetStaticFieldBasicTag(JDWP::FieldId fieldId);
-  static JDWP::JdwpError GetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError SetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, uint64_t value, int width);
-  static JDWP::JdwpError GetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply);
-  static JDWP::JdwpError SetStaticFieldValue(JDWP::FieldId fieldId, uint64_t value, int width);
+  static JDWP::JdwpTag GetFieldBasicTag(JDWP::FieldId fieldId)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpTag GetStaticFieldBasicTag(JDWP::FieldId fieldId)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);;
+  static JDWP::JdwpError GetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId,
+                                       JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError SetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId,
+                                       uint64_t value, int width)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError GetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId,
+                                             JDWP::ExpandBuf* pReply)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError SetStaticFieldValue(JDWP::FieldId fieldId, uint64_t value, int width)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
-  static std::string StringToUtf8(JDWP::ObjectId strId);
+  static std::string StringToUtf8(JDWP::ObjectId strId)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
   /*
    * Thread, ThreadGroup, Frame
    */
-  static bool GetThreadName(JDWP::ObjectId threadId, std::string& name);
+  static bool GetThreadName(JDWP::ObjectId threadId, std::string& name)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_)
+      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_);
   static JDWP::JdwpError GetThreadGroup(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply);
   static std::string GetThreadGroupName(JDWP::ObjectId threadGroupId);
-  static JDWP::ObjectId GetThreadGroupParent(JDWP::ObjectId threadGroupId);
-  static JDWP::ObjectId GetSystemThreadGroupId();
+  static JDWP::ObjectId GetThreadGroupParent(JDWP::ObjectId threadGroupId)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::ObjectId GetSystemThreadGroupId()
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static JDWP::ObjectId GetMainThreadGroupId();
 
   static bool GetThreadStatus(JDWP::ObjectId threadId, JDWP::JdwpThreadStatus* pThreadStatus, JDWP::JdwpSuspendStatus* pSuspendStatus);
-  static JDWP::JdwpError GetThreadSuspendCount(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply);
+  static JDWP::JdwpError GetThreadDebugSuspendCount(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply);
   static bool ThreadExists(JDWP::ObjectId threadId);
   static bool IsSuspended(JDWP::ObjectId threadId);
   //static void WaitForSuspend(JDWP::ObjectId threadId);
 
   // Fills 'thread_ids' with the threads in the given thread group. If thread_group_id == 0,
   // returns all threads.
-  static void GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& thread_ids);
+  static void GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& thread_ids)
+      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static void GetChildThreadGroups(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& child_thread_group_ids);
 
   static int GetThreadFrameCount(JDWP::ObjectId threadId);
-  static JDWP::JdwpError GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame, size_t frame_count, JDWP::ExpandBuf* buf);
+  static JDWP::JdwpError GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame,
+                                         size_t frame_count, JDWP::ExpandBuf* buf)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
-  static JDWP::ObjectId GetThreadSelfId();
-  static void SuspendVM();
+  static JDWP::ObjectId GetThreadSelfId()
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void SuspendVM()
+      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
+                     GlobalSynchronization::thread_suspend_count_lock_);
   static void ResumeVM();
-  static void SuspendThread(JDWP::ObjectId threadId);
-  static void ResumeThread(JDWP::ObjectId threadId);
+  static JDWP::JdwpError SuspendThread(JDWP::ObjectId threadId, bool request_suspension = true)
+      LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_,
+                     GlobalSynchronization::thread_list_lock_,
+                     GlobalSynchronization::thread_suspend_count_lock_);
+
+  static void ResumeThread(JDWP::ObjectId threadId)
+      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
+                     GlobalSynchronization::thread_suspend_count_lock_)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static void SuspendSelf();
 
-  static JDWP::JdwpError GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame_id, JDWP::ObjectId* result);
-  static void GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint8_t* buf, size_t expectedLen);
-  static void SetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint64_t value, size_t width);
+  static JDWP::JdwpError GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame_id,
+                                       JDWP::ObjectId* result)
+      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
+                     GlobalSynchronization::thread_suspend_count_lock_)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot,
+                            JDWP::JdwpTag tag, uint8_t* buf, size_t expectedLen)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void SetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot,
+                            JDWP::JdwpTag tag, uint64_t value, size_t width)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
   /*
    * Debugger notification
@@ -217,20 +281,41 @@
     kMethodEntry    = 0x04,
     kMethodExit     = 0x08,
   };
-  static void PostLocationEvent(const Method* method, int pcOffset, Object* thisPtr, int eventFlags);
-  static void PostException(Thread* thread, JDWP::FrameId throw_frame_id, Method* throw_method, uint32_t throw_dex_pc, Method* catch_method, uint32_t catch_dex_pc, Throwable* exception);
-  static void PostThreadStart(Thread* t);
-  static void PostThreadDeath(Thread* t);
-  static void PostClassPrepare(Class* c);
+  static void PostLocationEvent(const Method* method, int pcOffset, Object* thisPtr, int eventFlags)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void PostException(Thread* thread, JDWP::FrameId throw_frame_id, Method* throw_method,
+                            uint32_t throw_dex_pc, Method* catch_method, uint32_t catch_dex_pc,
+                            Throwable* exception)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void PostThreadStart(Thread* t)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void PostThreadDeath(Thread* t)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void PostClassPrepare(Class* c)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
-  static void UpdateDebugger(int32_t dex_pc, Thread* self);
+  static void UpdateDebugger(int32_t dex_pc, Thread* self)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
-  static void WatchLocation(const JDWP::JdwpLocation* pLoc);
-  static void UnwatchLocation(const JDWP::JdwpLocation* pLoc);
-  static JDWP::JdwpError ConfigureStep(JDWP::ObjectId threadId, JDWP::JdwpStepSize size, JDWP::JdwpStepDepth depth);
+  static void WatchLocation(const JDWP::JdwpLocation* pLoc)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void UnwatchLocation(const JDWP::JdwpLocation* pLoc)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static JDWP::JdwpError ConfigureStep(JDWP::ObjectId threadId, JDWP::JdwpStepSize size,
+                                       JDWP::JdwpStepDepth depth)
+      LOCKS_EXCLUDED(gBreakpointsLock)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static void UnconfigureStep(JDWP::ObjectId threadId);
 
-  static JDWP::JdwpError InvokeMethod(JDWP::ObjectId threadId, JDWP::ObjectId objectId, JDWP::RefTypeId classId, JDWP::MethodId methodId, uint32_t arg_count, uint64_t* arg_values, JDWP::JdwpTag* arg_types, uint32_t options, JDWP::JdwpTag* pResultTag, uint64_t* pResultValue, JDWP::ObjectId* pExceptObj);
+  static JDWP::JdwpError InvokeMethod(JDWP::ObjectId threadId, JDWP::ObjectId objectId,
+                                      JDWP::RefTypeId classId, JDWP::MethodId methodId,
+                                      uint32_t arg_count, uint64_t* arg_values,
+                                      JDWP::JdwpTag* arg_types, uint32_t options,
+                                      JDWP::JdwpTag* pResultTag, uint64_t* pResultValue,
+                                      JDWP::ObjectId* pExceptObj)
+      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
+                     GlobalSynchronization::thread_suspend_count_lock_)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static void ExecuteMethod(DebugInvokeReq* pReq);
 
   /* perform "late registration" of an object ID */
@@ -239,22 +324,28 @@
   /*
    * DDM support.
    */
-  static void DdmSendThreadNotification(Thread* t, uint32_t type);
+  static void DdmSendThreadNotification(Thread* t, uint32_t type)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static void DdmSetThreadNotification(bool enable);
   static bool DdmHandlePacket(const uint8_t* buf, int dataLen, uint8_t** pReplyBuf, int* pReplyLen);
-  static void DdmConnected();
-  static void DdmDisconnected();
-  static void DdmSendChunk(uint32_t type, const std::vector<uint8_t>& bytes);
-  static void DdmSendChunk(uint32_t type, size_t len, const uint8_t* buf);
-  static void DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count);
+  static void DdmConnected() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void DdmDisconnected() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void DdmSendChunk(uint32_t type, const std::vector<uint8_t>& bytes)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void DdmSendChunk(uint32_t type, size_t len, const uint8_t* buf)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
   /*
    * Recent allocation tracking support.
    */
-  static void RecordAllocation(Class* type, size_t byte_count);
+  static void RecordAllocation(Class* type, size_t byte_count)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static void SetAllocTrackingEnabled(bool enabled);
   static inline bool IsAllocTrackingEnabled() { return recent_allocation_records_ != NULL; }
-  static jbyteArray GetRecentAllocations();
+  static jbyteArray GetRecentAllocations()
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
   static void DumpRecentAllocations();
 
   enum HpifWhen {
@@ -263,7 +354,8 @@
     HPIF_WHEN_NEXT_GC = 2,
     HPIF_WHEN_EVERY_GC = 3
   };
-  static int DdmHandleHpifChunk(HpifWhen when);
+  static int DdmHandleHpifChunk(HpifWhen when)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
   enum HpsgWhen {
     HPSG_WHEN_NEVER = 0,
@@ -275,12 +367,15 @@
   };
   static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
 
-  static void DdmSendHeapInfo(HpifWhen reason);
-  static void DdmSendHeapSegments(bool native);
+  static void DdmSendHeapInfo(HpifWhen reason)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void DdmSendHeapSegments(bool native)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
  private:
-  static void DdmBroadcast(bool);
-  static void PostThreadStartOrStop(Thread*, uint32_t);
+  static void DdmBroadcast(bool) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
+  static void PostThreadStartOrStop(Thread*, uint32_t)
+      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
 
   static AllocRecord* recent_allocation_records_;
 };