Index: src/global-handles.h |
diff --git a/src/global-handles.h b/src/global-handles.h |
index cd75133a24367092ec07e87bd9fc451a8a9e9d64..2d889fe669f0bb9fa24e1d7f3bc4feed37240d32 100644 |
--- a/src/global-handles.h |
+++ b/src/global-handles.h |
@@ -156,6 +156,9 @@ class GlobalHandles { |
return number_of_global_handles_; |
} |
+ // Returns the current number of allocated blocks |
+ int block_count() const { return number_of_blocks_; } |
+ |
// Clear the weakness of a global handle. |
static void ClearWeakness(Object** location); |
@@ -275,11 +278,14 @@ class GlobalHandles { |
#ifdef DEBUG |
void PrintStats(); |
void Print(); |
+ void VerifyBlockInvariants(); |
#endif |
private: |
explicit GlobalHandles(Isolate* isolate); |
+ void SortBlocks(bool shouldPrune); |
+ |
// Migrates data from the internal representation (object_group_connections_, |
// retainer_infos_ and implicit_ref_connections_) to the public and more |
// efficient representation (object_groups_ and implicit_ref_groups_). |
@@ -293,20 +299,64 @@ class GlobalHandles { |
class Node; |
class NodeBlock; |
class NodeIterator; |
+ class BlockListIterator; |
+ // Base class for NodeBlock |
+ class BlockList { |
+ public: |
+ BlockList(); |
+ ~BlockList() { ASSERT(IsDetached()); } |
+ void Detach(); |
+ void InsertAsHead(BlockList* block) { |
+ ASSERT(IsAnchor()); |
+ InsertAsNext(block); |
+ } |
+ void InsertAsTail(BlockList* block) { |
+ ASSERT(IsAnchor()); |
+ prev_block_->InsertAsNext(block); |
+ } |
+ inline bool IsAnchor() { return first_free_ == NULL && used_nodes_ == 0; } |
+ inline bool IsDetached() { |
+ ASSERT_EQ(prev_block_ == this, next_block_ == this); |
+ return prev_block_ == this; |
+ } |
+ bool HasAtLeastLength(int length); |
+ bool IsUnused() { return used_nodes_ == 0; } |
+ int used_nodes() const { return used_nodes_; } |
+ BlockList* next() { return next_block_; } |
+ BlockList* prev() { return prev_block_; } |
+#ifdef DEBUG |
+ int LengthOfFreeList(); |
+#endif |
+ static void SortBlocks(GlobalHandles* global_handles, bool prune); |
+ |
+ protected: |
+ BlockList* prev_block_; |
+ BlockList* next_block_; |
+ Node* first_free_; |
+ int used_nodes_; |
+ |
+ private: |
+ // Needed for quicksort |
+ static int CompareBlocks(const void* a, const void* b); |
+ void InsertAsNext(BlockList* block); |
+ DISALLOW_COPY_AND_ASSIGN(BlockList); |
+ }; |
Isolate* isolate_; |
+ // Field always containing the number of blocks allocated. |
+ int number_of_blocks_; |
// Field always containing the number of handles to global objects. |
int number_of_global_handles_; |
- // List of all allocated node blocks. |
- NodeBlock* first_block_; |
- |
- // List of node blocks with used nodes. |
- NodeBlock* first_used_block_; |
+ // Anchors for doubly linked lists of blocks |
+ BlockList full_blocks_; |
+ BlockList non_full_blocks_; |
- // Free list of nodes. |
- Node* first_free_; |
+ // An array of all the anchors held by GlobalHandles. |
+ // This simplifies iteration across all blocks. |
+ static const int kAllAnchorsSize = 2; |
+ BlockList* all_anchors_[kAllAnchorsSize]; |
// Contains all nodes holding new space objects. Note: when the list |
// is accessed, some of the objects may have been promoted already. |