blob: ac8487b19fb6ee7b2127b9333e279f70e34e38f3 [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_GLOBAL_HANDLES_H_
6#define V8_GLOBAL_HANDLES_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "include/v8.h"
9#include "include/v8-profiler.h"
Ben Murdoch8b112d22011-06-08 16:22:53 +010010
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/handles.h"
12#include "src/list.h"
13#include "src/utils.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000014
15namespace v8 {
16namespace internal {
17
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018class HeapStats;
19class ObjectVisitor;
20
Steve Blocka7e24c12009-10-30 11:49:00 +000021// Structure for tracking global handles.
22// A single list keeps all the allocated global handles.
23// Destroyed handles stay in the list but is added to the free list.
24// At GC the destroyed global handles are removed from the free list
25// and deallocated.
26
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027// Data structures for tracking object groups and implicit references.
28
Steve Blocka7e24c12009-10-30 11:49:00 +000029// An object group is treated like a single JS object: if one of object in
30// the group is alive, all objects in the same group are considered alive.
31// An object group is used to simulate object relationship in a DOM tree.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032
33// An implicit references group consists of two parts: a parent object and a
34// list of children objects. If the parent is alive, all the children are alive
35// too.
36
37struct ObjectGroup {
38 explicit ObjectGroup(size_t length)
39 : info(NULL), length(length) {
40 DCHECK(length > 0);
41 objects = new Object**[length];
Ben Murdoch8b112d22011-06-08 16:22:53 +010042 }
Ben Murdoch8b112d22011-06-08 16:22:53 +010043 ~ObjectGroup();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044
45 v8::RetainedObjectInfo* info;
46 Object*** objects;
47 size_t length;
Steve Block44f0eee2011-05-26 01:26:41 +010048};
49
50
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051struct ImplicitRefGroup {
52 ImplicitRefGroup(HeapObject** parent, size_t length)
53 : parent(parent), length(length) {
54 DCHECK(length > 0);
55 children = new Object**[length];
Ben Murdoch8b112d22011-06-08 16:22:53 +010056 }
Ben Murdoch8b112d22011-06-08 16:22:53 +010057 ~ImplicitRefGroup();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058
59 HeapObject** parent;
60 Object*** children;
61 size_t length;
Steve Blocka7e24c12009-10-30 11:49:00 +000062};
63
64
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065// For internal bookkeeping.
66struct ObjectGroupConnection {
67 ObjectGroupConnection(UniqueId id, Object** object)
68 : id(id), object(object) {}
69
70 bool operator==(const ObjectGroupConnection& other) const {
71 return id == other.id;
72 }
73
74 bool operator<(const ObjectGroupConnection& other) const {
75 return id < other.id;
76 }
77
78 UniqueId id;
79 Object** object;
80};
81
82
83struct ObjectGroupRetainerInfo {
84 ObjectGroupRetainerInfo(UniqueId id, RetainedObjectInfo* info)
85 : id(id), info(info) {}
86
87 bool operator==(const ObjectGroupRetainerInfo& other) const {
88 return id == other.id;
89 }
90
91 bool operator<(const ObjectGroupRetainerInfo& other) const {
92 return id < other.id;
93 }
94
95 UniqueId id;
96 RetainedObjectInfo* info;
97};
98
Steve Block3ce2e202009-11-05 08:53:23 +000099
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400100enum WeaknessType {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 NORMAL_WEAK, // Embedder gets a handle to the dying object.
102 // In the following cases, the embedder gets the parameter they passed in
103 // earlier, and 0 or 2 first internal fields. Note that the internal
104 // fields must contain aligned non-V8 pointers. Getting pointers to V8
105 // objects through this interface would be GC unsafe so in that case the
106 // embedder gets a null pointer instead.
107 PHANTOM_WEAK,
108 PHANTOM_WEAK_2_INTERNAL_FIELDS
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400109};
110
111
Steve Block44f0eee2011-05-26 01:26:41 +0100112class GlobalHandles {
Steve Blocka7e24c12009-10-30 11:49:00 +0000113 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100114 ~GlobalHandles();
115
Steve Blocka7e24c12009-10-30 11:49:00 +0000116 // Creates a new global handle that is alive until Destroy is called.
Steve Block44f0eee2011-05-26 01:26:41 +0100117 Handle<Object> Create(Object* value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000118
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119 // Copy a global handle
120 static Handle<Object> CopyGlobal(Object** location);
121
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 // Destroy a global handle.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 static void Destroy(Object** location);
124
125 typedef WeakCallbackData<v8::Value, void>::Callback WeakCallback;
Steve Blocka7e24c12009-10-30 11:49:00 +0000126
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400127 // For a phantom weak reference, the callback does not have access to the
128 // dying object. Phantom weak references are preferred because they allow
129 // memory to be reclaimed in one GC cycle rather than two. However, for
130 // historical reasons the default is non-phantom.
131 enum PhantomState { Nonphantom, Phantom };
132
Steve Blocka7e24c12009-10-30 11:49:00 +0000133 // Make the global handle weak and set the callback parameter for the
134 // handle. When the garbage collector recognizes that only weak global
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400135 // handles point to an object the callback function is invoked (for each
136 // handle) with the handle and corresponding parameter as arguments. By
137 // default the handle still contains a pointer to the object that is being
138 // collected. For this reason the object is not collected until the next
139 // GC. For a phantom weak handle the handle is cleared (set to a Smi)
140 // before the callback is invoked, but the handle can still be identified
141 // in the callback by using the location() of the handle.
142 static void MakeWeak(Object** location, void* parameter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 WeakCallback weak_callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000144
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400145 // It would be nice to template this one, but it's really hard to get
146 // the template instantiator to work right if you do.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147 static void MakeWeak(Object** location, void* parameter,
148 WeakCallbackInfo<void>::Callback weak_callback,
149 v8::WeakCallbackType type);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400150
Steve Block44f0eee2011-05-26 01:26:41 +0100151 void RecordStats(HeapStats* stats);
Steve Blockd0582a62009-12-15 09:54:21 +0000152
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153 // Returns the current number of weak handles.
154 int NumberOfWeakHandles();
155
Steve Blocka7e24c12009-10-30 11:49:00 +0000156 // Returns the current number of weak handles to global objects.
157 // These handles are also included in NumberOfWeakHandles().
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 int NumberOfGlobalObjectWeakHandles();
Steve Blocka7e24c12009-10-30 11:49:00 +0000159
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100160 // Returns the current number of handles to global objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000161 int global_handles_count() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100162 return number_of_global_handles_;
163 }
164
Steve Blocka7e24c12009-10-30 11:49:00 +0000165 // Clear the weakness of a global handle.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000166 static void* ClearWeakness(Object** location);
Steve Blocka7e24c12009-10-30 11:49:00 +0000167
Ben Murdochda12d292016-06-02 14:46:10 +0100168 // Mark the reference to this object independent of any object group.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 static void MarkIndependent(Object** location);
170
171 // Mark the reference to this object externaly unreachable.
172 static void MarkPartiallyDependent(Object** location);
173
174 static bool IsIndependent(Object** location);
Ben Murdoch257744e2011-11-30 15:57:28 +0000175
Steve Blocka7e24c12009-10-30 11:49:00 +0000176 // Tells whether global handle is near death.
177 static bool IsNearDeath(Object** location);
178
179 // Tells whether global handle is weak.
180 static bool IsWeak(Object** location);
181
John Reck59135872010-11-02 12:39:01 -0700182 // Process pending weak handles.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183 // Returns the number of freed nodes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000184 int PostGarbageCollectionProcessing(
185 GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags);
Steve Blocka7e24c12009-10-30 11:49:00 +0000186
Steve Blockd0582a62009-12-15 09:54:21 +0000187 // Iterates over all strong handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100188 void IterateStrongRoots(ObjectVisitor* v);
Steve Blockd0582a62009-12-15 09:54:21 +0000189
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 // Iterates over all handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100191 void IterateAllRoots(ObjectVisitor* v);
192
193 // Iterates over all handles that have embedder-assigned class ID.
194 void IterateAllRootsWithClassIds(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000195
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000196 // Iterates over all handles in the new space that have embedder-assigned
197 // class ID.
198 void IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v);
199
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000200 // Iterate over all handles in the new space that are weak, unmodified
201 // and have class IDs
202 void IterateWeakRootsInNewSpaceWithClassIds(ObjectVisitor* v);
203
Steve Blocka7e24c12009-10-30 11:49:00 +0000204 // Iterates over all weak roots in heap.
Steve Block44f0eee2011-05-26 01:26:41 +0100205 void IterateWeakRoots(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000206
Steve Blocka7e24c12009-10-30 11:49:00 +0000207 // Find all weak handles satisfying the callback predicate, mark
208 // them as pending.
Steve Block44f0eee2011-05-26 01:26:41 +0100209 void IdentifyWeakHandles(WeakSlotCallback f);
Steve Blocka7e24c12009-10-30 11:49:00 +0000210
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211 // NOTE: Five ...NewSpace... functions below are used during
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000212 // scavenge collections and iterate over sets of handles that are
213 // guaranteed to contain all handles holding new space objects (but
214 // may also include old space objects).
215
216 // Iterates over strong and dependent handles. See the node above.
217 void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v);
218
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000219 // Finds weak independent or partially independent handles satisfying
220 // the callback predicate and marks them as pending. See the note above.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000221 void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
222
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223 // Iterates over weak independent or partially independent handles.
224 // See the note above.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000225 void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
Ben Murdoch257744e2011-11-30 15:57:28 +0000226
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 // Finds weak independent or unmodified handles satisfying
228 // the callback predicate and marks them as pending. See the note above.
229 void MarkNewSpaceWeakUnmodifiedObjectsPending(
230 WeakSlotCallbackWithHeap is_unscavenged);
231
232 // Iterates over weak independent or unmodified handles.
233 // See the note above.
234 void IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v);
235
236 // Identify unmodified objects that are in weak state and marks them
237 // unmodified
238 void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
239
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240 // Iterate over objects in object groups that have at least one object
241 // which requires visiting. The callback has to return true if objects
242 // can be skipped and false otherwise.
243 bool IterateObjectGroups(ObjectVisitor* v, WeakSlotCallbackWithHeap can_skip);
244
Ben Murdochda12d292016-06-02 14:46:10 +0100245 // Print all objects in object groups
246 void PrintObjectGroups();
247
Steve Blocka7e24c12009-10-30 11:49:00 +0000248 // Add an object group.
Steve Block44f0eee2011-05-26 01:26:41 +0100249 // Should be only used in GC callback function before a collection.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250 // All groups are destroyed after a garbage collection.
Steve Block44f0eee2011-05-26 01:26:41 +0100251 void AddObjectGroup(Object*** handles,
252 size_t length,
253 v8::RetainedObjectInfo* info);
254
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000255 // Associates handle with the object group represented by id.
Steve Block44f0eee2011-05-26 01:26:41 +0100256 // Should be only used in GC callback function before a collection.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257 // All groups are destroyed after a garbage collection.
258 void SetObjectGroupId(Object** handle, UniqueId id);
Steve Blocka7e24c12009-10-30 11:49:00 +0000259
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260 // Set RetainedObjectInfo for an object group. Should not be called more than
261 // once for a group. Should not be called for a group which contains no
262 // handles.
263 void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info);
Steve Block44f0eee2011-05-26 01:26:41 +0100264
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265 // Adds an implicit reference from a group to an object. Should be only used
266 // in GC callback function before a collection. All implicit references are
267 // destroyed after a mark-compact collection.
268 void SetReferenceFromGroup(UniqueId id, Object** child);
269
270 // Adds an implicit reference from a parent object to a child object. Should
271 // be only used in GC callback function before a collection. All implicit
272 // references are destroyed after a mark-compact collection.
273 void SetReference(HeapObject** parent, Object** child);
274
275 List<ObjectGroup*>* object_groups() {
276 ComputeObjectGroupsAndImplicitReferences();
277 return &object_groups_;
278 }
279
Steve Block44f0eee2011-05-26 01:26:41 +0100280 List<ImplicitRefGroup*>* implicit_ref_groups() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000281 ComputeObjectGroupsAndImplicitReferences();
Steve Block44f0eee2011-05-26 01:26:41 +0100282 return &implicit_ref_groups_;
283 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000284
285 // Remove bags, this should only happen after GC.
Steve Block44f0eee2011-05-26 01:26:41 +0100286 void RemoveObjectGroups();
287 void RemoveImplicitRefGroups();
Steve Blocka7e24c12009-10-30 11:49:00 +0000288
289 // Tear down the global handle structure.
Steve Block44f0eee2011-05-26 01:26:41 +0100290 void TearDown();
291
292 Isolate* isolate() { return isolate_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000293
294#ifdef DEBUG
Steve Block44f0eee2011-05-26 01:26:41 +0100295 void PrintStats();
296 void Print();
Steve Blocka7e24c12009-10-30 11:49:00 +0000297#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000298
Steve Blocka7e24c12009-10-30 11:49:00 +0000299 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100300 explicit GlobalHandles(Isolate* isolate);
301
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000302 // Migrates data from the internal representation (object_group_connections_,
303 // retainer_infos_ and implicit_ref_connections_) to the public and more
304 // efficient representation (object_groups_ and implicit_ref_groups_).
305 void ComputeObjectGroupsAndImplicitReferences();
306
307 // v8::internal::List is inefficient even for small number of elements, if we
308 // don't assign any initial capacity.
309 static const int kObjectGroupConnectionsCapacity = 20;
310
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000311 class PendingPhantomCallback;
312
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400313 // Helpers for PostGarbageCollectionProcessing.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000314 static void InvokeSecondPassPhantomCallbacks(
315 List<PendingPhantomCallback>* callbacks, Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400316 int PostScavengeProcessing(int initial_post_gc_processing_count);
317 int PostMarkSweepProcessing(int initial_post_gc_processing_count);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000318 int DispatchPendingPhantomCallbacks(bool synchronous_second_pass);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400319 void UpdateListOfNewSpaceNodes();
320
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000321 // Internal node structures.
Steve Blocka7e24c12009-10-30 11:49:00 +0000322 class Node;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000323 class NodeBlock;
324 class NodeIterator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000325 class PendingPhantomCallbacksSecondPassTask;
Steve Blocka7e24c12009-10-30 11:49:00 +0000326
Steve Block44f0eee2011-05-26 01:26:41 +0100327 Isolate* isolate_;
328
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100329 // Field always containing the number of handles to global objects.
330 int number_of_global_handles_;
331
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000332 // List of all allocated node blocks.
333 NodeBlock* first_block_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000334
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000335 // List of node blocks with used nodes.
336 NodeBlock* first_used_block_;
337
338 // Free list of nodes.
Steve Block44f0eee2011-05-26 01:26:41 +0100339 Node* first_free_;
Steve Blockd0582a62009-12-15 09:54:21 +0000340
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000341 // Contains all nodes holding new space objects. Note: when the list
342 // is accessed, some of the objects may have been promoted already.
343 List<Node*> new_space_nodes_;
Steve Block44f0eee2011-05-26 01:26:41 +0100344
Steve Block44f0eee2011-05-26 01:26:41 +0100345 int post_gc_processing_count_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000346
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000347 // Object groups and implicit references, public and more efficient
348 // representation.
Steve Block44f0eee2011-05-26 01:26:41 +0100349 List<ObjectGroup*> object_groups_;
350 List<ImplicitRefGroup*> implicit_ref_groups_;
351
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352 // Object groups and implicit references, temporary representation while
353 // constructing the groups.
354 List<ObjectGroupConnection> object_group_connections_;
355 List<ObjectGroupRetainerInfo> retainer_infos_;
356 List<ObjectGroupConnection> implicit_ref_connections_;
357
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400358 List<PendingPhantomCallback> pending_phantom_callbacks_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400359
Steve Block44f0eee2011-05-26 01:26:41 +0100360 friend class Isolate;
361
362 DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
Steve Blocka7e24c12009-10-30 11:49:00 +0000363};
364
365
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400366class GlobalHandles::PendingPhantomCallback {
367 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368 typedef v8::WeakCallbackInfo<void> Data;
369 PendingPhantomCallback(
370 Node* node, Data::Callback callback, void* parameter,
371 void* internal_fields[v8::kInternalFieldsInWeakCallback])
372 : node_(node), callback_(callback), parameter_(parameter) {
373 for (int i = 0; i < v8::kInternalFieldsInWeakCallback; ++i) {
374 internal_fields_[i] = internal_fields[i];
375 }
376 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400377
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000378 void Invoke(Isolate* isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400379
380 Node* node() { return node_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000381 Data::Callback callback() { return callback_; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400382
383 private:
384 Node* node_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400385 Data::Callback callback_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000386 void* parameter_;
387 void* internal_fields_[v8::kInternalFieldsInWeakCallback];
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400388};
389
390
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391class EternalHandles {
392 public:
393 enum SingletonHandle {
394 I18N_TEMPLATE_ONE,
395 I18N_TEMPLATE_TWO,
396 DATE_CACHE_VERSION,
397
398 NUMBER_OF_SINGLETON_HANDLES
399 };
400
401 EternalHandles();
402 ~EternalHandles();
403
404 int NumberOfHandles() { return size_; }
405
406 // Create an EternalHandle, overwriting the index.
407 void Create(Isolate* isolate, Object* object, int* index);
408
409 // Grab the handle for an existing EternalHandle.
410 inline Handle<Object> Get(int index) {
411 return Handle<Object>(GetLocation(index));
412 }
413
414 // Grab the handle for an existing SingletonHandle.
415 inline Handle<Object> GetSingleton(SingletonHandle singleton) {
416 DCHECK(Exists(singleton));
417 return Get(singleton_handles_[singleton]);
418 }
419
420 // Checks whether a SingletonHandle has been assigned.
421 inline bool Exists(SingletonHandle singleton) {
422 return singleton_handles_[singleton] != kInvalidIndex;
423 }
424
425 // Assign a SingletonHandle to an empty slot and returns the handle.
426 Handle<Object> CreateSingleton(Isolate* isolate,
427 Object* object,
428 SingletonHandle singleton) {
429 Create(isolate, object, &singleton_handles_[singleton]);
430 return Get(singleton_handles_[singleton]);
431 }
432
433 // Iterates over all handles.
434 void IterateAllRoots(ObjectVisitor* visitor);
435 // Iterates over all handles which might be in new space.
436 void IterateNewSpaceRoots(ObjectVisitor* visitor);
437 // Rebuilds new space list.
438 void PostGarbageCollectionProcessing(Heap* heap);
439
440 private:
441 static const int kInvalidIndex = -1;
442 static const int kShift = 8;
443 static const int kSize = 1 << kShift;
444 static const int kMask = 0xff;
445
446 // Gets the slot for an index
447 inline Object** GetLocation(int index) {
448 DCHECK(index >= 0 && index < size_);
449 return &blocks_[index >> kShift][index & kMask];
450 }
451
452 int size_;
453 List<Object**> blocks_;
454 List<int> new_space_indices_;
455 int singleton_handles_[NUMBER_OF_SINGLETON_HANDLES];
456
457 DISALLOW_COPY_AND_ASSIGN(EternalHandles);
458};
459
460
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000461} // namespace internal
462} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000463
464#endif // V8_GLOBAL_HANDLES_H_