Cleanup JDWP event matching

* Use std::vector for the event match list.
* Make event reporting methods void since result is never used.
* Use nullptr keyword instead of NULL.

Change-Id: Icd6f47e46cefc2cc63325df00037cd4b6a475259
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 7cc52c3..a3a043f 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -669,9 +669,7 @@
   // This may cause us to suspend all threads.
   if (gJdwpState->IsActive()) {
     ScopedObjectAccess soa(Thread::Current());
-    if (!gJdwpState->PostVMStart()) {
-      LOG(WARNING) << "Failed to post 'start' message to debugger";
-    }
+    gJdwpState->PostVMStart();
   }
 }
 
@@ -2569,7 +2567,7 @@
     VLOG(jdwp) << "    --> slot " << slot << " " << reqSigByte;
 
     size_t width = Dbg::GetTagWidth(reqSigByte);
-    uint8_t* ptr = expandBufAddSpace(pReply, width+1);
+    uint8_t* ptr = expandBufAddSpace(pReply, width + 1);
     JDWP::JdwpError error = Dbg::GetLocalValue(visitor, soa, slot, reqSigByte, ptr, width);
     if (error != JDWP::ERR_NONE) {
       return error;
diff --git a/runtime/jdwp/jdwp.h b/runtime/jdwp/jdwp.h
index 0c9451c..aa0c103 100644
--- a/runtime/jdwp/jdwp.h
+++ b/runtime/jdwp/jdwp.h
@@ -27,6 +27,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <string.h>
+#include <vector>
 
 struct iovec;
 
@@ -188,7 +189,7 @@
    * The VM has finished initializing.  Only called when the debugger is
    * connected at the time initialization completes.
    */
-  bool PostVMStart() LOCKS_EXCLUDED(event_list_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void PostVMStart() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   /*
    * A location of interest has been reached.  This is used for breakpoints,
@@ -202,7 +203,7 @@
    *
    * "returnValue" is non-null for MethodExit events only.
    */
-  bool PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr, int eventFlags,
+  void PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr, int eventFlags,
                          const JValue* returnValue)
      LOCKS_EXCLUDED(event_list_lock_)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -214,7 +215,7 @@
    * "fieldValue" is non-null for field modification events only.
    * "is_modification" is true for field modification, false for field access.
    */
-  bool PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field, mirror::Object* thisPtr,
+  void PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field, mirror::Object* thisPtr,
                       const JValue* fieldValue, bool is_modification)
       LOCKS_EXCLUDED(event_list_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -224,7 +225,7 @@
    *
    * Pass in a zeroed-out "*pCatchLoc" if the exception wasn't caught.
    */
-  bool PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
+  void PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
                      const EventLocation* pCatchLoc, mirror::Object* thisPtr)
       LOCKS_EXCLUDED(event_list_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -232,14 +233,14 @@
   /*
    * A thread has started or stopped.
    */
-  bool PostThreadChange(Thread* thread, bool start)
+  void PostThreadChange(Thread* thread, bool start)
       LOCKS_EXCLUDED(event_list_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   /*
    * Class has been prepared.
    */
-  bool PostClassPrepare(mirror::Class* klass)
+  void PostClassPrepare(mirror::Class* klass)
       LOCKS_EXCLUDED(event_list_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -307,15 +308,16 @@
   void SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
                                      ObjectId threadId)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  void CleanupMatchList(JdwpEvent** match_list,
-                        size_t match_count)
+  void CleanupMatchList(const std::vector<JdwpEvent*>& match_list)
       EXCLUSIVE_LOCKS_REQUIRED(event_list_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void EventFinish(ExpandBuf* pReq);
-  void FindMatchingEvents(JdwpEventKind eventKind,
-                          const ModBasket& basket,
-                          JdwpEvent** match_list,
-                          size_t* pMatchCount)
+  bool FindMatchingEvents(JdwpEventKind eventKind, const ModBasket& basket,
+                          std::vector<JdwpEvent*>* match_list)
+      LOCKS_EXCLUDED(event_list_lock_)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void FindMatchingEventsLocked(JdwpEventKind eventKind, const ModBasket& basket,
+                                std::vector<JdwpEvent*>* match_list)
       EXCLUSIVE_LOCKS_REQUIRED(event_list_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void UnregisterEvent(JdwpEvent* pEvent)
diff --git a/runtime/jdwp/jdwp_adb.cc b/runtime/jdwp/jdwp_adb.cc
index df7d068..adc2912 100644
--- a/runtime/jdwp/jdwp_adb.cc
+++ b/runtime/jdwp/jdwp_adb.cc
@@ -123,7 +123,7 @@
 bool InitAdbTransport(JdwpState* state, const JdwpOptions*) {
   VLOG(jdwp) << "ADB transport startup";
   state->netState = new JdwpAdbState(state);
-  return (state->netState != NULL);
+  return (state->netState != nullptr);
 }
 
 /*
@@ -145,7 +145,7 @@
   iov.iov_len        = 1;
 
   msghdr msg;
-  msg.msg_name       = NULL;
+  msg.msg_name       = nullptr;
   msg.msg_namelen    = 0;
   msg.msg_iov        = &iov;
   msg.msg_iovlen     = 1;
@@ -352,7 +352,7 @@
        * re-issue the select.  We're currently using #2, as it's more
        * reliable than #1 and generally better than #3.  Wastes two fds.
        */
-      selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
+      selCount = select(maxfd + 1, &readfds, nullptr, nullptr, nullptr);
       if (selCount < 0) {
         if (errno == EINTR) {
           continue;
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index 1e0a2d2..1bf16b2 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -172,9 +172,9 @@
  * not be added to the list, and an appropriate error will be returned.
  */
 JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
-  CHECK(pEvent != NULL);
-  CHECK(pEvent->prev == NULL);
-  CHECK(pEvent->next == NULL);
+  CHECK(pEvent != nullptr);
+  CHECK(pEvent->prev == nullptr);
+  CHECK(pEvent->next == nullptr);
 
   {
     /*
@@ -223,7 +223,7 @@
      * Add to list.
      */
     MutexLock mu(Thread::Current(), event_list_lock_);
-    if (event_list_ != NULL) {
+    if (event_list_ != nullptr) {
       pEvent->next = event_list_;
       event_list_->prev = pEvent;
     }
@@ -245,7 +245,7 @@
  * Grab the eventLock before calling here.
  */
 void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
-  if (pEvent->prev == NULL) {
+  if (pEvent->prev == nullptr) {
     /* head of the list */
     CHECK(event_list_ == pEvent);
 
@@ -254,11 +254,11 @@
     pEvent->prev->next = pEvent->next;
   }
 
-  if (pEvent->next != NULL) {
+  if (pEvent->next != nullptr) {
     pEvent->next->prev = pEvent->prev;
-    pEvent->next = NULL;
+    pEvent->next = nullptr;
   }
-  pEvent->prev = NULL;
+  pEvent->prev = nullptr;
 
   {
     /*
@@ -303,7 +303,7 @@
   }
 
   --event_list_size_;
-  CHECK(event_list_size_ != 0 || event_list_ == NULL);
+  CHECK(event_list_size_ != 0 || event_list_ == nullptr);
 }
 
 /*
@@ -343,7 +343,7 @@
   MutexLock mu(Thread::Current(), event_list_lock_);
 
   JdwpEvent* pEvent = event_list_;
-  while (pEvent != NULL) {
+  while (pEvent != nullptr) {
     JdwpEvent* pNextEvent = pEvent->next;
 
     UnregisterEvent(pEvent);
@@ -351,7 +351,7 @@
     pEvent = pNextEvent;
   }
 
-  event_list_ = NULL;
+  event_list_ = nullptr;
 }
 
 /*
@@ -372,13 +372,13 @@
  * Do not call this until the event has been removed from the list.
  */
 void EventFree(JdwpEvent* pEvent) {
-  if (pEvent == NULL) {
+  if (pEvent == nullptr) {
     return;
   }
 
   /* make sure it was removed from the list */
-  CHECK(pEvent->prev == NULL);
-  CHECK(pEvent->next == NULL);
+  CHECK(pEvent->prev == nullptr);
+  CHECK(pEvent->next == nullptr);
   /* want to check state->event_list_ != pEvent */
 
   /*
@@ -387,11 +387,11 @@
   for (int i = 0; i < pEvent->modCount; i++) {
     if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
       free(pEvent->mods[i].classMatch.classPattern);
-      pEvent->mods[i].classMatch.classPattern = NULL;
+      pEvent->mods[i].classMatch.classPattern = nullptr;
     }
     if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
       free(pEvent->mods[i].classExclude.classPattern);
-      pEvent->mods[i].classExclude.classPattern = NULL;
+      pEvent->mods[i].classExclude.classPattern = nullptr;
     }
   }
 
@@ -399,26 +399,12 @@
 }
 
 /*
- * Allocate storage for matching events.  To keep things simple we
- * use an array with enough storage for the entire list.
- *
- * The state->eventLock should be held before calling.
- */
-static JdwpEvent** AllocMatchList(size_t event_count) {
-  return new JdwpEvent*[event_count];
-}
-
-/*
  * Run through the list and remove any entries with an expired "count" mod
- * from the event list, then free the match list.
+ * from the event list.
  */
-void JdwpState::CleanupMatchList(JdwpEvent** match_list, size_t match_count) {
-  JdwpEvent** ppEvent = match_list;
-
-  while (match_count--) {
-    JdwpEvent* pEvent = *ppEvent;
-
-    for (int i = 0; i < pEvent->modCount; i++) {
+void JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) {
+  for (JdwpEvent* pEvent : match_list) {
+    for (int i = 0; i < pEvent->modCount; ++i) {
       if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
         VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
                                    pEvent->requestId);
@@ -427,11 +413,7 @@
         break;
       }
     }
-
-    ppEvent++;
   }
-
-  delete[] match_list;
 }
 
 /*
@@ -536,40 +518,55 @@
 }
 
 /*
- * Find all events of type "eventKind" with mods that match up with the
- * rest of the arguments.
+ * Find all events of type "event_kind" with mods that match up with the
+ * rest of the arguments while holding the event list lock. This method
+ * is used by FindMatchingEvents below.
  *
- * Found events are appended to "match_list", and "*pMatchCount" is advanced,
- * so this may be called multiple times for grouped events.
+ * Found events are appended to "match_list" so this may be called multiple times for grouped
+ * events.
  *
  * DO NOT call this multiple times for the same eventKind, as Count mods are
  * decremented during the scan.
  */
-void JdwpState::FindMatchingEvents(JdwpEventKind eventKind, const ModBasket& basket,
-                                   JdwpEvent** match_list, size_t* pMatchCount) {
-  /* start after the existing entries */
-  match_list += *pMatchCount;
-
+void JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket,
+                                         std::vector<JdwpEvent*>* match_list) {
   for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
-    if (pEvent->eventKind == eventKind && ModsMatch(pEvent, basket)) {
-      *match_list++ = pEvent;
-      (*pMatchCount)++;
+    if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) {
+      match_list->push_back(pEvent);
     }
   }
 }
 
 /*
+ * Find all events of type "event_kind" with mods that match up with the
+ * rest of the arguments and return true if at least one event matches,
+ * false otherwise.
+ *
+ * Found events are appended to "match_list" so this may be called multiple
+ * times for grouped events.
+ *
+ * DO NOT call this multiple times for the same eventKind, as Count mods are
+ * decremented during the scan.
+ */
+bool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket,
+                                   std::vector<JdwpEvent*>* match_list) {
+  MutexLock mu(Thread::Current(), event_list_lock_);
+  match_list->reserve(event_list_size_);
+  FindMatchingEventsLocked(event_kind, basket, match_list);
+  return !match_list->empty();
+}
+
+/*
  * Scan through the list of matches and determine the most severe
  * suspension policy.
  */
-static JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** match_list, int match_count) {
+static JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) {
   JdwpSuspendPolicy policy = SP_NONE;
 
-  while (match_count--) {
-    if ((*match_list)->suspend_policy > policy) {
-      policy = (*match_list)->suspend_policy;
+  for (JdwpEvent* pEvent : match_list) {
+    if (pEvent->suspend_policy > policy) {
+      policy = pEvent->suspend_policy;
     }
-    match_list++;
   }
 
   return policy;
@@ -626,19 +623,18 @@
 
 void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
                                               ObjectId threadId) {
-  Thread* self = Thread::Current();
+  Thread* const self = Thread::Current();
   self->AssertThreadSuspensionIsAllowable();
+  CHECK(pReq != nullptr);
   /* send request and possibly suspend ourselves */
-  if (pReq != NULL) {
-    JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
-    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
-    if (suspend_policy != SP_NONE) {
-      SetWaitForEventThread(threadId);
-    }
-    EventFinish(pReq);
-    SuspendByPolicy(suspend_policy, thread_self_id);
-    self->TransitionFromSuspendedToRunnable();
+  JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
+  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
+  if (suspend_policy != SP_NONE) {
+    SetWaitForEventThread(threadId);
   }
+  EventFinish(pReq);
+  SuspendByPolicy(suspend_policy, thread_self_id);
+  self->TransitionFromSuspendedToRunnable();
 }
 
 /*
@@ -729,10 +725,10 @@
   uint8_t* buf = expandBufGetBuffer(pReq);
 
   Set4BE(buf, expandBufGetLength(pReq));
-  Set4BE(buf+4, NextRequestSerial());
-  Set1(buf+8, 0);     /* flags */
-  Set1(buf+9, kJdwpEventCommandSet);
-  Set1(buf+10, kJdwpCompositeCommand);
+  Set4BE(buf + 4, NextRequestSerial());
+  Set1(buf + 8, 0);     /* flags */
+  Set1(buf + 9, kJdwpEventCommandSet);
+  Set1(buf + 10, kJdwpCompositeCommand);
 
   // Prevents from interleaving commands and events. Otherwise we could end up in sending an event
   // before sending the reply of the command being processed and would lead to bad synchronization
@@ -753,43 +749,30 @@
  * any application code has been executed".  The thread ID in the message
  * must be for the main thread.
  */
-bool JdwpState::PostVMStart() {
-  JdwpSuspendPolicy suspend_policy;
+void JdwpState::PostVMStart() {
+  JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE;
   ObjectId threadId = Dbg::GetThreadSelfId();
 
-  if (options_->suspend) {
-    suspend_policy = SP_ALL;
-  } else {
-    suspend_policy = SP_NONE;
-  }
+  VLOG(jdwp) << "EVENT: " << EK_VM_START;
+  VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
 
   ExpandBuf* pReq = eventPrep();
-  {
-    MutexLock mu(Thread::Current(), event_list_lock_);  // probably don't need this here
-
-    VLOG(jdwp) << "EVENT: " << EK_VM_START;
-    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
-
-    expandBufAdd1(pReq, suspend_policy);
-    expandBufAdd4BE(pReq, 1);
-
-    expandBufAdd1(pReq, EK_VM_START);
-    expandBufAdd4BE(pReq, 0);       /* requestId */
-    expandBufAdd8BE(pReq, threadId);
-  }
+  expandBufAdd1(pReq, suspend_policy);
+  expandBufAdd4BE(pReq, 1);
+  expandBufAdd1(pReq, EK_VM_START);
+  expandBufAdd4BE(pReq, 0);       /* requestId */
+  expandBufAddObjectId(pReq, threadId);
 
   Dbg::ManageDeoptimization();
 
   /* send request and possibly suspend ourselves */
   SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
-
-  return true;
 }
 
-static void LogMatchingEventsAndThread(JdwpEvent** match_list, size_t match_count,
+static void LogMatchingEventsAndThread(const std::vector<JdwpEvent*> match_list,
                                        ObjectId thread_id)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  for (size_t i = 0; i < match_count; ++i) {
+  for (size_t i = 0, e = match_list.size(); i < e; ++i) {
     JdwpEvent* pEvent = match_list[i];
     VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
                << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
@@ -831,7 +814,7 @@
  *  - Single-step to a line with a breakpoint.  Should get a single
  *    event message with both events in it.
  */
-bool JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
+void JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
                                   int eventFlags, const JValue* returnValue) {
   DCHECK(pLoc != nullptr);
   DCHECK(pLoc->method != nullptr);
@@ -852,7 +835,7 @@
    */
   if (basket.thread == GetDebugThread()) {
     VLOG(jdwp) << "Ignoring location event in JDWP thread";
-    return false;
+    return;
   }
 
   /*
@@ -866,73 +849,69 @@
    */
   if (InvokeInProgress()) {
     VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
-    return false;
+    return;
   }
 
-  size_t match_count = 0;
-  ExpandBuf* pReq = NULL;
-  JdwpSuspendPolicy suspend_policy = SP_NONE;
-  JdwpEvent** match_list = nullptr;
-  ObjectId thread_id = 0;
+  std::vector<JdwpEvent*> match_list;
   {
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      match_list = AllocMatchList(event_list_size_);
-      if ((eventFlags & Dbg::kBreakpoint) != 0) {
-        FindMatchingEvents(EK_BREAKPOINT, basket, match_list, &match_count);
-      }
-      if ((eventFlags & Dbg::kSingleStep) != 0) {
-        FindMatchingEvents(EK_SINGLE_STEP, basket, match_list, &match_count);
-      }
-      if ((eventFlags & Dbg::kMethodEntry) != 0) {
-        FindMatchingEvents(EK_METHOD_ENTRY, basket, match_list, &match_count);
-      }
-      if ((eventFlags & Dbg::kMethodExit) != 0) {
-        FindMatchingEvents(EK_METHOD_EXIT, basket, match_list, &match_count);
-        FindMatchingEvents(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, match_list, &match_count);
-      }
+    // We use the locked version because we have multiple possible match events.
+    MutexLock mu(Thread::Current(), event_list_lock_);
+    match_list.reserve(event_list_size_);
+    if ((eventFlags & Dbg::kBreakpoint) != 0) {
+      FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list);
     }
-    if (match_count != 0) {
-      suspend_policy = scanSuspendPolicy(match_list, match_count);
-
-      thread_id = Dbg::GetThreadId(basket.thread);
-      JDWP::JdwpLocation jdwp_location;
-      SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
-
-      if (VLOG_IS_ON(jdwp)) {
-        LogMatchingEventsAndThread(match_list, match_count, thread_id);
-        VLOG(jdwp) << "  location=" << jdwp_location;
-        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
-      }
-
-      pReq = eventPrep();
-      expandBufAdd1(pReq, suspend_policy);
-      expandBufAdd4BE(pReq, match_count);
-
-      for (size_t i = 0; i < match_count; i++) {
-        expandBufAdd1(pReq, match_list[i]->eventKind);
-        expandBufAdd4BE(pReq, match_list[i]->requestId);
-        expandBufAdd8BE(pReq, thread_id);
-        expandBufAddLocation(pReq, jdwp_location);
-        if (match_list[i]->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
-          Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
-        }
-      }
+    if ((eventFlags & Dbg::kSingleStep) != 0) {
+      FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list);
     }
-
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      CleanupMatchList(match_list, match_count);
+    if ((eventFlags & Dbg::kMethodEntry) != 0) {
+      FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list);
     }
+    if ((eventFlags & Dbg::kMethodExit) != 0) {
+      FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list);
+      FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list);
+    }
+  }
+  if (match_list.empty()) {
+    // No matching event.
+    return;
+  }
+  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
+
+  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
+  JDWP::JdwpLocation jdwp_location;
+  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
+
+  if (VLOG_IS_ON(jdwp)) {
+    LogMatchingEventsAndThread(match_list, thread_id);
+    VLOG(jdwp) << "  location=" << jdwp_location;
+    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
+  }
+
+  ExpandBuf* pReq = eventPrep();
+  expandBufAdd1(pReq, suspend_policy);
+  expandBufAdd4BE(pReq, match_list.size());
+
+  for (const JdwpEvent* pEvent : match_list) {
+    expandBufAdd1(pReq, pEvent->eventKind);
+    expandBufAdd4BE(pReq, pEvent->requestId);
+    expandBufAddObjectId(pReq, thread_id);
+    expandBufAddLocation(pReq, jdwp_location);
+    if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
+      Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
+    }
+  }
+
+  {
+    MutexLock mu(Thread::Current(), event_list_lock_);
+    CleanupMatchList(match_list);
   }
 
   Dbg::ManageDeoptimization();
 
   SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
-  return match_count != 0;
 }
 
-bool JdwpState::PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field,
+void JdwpState::PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field,
                                mirror::Object* this_object, const JValue* fieldValue,
                                bool is_modification) {
   DCHECK(pLoc != nullptr);
@@ -950,86 +929,73 @@
 
   if (InvokeInProgress()) {
     VLOG(jdwp) << "Not posting field event during invoke";
-    return false;
+    return;
   }
 
-  size_t match_count = 0;
-  ExpandBuf* pReq = NULL;
-  JdwpSuspendPolicy suspend_policy = SP_NONE;
-  JdwpEvent** match_list = nullptr;
-  ObjectId thread_id = 0;
+  std::vector<JdwpEvent*> match_list;
+  const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS;
+  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
+    // No matching event.
+    return;
+  }
+
+  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
+  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
+  ObjectRegistry* registry = Dbg::GetObjectRegistry();
+  ObjectId instance_id = registry->Add(basket.thisPtr);
+  RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
+  FieldId field_id = Dbg::ToFieldId(field);
+  JDWP::JdwpLocation jdwp_location;
+  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
+
+  if (VLOG_IS_ON(jdwp)) {
+    LogMatchingEventsAndThread(match_list, thread_id);
+    VLOG(jdwp) << "  location=" << jdwp_location;
+    VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, instance_id);
+    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, field_type_id) << " "
+        << Dbg::GetClassName(field_id);
+    VLOG(jdwp) << StringPrintf("  field=%#" PRIx32, field_id) << " "
+        << Dbg::GetFieldName(field_id);
+    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
+  }
+
+  ExpandBuf* pReq = eventPrep();
+  expandBufAdd1(pReq, suspend_policy);
+  expandBufAdd4BE(pReq, match_list.size());
+
+  // Get field's reference type tag.
+  JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
+
+  // Get instance type tag.
+  uint8_t tag;
   {
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      match_list = AllocMatchList(event_list_size_);
-      if (is_modification) {
-        FindMatchingEvents(EK_FIELD_MODIFICATION, basket, match_list, &match_count);
-      } else {
-        FindMatchingEvents(EK_FIELD_ACCESS, basket, match_list, &match_count);
-      }
+    ScopedObjectAccessUnchecked soa(Thread::Current());
+    tag = Dbg::TagFromObject(soa, basket.thisPtr);
+  }
+
+  for (const JdwpEvent* pEvent : match_list) {
+    expandBufAdd1(pReq, pEvent->eventKind);
+    expandBufAdd4BE(pReq, pEvent->requestId);
+    expandBufAddObjectId(pReq, thread_id);
+    expandBufAddLocation(pReq, jdwp_location);
+    expandBufAdd1(pReq, type_tag);
+    expandBufAddRefTypeId(pReq, field_type_id);
+    expandBufAddFieldId(pReq, field_id);
+    expandBufAdd1(pReq, tag);
+    expandBufAddObjectId(pReq, instance_id);
+    if (is_modification) {
+      Dbg::OutputFieldValue(field_id, fieldValue, pReq);
     }
-    if (match_count != 0) {
-      suspend_policy = scanSuspendPolicy(match_list, match_count);
+  }
 
-      thread_id = Dbg::GetThreadId(basket.thread);
-      ObjectRegistry* registry = Dbg::GetObjectRegistry();
-      ObjectId instance_id = registry->Add(basket.thisPtr);
-      RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
-      FieldId field_id = Dbg::ToFieldId(field);
-      JDWP::JdwpLocation jdwp_location;
-      SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
-
-      if (VLOG_IS_ON(jdwp)) {
-        LogMatchingEventsAndThread(match_list, match_count, thread_id);
-        VLOG(jdwp) << "  location=" << jdwp_location;
-        VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, instance_id);
-        VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, field_type_id) << " "
-                   << Dbg::GetClassName(field_id);
-        VLOG(jdwp) << StringPrintf("  field=%#" PRIx32, field_id) << " "
-                   << Dbg::GetFieldName(field_id);
-        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
-      }
-
-      pReq = eventPrep();
-      expandBufAdd1(pReq, suspend_policy);
-      expandBufAdd4BE(pReq, match_count);
-
-      // Get field's reference type tag.
-      JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
-
-      // Get instance type tag.
-      uint8_t tag;
-      {
-        ScopedObjectAccessUnchecked soa(Thread::Current());
-        tag = Dbg::TagFromObject(soa, basket.thisPtr);
-      }
-
-      for (size_t i = 0; i < match_count; i++) {
-        expandBufAdd1(pReq, match_list[i]->eventKind);
-        expandBufAdd4BE(pReq, match_list[i]->requestId);
-        expandBufAdd8BE(pReq, thread_id);
-        expandBufAddLocation(pReq, jdwp_location);
-        expandBufAdd1(pReq, type_tag);
-        expandBufAddRefTypeId(pReq, field_type_id);
-        expandBufAddFieldId(pReq, field_id);
-        expandBufAdd1(pReq, tag);
-        expandBufAddObjectId(pReq, instance_id);
-        if (is_modification) {
-          Dbg::OutputFieldValue(field_id, fieldValue, pReq);
-        }
-      }
-    }
-
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      CleanupMatchList(match_list, match_count);
-    }
+  {
+    MutexLock mu(Thread::Current(), event_list_lock_);
+    CleanupMatchList(match_list);
   }
 
   Dbg::ManageDeoptimization();
 
   SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
-  return match_count != 0;
 }
 
 /*
@@ -1038,7 +1004,7 @@
  * Valid mods:
  *  Count, ThreadOnly
  */
-bool JdwpState::PostThreadChange(Thread* thread, bool start) {
+void JdwpState::PostThreadChange(Thread* thread, bool start) {
   CHECK_EQ(thread, Thread::Current());
 
   /*
@@ -1046,61 +1012,45 @@
    */
   if (InvokeInProgress()) {
     LOG(WARNING) << "Not posting thread change during invoke";
-    return false;
+    return;
   }
 
   ModBasket basket;
   basket.thread = thread;
 
-  ExpandBuf* pReq = NULL;
-  JdwpSuspendPolicy suspend_policy = SP_NONE;
-  JdwpEvent** match_list = nullptr;
-  size_t match_count = 0;
-  ObjectId thread_id = 0;
+  std::vector<JdwpEvent*> match_list;
+  const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH;
+  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
+    // No matching event.
+    return;
+  }
+
+  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
+  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
+
+  if (VLOG_IS_ON(jdwp)) {
+    LogMatchingEventsAndThread(match_list, thread_id);
+    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
+  }
+
+  ExpandBuf* pReq = eventPrep();
+  expandBufAdd1(pReq, suspend_policy);
+  expandBufAdd4BE(pReq, match_list.size());
+
+  for (const JdwpEvent* pEvent : match_list) {
+    expandBufAdd1(pReq, pEvent->eventKind);
+    expandBufAdd4BE(pReq, pEvent->requestId);
+    expandBufAdd8BE(pReq, thread_id);
+  }
+
   {
-    {
-      // Don't allow the list to be updated while we scan it.
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      match_list = AllocMatchList(event_list_size_);
-      if (start) {
-        FindMatchingEvents(EK_THREAD_START, basket, match_list, &match_count);
-      } else {
-        FindMatchingEvents(EK_THREAD_DEATH, basket, match_list, &match_count);
-      }
-    }
-
-    if (match_count != 0) {
-      suspend_policy = scanSuspendPolicy(match_list, match_count);
-
-      thread_id = Dbg::GetThreadId(basket.thread);
-
-      if (VLOG_IS_ON(jdwp)) {
-        LogMatchingEventsAndThread(match_list, match_count, thread_id);
-        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
-      }
-
-      pReq = eventPrep();
-      expandBufAdd1(pReq, suspend_policy);
-      expandBufAdd4BE(pReq, match_count);
-
-      for (size_t i = 0; i < match_count; i++) {
-        expandBufAdd1(pReq, match_list[i]->eventKind);
-        expandBufAdd4BE(pReq, match_list[i]->requestId);
-        expandBufAdd8BE(pReq, thread_id);
-      }
-    }
-
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      CleanupMatchList(match_list, match_count);
-    }
+    MutexLock mu(Thread::Current(), event_list_lock_);
+    CleanupMatchList(match_list);
   }
 
   Dbg::ManageDeoptimization();
 
   SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
-
-  return match_count != 0;
 }
 
 /*
@@ -1132,7 +1082,7 @@
  * because there's a pretty good chance that we're not going to send it
  * up the debugger.
  */
-bool JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
+void JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
                               const EventLocation* pCatchLoc, mirror::Object* thisPtr) {
   DCHECK(exception_object != nullptr);
   DCHECK(pThrowLoc != nullptr);
@@ -1159,72 +1109,61 @@
   /* don't try to post an exception caused by the debugger */
   if (InvokeInProgress()) {
     VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
-    return false;
+    return;
   }
 
-  size_t match_count = 0;
-  ExpandBuf* pReq = NULL;
-  JdwpSuspendPolicy suspend_policy = SP_NONE;
-  JdwpEvent** match_list = nullptr;
-  ObjectId thread_id = 0;
+  std::vector<JdwpEvent*> match_list;
+  if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) {
+    // No matching event.
+    return;
+  }
+
+  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
+  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
+  ObjectRegistry* registry = Dbg::GetObjectRegistry();
+  ObjectId exceptionId = registry->Add(exception_object);
+  JDWP::JdwpLocation jdwp_throw_location;
+  JDWP::JdwpLocation jdwp_catch_location;
+  SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
+  SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
+
+  if (VLOG_IS_ON(jdwp)) {
+    std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass()));
+
+    LogMatchingEventsAndThread(match_list, thread_id);
+    VLOG(jdwp) << "  throwLocation=" << jdwp_throw_location;
+    if (jdwp_catch_location.class_id == 0) {
+      VLOG(jdwp) << "  catchLocation=uncaught";
+    } else {
+      VLOG(jdwp) << "  catchLocation=" << jdwp_catch_location;
+    }
+    VLOG(jdwp) << StringPrintf("  exception=%#" PRIx64, exceptionId) << " "
+        << exceptionClassName;
+    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
+  }
+
+  ExpandBuf* pReq = eventPrep();
+  expandBufAdd1(pReq, suspend_policy);
+  expandBufAdd4BE(pReq, match_list.size());
+
+  for (const JdwpEvent* pEvent : match_list) {
+    expandBufAdd1(pReq, pEvent->eventKind);
+    expandBufAdd4BE(pReq, pEvent->requestId);
+    expandBufAddObjectId(pReq, thread_id);
+    expandBufAddLocation(pReq, jdwp_throw_location);
+    expandBufAdd1(pReq, JT_OBJECT);
+    expandBufAddObjectId(pReq, exceptionId);
+    expandBufAddLocation(pReq, jdwp_catch_location);
+  }
+
   {
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      match_list = AllocMatchList(event_list_size_);
-      FindMatchingEvents(EK_EXCEPTION, basket, match_list, &match_count);
-    }
-    if (match_count != 0) {
-      suspend_policy = scanSuspendPolicy(match_list, match_count);
-
-      thread_id = Dbg::GetThreadId(basket.thread);
-      ObjectRegistry* registry = Dbg::GetObjectRegistry();
-      ObjectId exceptionId = registry->Add(exception_object);
-      JDWP::JdwpLocation jdwp_throw_location;
-      JDWP::JdwpLocation jdwp_catch_location;
-      SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
-      SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
-
-      if (VLOG_IS_ON(jdwp)) {
-        std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass()));
-
-        LogMatchingEventsAndThread(match_list, match_count, thread_id);
-        VLOG(jdwp) << "  throwLocation=" << jdwp_throw_location;
-        if (jdwp_catch_location.class_id == 0) {
-          VLOG(jdwp) << "  catchLocation=uncaught";
-        } else {
-          VLOG(jdwp) << "  catchLocation=" << jdwp_catch_location;
-        }
-        VLOG(jdwp) << StringPrintf("  exception=%#" PRIx64, exceptionId) << " "
-                   << exceptionClassName;
-        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
-      }
-
-      pReq = eventPrep();
-      expandBufAdd1(pReq, suspend_policy);
-      expandBufAdd4BE(pReq, match_count);
-
-      for (size_t i = 0; i < match_count; i++) {
-        expandBufAdd1(pReq, match_list[i]->eventKind);
-        expandBufAdd4BE(pReq, match_list[i]->requestId);
-        expandBufAdd8BE(pReq, thread_id);
-        expandBufAddLocation(pReq, jdwp_throw_location);
-        expandBufAdd1(pReq, JT_OBJECT);
-        expandBufAdd8BE(pReq, exceptionId);
-        expandBufAddLocation(pReq, jdwp_catch_location);
-      }
-    }
-
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      CleanupMatchList(match_list, match_count);
-    }
+    MutexLock mu(Thread::Current(), event_list_lock_);
+    CleanupMatchList(match_list);
   }
 
   Dbg::ManageDeoptimization();
 
   SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
