Clean up the mark-sweep/compact collector by removing outdated
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 23 Jan 2009 08:13:12 +0000 (08:13 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 23 Jan 2009 08:13:12 +0000 (08:13 +0000)
verification code and updating outdated comments.
Review URL: http://codereview.chromium.org/18502

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1131 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/mark-compact.cc
src/mark-compact.h

index ede5741..1d93f84 100644 (file)
 
 namespace v8 { namespace internal {
 
-#ifdef DEBUG
-// The verification code used between phases of the m-c collector does not
-// currently work.
-//
-// TODO(1240833): Fix the heap verification code and turn this into a real
-// flag.
-static const bool FLAG_verify_global_gc = false;
-#endif  // DEBUG
-
-// ----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // MarkCompactCollector
 
 bool MarkCompactCollector::compacting_collection_ = false;
@@ -177,7 +168,7 @@ void MarkCompactCollector::Finish() {
 }
 
 
-// ----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // Phase 1: tracing and marking live objects.
 //   before: all objects are in normal state.
 //   after: a live object's map pointer is marked as '00'.
@@ -729,10 +720,6 @@ void MarkCompactCollector::MarkLiveObjects() {
   symbol_table->IterateElements(&v);
   symbol_table->ElementsRemoved(v.PointersRemoved());
 
-#ifdef DEBUG
-  if (FLAG_verify_global_gc) VerifyHeapAfterMarkingPhase();
-#endif
-
   // Remove object groups after marking phase.
   GlobalHandles::RemoveObjectGroups();
 }
@@ -765,46 +752,6 @@ void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
     UNREACHABLE();
   }
 }
-
-
-void MarkCompactCollector::VerifyHeapAfterMarkingPhase() {
-  Heap::new_space()->Verify();
-  Heap::old_pointer_space()->Verify();
-  Heap::old_data_space()->Verify();
-  Heap::code_space()->Verify();
-  Heap::map_space()->Verify();
-
-  int live_objects;
-
-#define CHECK_LIVE_OBJECTS(it, expected)                   \
-          live_objects = 0;                                \
-          while (it.has_next()) {                          \
-            HeapObject* obj = HeapObject::cast(it.next()); \
-            if (obj->IsMarked()) live_objects++;           \
-          }                                                \
-          ASSERT(live_objects == expected);
-
-  SemiSpaceIterator new_it(Heap::new_space(), &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(new_it, live_young_objects_);
-
-  HeapObjectIterator old_pointer_it(Heap::old_pointer_space(),
-                                    &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(old_pointer_it, live_old_pointer_objects_);
-
-  HeapObjectIterator old_data_it(Heap::old_data_space(), &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(old_data_it, live_old_data_objects_);
-
-  HeapObjectIterator code_it(Heap::code_space(), &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(code_it, live_code_objects_);
-
-  HeapObjectIterator map_it(Heap::map_space(), &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(map_it, live_map_objects_);
-
-  LargeObjectIterator lo_it(Heap::lo_space(), &CountMarkedCallback);
-  CHECK_LIVE_OBJECTS(lo_it, live_lo_objects_);
-
-#undef CHECK_LIVE_OBJECTS
-}
 #endif  // DEBUG
 
 
@@ -1325,54 +1272,7 @@ int MarkCompactCollector::IterateLiveObjects(PagedSpace* space,
 }
 
 
-#ifdef DEBUG
-static int VerifyMapObject(HeapObject* obj) {
-  InstanceType type = reinterpret_cast<Map*>(obj)->instance_type();
-  ASSERT(FIRST_TYPE <= type && type <= LAST_TYPE);
-  return Map::kSize;
-}
-
-
-void MarkCompactCollector::VerifyHeapAfterEncodingForwardingAddresses() {
-  AllSpaces spaces;
-  while (Space* space = spaces.next()) space->Verify();
-
-  ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
-  int live_maps = IterateLiveObjects(Heap::map_space(), &VerifyMapObject);
-  ASSERT(live_maps == live_map_objects_);
-
-  // Verify page headers in paged spaces.
-  PagedSpaces paged_spaces;
-  while (PagedSpace* space = paged_spaces.next()) VerifyPageHeaders(space);
-}
-
-
-void MarkCompactCollector::VerifyPageHeaders(PagedSpace* space) {
-  PageIterator mc_it(space, PageIterator::PAGES_USED_BY_MC);
-  while (mc_it.has_next()) {
-    Page* p = mc_it.next();
-    Address mc_alloc_top = p->mc_relocation_top;
-    ASSERT(p->ObjectAreaStart() <= mc_alloc_top &&
-           mc_alloc_top <= p->ObjectAreaEnd());
-  }
-
-  int page_count = 0;
-  PageIterator it(space, PageIterator::PAGES_IN_USE);
-  while (it.has_next()) {
-    Page* p = it.next();
-    ASSERT(p->mc_page_index == page_count);
-    page_count++;
-
-    // first_forwarded could be 'deadbeed' if no live objects in this page
-    Address first_forwarded = p->mc_first_forwarded;
-    ASSERT(first_forwarded == kZapValue ||
-           space->Contains(first_forwarded));
-  }
-}
-#endif
-
-
-// ----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // Phase 3: Update pointers
 
 // Helper class for updating pointers in HeapObjects.
@@ -1494,8 +1394,6 @@ void MarkCompactCollector::UpdatePointers() {
   ASSERT(live_pointer_olds == live_old_pointer_objects_);
   ASSERT(live_codes == live_code_objects_);
   ASSERT(live_news == live_young_objects_);
-
-  if (FLAG_verify_global_gc) VerifyHeapAfterUpdatingPointers();
 #endif
 }
 
@@ -1601,19 +1499,7 @@ Address MarkCompactCollector::GetForwardingAddressInOldSpace(HeapObject* obj) {
 }
 
 
-#ifdef DEBUG
-void MarkCompactCollector::VerifyHeapAfterUpdatingPointers() {
-  ASSERT(state_ == UPDATE_POINTERS);
-
-  AllSpaces spaces;
-  while (Space* space = spaces.next()) space->Verify();
-  PagedSpaces paged_spaces;
-  while (PagedSpace* space = paged_spaces.next()) VerifyPageHeaders(space);
-}
-#endif
-
-
-// ----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // Phase 4: Relocate objects
 
 void MarkCompactCollector::RelocateObjects() {
@@ -1664,10 +1550,6 @@ void MarkCompactCollector::RelocateObjects() {
 #endif
   PagedSpaces spaces;
   while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo();
-
-#ifdef DEBUG
-  if (FLAG_verify_global_gc) VerifyHeapAfterRelocatingObjects();
-#endif
 }
 
 
@@ -1804,18 +1686,6 @@ int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
 }
 
 
-#ifdef DEBUG
-class VerifyCopyingVisitor: public ObjectVisitor {
- public:
-  void VisitPointers(Object** start, Object** end) {
-    for (Object** p = start; p < end; p++) {
-      MarkCompactCollector::VerifyCopyingObjects(p);
-    }
-  }
-};
-
-#endif
-
 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) {
   int obj_size = obj->Size();
 
@@ -1845,44 +1715,13 @@ int MarkCompactCollector::RelocateNewObject(HeapObject* obj) {
   if (FLAG_gc_verbose) {
     PrintF("relocate %p -> %p\n", old_addr, new_addr);
   }
-  if (FLAG_verify_global_gc) {
-    VerifyCopyingVisitor v;
-    HeapObject* copied_to = HeapObject::FromAddress(new_addr);
-    copied_to->Iterate(&v);
-  }
 #endif
 
   return obj_size;
 }
 
 
-#ifdef DEBUG
-void MarkCompactCollector::VerifyHeapAfterRelocatingObjects() {
-  ASSERT(state_ == RELOCATE_OBJECTS);
-
-  Heap::new_space()->Verify();
-  PagedSpaces spaces;
-  while (PagedSpace* space = spaces.next()) {
-    space->Verify();
-    PageIterator it(space, PageIterator::PAGES_IN_USE);
-    while (it.has_next()) {
-      Page* p = it.next();
-      ASSERT_PAGE_OFFSET(p->Offset(p->AllocationTop()));
-    }
-  }
-}
-#endif
-
-
-#ifdef DEBUG
-void MarkCompactCollector::VerifyCopyingObjects(Object** p) {
-  if (!(*p)->IsHeapObject()) return;
-  ASSERT(!Heap::InToSpace(*p));
-}
-#endif  // DEBUG
-
-
-// -----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // Phase 5: rebuild remembered sets
 
 void MarkCompactCollector::RebuildRSets() {
index 22dd890..746aead 100644 (file)
@@ -44,12 +44,12 @@ class RootMarkingVisitor;
 class MarkingVisitor;
 
 
-// ----------------------------------------------------------------------------
+// -------------------------------------------------------------------------
 // Mark-Compact collector
 //
 // All methods are static.
 
-class MarkCompactCollector : public AllStatic {
+class MarkCompactCollector: public AllStatic {
  public:
   // Type of functions to compute forwarding addresses of objects in
   // compacted spaces.  Given an object and its size, return a (non-failure)
@@ -127,21 +127,18 @@ class MarkCompactCollector : public AllStatic {
   // choosing spaces to compact.
   static void Prepare();
 
-  // Finishes GC, performs heap verification.
+  // Finishes GC, performs heap verification if enabled.
   static void Finish();
 
-  // --------------------------------------------------------------------------
-  // Phase 1: functions related to marking phase.
-  //   before: Heap is in normal state, collector is 'IDLE'.
+  // -----------------------------------------------------------------------
+  // Phase 1: Marking live objects.
   //
-  //           The first word of a page in old spaces has the end of
-  //           allocation address of the page.
+  //  Before: The heap has been prepared for garbage collection by
+  //          MarkCompactCollector::Prepare() and is otherwise in its
+  //          normal state.
   //
-  //           The word at Chunk::high_ address has the address of the
-  //           first page in the next chunk. (The address is tagged to
-  //           distinguish it from end-of-allocation address).
-  //
-  //    after: live objects are marked.
+  //   After: Live objects are marked and non-live objects are unmarked.
+
 
   friend class RootMarkingVisitor;
   friend class MarkingVisitor;
@@ -206,7 +203,6 @@ class MarkCompactCollector : public AllStatic {
 
 #ifdef DEBUG
   static void UpdateLiveObjectCount(HeapObject* obj);
-  static void VerifyHeapAfterMarkingPhase();
 #endif
 
   // We sweep the large object space in the same way whether we are
@@ -216,30 +212,50 @@ class MarkCompactCollector : public AllStatic {
   // Test whether a (possibly marked) object is a Map.
   static inline bool SafeIsMap(HeapObject* object);
 
-    // Map transitions from a live map to a dead map must be killed.
+  // Map transitions from a live map to a dead map must be killed.
   // We replace them with a null descriptor, with the same key.
   static void ClearNonLiveTransitions();
 
-  // --------------------------------------------------------------------------
-  // Phase 2: functions related to computing and encoding forwarding pointers
-  //   before: live objects' map pointers are marked as '00'
-  //    after: Map pointers of live old and map objects have encoded
-  //           forwarding pointers and map pointers
+  // -----------------------------------------------------------------------
+  // Phase 2: Sweeping to clear mark bits and free non-live objects for
+  // a non-compacting collection, or else computing and encoding
+  // forwarding addresses for a compacting collection.
+  //
+  //  Before: Live objects are marked and non-live objects are unmarked.
+  //
+  //   After: (Non-compacting collection.)  Live objects are unmarked,
+  //          non-live regions have been added to their space's free
+  //          list.
+  //
+  //   After: (Compacting collection.)  The forwarding address of live
+  //          objects in the paged spaces is encoded in their map word
+  //          along with their (non-forwarded) map pointer.
+  //
+  //          The forwarding address of live objects in the new space is
+  //          written to their map word's offset in the inactive
+  //          semispace.
   //
-  //           The 3rd word of a page has the page top offset after compaction.
+  //          Bookkeeping data is written to the remembered-set are of
+  //          eached paged-space page that contains live objects after
+  //          compaction:
   //
-  //           The 4th word of a page in the map space has the map index
-  //           of this page in the map table. This word is not used in
-  //           the old space.
+  //          The 3rd word of the page (first word of the remembered
+  //          set) contains the relocation top address, the address of
+  //          the first word after the end of the last live object in
+  //          the page after compaction.
   //
-  //           The 5th and 6th words of a page have the start and end
-  //           addresses of the first free region in the page.
+  //          The 4th word contains the zero-based index of the page in
+  //          its space.  This word is only used for map space pages, in
+  //          order to encode the map addresses in 21 bits to free 11
+  //          bits per map word for the forwarding address.
   //
-  //           The 7th word of a page in old spaces has the forwarding address
-  //           of the first live object in the page.
+  //          The 5th word contains the (nonencoded) forwarding address
+  //          of the first live object in the page.
   //
-  //           Live young objects have their forwarding pointers in
-  //           the from space at the same offset to the beginning of the space.
+  //          In both the new space and the paged spaces, a linked list
+  //          of live regions is constructructed (linked through
+  //          pointers in the non-live region immediately following each
+  //          live region) to speed further passes of the collector.
 
   // Encodes forwarding addresses of objects in compactable parts of the
   // heap.
@@ -272,19 +288,21 @@ class MarkCompactCollector : public AllStatic {
   static void DeallocateCodeBlock(Address start, int size_in_bytes);
   static void DeallocateMapBlock(Address start, int size_in_bytes);
 
-  // Phase 2: If we are not compacting the heap, we simply sweep the spaces
-  // except for the large object space, clearing mark bits and adding
-  // unmarked regions to each space's free list.
+  // If we are not compacting the heap, we simply sweep the spaces except
+  // for the large object space, clearing mark bits and adding unmarked
+  // regions to each space's free list.
   static void SweepSpaces();
 
-#ifdef DEBUG
-  static void VerifyHeapAfterEncodingForwardingAddresses();
-#endif
-
-  // --------------------------------------------------------------------------
-  // Phase 3: function related to updating pointers and decode map pointers
-  //   before: see after phase 2
-  //    after: all pointers are updated to forwarding addresses.
+  // -----------------------------------------------------------------------
+  // Phase 3: Updating pointers in live objects.
+  //
+  //  Before: Same as after phase 2 (compacting collection).
+  //
+  //   After: All pointers in live objects, including encoded map
+  //          pointers, are updated to point to their target's new
+  //          location.  The remembered set area of each paged-space
+  //          page containing live objects still contains bookkeeping
+  //          information.
 
   friend class UpdatingVisitor;  // helper for updating visited objects
 
@@ -302,14 +320,17 @@ class MarkCompactCollector : public AllStatic {
   // Calculates the forwarding address of an object in an old space.
   static Address GetForwardingAddressInOldSpace(HeapObject* obj);
 
-#ifdef DEBUG
-  static void VerifyHeapAfterUpdatingPointers();
-#endif
-
-  // --------------------------------------------------------------------------
-  // Phase 4: functions related to relocating objects
-  //     before: see after phase 3
-  //      after: heap is in a normal state, except remembered set is not built
+  // -----------------------------------------------------------------------
+  // Phase 4: Relocating objects.
+  //
+  //  Before: Pointers to live objects are updated to point to their
+  //          target's new location.  The remembered set area of each
+  //          paged-space page containing live objects still contains
+  //          bookkeeping information.
+  //
+  //   After: Objects have been moved to their new addresses. The
+  //          remembered set area of each paged-space page containing
+  //          live objects still contains bookkeeping information.
 
   // Relocates objects in all spaces.
   static void RelocateObjects();
@@ -334,18 +355,19 @@ class MarkCompactCollector : public AllStatic {
   // Copy a new object.
   static int RelocateNewObject(HeapObject* obj);
 
-#ifdef DEBUG
-  static void VerifyHeapAfterRelocatingObjects();
-#endif
-
-  // ---------------------------------------------------------------------------
-  // Phase 5: functions related to rebuilding remembered sets
+  // -----------------------------------------------------------------------
+  // Phase 5: Rebuilding remembered sets.
+  //
+  //  Before: The heap is in a normal state except that remembered sets
+  //          in the paged spaces are not correct.
+  //
+  //   After: The heap is in a normal state.
 
   // Rebuild remembered set in old and map spaces.
   static void RebuildRSets();
 
 #ifdef DEBUG
-  // ---------------------------------------------------------------------------
+  // -----------------------------------------------------------------------
   // Debugging variables, functions and classes
   // Counters used for debugging the marking phase of mark-compact or
   // mark-sweep collection.
@@ -371,12 +393,6 @@ class MarkCompactCollector : public AllStatic {
   // Number of live bytes in this collection.
   static int live_bytes_;
 
-  static void VerifyPageHeaders(PagedSpace* space);
-
-  // Verification functions when relocating objects.
-  friend class VerifyCopyingVisitor;
-  static void VerifyCopyingObjects(Object** p);
-
   friend class MarkObjectVisitor;
   static void VisitObject(HeapObject* obj);