blob: 9c4ffb4f1a435102fcdfba472a95e7acf5c5e5a0 [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
Emily Bernier958fae72015-03-24 16:35:39 -040099enum WeaknessType {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100100 // Embedder gets a handle to the dying object.
101 FINALIZER_WEAK,
Ben Murdoch014dc512016-03-22 12:00:34 +0000102 // 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,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100108 PHANTOM_WEAK_2_INTERNAL_FIELDS,
109 // The handle is automatically reset by the garbage collector when
110 // the object is no longer reachable.
111 PHANTOM_WEAK_RESET_HANDLE
Emily Bernier958fae72015-03-24 16:35:39 -0400112};
113
Steve Block44f0eee2011-05-26 01:26:41 +0100114class GlobalHandles {
Steve Blocka7e24c12009-10-30 11:49:00 +0000115 public:
Ben Murdoch62ed6312017-06-06 11:06:27 +0100116 enum IterationMode {
117 HANDLE_PHANTOM_NODES_VISIT_OTHERS,
118 VISIT_OTHERS,
119 HANDLE_PHANTOM_NODES
120 };
121
Steve Block44f0eee2011-05-26 01:26:41 +0100122 ~GlobalHandles();
123
Steve Blocka7e24c12009-10-30 11:49:00 +0000124 // Creates a new global handle that is alive until Destroy is called.
Steve Block44f0eee2011-05-26 01:26:41 +0100125 Handle<Object> Create(Object* value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000126
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 // Copy a global handle
128 static Handle<Object> CopyGlobal(Object** location);
129
Steve Blocka7e24c12009-10-30 11:49:00 +0000130 // Destroy a global handle.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131 static void Destroy(Object** location);
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 Bernier958fae72015-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 Murdoch014dc512016-03-22 12:00:34 +0000143 WeakCallbackInfo<void>::Callback weak_callback,
144 v8::WeakCallbackType type);
Emily Bernier958fae72015-03-24 16:35:39 -0400145
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100146 static void MakeWeak(Object*** location_addr);
147
Steve Block44f0eee2011-05-26 01:26:41 +0100148 void RecordStats(HeapStats* stats);
Steve Blockd0582a62009-12-15 09:54:21 +0000149
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 // Returns the current number of weak handles.
151 int NumberOfWeakHandles();
152
Steve Blocka7e24c12009-10-30 11:49:00 +0000153 // Returns the current number of weak handles to global objects.
154 // These handles are also included in NumberOfWeakHandles().
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000155 int NumberOfGlobalObjectWeakHandles();
Steve Blocka7e24c12009-10-30 11:49:00 +0000156
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100157 // Returns the current number of handles to global objects.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 int global_handles_count() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100159 return number_of_global_handles_;
160 }
161
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100162 size_t NumberOfPhantomHandleResets() {
163 return number_of_phantom_handle_resets_;
164 }
165
166 void ResetNumberOfPhantomHandleResets() {
167 number_of_phantom_handle_resets_ = 0;
168 }
169
Steve Blocka7e24c12009-10-30 11:49:00 +0000170 // Clear the weakness of a global handle.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171 static void* ClearWeakness(Object** location);
Steve Blocka7e24c12009-10-30 11:49:00 +0000172
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100173 // Mark the reference to this object independent of any object group.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000174 static void MarkIndependent(Object** location);
175
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 static bool IsIndependent(Object** location);
Ben Murdoch257744e2011-11-30 15:57:28 +0000177
Steve Blocka7e24c12009-10-30 11:49:00 +0000178 // Tells whether global handle is near death.
179 static bool IsNearDeath(Object** location);
180
181 // Tells whether global handle is weak.
182 static bool IsWeak(Object** location);
183
John Reck59135872010-11-02 12:39:01 -0700184 // Process pending weak handles.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185 // Returns the number of freed nodes.
Ben Murdoch014dc512016-03-22 12:00:34 +0000186 int PostGarbageCollectionProcessing(
187 GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags);
Steve Blocka7e24c12009-10-30 11:49:00 +0000188
Steve Blockd0582a62009-12-15 09:54:21 +0000189 // Iterates over all strong handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100190 void IterateStrongRoots(ObjectVisitor* v);
Steve Blockd0582a62009-12-15 09:54:21 +0000191
Steve Blocka7e24c12009-10-30 11:49:00 +0000192 // Iterates over all handles.
Steve Block44f0eee2011-05-26 01:26:41 +0100193 void IterateAllRoots(ObjectVisitor* v);
194
195 // Iterates over all handles that have embedder-assigned class ID.
196 void IterateAllRootsWithClassIds(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000197
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000198 // Iterates over all handles in the new space that have embedder-assigned
199 // class ID.
200 void IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v);
201
Ben Murdoch014dc512016-03-22 12:00:34 +0000202 // Iterate over all handles in the new space that are weak, unmodified
203 // and have class IDs
204 void IterateWeakRootsInNewSpaceWithClassIds(ObjectVisitor* v);
205
Steve Blocka7e24c12009-10-30 11:49:00 +0000206 // Iterates over all weak roots in heap.
Steve Block44f0eee2011-05-26 01:26:41 +0100207 void IterateWeakRoots(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000208
Steve Blocka7e24c12009-10-30 11:49:00 +0000209 // Find all weak handles satisfying the callback predicate, mark
210 // them as pending.
Steve Block44f0eee2011-05-26 01:26:41 +0100211 void IdentifyWeakHandles(WeakSlotCallback f);
Steve Blocka7e24c12009-10-30 11:49:00 +0000212
Ben Murdoch014dc512016-03-22 12:00:34 +0000213 // NOTE: Five ...NewSpace... functions below are used during
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000214 // scavenge collections and iterate over sets of handles that are
215 // guaranteed to contain all handles holding new space objects (but
216 // may also include old space objects).
217
218 // Iterates over strong and dependent handles. See the node above.
219 void IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v);
220
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000221 // Finds weak independent or partially independent handles satisfying
222 // the callback predicate and marks them as pending. See the note above.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000223 void IdentifyNewSpaceWeakIndependentHandles(WeakSlotCallbackWithHeap f);
224
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225 // Iterates over weak independent or partially independent handles.
226 // See the note above.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000227 void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
Ben Murdoch257744e2011-11-30 15:57:28 +0000228
Ben Murdoch014dc512016-03-22 12:00:34 +0000229 // Finds weak independent or unmodified handles satisfying
230 // the callback predicate and marks them as pending. See the note above.
231 void MarkNewSpaceWeakUnmodifiedObjectsPending(
232 WeakSlotCallbackWithHeap is_unscavenged);
233
234 // Iterates over weak independent or unmodified handles.
235 // See the note above.
Ben Murdoch62ed6312017-06-06 11:06:27 +0100236 template <IterationMode mode>
Ben Murdoch014dc512016-03-22 12:00:34 +0000237 void IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v);
238
239 // Identify unmodified objects that are in weak state and marks them
240 // unmodified
241 void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
242
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243 // Iterate over objects in object groups that have at least one object
244 // which requires visiting. The callback has to return true if objects
245 // can be skipped and false otherwise.
246 bool IterateObjectGroups(ObjectVisitor* v, WeakSlotCallbackWithHeap can_skip);
247
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100248 // Print all objects in object groups
249 void PrintObjectGroups();
250
Steve Blocka7e24c12009-10-30 11:49:00 +0000251 // Add an object group.
Steve Block44f0eee2011-05-26 01:26:41 +0100252 // Should be only used in GC callback function before a collection.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000253 // All groups are destroyed after a garbage collection.
Steve Block44f0eee2011-05-26 01:26:41 +0100254 void AddObjectGroup(Object*** handles,
255 size_t length,
256 v8::RetainedObjectInfo* info);
257
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000258 // Associates handle with the object group represented by id.
Steve Block44f0eee2011-05-26 01:26:41 +0100259 // Should be only used in GC callback function before a collection.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260 // All groups are destroyed after a garbage collection.
261 void SetObjectGroupId(Object** handle, UniqueId id);
Steve Blocka7e24c12009-10-30 11:49:00 +0000262
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000263 // Set RetainedObjectInfo for an object group. Should not be called more than
264 // once for a group. Should not be called for a group which contains no
265 // handles.
266 void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info);
Steve Block44f0eee2011-05-26 01:26:41 +0100267
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000268 // Adds an implicit reference from a group to an object. Should be only used
269 // in GC callback function before a collection. All implicit references are
270 // destroyed after a mark-compact collection.
271 void SetReferenceFromGroup(UniqueId id, Object** child);
272
273 // Adds an implicit reference from a parent object to a child object. Should
274 // be only used in GC callback function before a collection. All implicit
275 // references are destroyed after a mark-compact collection.
276 void SetReference(HeapObject** parent, Object** child);
277
278 List<ObjectGroup*>* object_groups() {
279 ComputeObjectGroupsAndImplicitReferences();
280 return &object_groups_;
281 }
282
Steve Block44f0eee2011-05-26 01:26:41 +0100283 List<ImplicitRefGroup*>* implicit_ref_groups() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000284 ComputeObjectGroupsAndImplicitReferences();
Steve Block44f0eee2011-05-26 01:26:41 +0100285 return &implicit_ref_groups_;
286 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000287
288 // Remove bags, this should only happen after GC.
Steve Block44f0eee2011-05-26 01:26:41 +0100289 void RemoveObjectGroups();
290 void RemoveImplicitRefGroups();
Steve Blocka7e24c12009-10-30 11:49:00 +0000291
292 // Tear down the global handle structure.
Steve Block44f0eee2011-05-26 01:26:41 +0100293 void TearDown();
294
295 Isolate* isolate() { return isolate_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000296
297#ifdef DEBUG
Steve Block44f0eee2011-05-26 01:26:41 +0100298 void PrintStats();
299 void Print();
Ben Murdoch62ed6312017-06-06 11:06:27 +0100300#endif // DEBUG
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000301
Steve Blocka7e24c12009-10-30 11:49:00 +0000302 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100303 explicit GlobalHandles(Isolate* isolate);
304
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000305 // Migrates data from the internal representation (object_group_connections_,
306 // retainer_infos_ and implicit_ref_connections_) to the public and more
307 // efficient representation (object_groups_ and implicit_ref_groups_).
308 void ComputeObjectGroupsAndImplicitReferences();
309
310 // v8::internal::List is inefficient even for small number of elements, if we
311 // don't assign any initial capacity.
312 static const int kObjectGroupConnectionsCapacity = 20;
313
Ben Murdoch014dc512016-03-22 12:00:34 +0000314 class PendingPhantomCallback;
315
Emily Bernier958fae72015-03-24 16:35:39 -0400316 // Helpers for PostGarbageCollectionProcessing.
Ben Murdoch014dc512016-03-22 12:00:34 +0000317 static void InvokeSecondPassPhantomCallbacks(
318 List<PendingPhantomCallback>* callbacks, Isolate* isolate);
Emily Bernier958fae72015-03-24 16:35:39 -0400319 int PostScavengeProcessing(int initial_post_gc_processing_count);
320 int PostMarkSweepProcessing(int initial_post_gc_processing_count);
Ben Murdoch014dc512016-03-22 12:00:34 +0000321 int DispatchPendingPhantomCallbacks(bool synchronous_second_pass);
Emily Bernier958fae72015-03-24 16:35:39 -0400322 void UpdateListOfNewSpaceNodes();
323
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000324 // Internal node structures.
Steve Blocka7e24c12009-10-30 11:49:00 +0000325 class Node;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000326 class NodeBlock;
327 class NodeIterator;
Ben Murdoch014dc512016-03-22 12:00:34 +0000328 class PendingPhantomCallbacksSecondPassTask;
Steve Blocka7e24c12009-10-30 11:49:00 +0000329
Steve Block44f0eee2011-05-26 01:26:41 +0100330 Isolate* isolate_;
331
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100332 // Field always containing the number of handles to global objects.
333 int number_of_global_handles_;
334
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000335 // List of all allocated node blocks.
336 NodeBlock* first_block_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000337
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000338 // List of node blocks with used nodes.
339 NodeBlock* first_used_block_;
340
341 // Free list of nodes.
Steve Block44f0eee2011-05-26 01:26:41 +0100342 Node* first_free_;
Steve Blockd0582a62009-12-15 09:54:21 +0000343
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000344 // Contains all nodes holding new space objects. Note: when the list
345 // is accessed, some of the objects may have been promoted already.
346 List<Node*> new_space_nodes_;
Steve Block44f0eee2011-05-26 01:26:41 +0100347
Steve Block44f0eee2011-05-26 01:26:41 +0100348 int post_gc_processing_count_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000349
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100350 size_t number_of_phantom_handle_resets_;
351
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352 // Object groups and implicit references, public and more efficient
353 // representation.
Steve Block44f0eee2011-05-26 01:26:41 +0100354 List<ObjectGroup*> object_groups_;
355 List<ImplicitRefGroup*> implicit_ref_groups_;
356
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000357 // Object groups and implicit references, temporary representation while
358 // constructing the groups.
359 List<ObjectGroupConnection> object_group_connections_;
360 List<ObjectGroupRetainerInfo> retainer_infos_;
361 List<ObjectGroupConnection> implicit_ref_connections_;
362
Emily Bernier958fae72015-03-24 16:35:39 -0400363 List<PendingPhantomCallback> pending_phantom_callbacks_;
Emily Bernier958fae72015-03-24 16:35:39 -0400364
Steve Block44f0eee2011-05-26 01:26:41 +0100365 friend class Isolate;
366
367 DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
Steve Blocka7e24c12009-10-30 11:49:00 +0000368};
369
370
Emily Bernier958fae72015-03-24 16:35:39 -0400371class GlobalHandles::PendingPhantomCallback {
372 public:
Ben Murdoch014dc512016-03-22 12:00:34 +0000373 typedef v8::WeakCallbackInfo<void> Data;
374 PendingPhantomCallback(
375 Node* node, Data::Callback callback, void* parameter,
376 void* internal_fields[v8::kInternalFieldsInWeakCallback])
377 : node_(node), callback_(callback), parameter_(parameter) {
378 for (int i = 0; i < v8::kInternalFieldsInWeakCallback; ++i) {
379 internal_fields_[i] = internal_fields[i];
380 }
381 }
Emily Bernier958fae72015-03-24 16:35:39 -0400382
Ben Murdoch014dc512016-03-22 12:00:34 +0000383 void Invoke(Isolate* isolate);
Emily Bernier958fae72015-03-24 16:35:39 -0400384
385 Node* node() { return node_; }
Ben Murdoch014dc512016-03-22 12:00:34 +0000386 Data::Callback callback() { return callback_; }
Emily Bernier958fae72015-03-24 16:35:39 -0400387
388 private:
389 Node* node_;
Emily Bernier958fae72015-03-24 16:35:39 -0400390 Data::Callback callback_;
Ben Murdoch014dc512016-03-22 12:00:34 +0000391 void* parameter_;
392 void* internal_fields_[v8::kInternalFieldsInWeakCallback];
Emily Bernier958fae72015-03-24 16:35:39 -0400393};
394
395
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000396class EternalHandles {
397 public:
398 enum SingletonHandle {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000399 DATE_CACHE_VERSION,
400
401 NUMBER_OF_SINGLETON_HANDLES
402 };
403
404 EternalHandles();
405 ~EternalHandles();
406
407 int NumberOfHandles() { return size_; }
408
409 // Create an EternalHandle, overwriting the index.
410 void Create(Isolate* isolate, Object* object, int* index);
411
412 // Grab the handle for an existing EternalHandle.
413 inline Handle<Object> Get(int index) {
414 return Handle<Object>(GetLocation(index));
415 }
416
417 // Grab the handle for an existing SingletonHandle.
418 inline Handle<Object> GetSingleton(SingletonHandle singleton) {
419 DCHECK(Exists(singleton));
420 return Get(singleton_handles_[singleton]);
421 }
422
423 // Checks whether a SingletonHandle has been assigned.
424 inline bool Exists(SingletonHandle singleton) {
425 return singleton_handles_[singleton] != kInvalidIndex;
426 }
427
428 // Assign a SingletonHandle to an empty slot and returns the handle.
429 Handle<Object> CreateSingleton(Isolate* isolate,
430 Object* object,
431 SingletonHandle singleton) {
432 Create(isolate, object, &singleton_handles_[singleton]);
433 return Get(singleton_handles_[singleton]);
434 }
435
436 // Iterates over all handles.
437 void IterateAllRoots(ObjectVisitor* visitor);
438 // Iterates over all handles which might be in new space.
439 void IterateNewSpaceRoots(ObjectVisitor* visitor);
440 // Rebuilds new space list.
441 void PostGarbageCollectionProcessing(Heap* heap);
442
443 private:
444 static const int kInvalidIndex = -1;
445 static const int kShift = 8;
446 static const int kSize = 1 << kShift;
447 static const int kMask = 0xff;
448
449 // Gets the slot for an index
450 inline Object** GetLocation(int index) {
451 DCHECK(index >= 0 && index < size_);
452 return &blocks_[index >> kShift][index & kMask];
453 }
454
455 int size_;
456 List<Object**> blocks_;
457 List<int> new_space_indices_;
458 int singleton_handles_[NUMBER_OF_SINGLETON_HANDLES];
459
460 DISALLOW_COPY_AND_ASSIGN(EternalHandles);
461};
462
463
Ben Murdoch014dc512016-03-22 12:00:34 +0000464} // namespace internal
465} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000466
467#endif // V8_GLOBAL_HANDLES_H_