Improved, safer handling of the symbol table. The symbols themselves
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 May 2009 05:13:09 +0000 (05:13 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 May 2009 05:13:09 +0000 (05:13 +0000)
are not treated as roots, but all their subparts are.
Review URL: http://codereview.chromium.org/108002

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

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

index 8c0231e..94cf315 100644 (file)
@@ -562,48 +562,58 @@ bool MarkCompactCollector::MustBeMarked(Object** p) {
 }
 
 
-// Helper class to unmark marked objects in a range of pointers but
-// not recursively.
-class UnmarkingVisitor : public ObjectVisitor {
+class SymbolMarkingVisitor : public ObjectVisitor {
  public:
   void VisitPointers(Object** start, Object** end) {
+    MarkingVisitor marker;
     for (Object** p = start; p < end; p++) {
-      if ((*p)->IsHeapObject() && HeapObject::cast(*p)->IsMarked()) {
-        MarkCompactCollector::ClearMark(HeapObject::cast(*p));
-      }
+      if (!(*p)->IsHeapObject()) continue;
+
+      HeapObject* object = HeapObject::cast(*p);
+      // If the object is marked, we have marked or are in the process
+      // of marking subparts.
+      if (object->IsMarked()) continue;
+
+      // The object is unmarked, we do not need to unmark to use its
+      // map.
+      Map* map = object->map();
+      object->IterateBody(map->instance_type(),
+                          object->SizeFromMap(map),
+                          &marker);
     }
   }
 };
 
 
-void MarkCompactCollector::ProcessRoots(RootMarkingVisitor* visitor) {
-  // Handle the symbol table specially.  Mark the prefix and the
-  // symbol table itself.  Do not mark the symbol table entries, but
-  // do explicitly mark all other objects reachable from them.
-  //
+void MarkCompactCollector::MarkSymbolTable() {
   // Objects reachable from symbols are marked as live so as to ensure
   // that if the symbol itself remains alive after GC for any reason,
   // and if it is a sliced string or a cons string backed by an
   // external string (even indirectly), then the external string does
   // not receive a weak reference callback.
   SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table());
-  // First mark everything reachable from the symbol table, then
-  // unmark just the elements themselves.
-  symbol_table->Iterate(visitor);
-  // There may be overflowed objects in the heap.  Visit them now.
-  while (marking_stack.overflowed()) {
-    RefillMarkingStack();
-    EmptyMarkingStack(visitor->stack_visitor());
-  }
-  UnmarkingVisitor unmarking_visitor;
-  symbol_table->IterateElements(&unmarking_visitor);
   // Mark the symbol table itself.
   SetMark(symbol_table);
+  // Explicitly mark the prefix.
+  MarkingVisitor marker;
+  symbol_table->IteratePrefix(&marker);
+  ProcessMarkingStack(&marker);
+  // Mark subparts of the symbols but not the symbols themselves
+  // (unless reachable from another symbol).
+  SymbolMarkingVisitor symbol_marker;
+  symbol_table->IterateElements(&symbol_marker);
+  ProcessMarkingStack(&marker);
+}
+
 
+void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
   // Mark the heap roots including global variables, stack variables,
   // etc., and all objects reachable from them.
   Heap::IterateStrongRoots(visitor);
 
+  // Handle the symbol table specially.
+  MarkSymbolTable();
+
   // There may be overflowed objects in the heap.  Visit them now.
   while (marking_stack.overflowed()) {
     RefillMarkingStack();
@@ -744,7 +754,7 @@ void MarkCompactCollector::MarkLiveObjects() {
   ASSERT(!marking_stack.overflowed());
 
   RootMarkingVisitor root_visitor;
-  ProcessRoots(&root_visitor);
+  MarkRoots(&root_visitor);
 
   // The objects reachable from the roots are marked black, unreachable
   // objects are white.  Mark objects reachable from object groups with at
index 1057241..94505b1 100644 (file)
@@ -161,18 +161,6 @@ class MarkCompactCollector: public AllStatic {
     obj->SetMark();
   }
 
-  // Used to clear mark bits during marking for objects that are not
-  // actually live.  Since it updates bookkeeping state, it is not
-  // used when clearing mark bits on live objects (eg, during
-  // sweeping).
-  static inline void ClearMark(HeapObject* obj) {
-    obj->ClearMark();
-    tracer_->decrement_marked_count();
-#ifdef DEBUG
-    UpdateLiveObjectCount(obj, -1);
-#endif
-  }
-
   // Creates back pointers for all map transitions, stores them in
   // the prototype field.  The original prototype pointers are restored
   // in ClearNonLiveTransitions().  All JSObject maps
@@ -185,7 +173,10 @@ class MarkCompactCollector: public AllStatic {
   static void MarkDescriptorArray(DescriptorArray* descriptors);
 
   // Mark the heap roots and all objects reachable from them.
-  static void ProcessRoots(RootMarkingVisitor* visitor);
+  static void MarkRoots(RootMarkingVisitor* visitor);
+
+  // Mark the symbol table specially.  References to symbols are weak.
+  static void MarkSymbolTable();
 
   // Mark objects in object groups that have at least one object in the
   // group marked.