-
-  return match_count != 0;
 }
 
 /*
@@ -1233,7 +1172,7 @@
  * Valid mods:
  *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
  */
-bool JdwpState::PostClassPrepare(mirror::Class* klass) {
+void JdwpState::PostClassPrepare(mirror::Class* klass) {
   DCHECK(klass != nullptr);
 
   ModBasket basket;
@@ -1244,80 +1183,69 @@
   /* suppress class prep caused by debugger */
   if (InvokeInProgress()) {
     VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
-    return false;
+    return;
   }
 
-  ExpandBuf* pReq = NULL;
-  JdwpSuspendPolicy suspend_policy = SP_NONE;
-  JdwpEvent** match_list = nullptr;
-  size_t match_count = 0;
-  ObjectId thread_id = 0;
+  std::vector<JdwpEvent*> match_list;
+  if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) {
+    // No matching event.
+    return;
+  }
+
+  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
+  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
+  ObjectRegistry* registry = Dbg::GetObjectRegistry();
+  RefTypeId class_id = registry->AddRefType(basket.locationClass);
+
+  // OLD-TODO - we currently always send both "verified" and "prepared" since
+  // debuggers seem to like that.  There might be some advantage to honesty,
+  // since the class may not yet be verified.
+  int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
+  JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass);
+  std::string temp;
+  std::string signature(basket.locationClass->GetDescriptor(&temp));
+
+  if (VLOG_IS_ON(jdwp)) {
+    LogMatchingEventsAndThread(match_list, thread_id);
+    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, class_id) << " " << signature;
+    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
+  }
+
+  if (thread_id == debug_thread_id_) {
+    /*
+     * JDWP says that, for a class prep in the debugger thread, we
+     * should set thread to null and if any threads were supposed
+     * to be suspended then we suspend all other threads.
+     */
+    VLOG(jdwp) << "  NOTE: class prepare in debugger thread!";
+    thread_id = 0;
+    if (suspend_policy == SP_EVENT_THREAD) {
+      suspend_policy = SP_ALL;
+    }
+  }
+
+  ExpandBuf* pReq = eventPrep();
+  expandBufAdd1(pReq, suspend_policy);
+  expandBufAdd4BE(pReq, match_list.size());
+
+  for (const JdwpEvent* pEvent : match_list) {
+    expandBufAdd1(pReq, pEvent->eventKind);
+    expandBufAdd4BE(pReq, pEvent->requestId);
+    expandBufAddObjectId(pReq, thread_id);
+    expandBufAdd1(pReq, tag);
+    expandBufAddRefTypeId(pReq, class_id);
+    expandBufAddUtf8String(pReq, signature);
+    expandBufAdd4BE(pReq, status);
+  }
+
   {
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      match_list = AllocMatchList(event_list_size_);
-      FindMatchingEvents(EK_CLASS_PREPARE, basket, match_list, &match_count);
-    }
-    if (match_count != 0) {
-      suspend_policy = scanSuspendPolicy(match_list, match_count);
-
-      thread_id = Dbg::GetThreadId(basket.thread);
-      ObjectRegistry* registry = Dbg::GetObjectRegistry();
-      RefTypeId class_id = registry->AddRefType(basket.locationClass);
-
-      // OLD-TODO - we currently always send both "verified" and "prepared" since
-      // debuggers seem to like that.  There might be some advantage to honesty,
-      // since the class may not yet be verified.
-      int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
-      JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass);
-      std::string temp;
-      std::string signature(basket.locationClass->GetDescriptor(&temp));
-
-      if (VLOG_IS_ON(jdwp)) {
-        LogMatchingEventsAndThread(match_list, match_count, thread_id);
-        VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, class_id) << " " << signature;
-        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
-      }
-
-      if (thread_id == debug_thread_id_) {
-        /*
-         * JDWP says that, for a class prep in the debugger thread, we
-         * should set thread to null and if any threads were supposed
-         * to be suspended then we suspend all other threads.
-         */
-        VLOG(jdwp) << "  NOTE: class prepare in debugger thread!";
-        thread_id = 0;
-        if (suspend_policy == SP_EVENT_THREAD) {
-          suspend_policy = SP_ALL;
-        }
-      }
-
-      pReq = eventPrep();
-      expandBufAdd1(pReq, suspend_policy);
-      expandBufAdd4BE(pReq, match_count);
-
-      for (size_t i = 0; i < match_count; i++) {
-        expandBufAdd1(pReq, match_list[i]->eventKind);
-        expandBufAdd4BE(pReq, match_list[i]->requestId);
-        expandBufAdd8BE(pReq, thread_id);
-        expandBufAdd1(pReq, tag);
-        expandBufAdd8BE(pReq, class_id);
-        expandBufAddUtf8String(pReq, signature);
-        expandBufAdd4BE(pReq, status);
-      }
-    }
-
-    {
-      MutexLock mu(Thread::Current(), event_list_lock_);
-      CleanupMatchList(match_list, match_count);
-    }
+    MutexLock mu(Thread::Current(), event_list_lock_);
+    CleanupMatchList(match_list);
   }
 
   Dbg::ManageDeoptimization();
 
   SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
