[V8] Introduce a QML compilation mode
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / global-handles.h
1 // Copyright 2011 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 "../include/v8-profiler.h"
32
33 #include "list.h"
34
35 namespace v8 {
36 namespace 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
44 // 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.
47 class ObjectGroup {
48  public:
49   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   }
60
61   void Dispose() {
62     if (info_ != NULL) info_->Dispose();
63     free(this);
64   }
65
66   size_t length_;
67   v8::RetainedObjectInfo* info_;
68   Object** objects_[1];  // Variable sized array.
69
70  private:
71   void* operator new(size_t size);
72   void operator delete(void* p);
73   ~ObjectGroup();
74   DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectGroup);
75 };
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.
81 class ImplicitRefGroup {
82  public:
83   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   }
94
95   void Dispose() {
96     free(this);
97   }
98
99   HeapObject** parent_;
100   size_t length_;
101   Object** children_[1];  // Variable sized array.
102
103  private:
104   void* operator new(size_t size);
105   void operator delete(void* p);
106   ~ImplicitRefGroup();
107   DISALLOW_IMPLICIT_CONSTRUCTORS(ImplicitRefGroup);
108 };
109
110
111 typedef void (*WeakReferenceGuest)(Object* object, void* parameter);
112
113 class GlobalHandles {
114  public:
115   ~GlobalHandles();
116
117   // Creates a new global handle that is alive until Destroy is called.
118   Handle<Object> Create(Object* value);
119
120   // Destroy a global handle.
121   void Destroy(Object** location);
122
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.
129   void MakeWeak(Object** location,
130                 void* parameter,
131                 WeakReferenceCallback callback);
132
133   static void SetWrapperClassId(Object** location, uint16_t class_id);
134
135   // Returns the current number of weak handles.
136   int NumberOfWeakHandles() { return number_of_weak_handles_; }
137
138   void RecordStats(HeapStats* stats);
139
140   // Returns the current number of weak handles to global objects.
141   // These handles are also included in NumberOfWeakHandles().
142   int NumberOfGlobalObjectWeakHandles() {
143     return number_of_global_object_weak_handles_;
144   }
145
146   // Returns the current number of handles to global objects.
147   int NumberOfGlobalHandles() {
148     return number_of_global_handles_;
149   }
150
151   // Clear the weakness of a global handle.
152   void ClearWeakness(Object** location);
153
154   // Clear the weakness of a global handle.
155   void MarkIndependent(Object** location);
156
157   // 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
163   // Process pending weak handles.
164   // Returns true if next major GC is likely to collect more garbage.
165   bool PostGarbageCollectionProcessing(GarbageCollector collector);
166
167   // Iterates over all strong handles.
168   void IterateStrongRoots(ObjectVisitor* v);
169
170   // Iterates over all handles.
171   void IterateAllRoots(ObjectVisitor* v);
172
173   // Iterates over all handles that have embedder-assigned class ID.
174   void IterateAllRootsWithClassIds(ObjectVisitor* v);
175
176   // Iterates over all weak roots in heap.
177   void IterateWeakRoots(ObjectVisitor* v);
178
179   // Iterates over weak roots that are bound to a given callback.
180   void IterateWeakRoots(WeakReferenceGuest f,
181                         WeakReferenceCallback callback);
182
183   // Find all weak handles satisfying the callback predicate, mark
184   // them as pending.
185   void IdentifyWeakHandles(WeakSlotCallback f);
186
187   // 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);
201
202   // Add an object group.
203   // Should be only used in GC callback function before a collection.
204   // All groups are destroyed after a mark-compact collection.
205   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.
212   void AddImplicitReferences(HeapObject** parent,
213                              Object*** children,
214                              size_t length);
215
216   // Returns the object groups.
217   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   }
223
224   // Remove bags, this should only happen after GC.
225   void RemoveObjectGroups();
226   void RemoveImplicitRefGroups();
227
228   // Tear down the global handle structure.
229   void TearDown();
230
231   Isolate* isolate() { return isolate_; }
232
233 #ifdef DEBUG
234   void PrintStats();
235   void Print();
236 #endif
237
238  private:
239   explicit GlobalHandles(Isolate* isolate);
240
241   // Internal node structures.
242   class Node;
243   class NodeBlock;
244   class NodeIterator;
245
246   Isolate* isolate_;
247
248   // Field always containing the number of weak and near-death handles.
249   int number_of_weak_handles_;
250
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_.
254   int number_of_global_object_weak_handles_;
255
256   // Field always containing the number of handles to global objects.
257   int number_of_global_handles_;
258
259   // List of all allocated node blocks.
260   NodeBlock* first_block_;
261
262   // List of node blocks with used nodes.
263   NodeBlock* first_used_block_;
264
265   // Free list of nodes.
266   Node* first_free_;
267
268   // 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_;
271
272   int post_gc_processing_count_;
273
274   List<ObjectGroup*> object_groups_;
275   List<ImplicitRefGroup*> implicit_ref_groups_;
276
277   friend class Isolate;
278
279   DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
280 };
281
282
283 } }  // namespace v8::internal
284
285 #endif  // V8_GLOBAL_HANDLES_H_