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:
parent
41d6cae46d
commit
930ab041a8
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
23
src/heap.cc
23
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<Object**>(&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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user