-
-  return match_count != 0;
 }
 
 /*
@@ -1331,7 +1259,7 @@
   uint8_t header[kJDWPHeaderLen + 8];
   size_t dataLen = 0;
 
-  CHECK(iov != NULL);
+  CHECK(iov != nullptr);
   CHECK_GT(iov_count, 0);
   CHECK_LT(iov_count, 10);
 
@@ -1348,12 +1276,12 @@
 
   /* form the header (JDWP plus DDMS) */
   Set4BE(header, sizeof(header) + dataLen);
-  Set4BE(header+4, NextRequestSerial());
-  Set1(header+8, 0);     /* flags */
-  Set1(header+9, kJDWPDdmCmdSet);
-  Set1(header+10, kJDWPDdmCmd);
-  Set4BE(header+11, type);
-  Set4BE(header+15, dataLen);
+  Set4BE(header + 4, NextRequestSerial());
+  Set1(header + 8, 0);     /* flags */
+  Set1(header + 9, kJDWPDdmCmdSet);
+  Set1(header + 10, kJDWPDdmCmd);
+  Set4BE(header + 11, type);
+  Set4BE(header + 15, dataLen);
 
   wrapiov[0].iov_base = header;
   wrapiov[0].iov_len = sizeof(header);
@@ -1364,7 +1292,7 @@
   bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
   if (safe_to_release_mutator_lock_over_send) {
     for (size_t i = 0; i < kMutatorLock; ++i) {
-      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != NULL) {
+      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
         safe_to_release_mutator_lock_over_send = false;
         break;
       }
diff --git a/runtime/jdwp/jdwp_expand_buf.cc b/runtime/jdwp/jdwp_expand_buf.cc
index 0a64f28..cc85cdd 100644
--- a/runtime/jdwp/jdwp_expand_buf.cc
+++ b/runtime/jdwp/jdwp_expand_buf.cc
@@ -57,7 +57,7 @@
  * Free a JdwpBuf and associated storage.
  */
 void expandBufFree(ExpandBuf* pBuf) {
-  if (pBuf == NULL) {
+  if (pBuf == nullptr) {
     return;
   }
 
@@ -93,7 +93,7 @@
   }
 
   uint8_t* newPtr = reinterpret_cast<uint8_t*>(realloc(pBuf->storage, pBuf->maxLen));
-  if (newPtr == NULL) {
+  if (newPtr == nullptr) {
     LOG(FATAL) << "realloc(" << pBuf->maxLen << ") failed";
   }
 
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index a39a7b76..b294e48 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -106,8 +106,8 @@
                              Dbg::GetMethodName(method_id).c_str());
   VLOG(jdwp) << StringPrintf("        %d args:", arg_count);
 
-  std::unique_ptr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : NULL);
-  std::unique_ptr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : NULL);
+  std::unique_ptr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : nullptr);
+  std::unique_ptr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : nullptr);
   for (int32_t i = 0; i < arg_count; ++i) {
     argTypes[i] = request->ReadTag();
     size_t width = Dbg::GetTagWidth(argTypes[i]);
@@ -124,7 +124,9 @@
   JdwpTag resultTag;
   uint64_t resultValue;
   ObjectId exceptObjId;
-  JdwpError err = Dbg::InvokeMethod(thread_id, object_id, class_id, method_id, arg_count, argValues.get(), argTypes.get(), options, &resultTag, &resultValue, &exceptObjId);
+  JdwpError err = Dbg::InvokeMethod(thread_id, object_id, class_id, method_id, arg_count,
+                                    argValues.get(), argTypes.get(), options, &resultTag,
+                                    &resultValue, &exceptObjId);
   if (err != ERR_NONE) {
     return err;
   }
@@ -203,7 +205,7 @@
     // Get class vs. interface and status flags.
     JDWP::JdwpTypeTag type_tag;
     uint32_t class_status;
-    JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, NULL);
+    JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, nullptr);
     if (status != ERR_NONE) {
       return status;
     }
