blob: ddf5fe29c383fcd87b5d9d8b7d576d662ae11e4b [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_GLOBAL_HANDLES_H_
29#define V8_GLOBAL_HANDLES_H_
30
Ben Murdoch8b112d22011-06-08 16:22:53 +010031#include "../include/v8-profiler.h"
32
Ben Murdoch257744e2011-11-30 15:57:28 +000033#include "list.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000034
35namespace v8 {
36namespace internal {
37
38// Structure for tracking global handles.
39// A single list keeps all the allocated global handles.
40// Destroyed handles stay in the list but is added to the free list.
41// At GC the destroyed global handles are removed from the free list
42// and deallocated.
43
Steve Blocka7e24c12009-10-30 11:49:00 +000044// An object group is treated like a single JS object: if one of object in
45// the group is alive, all objects in the same group are considered alive.
46// An object group is used to simulate object relationship in a DOM tree.
Ben Murdoch8b112d22011-06-08 16:22:53 +010047class ObjectGroup {
Steve Blocka7e24c12009-10-30 11:49:00 +000048 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +010049 static ObjectGroup* New(Object*** handles,
50 size_t length,
51 v8::RetainedObjectInfo* info) {
52 ASSERT(length > 0);
53 ObjectGroup* group = reinterpret_cast<ObjectGroup*>(
54 malloc(OFFSET_OF(ObjectGroup, objects_[length])));
55 group->length_ = length;
56 group->info_ = info;
57 CopyWords(group->objects_, handles, static_cast<int>(length));
58 return group;
59 }
Steve Blocka7e24c12009-10-30 11:49:00 +000060
Ben Murdoch8b112d22011-06-08 16:22:53 +010061 void Dispose() {
62 if (info_ != NULL) info_->Dispose();
63 free(this);
64 }
65
66 size_t length_;
Steve Block44f0eee2011-05-26 01:26:41 +010067 v8::RetainedObjectInfo* info_;
Ben Murdoch8b112d22011-06-08 16:22:53 +010068 Object** objects_[1]; // Variable sized array.
Steve Block44f0eee2011-05-26 01:26:41 +010069
70 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +010071 void* operator new(size_t size);
72 void operator delete(void* p);
73 ~ObjectGroup();
74 DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectGroup);
Steve Block44f0eee2011-05-26 01:26:41 +010075};
76
77
78// An implicit references group consists of two parts: a parent object and
79// a list of children objects. If the parent is alive, all the children
80// are alive too.
Ben Murdoch8b112d22011-06-08 16:22:53 +010081class ImplicitRefGroup {
Steve Block44f0eee2011-05-26 01:26:41 +010082 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +010083 static ImplicitRefGroup* New(HeapObject** parent,
84 Object*** children,
85 size_t length) {
86 ASSERT(length > 0);
87 ImplicitRefGroup* group = reinterpret_cast<ImplicitRefGroup*>(
88 malloc(OFFSET_OF(ImplicitRefGroup, children_[length])));
89 group->parent_ = parent;
90 group->length_ = length;
91 CopyWords(group->children_, children, static_cast<int>(length));
92 return group;
93 }
Steve Block44f0eee2011-05-26 01:26:41 +010094
Ben Murdoch8b112d22011-06-08 16:22:53 +010095 void Dispose() {
96 free(this);
97 }
98
99 HeapObject** parent_;
100 size_t length_;
101 Object** children_[1]; // Variable sized array.
Steve Block44f0eee2011-05-26 01:26:41 +0100102
103 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100104 void* operator new(size_t size);
105 void operator delete(void* p);
106 ~ImplicitRefGroup();
107 DISALLOW_IMPLICIT_CONSTRUCTORS(ImplicitRefGroup);
Steve Blocka7e24c12009-10-30 11:49:00 +0000108};
109
110
Steve Block3ce2e202009-11-05 08:53:23 +0000111typedef void (*WeakReferenceGuest)(Object* object, void* parameter);
112
Steve Block44f0eee2011-05-26 01:26:41 +0100113class GlobalHandles {
Steve Blocka7e24c12009-10-30 11:49:00 +0000114 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100115 ~GlobalHandles();
116
Steve Blocka7e24c12009-10-30 11:49:00 +0000117 // Creates a new global handle that is alive until Destroy is called.
Steve Block44f0eee2011-05-26 01:26:41 +0100118 Handle<Object> Create(Object* value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000119
120 // Destroy a global handle.
Steve Block44f0eee2011-05-26 01:26:41 +0100121 void Destroy(Object** location);
Steve Blocka7e24c12009-10-30 11:49:00 +0000122
123 // Make the global handle weak and set the callback parameter for the
124 // handle. When the garbage collector recognizes that only weak global
125 // handles point to an object the handles are cleared and the callback
126 // function is invoked (for each handle) with the handle and corresponding
127 // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The
128 // reason is that Smi::FromInt(0) does not change during garage collection.
Steve Block44f0eee2011-05-26 01:26:41 +0100129 void MakeWeak(Object** location,
130 void* parameter,
131 WeakReferenceCallback callback);
132
133 static void SetWrapperClassId(Object** location, uint16_t class_id);
Steve Blocka7e24c12009-10-30 11:49:00 +0000134
135 // Returns the current number of weak handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100136 int NumberOfWeakHandles() { return number_of_weak_handles_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000137
Steve Block44f0eee2011-05-26 01:26:41 +0100138 void RecordStats(HeapStats* stats);
Steve Blockd0582a62009-12-15 09:54:21 +0000139
Steve Blocka7e24c12009-10-30 11:49:00 +0000140 // Returns the current number of weak handles to global objects.
141 // These handles are also included in NumberOfWeakHandles().
Steve Block44f0eee2011-05-26 01:26:41 +0100142 int NumberOfGlobalObjectWeakHandles() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000143 return number_of_global_object_weak_handles_;
144 }
145
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100146 // Returns the current number of handles to global objects.
147 int NumberOfGlobalHandles() {
148 return number_of_global_handles_;
149 }
150
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 // Clear the weakness of a global handle.
Steve Block44f0eee2011-05-26 01:26:41 +0100152 void ClearWeakness(Object** location);
Steve Blocka7e24c12009-10-30 11:49:00 +0000153
Ben Murdoch257744e2011-11-30 15:57:28 +0000154 // Clear the weakness of a global handle.
155 void MarkIndependent(Object** location);
156
Steve Blocka7e24c12009-10-30 11:49:00 +0000157 // Tells whether global handle is near death.
158 static bool IsNearDeath(Object** location);
159
160 // Tells whether global handle is weak.
161 static bool IsWeak(Object** location);
162
John Reck59135872010-11-02 12:39:01 -0700163 // Process pending weak handles.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800164 // Returns true if next major GC is likely to collect more garbage.
Ben Murdoch257744e2011-11-30 15:57:28 +0000165 bool PostGarbageCollectionProcessing(GarbageCollector collector);
Steve Blocka7e24c12009-10-30 11:49:00 +0000166
Steve Blockd0582a62009-12-15 09:54:21 +0000167 // Iterates over all strong handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100168 void IterateStrongRoots(ObjectVisitor* v);
Steve Blockd0582a62009-12-15 09:54:21 +0000169
Steve Blocka7e24c12009-10-30 11:49:00 +0000170 // Iterates over all handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100171 void IterateAllRoots(ObjectVisitor* v);
172
173 // Iterates over all handles that have embedder-assigned class ID.
174 void IterateAllRootsWithClassIds(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000175
176 // Iterates over all weak roots in heap.
Steve Block44f0eee2011-05-26 01:26:41 +0100177 void IterateWeakRoots(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000178
Steve Block3ce2e202009-11-05 08:53:23 +0000179 // Iterates over weak roots that are bound to a given callback.
Steve Block44f0eee2011-05-26 01:26:41 +0100180 void IterateWeakRoots(WeakReferenceGuest f,
181 WeakReferenceCallback callback);
Steve Block3ce2e202009-11-05 08:53:23 +0000182
Steve Blocka7e24c12009-10-30 11:49:00 +0000183 // Find all weak handles satisfying the callback predicate, mark
184 // them as pending.
Steve Block44f0eee2011-05-26 01:26:41 +0100185 void IdentifyWeakHandles(WeakSlotCallback f);
Steve Blocka7e24c12009-10-30 11:49:00 +0000186
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000187 // NOTE: Three ...NewSpace... functions below are used during
188 // scavenge collections and iterate over sets of handles that are
189 // guaranteed to contain all handles holding new space objects (but
190 // may also include old space objects).
191
192 // Iterates over strong and dependent handles. See the node above.
193 void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v);
194
195 // Finds weak independent handles satisfying the callback predicate
196 // and marks them as pending. See the note above.
197 void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
198
199 // Iterates over weak independent handles. See the note above.
200 void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
Ben Murdoch257744e2011-11-30 15:57:28 +0000201
Steve Blocka7e24c12009-10-30 11:49:00 +0000202 // Add an object group.
Steve Block44f0eee2011-05-26 01:26:41 +0100203 // Should be only used in GC callback function before a collection.
Steve Blocka7e24c12009-10-30 11:49:00 +0000204 // All groups are destroyed after a mark-compact collection.
Steve Block44f0eee2011-05-26 01:26:41 +0100205 void AddObjectGroup(Object*** handles,
206 size_t length,
207 v8::RetainedObjectInfo* info);
208
209 // Add an implicit references' group.
210 // Should be only used in GC callback function before a collection.
211 // All groups are destroyed after a mark-compact collection.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100212 void AddImplicitReferences(HeapObject** parent,
Steve Block44f0eee2011-05-26 01:26:41 +0100213 Object*** children,
214 size_t length);
Steve Blocka7e24c12009-10-30 11:49:00 +0000215
216 // Returns the object groups.
Steve Block44f0eee2011-05-26 01:26:41 +0100217 List<ObjectGroup*>* object_groups() { return &object_groups_; }
218
219 // Returns the implicit references' groups.
220 List<ImplicitRefGroup*>* implicit_ref_groups() {
221 return &implicit_ref_groups_;
222 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000223
224 // Remove bags, this should only happen after GC.
Steve Block44f0eee2011-05-26 01:26:41 +0100225 void RemoveObjectGroups();
226 void RemoveImplicitRefGroups();
Steve Blocka7e24c12009-10-30 11:49:00 +0000227
228 // Tear down the global handle structure.
Steve Block44f0eee2011-05-26 01:26:41 +0100229 void TearDown();
230
231 Isolate* isolate() { return isolate_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000232
233#ifdef DEBUG
Steve Block44f0eee2011-05-26 01:26:41 +0100234 void PrintStats();
235 void Print();
Steve Blocka7e24c12009-10-30 11:49:00 +0000236#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000237
Steve Blocka7e24c12009-10-30 11:49:00 +0000238 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100239 explicit GlobalHandles(Isolate* isolate);
240
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000241 // Internal node structures.
Steve Blocka7e24c12009-10-30 11:49:00 +0000242 class Node;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000243 class NodeBlock;
244 class NodeIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000245
Steve Block44f0eee2011-05-26 01:26:41 +0100246 Isolate* isolate_;
247
Steve Blocka7e24c12009-10-30 11:49:00 +0000248 // Field always containing the number of weak and near-death handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100249 int number_of_weak_handles_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000250
251 // Field always containing the number of weak and near-death handles
252 // to global objects. These objects are also included in
253 // number_of_weak_handles_.
Steve Block44f0eee2011-05-26 01:26:41 +0100254 int number_of_global_object_weak_handles_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000255
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100256 // Field always containing the number of handles to global objects.
257 int number_of_global_handles_;
258
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000259 // List of all allocated node blocks.
260 NodeBlock* first_block_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000261
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000262 // List of node blocks with used nodes.
263 NodeBlock* first_used_block_;
264
265 // Free list of nodes.
Steve Block44f0eee2011-05-26 01:26:41 +0100266 Node* first_free_;
Steve Blockd0582a62009-12-15 09:54:21 +0000267
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000268 // Contains all nodes holding new space objects. Note: when the list
269 // is accessed, some of the objects may have been promoted already.
270 List<Node*> new_space_nodes_;
Steve Block44f0eee2011-05-26 01:26:41 +0100271
Steve Block44f0eee2011-05-26 01:26:41 +0100272 int post_gc_processing_count_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000273
Steve Block44f0eee2011-05-26 01:26:41 +0100274 List<ObjectGroup*> object_groups_;
275 List<ImplicitRefGroup*> implicit_ref_groups_;
276
277 friend class Isolate;
278
279 DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
Steve Blocka7e24c12009-10-30 11:49:00 +0000280};
281
282
283} } // namespace v8::internal
284
285#endif // V8_GLOBAL_HANDLES_H_