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) {
|
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(¤t->object_);
|
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() {
|
void GlobalHandles::TearDown() {
|
||||||
// Reset all the lists.
|
// Reset all the lists.
|
||||||
set_head(NULL);
|
set_head(NULL);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
23
src/heap.cc
23
src/heap.cc
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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(),
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user