• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #ifndef ECMASCRIPT_MEM_CHUNK_ALLOCATOR_H
17 #define ECMASCRIPT_MEM_CHUNK_ALLOCATOR_H
18 
19 #include "ecmascript/mem/chunk.h"
20 
21 namespace panda::ecmascript {
22 template<typename T>
23 class ChunkAllocator {
24 public:
25     // used for std allocator
26     using value_type = T;
27     using pointer = T *;
28     using reference = T &;
29     using const_pointer = const T *;
30     using const_reference = const T &;
31     using size_type = size_t;
32     using difference_type = ptrdiff_t;
33 
34     template<typename U>
35     struct Rebind {
36         using other = ChunkAllocator<U>;
37     };
38 
39     template<typename U>
40     using rebind = Rebind<U>;
41 
ChunkAllocator(Chunk * chunk)42     explicit ChunkAllocator(Chunk *chunk) : chunk_(chunk) {}
43 
44     template<typename U>
ChunkAllocator(const ChunkAllocator<U> & other)45     explicit ChunkAllocator(const ChunkAllocator<U> &other) : chunk_(other.chunk_)
46     {
47     }
48     template<typename U>
49     friend class ChunkAllocator;
50 
51     ChunkAllocator(const ChunkAllocator &) = default;
52     ChunkAllocator &operator=(const ChunkAllocator &) = default;
ChunkAllocator(ChunkAllocator && other)53     ChunkAllocator(ChunkAllocator &&other) noexcept
54     {
55         chunk_ = other.chunk_;
56         other.chunk_ = nullptr;
57     }
58     ChunkAllocator &operator=(ChunkAllocator &&other) noexcept
59     {
60         chunk_ = other.chunk_;
61         other.chunk_ = nullptr;
62         return *this;
63     }
64     ~ChunkAllocator() = default;
65 
66     // NOLINTNEXTLINE(readability-identifier-naming)
max_size()67     size_type max_size() const
68     {
69         return static_cast<size_type>(-1) / sizeof(T);
70     }
71 
72     // NOLINTNEXTLINE(readability-identifier-naming)
address(reference x)73     pointer address(reference x) const
74     {
75         return &x;
76     }
77     // NOLINTNEXTLINE(readability-identifier-naming)
address(const_reference x)78     const_pointer address(const_reference x) const
79     {
80         return &x;
81     }
82 
83     // NOLINTNEXTLINE(readability-identifier-naming)
84     pointer allocate(size_type n, [[maybe_unused]] const void *ptr = nullptr)
85     {
86         ASSERT(n <= max_size());
87         return chunk_->NewArray<T>(n);
88     }
89 
90     // NOLINTNEXTLINE(readability-identifier-naming)
deallocate(pointer p,size_type n)91     void deallocate([[maybe_unused]] pointer p, [[maybe_unused]] size_type n) {}
92 
93     template<typename U, typename... Args>
construct(U * p,Args &&...args)94     void construct(U *p, Args &&... args)  // NOLINT(readability-identifier-naming)
95     {
96         ::new (static_cast<void *>(p)) U(std::forward<Args>(args)...);
97     }
98     template<typename U>
destroy(U * p)99     void destroy(U *p)  // NOLINT(readability-identifier-naming)
100     {
101         if (p == nullptr) {
102             return;
103         }
104         p->~U();
105     }
106 
107     bool operator==(ChunkAllocator const &other) const
108     {
109         return chunk_ == other.chunk_;
110     }
111     bool operator!=(ChunkAllocator const &other) const
112     {
113         return chunk_ != other.chunk_;
114     }
115 
Alloc(size_t size)116     [[nodiscard]] void *Alloc(size_t size)
117     {
118         return chunk_->NewArray<uint8_t>(size);
119     }
120 
AllocArray(size_t size)121     [[nodiscard]] T *AllocArray(size_t size)
122     {
123         return chunk_->NewArray<T>(size);
124     }
125 
Delete(T * ptr)126     void Delete(T *ptr)
127     {
128         if (ptr == nullptr) {
129             LOG_ECMA_MEM(FATAL) << "free nullptr";
130             UNREACHABLE();
131         }
132         // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon)
133         if constexpr (std::is_class_v<T>) {
134             ptr->~T();
135         }
136         Free(ptr);
137     }
138 
Free(void * mem)139     void Free([[maybe_unused]] void *mem) {}
140 
chunk()141     Chunk *chunk()
142     {
143         return chunk_;
144     }
145 
146 private:
147     Chunk *chunk_;
148 };
149 }  // namespace panda::ecmascript
150 
151 #endif  // ECMASCRIPT_MEM_CHUNK_ALLOCATOR_H
152