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_C_ADDRESS_ALLOCATOR_H 17 #define ECMASCRIPT_MEM_C_ADDRESS_ALLOCATOR_H 18 19 #include "ecmascript/mem/chunk.h" 20 21 namespace panda::ecmascript { 22 template<typename T> 23 class CAddressAllocator { 24 public: 25 // using by 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 = CAddressAllocator<U>; 37 }; 38 39 template<typename U> 40 using rebind = Rebind<U>; 41 42 CAddressAllocator() = default; 43 44 template<typename U> CAddressAllocator(const CAddressAllocator<U> & other)45 explicit CAddressAllocator(const CAddressAllocator<U> &other [[maybe_unused]]) 46 { 47 } 48 49 CAddressAllocator(const CAddressAllocator &) = default; 50 CAddressAllocator &operator=(const CAddressAllocator &) = default; 51 CAddressAllocator(CAddressAllocator &&other) noexcept = default; 52 CAddressAllocator &operator=(CAddressAllocator &&other) noexcept = default; 53 ~CAddressAllocator() = default; 54 55 // NOLINTNEXTLINE(readability-identifier-naming) max_size()56 size_type max_size() const 57 { 58 return static_cast<size_type>(-1) / sizeof(T); 59 } 60 61 bool operator==([[maybe_unused]] CAddressAllocator const &other) const 62 { 63 return false; 64 } 65 66 bool operator!=([[maybe_unused]] CAddressAllocator const &other) const 67 { 68 return true; 69 } 70 71 // NOLINTNEXTLINE(readability-identifier-naming) 72 pointer allocate(size_type n, [[maybe_unused]] const void *ptr = nullptr) 73 { 74 ASSERT(n <= max_size()); 75 return static_cast<T *>(Allocate(n * sizeof(T))); 76 } 77 78 // NOLINTNEXTLINE(readability-identifier-naming) deallocate(pointer p,size_type n)79 void deallocate(pointer p, [[maybe_unused]] size_type n) 80 { 81 Free(static_cast<void *>(p)); 82 } 83 84 template<typename U, typename... Args> construct(U * p,Args &&...args)85 void construct(U *p, Args &&... args) // NOLINT(readability-identifier-naming) 86 { 87 if (p == nullptr) { 88 return; 89 } 90 ::new (static_cast<void *>(p)) U(std::forward<Args>(args)...); 91 } 92 template<typename U> destroy(U * p)93 void destroy(U *p) // NOLINT(readability-identifier-naming) 94 { 95 if (p == nullptr) { 96 return; 97 } 98 p->~U(); 99 } 100 Allocate(size_t size)101 [[nodiscard]] void *Allocate(size_t size) 102 { 103 if (size == 0) { 104 LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; 105 UNREACHABLE(); 106 } 107 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 108 void *ptr = malloc(size); 109 if (ptr == nullptr) { 110 LOG_ECMA_MEM(FATAL) << "malloc failed"; 111 UNREACHABLE(); 112 } 113 return ptr; 114 } 115 116 template<typename S, typename... Args> New(Args &&...args)117 [[nodiscard]] S *New(Args &&... args) 118 { 119 auto p = reinterpret_cast<void *>(Allocate(sizeof(S))); 120 new (p) S(std::forward<Args>(args)...); 121 return reinterpret_cast<S *>(p); 122 } 123 124 template<class S> Finalize(S * ptr)125 void Finalize(S *ptr) 126 { 127 ASSERT(ptr != nullptr); 128 // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 129 if constexpr (std::is_class_v<S>) { 130 ptr->~S(); 131 } 132 Free(ptr); 133 } 134 AllocArray(size_t size)135 [[nodiscard]] T *AllocArray(size_t size) 136 { 137 return static_cast<T *>(Allocate(size * sizeof(T))); 138 } 139 Delete(T * ptr)140 void Delete(T *ptr) 141 { 142 if (ptr == nullptr) { 143 return; 144 } 145 // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 146 if constexpr (std::is_class_v<T>) { 147 ptr->~T(); 148 } 149 Free(ptr); 150 } 151 Free(void * mem)152 void Free(void *mem) 153 { 154 if (mem == nullptr) { 155 return; 156 } 157 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 158 free(mem); 159 } 160 }; 161 } // namespace panda::ecmascript 162 163 #endif // ECMASCRIPT_MEM_C_ADDRESS_ALLOCATOR_H