• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef PANDA_RUNTIME_MEM_RUNSLOTS_STL_ADAPTER_H
16 #define PANDA_RUNTIME_MEM_RUNSLOTS_STL_ADAPTER_H
17 
18 #include "runtime/mem/runslots_allocator.h"
19 
20 namespace panda::mem {
21 
22 // Adapter for use of RunSlotsAllocator in STL containers.
23 template <typename T, typename AllocConfigT, typename LockConfigT>
24 class RunSlotsAllocatorAdapter;
25 
26 template <typename AllocConfigT, typename LockConfigT>
27 class RunSlotsAllocatorAdapter<void, AllocConfigT, LockConfigT> {
28 public:
29     using value_type = void;
30     using pointer = void *;
31     using const_pointer = const void *;
32 
33     template <typename U>
34     struct Rebind {
35         using other = RunSlotsAllocatorAdapter<U, AllocConfigT, LockConfigT>;
36     };
37 
38     template <typename U>
39     using rebind = Rebind<U>;
40 
RunSlotsAllocatorAdapter(RunSlotsAllocator<AllocConfigT,LockConfigT> * allocator)41     explicit RunSlotsAllocatorAdapter(RunSlotsAllocator<AllocConfigT, LockConfigT> *allocator) : allocator_(allocator)
42     {
43     }
44     template <typename U>
45     // NOLINTNEXTLINE(google-explicit-constructor)
RunSlotsAllocatorAdapter(const RunSlotsAllocatorAdapter<U,AllocConfigT,LockConfigT> & other)46     RunSlotsAllocatorAdapter(const RunSlotsAllocatorAdapter<U, AllocConfigT, LockConfigT> &other)
47         : allocator_(other.allocator_)
48     {
49     }
50     DEFAULT_COPY_SEMANTIC(RunSlotsAllocatorAdapter);
51     DEFAULT_MOVE_SEMANTIC(RunSlotsAllocatorAdapter);
52     ~RunSlotsAllocatorAdapter() = default;
53 
54 private:
55     RunSlotsAllocator<AllocConfigT, LockConfigT> *allocator_;
56 
57     template <typename U, typename AllocConfigT_, typename LockConfigT_>
58     friend class RunSlotsAllocatorAdapter;
59 };
60 
61 template <typename T, typename AllocConfigT, typename LockConfigT>
62 class RunSlotsAllocatorAdapter {
63 public:
64     using value_type = T;
65     using pointer = T *;
66     using reference = T &;
67     using const_pointer = const T *;
68     using const_reference = const T &;
69     using size_type = size_t;
70     using difference_type = ptrdiff_t;
71 
72     template <typename U>
73     struct Rebind {
74         using other = RunSlotsAllocatorAdapter<U, AllocConfigT, LockConfigT>;
75     };
76 
77     template <typename U>
78     using rebind = Rebind<U>;
79 
RunSlotsAllocatorAdapter(AllocConfigT * allocator)80     explicit RunSlotsAllocatorAdapter(AllocConfigT *allocator) : allocator_(allocator) {}
81     template <typename U>
82     // NOLINTNEXTLINE(google-explicit-constructor)
RunSlotsAllocatorAdapter(const RunSlotsAllocatorAdapter<U,AllocConfigT,LockConfigT> & other)83     RunSlotsAllocatorAdapter(const RunSlotsAllocatorAdapter<U, AllocConfigT, LockConfigT> &other)
84         : allocator_(other.allocator_)
85     {
86     }
87     RunSlotsAllocatorAdapter(const RunSlotsAllocatorAdapter &) = default;
88     RunSlotsAllocatorAdapter &operator=(const RunSlotsAllocatorAdapter &) = default;
RunSlotsAllocatorAdapter(RunSlotsAllocatorAdapter && other)89     RunSlotsAllocatorAdapter(RunSlotsAllocatorAdapter &&other) noexcept
90     {
91         allocator_ = other.allocator_;
92         other.allocator_ = nullptr;
93     }
94     RunSlotsAllocatorAdapter &operator=(RunSlotsAllocatorAdapter &&other) noexcept
95     {
96         allocator_ = other.allocator_;
97         other.allocator_ = nullptr;
98         return *this;
99     }
100     ~RunSlotsAllocatorAdapter() = default;
101 
102     // NOLINTNEXTLINE(readability-identifier-naming)
max_size()103     size_type max_size() const
104     {
105         // TODO(aemelenko): This solution significantly limits max array size
106         return RunSlots<>::MaxSlotSize() / sizeof(T);
107     }
108 
109     // NOLINTNEXTLINE(readability-identifier-naming)
address(reference x)110     pointer address(reference x) const
111     {
112         return &x;
113     }
114     // NOLINTNEXTLINE(readability-identifier-naming)
address(const_reference x)115     const_pointer address(const_reference x) const
116     {
117         return &x;
118     }
119 
120     // NOLINTNEXTLINE(readability-identifier-naming)
121     pointer allocate(size_type n,
122                      [[maybe_unused]]
123                      typename RunSlotsAllocatorAdapter<void, AllocConfigT, LockConfigT>::pointer ptr = nullptr)
124     {
125         ASSERT(n <= max_size());
126         return allocator_->template AllocArray<T>(n);
127     }
128 
129     // NOLINTNEXTLINE(readability-identifier-naming)
deallocate(pointer p,size_type n)130     void deallocate([[maybe_unused]] pointer p, [[maybe_unused]] size_type n)
131     {
132         allocator_->Free(static_cast<void *>(p));
133     }
134 
135     template <typename U, typename... Args>
construct(U * p,Args &&...args)136     void construct(U *p, Args &&... args)
137     {  // NOLINT(readability-identifier-naming)
138         ::new (static_cast<void *>(p)) U(std::forward<Args>(args)...);
139     }
140     template <typename U>
destroy(U * p)141     void destroy(U *p)
142     {  // NOLINT(readability-identifier-naming)
143         p->~U();
144     }
145 
146 private:
147     RunSlotsAllocator<AllocConfigT, LockConfigT> *allocator_ {nullptr};
148 
149     template <typename U, typename AllocConfigT_, typename LockConfigT_>
150     friend class RunSlotsAllocatorAdapter;
151 
152     template <typename U>
153     // NOLINTNEXTLINE(readability-redundant-declaration)
154     friend inline bool operator==(const RunSlotsAllocatorAdapter &,
155                                   const RunSlotsAllocatorAdapter<U, AllocConfigT, LockConfigT> &rhs);
156 };
157 
158 template <typename T, typename AllocConfigT, typename LockConfigT>
159 inline bool operator==(const RunSlotsAllocatorAdapter<T, AllocConfigT, LockConfigT> &lhs,
160                        const RunSlotsAllocatorAdapter<T, AllocConfigT, LockConfigT> &rhs)
161 {
162     return lhs.allocator_ == rhs.allocator_;
163 }
164 
165 template <typename T, typename AllocConfigT, typename LockConfigT>
166 inline bool operator!=(const RunSlotsAllocatorAdapter<T, AllocConfigT, LockConfigT> &lhs,
167                        const RunSlotsAllocatorAdapter<T, AllocConfigT, LockConfigT> &rhs)
168 {
169     return !(lhs == rhs);
170 }
171 
172 template <typename AllocConfigT, typename LockConfigT>
Adapter()173 inline RunSlotsAllocatorAdapter<void, AllocConfigT, LockConfigT> RunSlotsAllocator<AllocConfigT, LockConfigT>::Adapter()
174 {
175     return RunSlotsAllocatorAdapter<void, AllocConfigT, LockConfigT>(this);
176 }
177 
178 }  // namespace panda::mem
179 
180 #endif  // PANDA_RUNTIME_MEM_RUNSLOTS_STL_ADAPTER_H
181