Sweep the monitor list.

Change-Id: I343261206f8bbabd245b404dd95d532255e5d870
diff --git a/src/monitor.cc b/src/monitor.cc
index 9a0233f..bc577a4 100644
--- a/src/monitor.cc
+++ b/src/monitor.cc
@@ -26,6 +26,7 @@
 
 #include "mutex.h"
 #include "object.h"
+#include "stl_util.h"
 #include "thread.h"
 #include "thread_list.h"
 
@@ -94,6 +95,10 @@
 
 bool Monitor::is_verbose_ = false;
 
+bool Monitor::IsVerbose() {
+  return is_verbose_;
+}
+
 void Monitor::SetVerbose(bool is_verbose) {
   is_verbose_ = is_verbose;
 }
@@ -104,7 +109,6 @@
       obj_(obj),
       wait_set_(NULL),
       lock_("a monitor lock"),
-      next_(NULL),
       owner_filename_(NULL),
       owner_line_number_(0) {
 }
@@ -174,48 +178,8 @@
   }
 }
 
-// Global list of all monitors. Used for cleanup.
-static Monitor* gMonitorList = NULL;
-
-void Monitor::FreeMonitorList() {
-  Monitor* m = gMonitorList;
-  while (m != NULL) {
-    Monitor* next = m->next_;
-    delete m;
-    m = next;
-  }
-}
-
-/*
- * Frees monitor objects belonging to unmarked objects.
- */
-static void SweepMonitorList(Monitor** mon, bool (isUnmarkedObject)(void*)) {
-  UNIMPLEMENTED(FATAL);
-#if 0
-  Monitor handle;
-  Monitor *curr;
-
-  DCHECK(mon != NULL);
-  DCHECK(isUnmarkedObject != NULL);
-  Monitor* prev = &handle;
-  prev->next = curr = *mon;
-  while (curr != NULL) {
-    Object* obj = curr->obj;
-    if ((*isUnmarkedObject)(obj) != 0) {
-      prev->next = curr->next;
-      delete curr;
-      curr = prev->next;
-    } else {
-      prev = curr;
-      curr = curr->next;
-    }
-  }
-  *mon = handle.next;
-#endif
-}
-
-void Monitor::SweepMonitorList(bool (isUnmarkedObject)(void*)) {
-  ::art::SweepMonitorList(&gMonitorList, isUnmarkedObject);
+Object* Monitor::GetObject() {
+  return obj_;
 }
 
 /*
@@ -648,10 +612,7 @@
   if (is_verbose_) {
     LOG(INFO) << "monitor: created monitor " << m << " for object " << obj;
   }
-  // Replace the head of the list with the new monitor.
-  do {
-    m->next_ = gMonitorList;
-  } while (android_atomic_release_cas((int32_t)m->next_, (int32_t)m, (int32_t*)(void*)&gMonitorList) != 0);
+  Runtime::Current()->GetMonitorList()->Add(m);
   m->Lock(self);
   // Propagate the lock state.
   uint32_t thin = *obj->GetRawLockWordAddress();
@@ -945,4 +906,35 @@
   os << "\n";
 }
 
+MonitorList::MonitorList() : lock_("MonitorList lock") {
+}
+
+MonitorList::~MonitorList() {
+  MutexLock mu(lock_);
+  STLDeleteElements(&list_);
+}
+
+void MonitorList::Add(Monitor* m) {
+  MutexLock mu(lock_);
+  list_.push_front(m);
+}
+
+void MonitorList::SweepMonitorList(Heap::IsMarkedTester is_marked, void* arg) {
+  MutexLock mu(lock_);
+  typedef std::list<Monitor*>::iterator It; // TODO: C++0x auto
+  It it = list_.begin();
+  while (it != list_.end()) {
+    Monitor* m = *it;
+    if (!is_marked(m->GetObject(), arg)) {
+      if (Monitor::IsVerbose()) {
+        LOG(INFO) << "freeing monitor " << m << " belonging to unmarked object " << m->GetObject();
+      }
+      delete m;
+      it = list_.erase(it);
+    } else {
+      ++it;
+    }
+  }
+}
+
 }  // namespace art