v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
persistent-node.h
Go to the documentation of this file.
1// Copyright 2020 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 INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
6#define INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
7
8#include <array>
9#include <memory>
10#include <vector>
11
13#include "cppgc/trace-trait.h"
14#include "v8config.h" // NOLINT(build/include_directory)
15
16namespace cppgc {
17namespace internal {
18
19class CrossThreadPersistentRegion;
20class FatalOutOfMemoryHandler;
21class HeapBase;
22class RootVisitor;
23
24// PersistentNode represents a variant of two states:
25// 1) traceable node with a back pointer to the Persistent object;
26// 2) freelist entry.
27class PersistentNode final {
28 public:
29 PersistentNode() = default;
30
33
35 CPPGC_DCHECK(trace);
36 owner_ = owner;
37 trace_ = trace;
38 }
39
41 next_ = next;
42 trace_ = nullptr;
43 }
44
45 void UpdateOwner(void* owner) {
47 owner_ = owner;
48 }
49
52 return next_;
53 }
54
55 void Trace(RootVisitor& root_visitor) const {
57 trace_(root_visitor, owner_);
58 }
59
60 bool IsUsed() const { return trace_; }
61
62 void* owner() const {
64 return owner_;
65 }
66
67 private:
68 // PersistentNode acts as a designated union:
69 // If trace_ != nullptr, owner_ points to the corresponding Persistent handle.
70 // Otherwise, next_ points to the next freed PersistentNode.
71 union {
72 void* owner_ = nullptr;
74 };
76};
77
79 using PersistentNodeSlots = std::array<PersistentNode, 256u>;
80
81 public:
82 // Clears Persistent fields to avoid stale pointers after heap teardown.
84
87
88 void Iterate(RootVisitor&);
89
90 size_t NodesInUse() const;
91
92 void ClearAllUsedNodes();
93
94 protected:
95 explicit PersistentRegionBase(const FatalOutOfMemoryHandler& oom_handler);
96
98 TraceRootCallback trace) {
99 PersistentNode* node = nullptr;
100 if (V8_LIKELY(free_list_head_)) {
101 node = free_list_head_;
102 free_list_head_ = free_list_head_->FreeListNext();
103 CPPGC_DCHECK(!node->IsUsed());
104 node->InitializeAsUsedNode(owner, trace);
105 nodes_in_use_++;
106 }
107 return node;
108 }
109
111 CPPGC_DCHECK(node);
112 CPPGC_DCHECK(node->IsUsed());
113 node->InitializeAsFreeNode(free_list_head_);
114 free_list_head_ = node;
115 CPPGC_DCHECK(nodes_in_use_ > 0);
116 nodes_in_use_--;
117 }
118
119 PersistentNode* RefillFreeListAndAllocateNode(void* owner,
120 TraceRootCallback trace);
121
122 private:
123 template <typename PersistentBaseClass>
124 void ClearAllUsedNodes();
125
126 void RefillFreeList();
127
128 std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_;
129 PersistentNode* free_list_head_ = nullptr;
130 size_t nodes_in_use_ = 0;
132
134};
135
136// Variant of PersistentRegionBase that checks whether the allocation and
137// freeing happens only on the thread that created the heap.
139 public:
141 const FatalOutOfMemoryHandler& oom_handler)
142 : PersistentRegionBase(oom_handler), heap_(heap) {
143 CPPGC_DCHECK(IsCreationThread());
144 }
145 // Clears Persistent fields to avoid stale pointers after heap teardown.
146 ~PersistentRegion() = default;
147
150
152 CPPGC_DCHECK(IsCreationThread());
153 auto* node = TryAllocateNodeFromFreeList(owner, trace);
154 if (V8_LIKELY(node)) return node;
155
156 // Slow path allocation allows for checking thread correspondence.
157 CPPGC_CHECK(IsCreationThread());
158 return RefillFreeListAndAllocateNode(owner, trace);
159 }
160
162 CPPGC_DCHECK(IsCreationThread());
163 PersistentRegionBase::FreeNode(node);
164 }
165
166 private:
167 bool IsCreationThread();
168
170};
171
172// CrossThreadPersistent uses PersistentRegionBase but protects it using this
173// lock when needed.
175 public:
178
179 static void AssertLocked();
180};
181
182// Variant of PersistentRegionBase that checks whether the PersistentRegionLock
183// is locked.
185 : protected PersistentRegionBase {
186 public:
188 // Clears Persistent fields to avoid stale pointers after heap teardown.
190
193 delete;
194
196 PersistentRegionLock::AssertLocked();
197 auto* node = TryAllocateNodeFromFreeList(owner, trace);
198 if (V8_LIKELY(node)) return node;
199
200 return RefillFreeListAndAllocateNode(owner, trace);
201 }
202
204 PersistentRegionLock::AssertLocked();
205 PersistentRegionBase::FreeNode(node);
206 }
207
208 void Iterate(RootVisitor&);
209
210 size_t NodesInUse() const;
211
212 void ClearAllUsedNodes();
213};
214
215} // namespace internal
216
217} // namespace cppgc
218
219#endif // INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
CrossThreadPersistentRegion & operator=(const CrossThreadPersistentRegion &)=delete
V8_INLINE PersistentNode * AllocateNode(void *owner, TraceRootCallback trace)
V8_INLINE void FreeNode(PersistentNode *node)
CrossThreadPersistentRegion(const CrossThreadPersistentRegion &)=delete
void InitializeAsFreeNode(PersistentNode *next)
void Trace(RootVisitor &root_visitor) const
PersistentNode(const PersistentNode &)=delete
PersistentNode * FreeListNext() const
void InitializeAsUsedNode(void *owner, TraceRootCallback trace)
PersistentNode & operator=(const PersistentNode &)=delete
const FatalOutOfMemoryHandler & oom_handler_
PersistentRegionBase & operator=(const PersistentRegionBase &)=delete
std::array< PersistentNode, 256u > PersistentNodeSlots
std::vector< std::unique_ptr< PersistentNodeSlots > > nodes_
PersistentNode * TryAllocateNodeFromFreeList(void *owner, TraceRootCallback trace)
void FreeNode(PersistentNode *node)
PersistentRegionBase(const PersistentRegionBase &)=delete
PersistentRegion(const PersistentRegion &)=delete
V8_INLINE PersistentNode * AllocateNode(void *owner, TraceRootCallback trace)
PersistentRegion & operator=(const PersistentRegion &)=delete
V8_INLINE void FreeNode(PersistentNode *node)
V8_INLINE PersistentRegion(const HeapBase &heap, const FatalOutOfMemoryHandler &oom_handler)
#define CPPGC_DCHECK(condition)
Definition logging.h:36
#define CPPGC_CHECK(condition)
Definition logging.h:45
Node * node
void(*)(RootVisitor &, const void *object) TraceRootCallback
Definition trace-trait.h:21
Heap * heap_
#define V8_EXPORT
Definition v8config.h:800
#define V8_INLINE
Definition v8config.h:500
#define V8_LIKELY(condition)
Definition v8config.h:661