@@ -371,7 +373,7 @@
 static JdwpError VM_CapabilitiesNew(JdwpState*, Request* request, ExpandBuf* reply)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   // The first few capabilities are the same as those reported by the older call.
-  VM_Capabilities(NULL, request, reply);
+  VM_Capabilities(nullptr, request, reply);
 
   expandBufAdd1(reply, false);   // canRedefineClasses
   expandBufAdd1(reply, false);   // canAddMethod
@@ -507,7 +509,7 @@
   RefTypeId refTypeId = request->ReadRefTypeId();
   JDWP::JdwpTypeTag type_tag;
   uint32_t class_status;
-  JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, NULL);
+  JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, nullptr);
   if (status != ERR_NONE) {
     return status;
   }
@@ -1432,7 +1434,7 @@
 static JdwpError DDM_Chunk(JdwpState* state, Request* request, ExpandBuf* pReply)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   state->NotifyDdmsActive();
-  uint8_t* replyBuf = NULL;
+  uint8_t* replyBuf = nullptr;
   int replyLen = -1;
   if (Dbg::DdmHandlePacket(request, &replyBuf, &replyLen)) {
     // If they want to send something back, we copy it into the buffer.
@@ -1481,11 +1483,11 @@
   { 1,    12, VM_Capabilities,          "VirtualMachine.Capabilities" },
   { 1,    13, VM_ClassPaths,            "VirtualMachine.ClassPaths" },
   { 1,    14, VM_DisposeObjects,        "VirtualMachine.DisposeObjects" },
-  { 1,    15, NULL,                     "VirtualMachine.HoldEvents" },
-  { 1,    16, NULL,                     "VirtualMachine.ReleaseEvents" },
+  { 1,    15, nullptr,                  "VirtualMachine.HoldEvents" },
+  { 1,    16, nullptr,                  "VirtualMachine.ReleaseEvents" },
   { 1,    17, VM_CapabilitiesNew,       "VirtualMachine.CapabilitiesNew" },
-  { 1,    18, NULL,                     "VirtualMachine.RedefineClasses" },
-  { 1,    19, NULL,                     "VirtualMachine.SetDefaultStratum" },
+  { 1,    18, nullptr,                  "VirtualMachine.RedefineClasses" },
+  { 1,    19, nullptr,                  "VirtualMachine.SetDefaultStratum" },
   { 1,    20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
   { 1,    21, VM_InstanceCounts,        "VirtualMachine.InstanceCounts" },
 
@@ -1497,7 +1499,7 @@
   { 2,    5,  RT_Methods,              "ReferenceType.Methods" },
   { 2,    6,  RT_GetValues,            "ReferenceType.GetValues" },
   { 2,    7,  RT_SourceFile,           "ReferenceType.SourceFile" },
-  { 2,    8,  NULL,                    "ReferenceType.NestedTypes" },
+  { 2,    8,  nullptr,                 "ReferenceType.NestedTypes" },
   { 2,    9,  RT_Status,               "ReferenceType.Status" },
   { 2,    10, RT_Interfaces,           "ReferenceType.Interfaces" },
   { 2,    11, RT_ClassObject,          "ReferenceType.ClassObject" },
@@ -1506,8 +1508,8 @@
   { 2,    14, RT_FieldsWithGeneric,    "ReferenceType.FieldsWithGeneric" },
   { 2,    15, RT_MethodsWithGeneric,   "ReferenceType.MethodsWithGeneric" },
   { 2,    16, RT_Instances,            "ReferenceType.Instances" },
-  { 2,    17, NULL,                    "ReferenceType.ClassFileVersion" },
-  { 2,    18, NULL,                    "ReferenceType.ConstantPool" },
+  { 2,    17, nullptr,                 "ReferenceType.ClassFileVersion" },
+  { 2,    18, nullptr,                 "ReferenceType.ConstantPool" },
 
   /* ClassType command set (3) */
   { 3,    1,  CT_Superclass,    "ClassType.Superclass" },
@@ -1524,7 +1526,7 @@
   { 6,    1,  M_LineTable,                "Method.LineTable" },
   { 6,    2,  M_VariableTable,            "Method.VariableTable" },
   { 6,    3,  M_Bytecodes,                "Method.Bytecodes" },
-  { 6,    4,  NULL,                       "Method.IsObsolete" },
+  { 6,    4,  nullptr,                    "Method.IsObsolete" },
   { 6,    5,  M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },
 
   /* Field command set (8) */
@@ -1533,7 +1535,7 @@
   { 9,    1,  OR_ReferenceType,     "ObjectReference.ReferenceType" },
   { 9,    2,  OR_GetValues,         "ObjectReference.GetValues" },
   { 9,    3,  OR_SetValues,         "ObjectReference.SetValues" },
-  { 9,    4,  NULL,                 "ObjectReference.UNUSED" },
+  { 9,    4,  nullptr,              "ObjectReference.UNUSED" },
   { 9,    5,  OR_MonitorInfo,       "ObjectReference.MonitorInfo" },
   { 9,    6,  OR_InvokeMethod,      "ObjectReference.InvokeMethod" },
   { 9,    7,  OR_DisableCollection, "ObjectReference.DisableCollection" },
@@ -1554,11 +1556,11 @@
   { 11,   7,  TR_FrameCount,                  "ThreadReference.FrameCount" },
   { 11,   8,  TR_OwnedMonitors,               "ThreadReference.OwnedMonitors" },
   { 11,   9,  TR_CurrentContendedMonitor,     "ThreadReference.CurrentContendedMonitor" },
-  { 11,   10, NULL,                           "ThreadReference.Stop" },
+  { 11,   10, nullptr,                        "ThreadReference.Stop" },
   { 11,   11, TR_Interrupt,                   "ThreadReference.Interrupt" },
   { 11,   12, TR_DebugSuspendCount,           "ThreadReference.SuspendCount" },
   { 11,   13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
-  { 11,   14, NULL,                           "ThreadReference.ForceEarlyReturn" },
+  { 11,   14, nullptr,                        "ThreadReference.ForceEarlyReturn" },
 
   /* ThreadGroupReference command set (12) */
   { 12,   1,  TGR_Name,         "ThreadGroupReference.Name" },
@@ -1576,26 +1578,27 @@
   /* EventRequest command set (15) */
   { 15,   1,  ER_Set,           "EventRequest.Set" },
   { 15,   2,  ER_Clear,         "EventRequest.Clear" },
-  { 15,   3,  NULL,             "EventRequest.ClearAllBreakpoints" },
+  { 15,   3,  nullptr,          "EventRequest.ClearAllBreakpoints" },
 
   /* StackFrame command set (16) */
   { 16,   1,  SF_GetValues,     "StackFrame.GetValues" },
   { 16,   2,  SF_SetValues,     "StackFrame.SetValues" },
   { 16,   3,  SF_ThisObject,    "StackFrame.ThisObject" },
-  { 16,   4,  NULL,             "StackFrame.PopFrames" },
+  { 16,   4,  nullptr,          "StackFrame.PopFrames" },
 
   /* ClassObjectReference command set (17) */
   { 17,   1,  COR_ReflectedType, "ClassObjectReference.ReflectedType" },
 
   /* Event command set (64) */
-  { 64, 100,  NULL, "Event.Composite" },  // sent from VM to debugger, never received by VM
+  { 64, 100,  nullptr, "Event.Composite" },  // sent from VM to debugger, never received by VM
 
   { 199,  1,  DDM_Chunk,        "DDM.Chunk" },
 };
 
 static const char* GetCommandName(Request* request) {
   for (size_t i = 0; i < arraysize(gHandlers); ++i) {
-    if (gHandlers[i].cmdSet == request->GetCommandSet() && gHandlers[i].cmd == request->GetCommand()) {
+    if (gHandlers[i].cmdSet == request->GetCommandSet() &&
+        gHandlers[i].cmd == request->GetCommand()) {
       return gHandlers[i].name;
     }
   }
@@ -1663,7 +1666,9 @@
 
   size_t i;
   for (i = 0; i < arraysize(gHandlers); ++i) {
-    if (gHandlers[i].cmdSet == request->GetCommandSet() && gHandlers[i].cmd == request->GetCommand() && gHandlers[i].func != NULL) {
+    if (gHandlers[i].cmdSet == request->GetCommandSet() &&
+        gHandlers[i].cmd == request->GetCommand() &&
+        gHandlers[i].func != nullptr) {
       VLOG(jdwp) << DescribeCommand(request);
       result = (*gHandlers[i].func)(this, request, pReply);
       if (result == ERR_NONE) {
diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc
index c500ef5..bfd4252 100644
--- a/runtime/jdwp/jdwp_main.cc
+++ b/runtime/jdwp/jdwp_main.cc
@@ -139,7 +139,7 @@
 }
 
 bool JdwpState::IsConnected() {
-  return netState != NULL && netState->IsConnected();
+  return netState != nullptr && netState->IsConnected();
 }
 
 void JdwpState::SendBufferedRequest(uint32_t type, const std::vector<iovec>& iov) {
@@ -202,18 +202,18 @@
       thread_start_lock_("JDWP thread start lock", kJdwpStartLock),
       thread_start_cond_("JDWP thread start condition variable", thread_start_lock_),
       pthread_(0),
-      thread_(NULL),
+      thread_(nullptr),
       debug_thread_started_(false),
       debug_thread_id_(0),
       run(false),
-      netState(NULL),
+      netState(nullptr),
       attach_lock_("JDWP attach lock", kJdwpAttachLock),
       attach_cond_("JDWP attach condition variable", attach_lock_),
       last_activity_time_ms_(0),
       request_serial_(0x10000000),
       event_serial_(0x20000000),
       event_list_lock_("JDWP event list lock", kJdwpEventListLock),
-      event_list_(NULL),
+      event_list_(nullptr),
       event_list_size_(0),
       event_thread_lock_("JDWP event thread lock"),
       event_thread_cond_("JDWP event thread condition variable", event_thread_lock_),
@@ -289,7 +289,7 @@
     }
     if (!state->IsActive()) {
       LOG(ERROR) << "JDWP connection failed";
-      return NULL;
+      return nullptr;
     }
 
     LOG(INFO) << "JDWP connected";
@@ -317,7 +317,7 @@
   UnregisterAll();
   {
     MutexLock mu(Thread::Current(), event_list_lock_);
-    CHECK(event_list_ == NULL);
+    CHECK(event_list_ == nullptr);
   }
 
   Dbg::ProcessDelayedFullUndeoptimizations();
@@ -336,7 +336,7 @@
  * Tell the JDWP thread to shut down.  Frees "state".
  */
 JdwpState::~JdwpState() {
-  if (netState != NULL) {
+  if (netState != nullptr) {
     /*
      * Close down the network to inspire the thread to halt.
      */
@@ -353,9 +353,9 @@
 
     VLOG(jdwp) << "JDWP freeing netstate...";
     delete netState;
-    netState = NULL;
+    netState = nullptr;
   }
-  CHECK(netState == NULL);
+  CHECK(netState == nullptr);
 
   ResetState();
 }
@@ -398,10 +398,10 @@
  */
 static void* StartJdwpThread(void* arg) {
   JdwpState* state = reinterpret_cast<JdwpState*>(arg);
-  CHECK(state != NULL);
+  CHECK(state != nullptr);
 
   state->Run();
-  return NULL;
+  return nullptr;
 }
 
 void JdwpState::Run() {
diff --git a/runtime/jdwp/jdwp_socket.cc b/runtime/jdwp/jdwp_socket.cc
index 7119ce5..cbdde24 100644
--- a/runtime/jdwp/jdwp_socket.cc
+++ b/runtime/jdwp/jdwp_socket.cc
@@ -77,12 +77,12 @@
       /* scan through a range of ports, binding to the first available */
       for (port = kBasePort; port <= kMaxPort; port++) {
         state->netState = SocketStartup(state, port, true);
-        if (state->netState != NULL) {
+        if (state->netState != nullptr) {
           break;
         }
       }
     }
-    if (state->netState == NULL) {
+    if (state->netState == nullptr) {
       LOG(ERROR) << "JDWP net startup failed (req port=" << options->port << ")";
       return false;
     }
@@ -157,7 +157,7 @@
  fail:
   netState->Shutdown();
   delete netState;
-  return NULL;
+  return nullptr;
 }
 
 /*
@@ -284,7 +284,7 @@
 #else
   h_errno = 0;
   pEntry = gethostbyname(options->host.c_str());
-  if (pEntry == NULL) {
+  if (pEntry == nullptr) {
     PLOG(WARNING) << "gethostbyname('" << options->host << "') failed";
     return false;
   }
@@ -403,7 +403,7 @@
        * re-issue the select.  We're currently using #2, as it's more
        * reliable than #1 and generally better than #3.  Wastes two fds.
        */
-      selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
+      selCount = select(maxfd + 1, &readfds, nullptr, nullptr, nullptr);
       if (selCount < 0) {
         if (errno == EINTR) {
           continue;
diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc
index 9123994..20db368 100644
--- a/runtime/jdwp/object_registry.cc
+++ b/runtime/jdwp/object_registry.cc
@@ -138,7 +138,7 @@
 
 jobject ObjectRegistry::GetJObject(JDWP::ObjectId id) {
   if (id == 0) {
-    return NULL;
+    return nullptr;
   }
   Thread* self = Thread::Current();
   MutexLock mu(self, lock_);
@@ -194,7 +194,7 @@
   ObjectRegistryEntry& entry = *it->second;
   if (entry.jni_reference_type == JNIWeakGlobalRefType) {
     JNIEnv* env = self->GetJniEnv();
-    return env->IsSameObject(entry.jni_reference, NULL);  // Has the jweak been collected?
+    return env->IsSameObject(entry.jni_reference, nullptr);  // Has the jweak been collected?
   } else {
     return false;  // We hold a strong reference, so we know this is live.
   }