Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/include/cppgc/internal/persistent-node.h')
-rw-r--r--deps/v8/include/cppgc/internal/persistent-node.h109
1 files changed, 109 insertions, 0 deletions
diff --git a/deps/v8/include/cppgc/internal/persistent-node.h b/deps/v8/include/cppgc/internal/persistent-node.h
new file mode 100644
index 00000000000..11cf69623e8
--- /dev/null
+++ b/deps/v8/include/cppgc/internal/persistent-node.h
@@ -0,0 +1,109 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
+#define INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_
+
+#include <array>
+#include <memory>
+#include <vector>
+
+#include "cppgc/internal/logging.h"
+#include "cppgc/trace-trait.h"
+#include "v8config.h" // NOLINT(build/include_directory)
+
+namespace cppgc {
+
+class Visitor;
+
+namespace internal {
+
+// PersistentNode represesents a variant of two states:
+// 1) traceable node with a back pointer to the Persistent object;
+// 2) freelist entry.
+class PersistentNode final {
+ public:
+ PersistentNode() = default;
+
+ PersistentNode(const PersistentNode&) = delete;
+ PersistentNode& operator=(const PersistentNode&) = delete;
+
+ void InitializeAsUsedNode(void* owner, TraceCallback trace) {
+ owner_ = owner;
+ trace_ = trace;
+ }
+
+ void InitializeAsFreeNode(PersistentNode* next) {
+ next_ = next;
+ trace_ = nullptr;
+ }
+
+ void UpdateOwner(void* owner) {
+ CPPGC_DCHECK(IsUsed());
+ owner_ = owner;
+ }
+
+ PersistentNode* FreeListNext() const {
+ CPPGC_DCHECK(!IsUsed());
+ return next_;
+ }
+
+ void Trace(Visitor* visitor) const {
+ CPPGC_DCHECK(IsUsed());
+ trace_(visitor, owner_);
+ }
+
+ bool IsUsed() const { return trace_; }
+
+ private:
+ // PersistentNode acts as a designated union:
+ // If trace_ != nullptr, owner_ points to the corresponding Persistent handle.
+ // Otherwise, next_ points to the next freed PersistentNode.
+ union {
+ void* owner_ = nullptr;
+ PersistentNode* next_;
+ };
+ TraceCallback trace_ = nullptr;
+};
+
+class V8_EXPORT PersistentRegion {
+ using PersistentNodeSlots = std::array<PersistentNode, 256u>;
+
+ public:
+ PersistentRegion() = default;
+
+ PersistentRegion(const PersistentRegion&) = delete;
+ PersistentRegion& operator=(const PersistentRegion&) = delete;
+
+ PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
+ if (!free_list_head_) {
+ EnsureNodeSlots();
+ }
+ PersistentNode* node = free_list_head_;
+ free_list_head_ = free_list_head_->FreeListNext();
+ node->InitializeAsUsedNode(owner, trace);
+ return node;
+ }
+
+ void FreeNode(PersistentNode* node) {
+ node->InitializeAsFreeNode(free_list_head_);
+ free_list_head_ = node;
+ }
+
+ void Trace(Visitor*);
+
+ size_t NodesInUse() const;
+
+ private:
+ void EnsureNodeSlots();
+
+ std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_;
+ PersistentNode* free_list_head_ = nullptr;
+};
+
+} // namespace internal
+
+} // namespace cppgc
+
+#endif // INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_