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