Made iteration of global handles more efficient on scavenges.

Review URL: http://codereview.chromium.org/355041


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3230 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
christian.plesner.hansen@gmail.com 2009-11-05 15:12:36 +00:00
parent 41d6cae46d
commit 930ab041a8
8 changed files with 41 additions and 26 deletions

View File

@ -390,8 +390,8 @@ void GlobalHandles::PostGarbageCollectionProcessing() {
} }
void GlobalHandles::IterateRoots(ObjectVisitor* v) { void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) {
// Traversal of global handles marked as NORMAL or NEAR_DEATH. // Traversal of global handles marked as NORMAL.
for (Node* current = head_; current != NULL; current = current->next()) { for (Node* current = head_; current != NULL; current = current->next()) {
if (current->state_ == Node::NORMAL) { if (current->state_ == Node::NORMAL) {
v->VisitPointer(&current->object_); v->VisitPointer(&current->object_);
@ -400,6 +400,15 @@ void GlobalHandles::IterateRoots(ObjectVisitor* v) {
} }
void GlobalHandles::IterateAllRoots(ObjectVisitor* v) {
for (Node* current = head_; current != NULL; current = current->next()) {
if (current->state_ != Node::DESTROYED) {
v->VisitPointer(&current->object_);
}
}
}
void GlobalHandles::TearDown() { void GlobalHandles::TearDown() {
// Reset all the lists. // Reset all the lists.
set_head(NULL); set_head(NULL);

View File

@ -95,8 +95,11 @@ class GlobalHandles : public AllStatic {
// Process pending weak handles. // Process pending weak handles.
static void PostGarbageCollectionProcessing(); static void PostGarbageCollectionProcessing();
// Iterates over all strong handles.
static void IterateStrongRoots(ObjectVisitor* v);
// Iterates over all handles. // Iterates over all handles.
static void IterateRoots(ObjectVisitor* v); static void IterateAllRoots(ObjectVisitor* v);
// Iterates over all weak roots in heap. // Iterates over all weak roots in heap.
static void IterateWeakRoots(ObjectVisitor* v); static void IterateWeakRoots(ObjectVisitor* v);

View File

@ -295,6 +295,8 @@ enum GarbageCollector { SCAVENGER, MARK_COMPACTOR };
enum Executability { NOT_EXECUTABLE, EXECUTABLE }; enum Executability { NOT_EXECUTABLE, EXECUTABLE };
enum VisitMode { VISIT_ALL, VISIT_ONLY_STRONG };
// A CodeDesc describes a buffer holding instructions and relocation // A CodeDesc describes a buffer holding instructions and relocation
// information. The instructions start at the beginning of the buffer // information. The instructions start at the beginning of the buffer

View File

@ -536,7 +536,7 @@ RetainerHeapProfile::RetainerHeapProfile()
: zscope_(DELETE_ON_EXIT) { : zscope_(DELETE_ON_EXIT) {
JSObjectsCluster roots(JSObjectsCluster::ROOTS); JSObjectsCluster roots(JSObjectsCluster::ROOTS);
ReferencesExtractor extractor(roots, this); ReferencesExtractor extractor(roots, this);
Heap::IterateRoots(&extractor); Heap::IterateRoots(&extractor, VISIT_ONLY_STRONG);
} }

View File

@ -733,10 +733,7 @@ void Heap::Scavenge() {
ScavengeVisitor scavenge_visitor; ScavengeVisitor scavenge_visitor;
// Copy roots. // Copy roots.
IterateRoots(&scavenge_visitor); IterateRoots(&scavenge_visitor, VISIT_ALL);
// Copy objects reachable from weak pointers.
GlobalHandles::IterateWeakRoots(&scavenge_visitor);
// Copy objects reachable from the old generation. By definition, // Copy objects reachable from the old generation. By definition,
// there are no intergenerational pointers in code or data spaces. // there are no intergenerational pointers in code or data spaces.
@ -3117,7 +3114,7 @@ void Heap::Verify() {
ASSERT(HasBeenSetup()); ASSERT(HasBeenSetup());
VerifyPointersVisitor visitor; VerifyPointersVisitor visitor;
IterateRoots(&visitor); IterateRoots(&visitor, VISIT_ONLY_STRONG);
new_space_.Verify(); new_space_.Verify();
@ -3244,14 +3241,14 @@ void Heap::IterateRSet(PagedSpace* space, ObjectSlotCallback copy_object_func) {
} }
void Heap::IterateRoots(ObjectVisitor* v) { void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
IterateStrongRoots(v); IterateStrongRoots(v, mode);
v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
v->Synchronize("symbol_table"); v->Synchronize("symbol_table");
} }
void Heap::IterateStrongRoots(ObjectVisitor* v) { void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
v->Synchronize("strong_root_list"); v->Synchronize("strong_root_list");
@ -3284,7 +3281,11 @@ void Heap::IterateStrongRoots(ObjectVisitor* v) {
v->Synchronize("builtins"); v->Synchronize("builtins");
// Iterate over global handles. // Iterate over global handles.
GlobalHandles::IterateRoots(v); if (mode == VISIT_ONLY_STRONG) {
GlobalHandles::IterateStrongRoots(v);
} else {
GlobalHandles::IterateAllRoots(v);
}
v->Synchronize("globalhandles"); v->Synchronize("globalhandles");
// Iterate over pointers being held by inactive threads. // Iterate over pointers being held by inactive threads.
@ -3893,7 +3894,7 @@ void Heap::TracePathToObject() {
search_for_any_global = false; search_for_any_global = false;
MarkRootVisitor root_visitor; MarkRootVisitor root_visitor;
IterateRoots(&root_visitor); IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
} }
@ -3905,7 +3906,7 @@ void Heap::TracePathToGlobal() {
search_for_any_global = true; search_for_any_global = true;
MarkRootVisitor root_visitor; MarkRootVisitor root_visitor;
IterateRoots(&root_visitor); IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
} }
#endif #endif

View File

@ -730,9 +730,9 @@ class Heap : public AllStatic {
static String* hidden_symbol() { return hidden_symbol_; } static String* hidden_symbol() { return hidden_symbol_; }
// Iterates over all roots in the heap. // Iterates over all roots in the heap.
static void IterateRoots(ObjectVisitor* v); static void IterateRoots(ObjectVisitor* v, VisitMode mode);
// Iterates over all strong roots in the heap. // Iterates over all strong roots in the heap.
static void IterateStrongRoots(ObjectVisitor* v); static void IterateStrongRoots(ObjectVisitor* v, VisitMode mode);
// Iterates remembered set of an old space. // Iterates remembered set of an old space.
static void IterateRSet(PagedSpace* space, ObjectSlotCallback callback); static void IterateRSet(PagedSpace* space, ObjectSlotCallback callback);

View File

@ -593,7 +593,7 @@ void MarkCompactCollector::MarkSymbolTable() {
void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
// Mark the heap roots including global variables, stack variables, // Mark the heap roots including global variables, stack variables,
// etc., and all objects reachable from them. // etc., and all objects reachable from them.
Heap::IterateStrongRoots(visitor); Heap::IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
// Handle the symbol table specially. // Handle the symbol table specially.
MarkSymbolTable(); MarkSymbolTable();
@ -1455,7 +1455,7 @@ void MarkCompactCollector::UpdatePointers() {
state_ = UPDATE_POINTERS; state_ = UPDATE_POINTERS;
#endif #endif
UpdatingVisitor updating_visitor; UpdatingVisitor updating_visitor;
Heap::IterateRoots(&updating_visitor); Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
GlobalHandles::IterateWeakRoots(&updating_visitor); GlobalHandles::IterateWeakRoots(&updating_visitor);
int live_maps = IterateLiveObjects(Heap::map_space(), int live_maps = IterateLiveObjects(Heap::map_space(),

View File

@ -1101,7 +1101,7 @@ void Serializer::Serialize() {
InitializeAllocators(); InitializeAllocators();
reference_encoder_ = new ExternalReferenceEncoder(); reference_encoder_ = new ExternalReferenceEncoder();
PutHeader(); PutHeader();
Heap::IterateRoots(this); Heap::IterateRoots(this, VISIT_ONLY_STRONG);
PutLog(); PutLog();
PutContextStack(); PutContextStack();
Disable(); Disable();
@ -1204,7 +1204,7 @@ void Serializer::PutHeader() {
writer_->PutC('G'); writer_->PutC('G');
writer_->PutC('['); writer_->PutC('[');
GlobalHandlesRetriever ghr(&global_handles_); GlobalHandlesRetriever ghr(&global_handles_);
GlobalHandles::IterateRoots(&ghr); GlobalHandles::IterateStrongRoots(&ghr);
for (int i = 0; i < global_handles_.length(); i++) { for (int i = 0; i < global_handles_.length(); i++) {
writer_->PutC('N'); writer_->PutC('N');
} }
@ -1441,7 +1441,7 @@ class GlobalHandleDestroyer : public ObjectVisitor {
void Deserializer::Deserialize() { void Deserializer::Deserialize() {
// No global handles. // No global handles.
NoGlobalHandlesChecker checker; NoGlobalHandlesChecker checker;
GlobalHandles::IterateRoots(&checker); GlobalHandles::IterateStrongRoots(&checker);
// No active threads. // No active threads.
ASSERT_EQ(NULL, ThreadState::FirstInUse()); ASSERT_EQ(NULL, ThreadState::FirstInUse());
// No active handles. // No active handles.
@ -1450,12 +1450,12 @@ void Deserializer::Deserialize() {
// By setting linear allocation only, we forbid the use of free list // By setting linear allocation only, we forbid the use of free list
// allocation which is not predicted by SimulatedAddress. // allocation which is not predicted by SimulatedAddress.
GetHeader(); GetHeader();
Heap::IterateRoots(this); Heap::IterateRoots(this, VISIT_ONLY_STRONG);
GetContextStack(); GetContextStack();
// Any global handles that have been set up by deserialization are leaked // Any global handles that have been set up by deserialization are leaked
// since noone is keeping track of them. So we discard them now. // since noone is keeping track of them. So we discard them now.
GlobalHandleDestroyer destroyer; GlobalHandleDestroyer destroyer;
GlobalHandles::IterateRoots(&destroyer); GlobalHandles::IterateStrongRoots(&destroyer);
} }
@ -1858,7 +1858,7 @@ void Deserializer2::Deserialize() {
ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty()); ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty());
ASSERT(external_reference_decoder_ == NULL); ASSERT(external_reference_decoder_ == NULL);
external_reference_decoder_ = new ExternalReferenceDecoder(); external_reference_decoder_ = new ExternalReferenceDecoder();
Heap::IterateRoots(this); Heap::IterateRoots(this, VISIT_ONLY_STRONG);
ASSERT(source_->AtEOF()); ASSERT(source_->AtEOF());
delete external_reference_decoder_; delete external_reference_decoder_;
external_reference_decoder_ = NULL; external_reference_decoder_ = NULL;
@ -2129,7 +2129,7 @@ void Serializer2::Serialize() {
CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles()); CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles());
ASSERT(external_reference_encoder_ == NULL); ASSERT(external_reference_encoder_ == NULL);
external_reference_encoder_ = new ExternalReferenceEncoder(); external_reference_encoder_ = new ExternalReferenceEncoder();
Heap::IterateRoots(this); Heap::IterateRoots(this, VISIT_ONLY_STRONG);
delete external_reference_encoder_; delete external_reference_encoder_;
external_reference_encoder_ = NULL; external_reference_encoder_ = NULL;
} }