V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
global-handles.h
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_GLOBAL_HANDLES_H_
6 #define V8_GLOBAL_HANDLES_H_
7 
8 #include <type_traits>
9 #include <vector>
10 
11 #include "include/v8.h"
12 #include "include/v8-profiler.h"
13 
14 #include "src/handles.h"
15 #include "src/utils.h"
16 
17 namespace v8 {
18 namespace internal {
19 
20 class HeapStats;
21 class RootVisitor;
22 
23 // Structure for tracking global handles.
24 // A single list keeps all the allocated global handles.
25 // Destroyed handles stay in the list but is added to the free list.
26 // At GC the destroyed global handles are removed from the free list
27 // and deallocated.
28 
29 enum WeaknessType {
30  // Embedder gets a handle to the dying object.
31  FINALIZER_WEAK,
32  // In the following cases, the embedder gets the parameter they passed in
33  // earlier, and 0 or 2 first embedder fields. Note that the internal
34  // fields must contain aligned non-V8 pointers. Getting pointers to V8
35  // objects through this interface would be GC unsafe so in that case the
36  // embedder gets a null pointer instead.
37  PHANTOM_WEAK,
38  PHANTOM_WEAK_2_EMBEDDER_FIELDS,
39  // The handle is automatically reset by the garbage collector when
40  // the object is no longer reachable.
41  PHANTOM_WEAK_RESET_HANDLE
42 };
43 
45  public:
46  ~GlobalHandles();
47 
48  // Creates a new global handle that is alive until Destroy is called.
49  Handle<Object> Create(Object* value);
50  // TODO(jkummerow): This and the other Object*/Address overloads below are
51  // temporary. Eventually the respective Object* version should go away.
52  Handle<Object> Create(Address value);
53 
54  template <typename T>
55  Handle<T> Create(T* value) {
56  static_assert(std::is_base_of<Object, T>::value, "static type violation");
57  // The compiler should only pick this method if T is not Object.
58  static_assert(!std::is_same<Object, T>::value, "compiler error");
59  return Handle<T>::cast(Create(static_cast<Object*>(value)));
60  }
61 
62  // Copy a global handle
63  static Handle<Object> CopyGlobal(Address* location);
64 
65  // Destroy a global handle.
66  static void Destroy(Address* location);
67 
68  // Make the global handle weak and set the callback parameter for the
69  // handle. When the garbage collector recognizes that only weak global
70  // handles point to an object the callback function is invoked (for each
71  // handle) with the handle and corresponding parameter as arguments. By
72  // default the handle still contains a pointer to the object that is being
73  // collected. For this reason the object is not collected until the next
74  // GC. For a phantom weak handle the handle is cleared (set to a Smi)
75  // before the callback is invoked, but the handle can still be identified
76  // in the callback by using the location() of the handle.
77  static void MakeWeak(Address* location, void* parameter,
79  v8::WeakCallbackType type);
80 
81  static void MakeWeak(Address** location_addr);
82 
83  static void AnnotateStrongRetainer(Address* location, const char* label);
84 
85  void RecordStats(HeapStats* stats);
86 
87  // Returns the current number of handles to global objects.
88  int global_handles_count() const {
89  return number_of_global_handles_;
90  }
91 
92  size_t NumberOfPhantomHandleResets() {
93  return number_of_phantom_handle_resets_;
94  }
95 
96  void ResetNumberOfPhantomHandleResets() {
97  number_of_phantom_handle_resets_ = 0;
98  }
99 
100  size_t NumberOfNewSpaceNodes() { return new_space_nodes_.size(); }
101 
102  // Clear the weakness of a global handle.
103  static void* ClearWeakness(Address* location);
104 
105  // Tells whether global handle is near death.
106  static bool IsNearDeath(Address* location);
107 
108  // Tells whether global handle is weak.
109  static bool IsWeak(Address* location);
110 
111  int InvokeFirstPassWeakCallbacks();
112 
113  // Process pending weak handles.
114  // Returns the number of freed nodes.
115  int PostGarbageCollectionProcessing(
116  GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags);
117 
118  void IterateStrongRoots(RootVisitor* v);
119 
120  void IterateWeakRoots(RootVisitor* v);
121 
122  void IterateAllRoots(RootVisitor* v);
123 
124  void IterateAllNewSpaceRoots(RootVisitor* v);
125  void IterateNewSpaceRoots(RootVisitor* v, size_t start, size_t end);
126 
127  // Iterates over all handles that have embedder-assigned class ID.
128  void IterateAllRootsWithClassIds(v8::PersistentHandleVisitor* v);
129 
130  // Iterates over all handles in the new space that have embedder-assigned
131  // class ID.
132  void IterateAllRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v);
133 
134  // Iterate over all handles in the new space that are weak, unmodified
135  // and have class IDs
136  void IterateWeakRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v);
137 
138  // Iterates over weak roots on the heap.
139  void IterateWeakRootsForFinalizers(RootVisitor* v);
140  void IterateWeakRootsForPhantomHandles(
141  WeakSlotCallbackWithHeap should_reset_handle);
142 
143  // Marks all handles that should be finalized based on the predicate
144  // |should_reset_handle| as pending.
145  void IdentifyWeakHandles(WeakSlotCallbackWithHeap should_reset_handle);
146 
147  // NOTE: Five ...NewSpace... functions below are used during
148  // scavenge collections and iterate over sets of handles that are
149  // guaranteed to contain all handles holding new space objects (but
150  // may also include old space objects).
151 
152  // Iterates over strong and dependent handles. See the note above.
153  void IterateNewSpaceStrongAndDependentRoots(RootVisitor* v);
154 
155  // Iterates over strong and dependent handles. See the note above.
156  // Also marks unmodified nodes in the same iteration.
157  void IterateNewSpaceStrongAndDependentRootsAndIdentifyUnmodified(
158  RootVisitor* v, size_t start, size_t end);
159 
160  // Marks weak unmodified handles satisfying |is_dead| as pending.
161  void MarkNewSpaceWeakUnmodifiedObjectsPending(
162  WeakSlotCallbackWithHeap is_dead);
163 
164  // Iterates over weak independent or unmodified handles.
165  // See the note above.
166  void IterateNewSpaceWeakUnmodifiedRootsForFinalizers(RootVisitor* v);
167  void IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles(
168  RootVisitor* v, WeakSlotCallbackWithHeap should_reset_handle);
169 
170  // Identify unmodified objects that are in weak state and marks them
171  // unmodified
172  void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
173 
174  // Tear down the global handle structure.
175  void TearDown();
176 
177  Isolate* isolate() { return isolate_; }
178 
179 #ifdef DEBUG
180  void PrintStats();
181  void Print();
182 #endif // DEBUG
183 
184  void InvokeSecondPassPhantomCallbacks();
185 
186  private:
187  // Internal node structures.
188  class Node;
189  class NodeBlock;
190  class NodeIterator;
192 
193  explicit GlobalHandles(Isolate* isolate);
194 
195  void InvokeSecondPassPhantomCallbacksFromTask();
196  int PostScavengeProcessing(int initial_post_gc_processing_count);
197  int PostMarkSweepProcessing(int initial_post_gc_processing_count);
198  void InvokeOrScheduleSecondPassPhantomCallbacks(bool synchronous_second_pass);
199  void UpdateListOfNewSpaceNodes();
200  void ApplyPersistentHandleVisitor(v8::PersistentHandleVisitor* visitor,
201  Node* node);
202 
203  Isolate* isolate_;
204 
205  // List of all allocated node blocks.
206  NodeBlock* first_block_;
207 
208  // List of node blocks with used nodes.
209  NodeBlock* first_used_block_;
210 
211  // Free list of nodes.
212  Node* first_free_;
213 
214  // Contains all nodes holding new space objects. Note: when the list
215  // is accessed, some of the objects may have been promoted already.
216  std::vector<Node*> new_space_nodes_;
217 
218  // Field always containing the number of handles to global objects.
219  int number_of_global_handles_;
220 
221  int post_gc_processing_count_;
222 
223  size_t number_of_phantom_handle_resets_;
224 
225  std::vector<PendingPhantomCallback> pending_phantom_callbacks_;
226  std::vector<PendingPhantomCallback> second_pass_callbacks_;
227  bool second_pass_callbacks_task_posted_ = false;
228 
229  friend class Isolate;
230 
231  DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
232 };
233 
234 
236  public:
239  Node* node, Data::Callback callback, void* parameter,
240  void* embedder_fields[v8::kEmbedderFieldsInWeakCallback])
241  : node_(node), callback_(callback), parameter_(parameter) {
242  for (int i = 0; i < v8::kEmbedderFieldsInWeakCallback; ++i) {
243  embedder_fields_[i] = embedder_fields[i];
244  }
245  }
246 
247  void Invoke(Isolate* isolate);
248 
249  Node* node() { return node_; }
250  Data::Callback callback() { return callback_; }
251 
252  private:
253  Node* node_;
254  Data::Callback callback_;
255  void* parameter_;
256  void* embedder_fields_[v8::kEmbedderFieldsInWeakCallback];
257 };
258 
259 
261  public:
262  EternalHandles();
263  ~EternalHandles();
264 
265  int NumberOfHandles() { return size_; }
266 
267  // Create an EternalHandle, overwriting the index.
268  void Create(Isolate* isolate, Object* object, int* index);
269 
270  // Grab the handle for an existing EternalHandle.
271  inline Handle<Object> Get(int index) {
272  return Handle<Object>(GetLocation(index));
273  }
274 
275  // Iterates over all handles.
276  void IterateAllRoots(RootVisitor* visitor);
277  // Iterates over all handles which might be in new space.
278  void IterateNewSpaceRoots(RootVisitor* visitor);
279  // Rebuilds new space list.
280  void PostGarbageCollectionProcessing();
281 
282  private:
283  static const int kInvalidIndex = -1;
284  static const int kShift = 8;
285  static const int kSize = 1 << kShift;
286  static const int kMask = 0xff;
287 
288  // Gets the slot for an index. This returns an Address* rather than an
289  // ObjectSlot in order to avoid #including slots.h in this header file.
290  inline Address* GetLocation(int index) {
291  DCHECK(index >= 0 && index < size_);
292  return &blocks_[index >> kShift][index & kMask];
293  }
294 
295  int size_;
296  std::vector<Address*> blocks_;
297  std::vector<int> new_space_indices_;
298 
299  DISALLOW_COPY_AND_ASSIGN(EternalHandles);
300 };
301 
302 
303 } // namespace internal
304 } // namespace v8
305 
306 #endif // V8_GLOBAL_HANDLES_H_
Definition: libplatform.h:13