blob: b77fcb79274d76a05507377c80ddfa5733c3b7ba [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2007-2008 the V8 project authors. All rights reserved.
2// 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
31#include "list-inl.h"
32
Steve Block1bd4c0f2011-06-01 16:23:13 +010033#include "../include/v8-profiler.h"
34
Steve Blocka7e24c12009-10-30 11:49:00 +000035namespace 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.
47class ObjectGroup : public Malloced {
48 public:
49 ObjectGroup() : objects_(4) {}
Steve Block44f0eee2011-05-26 01:26:41 +010050 ObjectGroup(size_t capacity, v8::RetainedObjectInfo* info)
51 : objects_(static_cast<int>(capacity)),
52 info_(info) { }
53 ~ObjectGroup();
Steve Blocka7e24c12009-10-30 11:49:00 +000054
55 List<Object**> objects_;
Steve Block44f0eee2011-05-26 01:26:41 +010056 v8::RetainedObjectInfo* info_;
57
58 private:
59 DISALLOW_COPY_AND_ASSIGN(ObjectGroup);
60};
61
62
63// An implicit references group consists of two parts: a parent object and
64// a list of children objects. If the parent is alive, all the children
65// are alive too.
66class ImplicitRefGroup : public Malloced {
67 public:
68 ImplicitRefGroup() : children_(4) {}
69 ImplicitRefGroup(HeapObject* parent, size_t capacity)
70 : parent_(parent),
71 children_(static_cast<int>(capacity)) { }
72
73 HeapObject* parent_;
74 List<Object**> children_;
75
76 private:
77 DISALLOW_COPY_AND_ASSIGN(ImplicitRefGroup);
Steve Blocka7e24c12009-10-30 11:49:00 +000078};
79
80
Steve Block3ce2e202009-11-05 08:53:23 +000081typedef void (*WeakReferenceGuest)(Object* object, void* parameter);
82
Steve Block44f0eee2011-05-26 01:26:41 +010083class GlobalHandles {
Steve Blocka7e24c12009-10-30 11:49:00 +000084 public:
Steve Block44f0eee2011-05-26 01:26:41 +010085 ~GlobalHandles();
86
Steve Blocka7e24c12009-10-30 11:49:00 +000087 // Creates a new global handle that is alive until Destroy is called.
Steve Block44f0eee2011-05-26 01:26:41 +010088 Handle<Object> Create(Object* value);
Steve Blocka7e24c12009-10-30 11:49:00 +000089
90 // Destroy a global handle.
Steve Block44f0eee2011-05-26 01:26:41 +010091 void Destroy(Object** location);
Steve Blocka7e24c12009-10-30 11:49:00 +000092
93 // Make the global handle weak and set the callback parameter for the
94 // handle. When the garbage collector recognizes that only weak global
95 // handles point to an object the handles are cleared and the callback
96 // function is invoked (for each handle) with the handle and corresponding
97 // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The
98 // reason is that Smi::FromInt(0) does not change during garage collection.
Steve Block44f0eee2011-05-26 01:26:41 +010099 void MakeWeak(Object** location,
100 void* parameter,
101 WeakReferenceCallback callback);
102
103 static void SetWrapperClassId(Object** location, uint16_t class_id);
Steve Blocka7e24c12009-10-30 11:49:00 +0000104
105 // Returns the current number of weak handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100106 int NumberOfWeakHandles() { return number_of_weak_handles_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000107
Steve Block44f0eee2011-05-26 01:26:41 +0100108 void RecordStats(HeapStats* stats);
Steve Blockd0582a62009-12-15 09:54:21 +0000109
Steve Blocka7e24c12009-10-30 11:49:00 +0000110 // Returns the current number of weak handles to global objects.
111 // These handles are also included in NumberOfWeakHandles().
Steve Block44f0eee2011-05-26 01:26:41 +0100112 int NumberOfGlobalObjectWeakHandles() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000113 return number_of_global_object_weak_handles_;
114 }
115
116 // Clear the weakness of a global handle.
Steve Block44f0eee2011-05-26 01:26:41 +0100117 void ClearWeakness(Object** location);
Steve Blocka7e24c12009-10-30 11:49:00 +0000118
119 // Tells whether global handle is near death.
120 static bool IsNearDeath(Object** location);
121
122 // Tells whether global handle is weak.
123 static bool IsWeak(Object** location);
124
John Reck59135872010-11-02 12:39:01 -0700125 // Process pending weak handles.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800126 // Returns true if next major GC is likely to collect more garbage.
Steve Block44f0eee2011-05-26 01:26:41 +0100127 bool PostGarbageCollectionProcessing();
Steve Blocka7e24c12009-10-30 11:49:00 +0000128
Steve Blockd0582a62009-12-15 09:54:21 +0000129 // Iterates over all strong handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100130 void IterateStrongRoots(ObjectVisitor* v);
Steve Blockd0582a62009-12-15 09:54:21 +0000131
Steve Blocka7e24c12009-10-30 11:49:00 +0000132 // Iterates over all handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100133 void IterateAllRoots(ObjectVisitor* v);
134
135 // Iterates over all handles that have embedder-assigned class ID.
136 void IterateAllRootsWithClassIds(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000137
138 // Iterates over all weak roots in heap.
Steve Block44f0eee2011-05-26 01:26:41 +0100139 void IterateWeakRoots(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000140
Steve Block3ce2e202009-11-05 08:53:23 +0000141 // Iterates over weak roots that are bound to a given callback.
Steve Block44f0eee2011-05-26 01:26:41 +0100142 void IterateWeakRoots(WeakReferenceGuest f,
143 WeakReferenceCallback callback);
Steve Block3ce2e202009-11-05 08:53:23 +0000144
Steve Blocka7e24c12009-10-30 11:49:00 +0000145 // Find all weak handles satisfying the callback predicate, mark
146 // them as pending.
Steve Block44f0eee2011-05-26 01:26:41 +0100147 void IdentifyWeakHandles(WeakSlotCallback f);
Steve Blocka7e24c12009-10-30 11:49:00 +0000148
149 // Add an object group.
Steve Block44f0eee2011-05-26 01:26:41 +0100150 // Should be only used in GC callback function before a collection.
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 // All groups are destroyed after a mark-compact collection.
Steve Block44f0eee2011-05-26 01:26:41 +0100152 void AddObjectGroup(Object*** handles,
153 size_t length,
154 v8::RetainedObjectInfo* info);
155
156 // Add an implicit references' group.
157 // Should be only used in GC callback function before a collection.
158 // All groups are destroyed after a mark-compact collection.
159 void AddImplicitReferences(HeapObject* parent,
160 Object*** children,
161 size_t length);
Steve Blocka7e24c12009-10-30 11:49:00 +0000162
163 // Returns the object groups.
Steve Block44f0eee2011-05-26 01:26:41 +0100164 List<ObjectGroup*>* object_groups() { return &object_groups_; }
165
166 // Returns the implicit references' groups.
167 List<ImplicitRefGroup*>* implicit_ref_groups() {
168 return &implicit_ref_groups_;
169 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000170
171 // Remove bags, this should only happen after GC.
Steve Block44f0eee2011-05-26 01:26:41 +0100172 void RemoveObjectGroups();
173 void RemoveImplicitRefGroups();
Steve Blocka7e24c12009-10-30 11:49:00 +0000174
175 // Tear down the global handle structure.
Steve Block44f0eee2011-05-26 01:26:41 +0100176 void TearDown();
177
178 Isolate* isolate() { return isolate_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000179
180#ifdef DEBUG
Steve Block44f0eee2011-05-26 01:26:41 +0100181 void PrintStats();
182 void Print();
Steve Blocka7e24c12009-10-30 11:49:00 +0000183#endif
Steve Blockd0582a62009-12-15 09:54:21 +0000184 class Pool;
Steve Blocka7e24c12009-10-30 11:49:00 +0000185 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100186 explicit GlobalHandles(Isolate* isolate);
187
Steve Blocka7e24c12009-10-30 11:49:00 +0000188 // Internal node structure, one for each global handle.
189 class Node;
190
Steve Block44f0eee2011-05-26 01:26:41 +0100191 Isolate* isolate_;
192
Steve Blocka7e24c12009-10-30 11:49:00 +0000193 // Field always containing the number of weak and near-death handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100194 int number_of_weak_handles_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000195
196 // Field always containing the number of weak and near-death handles
197 // to global objects. These objects are also included in
198 // number_of_weak_handles_.
Steve Block44f0eee2011-05-26 01:26:41 +0100199 int number_of_global_object_weak_handles_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000200
201 // Global handles are kept in a single linked list pointed to by head_.
Steve Block44f0eee2011-05-26 01:26:41 +0100202 Node* head_;
203 Node* head() { return head_; }
204 void set_head(Node* value) { head_ = value; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000205
206 // Free list for DESTROYED global handles not yet deallocated.
Steve Block44f0eee2011-05-26 01:26:41 +0100207 Node* first_free_;
208 Node* first_free() { return first_free_; }
209 void set_first_free(Node* value) { first_free_ = value; }
Steve Blockd0582a62009-12-15 09:54:21 +0000210
211 // List of deallocated nodes.
212 // Deallocated nodes form a prefix of all the nodes and
213 // |first_deallocated| points to last deallocated node before
214 // |head|. Those deallocated nodes are additionally linked
215 // by |next_free|:
216 // 1st deallocated head
217 // | |
218 // V V
219 // node node ... node node
220 // .next -> .next -> .next ->
221 // <- .next_free <- .next_free <- .next_free
Steve Block44f0eee2011-05-26 01:26:41 +0100222 Node* first_deallocated_;
223 Node* first_deallocated() { return first_deallocated_; }
224 void set_first_deallocated(Node* value) {
Steve Blockd0582a62009-12-15 09:54:21 +0000225 first_deallocated_ = value;
226 }
Steve Block44f0eee2011-05-26 01:26:41 +0100227
228 Pool* pool_;
229 int post_gc_processing_count_;
230 List<ObjectGroup*> object_groups_;
231 List<ImplicitRefGroup*> implicit_ref_groups_;
232
233 friend class Isolate;
234
235 DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
Steve Blocka7e24c12009-10-30 11:49:00 +0000236};
237
238
239} } // namespace v8::internal
240
241#endif // V8_GLOBAL_HANDLES_H_