| | |
| | |
| | |
| |
|
| | #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" |
| |
|
| | namespace cppgc { |
| |
|
| | class Visitor; |
| |
|
| | namespace internal { |
| |
|
| | |
| | |
| | |
| | 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: |
| | |
| | |
| | |
| | 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; |
| | }; |
| |
|
| | } |
| |
|
| | } |
| |
|
| | #endif |
| |
|