Refactor spaces and add free list large object space

Added some more abstraction for spaces, we now have ContinuousSpaces and DiscontinousSpaces.

Added a free list version of large object space.

Performance should be better than the memory map version since we avoid creating more than
one memory map.

Added a cause for Gc which prints with the Gc message, dalvik has this as well.

Change-Id: Ie4aa6b204fbde7193e8305eb246158fae0444cc1
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index cdb73db..e9056f5 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -190,7 +190,7 @@
   mark_sweep->CheckObject(root);
 }
 
-void MarkSweep::CopyMarkBits(Space* space) {
+void MarkSweep::CopyMarkBits(ContinuousSpace* space) {
   SpaceBitmap* live_bitmap = space->GetLiveBitmap();
   SpaceBitmap* mark_bitmap = space->GetMarkBitmap();
   mark_bitmap->CopyFrom(live_bitmap);
@@ -212,21 +212,6 @@
   MarkSweep* const mark_sweep_;
 };
 
-// Marks all objects that are in images and have been touched by the mutator
-void MarkSweep::ScanDirtyImageRoots() {
-  const Spaces& spaces = heap_->GetSpaces();
-  CardTable* card_table = heap_->GetCardTable();
-  ScanImageRootVisitor image_root_visitor(this);
-  // TODO: C++ 0x auto
-  for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
-    Space* space = *it;
-    if (space->IsImageSpace()) {
-      card_table->Scan(space->GetLiveBitmap(), space->Begin(), space->End(), image_root_visitor,
-                       IdentityFunctor());
-    }
-  }
-}
-
 void MarkSweep::ScanGrayObjects(bool update_finger) {
   const Spaces& spaces = heap_->GetSpaces();
   CardTable* card_table = heap_->GetCardTable();
@@ -234,7 +219,7 @@
   SetFingerVisitor finger_visitor(this);
   // TODO: C++ 0x auto
   for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
-    Space* space = *it;
+    ContinuousSpace* space = *it;
     byte* begin = space->Begin();
     byte* end = space->End();
     // Image spaces are handled properly since live == marked for them.
@@ -271,8 +256,8 @@
   CheckBitmapVisitor visitor(this);
   const Spaces& spaces = heap_->GetSpaces();
   for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
-    const Space* space = *it;
-    if (space->IsImageSpace()) {
+    if ((*it)->IsImageSpace()) {
+      ImageSpace* space = (*it)->AsImageSpace();
       uintptr_t begin = reinterpret_cast<uintptr_t>(space->Begin());
       uintptr_t end = reinterpret_cast<uintptr_t>(space->End());
       SpaceBitmap* live_bitmap = space->GetLiveBitmap();
@@ -314,7 +299,7 @@
   SetFingerVisitor set_finger_visitor(this);
   ScanObjectVisitor scan_visitor(this);
   for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
-    Space* space = *it;
+    ContinuousSpace* space = *it;
     if (space->GetGcRetentionPolicy() == GCRP_ALWAYS_COLLECT ||
         (!partial && space->GetGcRetentionPolicy() == GCRP_FULL_COLLECT)
         ) {
@@ -544,7 +529,7 @@
     } else if (!large_mark_objects->Test(obj)) {
       ++freed_large_objects;
       size_t size = large_object_space->AllocationSize(obj);
-      freed_bytes_ += size;
+      freed_bytes += size;
       large_object_space->Free(obj);
     }
   }
@@ -574,7 +559,7 @@
   scc.mark_sweep = this;
   // TODO: C++0x auto
   for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
-    Space* space = *it;
+    ContinuousSpace* space = *it;
     if (
         space->GetGcRetentionPolicy() == GCRP_ALWAYS_COLLECT ||
         (!partial && space->GetGcRetentionPolicy() == GCRP_FULL_COLLECT)
@@ -603,7 +588,6 @@
 void MarkSweep::SweepLargeObjects(bool swap_bitmaps) {
   // Sweep large objects
   LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace();
-  MutexLock mu(large_object_space->GetLock());
   SpaceSetMap* large_live_objects = large_object_space->GetLiveObjects();
   SpaceSetMap* large_mark_objects = large_object_space->GetMarkObjects();
   if (swap_bitmaps) {
@@ -612,17 +596,19 @@
   SpaceSetMap::Objects& live_objects = large_live_objects->GetObjects();
   // O(n*log(n)) but hopefully there are not too many large objects.
   size_t freed_objects = 0;
+  size_t freed_bytes = 0;
   // TODO: C++0x
   for (SpaceSetMap::Objects::iterator it = live_objects.begin(); it != live_objects.end(); ++it) {
     if (!large_mark_objects->Test(*it)) {
-      freed_bytes_ += large_object_space->AllocationSize(*it);
+      freed_bytes += large_object_space->AllocationSize(*it);
       large_object_space->Free(const_cast<Object*>(*it));
       ++freed_objects;
     }
   }
   freed_objects_ += freed_objects;
+  freed_bytes_ += freed_bytes;
   // Large objects don't count towards bytes_allocated.
-  GetHeap()->RecordFree(freed_objects, 0);
+  GetHeap()->RecordFree(freed_objects, freed_bytes);
 }
 
 // Scans instance fields.
@@ -986,7 +972,6 @@
 
   // Reset the marked large objects.
   LargeObjectSpace* large_objects = GetHeap()->GetLargeObjectsSpace();
-  MutexLock mu(large_objects->GetLock());
   large_objects->GetMarkObjects()->Clear();
 }