Commit 5872e8ee authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

Refactor storage of global handles.

We used to have a linked list of nodes that were internally
block-allocated.

I kept the node blocks and put them on two lists: 1) the list of all
allocated blocks, 2) the list of blocks with used nodes. (1) is used
to reclaim blocks and (2) is used for traversal during GC. To make
traversal on scavenges faster the nodes holding new space objects are
grouped in an auxiliary array.

This changes the minimal memory usage from 5 words per global handle
to 4. Additional word is used for new space handles.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8186 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7c9cf0b3
......@@ -176,8 +176,8 @@ void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
heap_stats.pending_global_handle_count = &pending_global_handle_count;
int near_death_global_handle_count;
heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
int destroyed_global_handle_count;
heap_stats.destroyed_global_handle_count = &destroyed_global_handle_count;
int free_global_handle_count;
heap_stats.free_global_handle_count = &free_global_handle_count;
intptr_t memory_allocator_size;
heap_stats.memory_allocator_size = &memory_allocator_size;
intptr_t memory_allocator_capacity;
......
This diff is collapsed.
......@@ -163,7 +163,7 @@ class GlobalHandles {
void IterateStrongRoots(ObjectVisitor* v);
// Iterates over all strong and dependent handles.
void IterateStrongAndDependentRoots(ObjectVisitor* v);
void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v);
// Iterates over all handles.
void IterateAllRoots(ObjectVisitor* v);
......@@ -175,7 +175,7 @@ class GlobalHandles {
void IterateWeakRoots(ObjectVisitor* v);
// Iterates over all weak independent roots in heap.
void IterateWeakIndependentRoots(ObjectVisitor* v);
void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
// Iterates over weak roots that are bound to a given callback.
void IterateWeakRoots(WeakReferenceGuest f,
......@@ -187,7 +187,7 @@ class GlobalHandles {
// Find all weak independent handles satisfying the callback predicate, mark
// them as pending.
void IdentifyWeakIndependentHandles(WeakSlotCallbackWithHeap f);
void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
// Add an object group.
// Should be only used in GC callback function before a collection.
......@@ -224,12 +224,14 @@ class GlobalHandles {
void PrintStats();
void Print();
#endif
class Pool;
private:
explicit GlobalHandles(Isolate* isolate);
// Internal node structure, one for each global handle.
// Internal node structures.
class Node;
class NodeBlock;
class NodeIterator;
Isolate* isolate_;
......@@ -241,35 +243,21 @@ class GlobalHandles {
// number_of_weak_handles_.
int number_of_global_object_weak_handles_;
// Global handles are kept in a single linked list pointed to by head_.
Node* head_;
Node* head() { return head_; }
void set_head(Node* value) { head_ = value; }
// List of all allocated node blocks.
NodeBlock* first_block_;
// List of node blocks with used nodes.
NodeBlock* first_used_block_;
// Free list for DESTROYED global handles not yet deallocated.
// Free list of nodes.
Node* first_free_;
Node* first_free() { return first_free_; }
void set_first_free(Node* value) { first_free_ = value; }
// List of deallocated nodes.
// Deallocated nodes form a prefix of all the nodes and
// |first_deallocated| points to last deallocated node before
// |head|. Those deallocated nodes are additionally linked
// by |next_free|:
// 1st deallocated head
// | |
// V V
// node node ... node node
// .next -> .next -> .next ->
// <- .next_free <- .next_free <- .next_free
Node* first_deallocated_;
Node* first_deallocated() { return first_deallocated_; }
void set_first_deallocated(Node* value) {
first_deallocated_ = value;
}
Pool* pool_;
// Contains all nodes holding new space objects. Note: when the list
// is accessed, some of the objects may have been promoted already.
List<Node*> new_space_nodes_;
int post_gc_processing_count_;
List<ObjectGroup*> object_groups_;
List<ImplicitRefGroup*> implicit_ref_groups_;
......
......@@ -1063,9 +1063,10 @@ void Heap::Scavenge() {
scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_));
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
isolate_->global_handles()->IdentifyWeakIndependentHandles(
isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
&IsUnscavengedHeapObject);
isolate_->global_handles()->IterateWeakIndependentRoots(&scavenge_visitor);
isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
&scavenge_visitor);
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
......@@ -4612,7 +4613,7 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
isolate_->global_handles()->IterateStrongRoots(v);
break;
case VISIT_ALL_IN_SCAVENGE:
isolate_->global_handles()->IterateStrongAndDependentRoots(v);
isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
break;
case VISIT_ALL_IN_SWEEP_NEWSPACE:
case VISIT_ALL:
......
......@@ -1637,7 +1637,7 @@ class HeapStats {
int* weak_global_handle_count; // 15
int* pending_global_handle_count; // 16
int* near_death_global_handle_count; // 17
int* destroyed_global_handle_count; // 18
int* free_global_handle_count; // 18
intptr_t* memory_allocator_size; // 19
intptr_t* memory_allocator_capacity; // 20
int* objects_per_type; // 21
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment