OLD | NEW |
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 30 matching lines...) Expand all Loading... |
41 | 41 |
42 // An object group is treated like a single JS object: if one of object in | 42 // An object group is treated like a single JS object: if one of object in |
43 // the group is alive, all objects in the same group are considered alive. | 43 // the group is alive, all objects in the same group are considered alive. |
44 // An object group is used to simulate object relationship in a DOM tree. | 44 // An object group is used to simulate object relationship in a DOM tree. |
45 class ObjectGroup : public Malloced { | 45 class ObjectGroup : public Malloced { |
46 public: | 46 public: |
47 ObjectGroup() : objects_(4) {} | 47 ObjectGroup() : objects_(4) {} |
48 ObjectGroup(size_t capacity, v8::RetainedObjectInfo* info) | 48 ObjectGroup(size_t capacity, v8::RetainedObjectInfo* info) |
49 : objects_(static_cast<int>(capacity)), | 49 : objects_(static_cast<int>(capacity)), |
50 info_(info) { } | 50 info_(info) { } |
51 ~ObjectGroup() { if (info_ != NULL) info_->Dispose(); } | 51 ~ObjectGroup(); |
52 | 52 |
53 List<Object**> objects_; | 53 List<Object**> objects_; |
54 v8::RetainedObjectInfo* info_; | 54 v8::RetainedObjectInfo* info_; |
55 | 55 |
56 private: | 56 private: |
57 DISALLOW_COPY_AND_ASSIGN(ObjectGroup); | 57 DISALLOW_COPY_AND_ASSIGN(ObjectGroup); |
58 }; | 58 }; |
59 | 59 |
60 | 60 |
61 // An implicit references group consists of two parts: a parent object and | 61 // An implicit references group consists of two parts: a parent object and |
62 // a list of children objects. If the parent is alive, all the children | 62 // a list of children objects. If the parent is alive, all the children |
63 // are alive too. | 63 // are alive too. |
64 class ImplicitRefGroup : public Malloced { | 64 class ImplicitRefGroup : public Malloced { |
65 public: | 65 public: |
66 ImplicitRefGroup() : children_(4) {} | 66 ImplicitRefGroup() : children_(4) {} |
67 ImplicitRefGroup(HeapObject* parent, size_t capacity) | 67 ImplicitRefGroup(HeapObject* parent, size_t capacity) |
68 : parent_(parent), | 68 : parent_(parent), |
69 children_(static_cast<int>(capacity)) { } | 69 children_(static_cast<int>(capacity)) { } |
70 | 70 |
71 HeapObject* parent_; | 71 HeapObject* parent_; |
72 List<Object**> children_; | 72 List<Object**> children_; |
73 | 73 |
74 private: | 74 private: |
75 DISALLOW_COPY_AND_ASSIGN(ImplicitRefGroup); | 75 DISALLOW_COPY_AND_ASSIGN(ImplicitRefGroup); |
76 }; | 76 }; |
77 | 77 |
78 | 78 |
79 typedef void (*WeakReferenceGuest)(Object* object, void* parameter); | 79 typedef void (*WeakReferenceGuest)(Object* object, void* parameter); |
80 | 80 |
81 class GlobalHandles : public AllStatic { | 81 class GlobalHandles { |
82 public: | 82 public: |
| 83 ~GlobalHandles(); |
| 84 |
83 // Creates a new global handle that is alive until Destroy is called. | 85 // Creates a new global handle that is alive until Destroy is called. |
84 static Handle<Object> Create(Object* value); | 86 Handle<Object> Create(Object* value); |
85 | 87 |
86 // Destroy a global handle. | 88 // Destroy a global handle. |
87 static void Destroy(Object** location); | 89 void Destroy(Object** location); |
88 | 90 |
89 // Make the global handle weak and set the callback parameter for the | 91 // Make the global handle weak and set the callback parameter for the |
90 // handle. When the garbage collector recognizes that only weak global | 92 // handle. When the garbage collector recognizes that only weak global |
91 // handles point to an object the handles are cleared and the callback | 93 // handles point to an object the handles are cleared and the callback |
92 // function is invoked (for each handle) with the handle and corresponding | 94 // function is invoked (for each handle) with the handle and corresponding |
93 // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The | 95 // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The |
94 // reason is that Smi::FromInt(0) does not change during garage collection. | 96 // reason is that Smi::FromInt(0) does not change during garage collection. |
95 static void MakeWeak(Object** location, | 97 void MakeWeak(Object** location, |
96 void* parameter, | 98 void* parameter, |
97 WeakReferenceCallback callback); | 99 WeakReferenceCallback callback); |
98 | 100 |
99 static void SetWrapperClassId(Object** location, uint16_t class_id); | 101 static void SetWrapperClassId(Object** location, uint16_t class_id); |
100 | 102 |
101 // Returns the current number of weak handles. | 103 // Returns the current number of weak handles. |
102 static int NumberOfWeakHandles() { return number_of_weak_handles_; } | 104 int NumberOfWeakHandles() { return number_of_weak_handles_; } |
103 | 105 |
104 static void RecordStats(HeapStats* stats); | 106 void RecordStats(HeapStats* stats); |
105 | 107 |
106 // Returns the current number of weak handles to global objects. | 108 // Returns the current number of weak handles to global objects. |
107 // These handles are also included in NumberOfWeakHandles(). | 109 // These handles are also included in NumberOfWeakHandles(). |
108 static int NumberOfGlobalObjectWeakHandles() { | 110 int NumberOfGlobalObjectWeakHandles() { |
109 return number_of_global_object_weak_handles_; | 111 return number_of_global_object_weak_handles_; |
110 } | 112 } |
111 | 113 |
112 // Clear the weakness of a global handle. | 114 // Clear the weakness of a global handle. |
113 static void ClearWeakness(Object** location); | 115 void ClearWeakness(Object** location); |
114 | 116 |
115 // Tells whether global handle is near death. | 117 // Tells whether global handle is near death. |
116 static bool IsNearDeath(Object** location); | 118 static bool IsNearDeath(Object** location); |
117 | 119 |
118 // Tells whether global handle is weak. | 120 // Tells whether global handle is weak. |
119 static bool IsWeak(Object** location); | 121 static bool IsWeak(Object** location); |
120 | 122 |
121 // Process pending weak handles. | 123 // Process pending weak handles. |
122 // Returns true if next major GC is likely to collect more garbage. | 124 // Returns true if next major GC is likely to collect more garbage. |
123 static bool PostGarbageCollectionProcessing(); | 125 bool PostGarbageCollectionProcessing(); |
124 | 126 |
125 // Iterates over all strong handles. | 127 // Iterates over all strong handles. |
126 static void IterateStrongRoots(ObjectVisitor* v); | 128 void IterateStrongRoots(ObjectVisitor* v); |
127 | 129 |
128 // Iterates over all handles. | 130 // Iterates over all handles. |
129 static void IterateAllRoots(ObjectVisitor* v); | 131 void IterateAllRoots(ObjectVisitor* v); |
130 | 132 |
131 // Iterates over all handles that have embedder-assigned class ID. | 133 // Iterates over all handles that have embedder-assigned class ID. |
132 static void IterateAllRootsWithClassIds(ObjectVisitor* v); | 134 void IterateAllRootsWithClassIds(ObjectVisitor* v); |
133 | 135 |
134 // Iterates over all weak roots in heap. | 136 // Iterates over all weak roots in heap. |
135 static void IterateWeakRoots(ObjectVisitor* v); | 137 void IterateWeakRoots(ObjectVisitor* v); |
136 | 138 |
137 // Iterates over weak roots that are bound to a given callback. | 139 // Iterates over weak roots that are bound to a given callback. |
138 static void IterateWeakRoots(WeakReferenceGuest f, | 140 void IterateWeakRoots(WeakReferenceGuest f, |
139 WeakReferenceCallback callback); | 141 WeakReferenceCallback callback); |
140 | 142 |
141 // Find all weak handles satisfying the callback predicate, mark | 143 // Find all weak handles satisfying the callback predicate, mark |
142 // them as pending. | 144 // them as pending. |
143 static void IdentifyWeakHandles(WeakSlotCallback f); | 145 void IdentifyWeakHandles(WeakSlotCallback f); |
144 | 146 |
145 // Add an object group. | 147 // Add an object group. |
146 // Should be only used in GC callback function before a collection. | 148 // Should be only used in GC callback function before a collection. |
147 // All groups are destroyed after a mark-compact collection. | 149 // All groups are destroyed after a mark-compact collection. |
148 static void AddObjectGroup(Object*** handles, | 150 void AddObjectGroup(Object*** handles, |
149 size_t length, | 151 size_t length, |
150 v8::RetainedObjectInfo* info); | 152 v8::RetainedObjectInfo* info); |
151 | 153 |
152 // Add an implicit references' group. | 154 // Add an implicit references' group. |
153 // Should be only used in GC callback function before a collection. | 155 // Should be only used in GC callback function before a collection. |
154 // All groups are destroyed after a mark-compact collection. | 156 // All groups are destroyed after a mark-compact collection. |
155 static void AddImplicitReferences(HeapObject* parent, | 157 void AddImplicitReferences(HeapObject* parent, |
156 Object*** children, | 158 Object*** children, |
157 size_t length); | 159 size_t length); |
158 | 160 |
159 // Returns the object groups. | 161 // Returns the object groups. |
160 static List<ObjectGroup*>* ObjectGroups(); | 162 List<ObjectGroup*>* object_groups() { return &object_groups_; } |
161 | 163 |
162 // Returns the implicit references' groups. | 164 // Returns the implicit references' groups. |
163 static List<ImplicitRefGroup*>* ImplicitRefGroups(); | 165 List<ImplicitRefGroup*>* implicit_ref_groups() { |
| 166 return &implicit_ref_groups_; |
| 167 } |
164 | 168 |
165 // Remove bags, this should only happen after GC. | 169 // Remove bags, this should only happen after GC. |
166 static void RemoveObjectGroups(); | 170 void RemoveObjectGroups(); |
167 static void RemoveImplicitRefGroups(); | 171 void RemoveImplicitRefGroups(); |
168 | 172 |
169 // Tear down the global handle structure. | 173 // Tear down the global handle structure. |
170 static void TearDown(); | 174 void TearDown(); |
| 175 |
| 176 Isolate* isolate() { return isolate_; } |
171 | 177 |
172 #ifdef DEBUG | 178 #ifdef DEBUG |
173 static void PrintStats(); | 179 void PrintStats(); |
174 static void Print(); | 180 void Print(); |
175 #endif | 181 #endif |
176 class Pool; | 182 class Pool; |
177 private: | 183 private: |
| 184 explicit GlobalHandles(Isolate* isolate); |
| 185 |
178 // Internal node structure, one for each global handle. | 186 // Internal node structure, one for each global handle. |
179 class Node; | 187 class Node; |
180 | 188 |
| 189 Isolate* isolate_; |
| 190 |
181 // Field always containing the number of weak and near-death handles. | 191 // Field always containing the number of weak and near-death handles. |
182 static int number_of_weak_handles_; | 192 int number_of_weak_handles_; |
183 | 193 |
184 // Field always containing the number of weak and near-death handles | 194 // Field always containing the number of weak and near-death handles |
185 // to global objects. These objects are also included in | 195 // to global objects. These objects are also included in |
186 // number_of_weak_handles_. | 196 // number_of_weak_handles_. |
187 static int number_of_global_object_weak_handles_; | 197 int number_of_global_object_weak_handles_; |
188 | 198 |
189 // Global handles are kept in a single linked list pointed to by head_. | 199 // Global handles are kept in a single linked list pointed to by head_. |
190 static Node* head_; | 200 Node* head_; |
191 static Node* head() { return head_; } | 201 Node* head() { return head_; } |
192 static void set_head(Node* value) { head_ = value; } | 202 void set_head(Node* value) { head_ = value; } |
193 | 203 |
194 // Free list for DESTROYED global handles not yet deallocated. | 204 // Free list for DESTROYED global handles not yet deallocated. |
195 static Node* first_free_; | 205 Node* first_free_; |
196 static Node* first_free() { return first_free_; } | 206 Node* first_free() { return first_free_; } |
197 static void set_first_free(Node* value) { first_free_ = value; } | 207 void set_first_free(Node* value) { first_free_ = value; } |
198 | 208 |
199 // List of deallocated nodes. | 209 // List of deallocated nodes. |
200 // Deallocated nodes form a prefix of all the nodes and | 210 // Deallocated nodes form a prefix of all the nodes and |
201 // |first_deallocated| points to last deallocated node before | 211 // |first_deallocated| points to last deallocated node before |
202 // |head|. Those deallocated nodes are additionally linked | 212 // |head|. Those deallocated nodes are additionally linked |
203 // by |next_free|: | 213 // by |next_free|: |
204 // 1st deallocated head | 214 // 1st deallocated head |
205 // | | | 215 // | | |
206 // V V | 216 // V V |
207 // node node ... node node | 217 // node node ... node node |
208 // .next -> .next -> .next -> | 218 // .next -> .next -> .next -> |
209 // <- .next_free <- .next_free <- .next_free | 219 // <- .next_free <- .next_free <- .next_free |
210 static Node* first_deallocated_; | 220 Node* first_deallocated_; |
211 static Node* first_deallocated() { return first_deallocated_; } | 221 Node* first_deallocated() { return first_deallocated_; } |
212 static void set_first_deallocated(Node* value) { | 222 void set_first_deallocated(Node* value) { |
213 first_deallocated_ = value; | 223 first_deallocated_ = value; |
214 } | 224 } |
| 225 |
| 226 Pool* pool_; |
| 227 int post_gc_processing_count_; |
| 228 List<ObjectGroup*> object_groups_; |
| 229 List<ImplicitRefGroup*> implicit_ref_groups_; |
| 230 |
| 231 friend class Isolate; |
| 232 |
| 233 DISALLOW_COPY_AND_ASSIGN(GlobalHandles); |
215 }; | 234 }; |
216 | 235 |
217 | 236 |
218 } } // namespace v8::internal | 237 } } // namespace v8::internal |
219 | 238 |
220 #endif // V8_GLOBAL_HANDLES_H_ | 239 #endif // V8_GLOBAL_HANDLES_H_ |
OLD | NEW |