v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
persistent-node.cc
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
6
7#include <algorithm>
8#include <numeric>
9
16
17namespace cppgc {
18namespace internal {
19
21 const FatalOutOfMemoryHandler& oom_handler)
22 : oom_handler_(oom_handler) {}
23
25
26template <typename PersistentBaseClass>
28 for (auto& slots : nodes_) {
29 for (auto& node : *slots) {
30 if (!node.IsUsed()) continue;
31
32 static_cast<PersistentBaseClass*>(node.owner())->ClearFromGC();
33
34 // Add nodes back to the free list to allow reusing for subsequent
35 // creation calls.
36 node.InitializeAsFreeNode(free_list_head_);
40 }
41 }
43}
44
45template void
48
52
54#ifdef DEBUG
55 const size_t accumulated_nodes_in_use_ = std::accumulate(
56 nodes_.cbegin(), nodes_.cend(), 0u, [](size_t acc, const auto& slots) {
57 return acc + std::count_if(slots->cbegin(), slots->cend(),
58 [](const PersistentNode& node) {
59 return node.IsUsed();
60 });
61 });
62 DCHECK_EQ(accumulated_nodes_in_use_, nodes_in_use_);
63#endif // DEBUG
64 return nodes_in_use_;
65}
66
67void PersistentRegionBase::RefillFreeList() {
68 auto node_slots = std::make_unique<PersistentNodeSlots>();
69 if (!node_slots.get()) {
70 oom_handler_("Oilpan: PersistentRegionBase::RefillFreeList()");
71 }
72 nodes_.push_back(std::move(node_slots));
73 for (auto& node : *nodes_.back()) {
74 node.InitializeAsFreeNode(free_list_head_);
75 free_list_head_ = &node;
76 }
77}
78
79PersistentNode* PersistentRegionBase::RefillFreeListAndAllocateNode(
80 void* owner, TraceRootCallback trace) {
81 RefillFreeList();
82 auto* node = TryAllocateNodeFromFreeList(owner, trace);
83 CPPGC_DCHECK(node);
84 return node;
85}
86
87void PersistentRegionBase::Iterate(RootVisitor& root_visitor) {
88 free_list_head_ = nullptr;
89 for (auto& slots : nodes_) {
90 bool is_empty = true;
91 for (auto& node : *slots) {
92 if (node.IsUsed()) {
93 node.Trace(root_visitor);
94 is_empty = false;
95 } else {
96 node.InitializeAsFreeNode(free_list_head_);
97 free_list_head_ = &node;
98 }
99 }
100 if (is_empty) {
101 PersistentNode* first_next = (*slots)[0].FreeListNext();
102 // First next was processed first in the loop above, guaranteeing that it
103 // either points to null or into a different node block.
104 CPPGC_DCHECK(!first_next || first_next < &slots->front() ||
105 first_next > &slots->back());
106 free_list_head_ = first_next;
107 slots.reset();
108 }
109 }
110 nodes_.erase(std::remove_if(nodes_.begin(), nodes_.end(),
111 [](const auto& ptr) { return !ptr; }),
112 nodes_.end());
113}
114
115bool PersistentRegion::IsCreationThread() {
116 return heap_.CurrentThreadIsHeapThread();
117}
118
119PersistentRegionLock::PersistentRegionLock() {
120 ProcessGlobalLock::Lock<
121 ProcessGlobalLock::Reason::kForCrossThreadHandleCreation>();
122}
123
124PersistentRegionLock::~PersistentRegionLock() {
125 ProcessGlobalLock::Unlock<
126 ProcessGlobalLock::Reason::kForCrossThreadHandleCreation>();
127}
128
129// static
130void PersistentRegionLock::AssertLocked() { ProcessGlobalLock::AssertHeld(); }
131
132CrossThreadPersistentRegion::CrossThreadPersistentRegion(
133 const FatalOutOfMemoryHandler& oom_handler)
134 : PersistentRegionBase(oom_handler) {}
135
142
147
149 // This method does not require a lock.
151}
152
157
158} // namespace internal
159} // namespace cppgc
PersistentNode * FreeListNext() const
std::vector< std::unique_ptr< PersistentNodeSlots > > nodes_
PersistentRegionBase(const PersistentRegionBase &)=delete
bool is_empty
Definition sweeper.cc:229
ZoneLinkedList< BFEntry > nodes_
#define CPPGC_DCHECK(condition)
Definition logging.h:36
Node * node
void(*)(RootVisitor &, const void *object) TraceRootCallback
Definition trace-trait.h:21
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
Heap * heap_