blob: 153d4dac1a2b1e7617d82359e64bdfbe3d704347 [file] [log] [blame]
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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
ricow@chromium.org8b0c11e2011-04-12 05:56:07 +000031#include "../include/v8-profiler.h"
32
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000033#include "list.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034
kasperl@chromium.org71affb52009-05-26 05:44:31 +000035namespace v8 {
36namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037
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
ager@chromium.org8bb60582008-12-11 12:02:20 +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.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046// An object group is used to simulate object relationship in a DOM tree.
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000047class ObjectGroup {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048 public:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000049 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 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000060
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000061 void Dispose() {
ricow@chromium.org8b0c11e2011-04-12 05:56:07 +000062 if (info_ != NULL) info_->Dispose();
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000063 free(this);
64 }
65
66 size_t length_;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +000067 v8::RetainedObjectInfo* info_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000068 Object** objects_[1]; // Variable sized array.
whesse@chromium.orgb08986c2011-03-14 16:13:42 +000069
70 private:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000071 void* operator new(size_t size);
72 void operator delete(void* p);
73 ~ObjectGroup();
74 DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectGroup);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000075};
76
77
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +000078// 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.
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000081class ImplicitRefGroup {
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +000082 public:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000083 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 }
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +000094
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000095 void Dispose() {
96 free(this);
97 }
98
99 HeapObject** parent_;
100 size_t length_;
101 Object** children_[1]; // Variable sized array.
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +0000102
103 private:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000104 void* operator new(size_t size);
105 void operator delete(void* p);
106 ~ImplicitRefGroup();
107 DISALLOW_IMPLICIT_CONSTRUCTORS(ImplicitRefGroup);
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +0000108};
109
110
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000111typedef void (*WeakReferenceGuest)(Object* object, void* parameter);
112
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000113class GlobalHandles {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000115 ~GlobalHandles();
116
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000117 // Creates a new global handle that is alive until Destroy is called.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000118 Handle<Object> Create(Object* value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000119
120 // Destroy a global handle.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000121 void Destroy(Object** location);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000129 void MakeWeak(Object** location,
130 void* parameter,
131 WeakReferenceCallback callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000132
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000133 static void SetWrapperClassId(Object** location, uint16_t class_id);
134
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135 // Returns the current number of weak handles.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000136 int NumberOfWeakHandles() { return number_of_weak_handles_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000137
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000138 void RecordStats(HeapStats* stats);
ager@chromium.org60121232009-12-03 11:25:37 +0000139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140 // Returns the current number of weak handles to global objects.
141 // These handles are also included in NumberOfWeakHandles().
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000142 int NumberOfGlobalObjectWeakHandles() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000143 return number_of_global_object_weak_handles_;
144 }
145
146 // Clear the weakness of a global handle.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000147 void ClearWeakness(Object** location);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000148
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000149 // Clear the weakness of a global handle.
150 void MarkIndependent(Object** location);
151
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000152 // Tells whether global handle is near death.
153 static bool IsNearDeath(Object** location);
154
155 // Tells whether global handle is weak.
156 static bool IsWeak(Object** location);
157
lrn@chromium.org303ada72010-10-27 09:33:13 +0000158 // Process pending weak handles.
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +0000159 // Returns true if next major GC is likely to collect more garbage.
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000160 bool PostGarbageCollectionProcessing(GarbageCollector collector);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000161
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000162 // Iterates over all strong handles.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000163 void IterateStrongRoots(ObjectVisitor* v);
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000164
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000165 // Iterates over all handles.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000166 void IterateAllRoots(ObjectVisitor* v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000168 // Iterates over all handles that have embedder-assigned class ID.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000169 void IterateAllRootsWithClassIds(ObjectVisitor* v);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000171 // Iterates over all weak roots in heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000172 void IterateWeakRoots(ObjectVisitor* v);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000173
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000174 // Iterates over weak roots that are bound to a given callback.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000175 void IterateWeakRoots(WeakReferenceGuest f,
176 WeakReferenceCallback callback);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000177
ager@chromium.org9085a012009-05-11 19:22:57 +0000178 // Find all weak handles satisfying the callback predicate, mark
179 // them as pending.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000180 void IdentifyWeakHandles(WeakSlotCallback f);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000181
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000182 // NOTE: Three ...NewSpace... functions below are used during
183 // scavenge collections and iterate over sets of handles that are
184 // guaranteed to contain all handles holding new space objects (but
185 // may also include old space objects).
186
187 // Iterates over strong and dependent handles. See the node above.
188 void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v);
189
190 // Finds weak independent handles satisfying the callback predicate
191 // and marks them as pending. See the note above.
192 void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
193
194 // Iterates over weak independent handles. See the note above.
195 void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000196
ager@chromium.org8bb60582008-12-11 12:02:20 +0000197 // Add an object group.
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +0000198 // Should be only used in GC callback function before a collection.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199 // All groups are destroyed after a mark-compact collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000200 void AddObjectGroup(Object*** handles,
201 size_t length,
202 v8::RetainedObjectInfo* info);
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +0000203
204 // Add an implicit references' group.
205 // Should be only used in GC callback function before a collection.
206 // All groups are destroyed after a mark-compact collection.
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000207 void AddImplicitReferences(HeapObject** parent,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000208 Object*** children,
209 size_t length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210
211 // Returns the object groups.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000212 List<ObjectGroup*>* object_groups() { return &object_groups_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000213
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +0000214 // Returns the implicit references' groups.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000215 List<ImplicitRefGroup*>* implicit_ref_groups() {
216 return &implicit_ref_groups_;
217 }
ricow@chromium.orgbadaffc2011-03-17 12:15:27 +0000218
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000219 // Remove bags, this should only happen after GC.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000220 void RemoveObjectGroups();
221 void RemoveImplicitRefGroups();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222
223 // Tear down the global handle structure.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000224 void TearDown();
225
226 Isolate* isolate() { return isolate_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000227
228#ifdef DEBUG
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000229 void PrintStats();
230 void Print();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231#endif
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000233 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000234 explicit GlobalHandles(Isolate* isolate);
235
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000236 // Internal node structures.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237 class Node;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000238 class NodeBlock;
239 class NodeIterator;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000241 Isolate* isolate_;
242
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243 // Field always containing the number of weak and near-death handles.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000244 int number_of_weak_handles_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000245
246 // Field always containing the number of weak and near-death handles
247 // to global objects. These objects are also included in
248 // number_of_weak_handles_.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000249 int number_of_global_object_weak_handles_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000251 // List of all allocated node blocks.
252 NodeBlock* first_block_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000253
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000254 // List of node blocks with used nodes.
255 NodeBlock* first_used_block_;
256
257 // Free list of nodes.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000258 Node* first_free_;
ager@chromium.org3811b432009-10-28 14:53:37 +0000259
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000260 // Contains all nodes holding new space objects. Note: when the list
261 // is accessed, some of the objects may have been promoted already.
262 List<Node*> new_space_nodes_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000263
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000264 int post_gc_processing_count_;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000265
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000266 List<ObjectGroup*> object_groups_;
267 List<ImplicitRefGroup*> implicit_ref_groups_;
268
269 friend class Isolate;
270
271 DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272};
273
274
275} } // namespace v8::internal
276
277#endif // V8_GLOBAL_HANDLES_H_