Improved, safer handling of the symbol table. The symbols themselves

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
This commit is contained in:
kmillikin@chromium.org 2009-05-05 05:13:09 +00:00
parent 282bc7a7b4
commit 3af69aed22
2 changed files with 36 additions and 35 deletions

View 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

View 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.