From 930ab041a8d2e11ccafb140832aa2b569650a09c Mon Sep 17 00:00:00 2001 From: "christian.plesner.hansen@gmail.com" Date: Thu, 5 Nov 2009 15:12:36 +0000 Subject: [PATCH] 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 --- src/global-handles.cc | 13 +++++++++++-- src/global-handles.h | 5 ++++- src/globals.h | 2 ++ src/heap-profiler.cc | 2 +- src/heap.cc | 23 ++++++++++++----------- src/heap.h | 4 ++-- src/mark-compact.cc | 4 ++-- src/serialize.cc | 14 +++++++------- 8 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/global-handles.cc b/src/global-handles.cc index a57c8b0c27..54a7ccb00f 100644 --- a/src/global-handles.cc +++ b/src/global-handles.cc @@ -390,8 +390,8 @@ void GlobalHandles::PostGarbageCollectionProcessing() { } -void GlobalHandles::IterateRoots(ObjectVisitor* v) { - // Traversal of global handles marked as NORMAL or NEAR_DEATH. +void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) { + // Traversal of global handles marked as NORMAL. for (Node* current = head_; current != NULL; current = current->next()) { if (current->state_ == Node::NORMAL) { v->VisitPointer(¤t->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(¤t->object_); + } + } +} + + void GlobalHandles::TearDown() { // Reset all the lists. set_head(NULL); diff --git a/src/global-handles.h b/src/global-handles.h index 87eb9b8301..8ee4ecbee2 100644 --- a/src/global-handles.h +++ b/src/global-handles.h @@ -95,8 +95,11 @@ class GlobalHandles : public AllStatic { // Process pending weak handles. static void PostGarbageCollectionProcessing(); + // Iterates over all strong handles. + static void IterateStrongRoots(ObjectVisitor* v); + // Iterates over all handles. - static void IterateRoots(ObjectVisitor* v); + static void IterateAllRoots(ObjectVisitor* v); // Iterates over all weak roots in heap. static void IterateWeakRoots(ObjectVisitor* v); diff --git a/src/globals.h b/src/globals.h index ae10b72de7..825f844658 100644 --- a/src/globals.h +++ b/src/globals.h @@ -295,6 +295,8 @@ enum GarbageCollector { SCAVENGER, MARK_COMPACTOR }; enum Executability { NOT_EXECUTABLE, EXECUTABLE }; +enum VisitMode { VISIT_ALL, VISIT_ONLY_STRONG }; + // A CodeDesc describes a buffer holding instructions and relocation // information. The instructions start at the beginning of the buffer diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc index 7f7cd7f169..bd1cd2d9cf 100644 --- a/src/heap-profiler.cc +++ b/src/heap-profiler.cc @@ -536,7 +536,7 @@ RetainerHeapProfile::RetainerHeapProfile() : zscope_(DELETE_ON_EXIT) { JSObjectsCluster roots(JSObjectsCluster::ROOTS); ReferencesExtractor extractor(roots, this); - Heap::IterateRoots(&extractor); + Heap::IterateRoots(&extractor, VISIT_ONLY_STRONG); } diff --git a/src/heap.cc b/src/heap.cc index 23e4b3b8fc..783b5ff1d0 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -733,10 +733,7 @@ void Heap::Scavenge() { ScavengeVisitor scavenge_visitor; // Copy roots. - IterateRoots(&scavenge_visitor); - - // Copy objects reachable from weak pointers. - GlobalHandles::IterateWeakRoots(&scavenge_visitor); + IterateRoots(&scavenge_visitor, VISIT_ALL); // Copy objects reachable from the old generation. By definition, // there are no intergenerational pointers in code or data spaces. @@ -3117,7 +3114,7 @@ void Heap::Verify() { ASSERT(HasBeenSetup()); VerifyPointersVisitor visitor; - IterateRoots(&visitor); + IterateRoots(&visitor, VISIT_ONLY_STRONG); new_space_.Verify(); @@ -3244,14 +3241,14 @@ void Heap::IterateRSet(PagedSpace* space, ObjectSlotCallback copy_object_func) { } -void Heap::IterateRoots(ObjectVisitor* v) { - IterateStrongRoots(v); +void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { + IterateStrongRoots(v, mode); v->VisitPointer(reinterpret_cast(&roots_[kSymbolTableRootIndex])); v->Synchronize("symbol_table"); } -void Heap::IterateStrongRoots(ObjectVisitor* v) { +void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); v->Synchronize("strong_root_list"); @@ -3284,7 +3281,11 @@ void Heap::IterateStrongRoots(ObjectVisitor* v) { v->Synchronize("builtins"); // Iterate over global handles. - GlobalHandles::IterateRoots(v); + if (mode == VISIT_ONLY_STRONG) { + GlobalHandles::IterateStrongRoots(v); + } else { + GlobalHandles::IterateAllRoots(v); + } v->Synchronize("globalhandles"); // Iterate over pointers being held by inactive threads. @@ -3893,7 +3894,7 @@ void Heap::TracePathToObject() { search_for_any_global = false; MarkRootVisitor root_visitor; - IterateRoots(&root_visitor); + IterateRoots(&root_visitor, VISIT_ONLY_STRONG); } @@ -3905,7 +3906,7 @@ void Heap::TracePathToGlobal() { search_for_any_global = true; MarkRootVisitor root_visitor; - IterateRoots(&root_visitor); + IterateRoots(&root_visitor, VISIT_ONLY_STRONG); } #endif diff --git a/src/heap.h b/src/heap.h index 6639e641d9..cde04ed4b0 100644 --- a/src/heap.h +++ b/src/heap.h @@ -730,9 +730,9 @@ class Heap : public AllStatic { static String* hidden_symbol() { return hidden_symbol_; } // 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. - static void IterateStrongRoots(ObjectVisitor* v); + static void IterateStrongRoots(ObjectVisitor* v, VisitMode mode); // Iterates remembered set of an old space. static void IterateRSet(PagedSpace* space, ObjectSlotCallback callback); diff --git a/src/mark-compact.cc b/src/mark-compact.cc index 5a3ab89057..785462e506 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -593,7 +593,7 @@ void MarkCompactCollector::MarkSymbolTable() { void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { // Mark the heap roots including global variables, stack variables, // etc., and all objects reachable from them. - Heap::IterateStrongRoots(visitor); + Heap::IterateStrongRoots(visitor, VISIT_ONLY_STRONG); // Handle the symbol table specially. MarkSymbolTable(); @@ -1455,7 +1455,7 @@ void MarkCompactCollector::UpdatePointers() { state_ = UPDATE_POINTERS; #endif UpdatingVisitor updating_visitor; - Heap::IterateRoots(&updating_visitor); + Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); GlobalHandles::IterateWeakRoots(&updating_visitor); int live_maps = IterateLiveObjects(Heap::map_space(), diff --git a/src/serialize.cc b/src/serialize.cc index 17ed7b4a12..98c4b6e7e7 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -1101,7 +1101,7 @@ void Serializer::Serialize() { InitializeAllocators(); reference_encoder_ = new ExternalReferenceEncoder(); PutHeader(); - Heap::IterateRoots(this); + Heap::IterateRoots(this, VISIT_ONLY_STRONG); PutLog(); PutContextStack(); Disable(); @@ -1204,7 +1204,7 @@ void Serializer::PutHeader() { writer_->PutC('G'); writer_->PutC('['); GlobalHandlesRetriever ghr(&global_handles_); - GlobalHandles::IterateRoots(&ghr); + GlobalHandles::IterateStrongRoots(&ghr); for (int i = 0; i < global_handles_.length(); i++) { writer_->PutC('N'); } @@ -1441,7 +1441,7 @@ class GlobalHandleDestroyer : public ObjectVisitor { void Deserializer::Deserialize() { // No global handles. NoGlobalHandlesChecker checker; - GlobalHandles::IterateRoots(&checker); + GlobalHandles::IterateStrongRoots(&checker); // No active threads. ASSERT_EQ(NULL, ThreadState::FirstInUse()); // No active handles. @@ -1450,12 +1450,12 @@ void Deserializer::Deserialize() { // By setting linear allocation only, we forbid the use of free list // allocation which is not predicted by SimulatedAddress. GetHeader(); - Heap::IterateRoots(this); + Heap::IterateRoots(this, VISIT_ONLY_STRONG); GetContextStack(); // Any global handles that have been set up by deserialization are leaked // since noone is keeping track of them. So we discard them now. GlobalHandleDestroyer destroyer; - GlobalHandles::IterateRoots(&destroyer); + GlobalHandles::IterateStrongRoots(&destroyer); } @@ -1858,7 +1858,7 @@ void Deserializer2::Deserialize() { ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty()); ASSERT(external_reference_decoder_ == NULL); external_reference_decoder_ = new ExternalReferenceDecoder(); - Heap::IterateRoots(this); + Heap::IterateRoots(this, VISIT_ONLY_STRONG); ASSERT(source_->AtEOF()); delete external_reference_decoder_; external_reference_decoder_ = NULL; @@ -2129,7 +2129,7 @@ void Serializer2::Serialize() { CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles()); ASSERT(external_reference_encoder_ == NULL); external_reference_encoder_ = new ExternalReferenceEncoder(); - Heap::IterateRoots(this); + Heap::IterateRoots(this, VISIT_ONLY_STRONG); delete external_reference_encoder_; external_reference_encoder_ = NULL; }