14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_MEM_C_ADDRESS_ALLOCATOR_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_C_ADDRESS_ALLOCATOR_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/mem/chunk.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_cinamespace panda::ecmascript { 224514f5e3Sopenharmony_citemplate<typename T> 234514f5e3Sopenharmony_ciclass CAddressAllocator { 244514f5e3Sopenharmony_cipublic: 254514f5e3Sopenharmony_ci // using by std allocator 264514f5e3Sopenharmony_ci using value_type = T; 274514f5e3Sopenharmony_ci using pointer = T *; 284514f5e3Sopenharmony_ci using reference = T &; 294514f5e3Sopenharmony_ci using const_pointer = const T *; 304514f5e3Sopenharmony_ci using const_reference = const T &; 314514f5e3Sopenharmony_ci using size_type = size_t; 324514f5e3Sopenharmony_ci using difference_type = ptrdiff_t; 334514f5e3Sopenharmony_ci using propagate_on_container_swap = std::true_type; 344514f5e3Sopenharmony_ci 354514f5e3Sopenharmony_ci template<typename U> 364514f5e3Sopenharmony_ci struct Rebind { 374514f5e3Sopenharmony_ci using other = CAddressAllocator<U>; 384514f5e3Sopenharmony_ci }; 394514f5e3Sopenharmony_ci 404514f5e3Sopenharmony_ci template<typename U> 414514f5e3Sopenharmony_ci using rebind = Rebind<U>; 424514f5e3Sopenharmony_ci 434514f5e3Sopenharmony_ci CAddressAllocator() = default; 444514f5e3Sopenharmony_ci 454514f5e3Sopenharmony_ci template<typename U> 464514f5e3Sopenharmony_ci explicit CAddressAllocator(const CAddressAllocator<U> &other [[maybe_unused]]) 474514f5e3Sopenharmony_ci { 484514f5e3Sopenharmony_ci } 494514f5e3Sopenharmony_ci 504514f5e3Sopenharmony_ci CAddressAllocator(const CAddressAllocator &) = default; 514514f5e3Sopenharmony_ci CAddressAllocator &operator=(const CAddressAllocator &) = default; 524514f5e3Sopenharmony_ci CAddressAllocator(CAddressAllocator &&other) noexcept = default; 534514f5e3Sopenharmony_ci CAddressAllocator &operator=(CAddressAllocator &&other) noexcept = default; 544514f5e3Sopenharmony_ci ~CAddressAllocator() = default; 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_ci // NOLINTNEXTLINE(readability-identifier-naming) 574514f5e3Sopenharmony_ci size_type max_size() const 584514f5e3Sopenharmony_ci { 594514f5e3Sopenharmony_ci return static_cast<size_type>(-1) / sizeof(T); 604514f5e3Sopenharmony_ci } 614514f5e3Sopenharmony_ci 624514f5e3Sopenharmony_ci bool operator==([[maybe_unused]] CAddressAllocator const &other) const 634514f5e3Sopenharmony_ci { 644514f5e3Sopenharmony_ci return false; 654514f5e3Sopenharmony_ci } 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_ci bool operator!=([[maybe_unused]] CAddressAllocator const &other) const 684514f5e3Sopenharmony_ci { 694514f5e3Sopenharmony_ci return true; 704514f5e3Sopenharmony_ci } 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_ci // NOLINTNEXTLINE(readability-identifier-naming) 734514f5e3Sopenharmony_ci pointer allocate(size_type n, [[maybe_unused]] const void *ptr = nullptr) 744514f5e3Sopenharmony_ci { 754514f5e3Sopenharmony_ci ASSERT(n <= max_size()); 764514f5e3Sopenharmony_ci return static_cast<T *>(Allocate(n * sizeof(T))); 774514f5e3Sopenharmony_ci } 784514f5e3Sopenharmony_ci 794514f5e3Sopenharmony_ci // NOLINTNEXTLINE(readability-identifier-naming) 804514f5e3Sopenharmony_ci void deallocate(pointer p, [[maybe_unused]] size_type n) 814514f5e3Sopenharmony_ci { 824514f5e3Sopenharmony_ci Free(static_cast<void *>(p)); 834514f5e3Sopenharmony_ci } 844514f5e3Sopenharmony_ci 854514f5e3Sopenharmony_ci template<typename U, typename... Args> 864514f5e3Sopenharmony_ci void construct(U *p, Args &&... args) // NOLINT(readability-identifier-naming) 874514f5e3Sopenharmony_ci { 884514f5e3Sopenharmony_ci if (p == nullptr) { 894514f5e3Sopenharmony_ci return; 904514f5e3Sopenharmony_ci } 914514f5e3Sopenharmony_ci ::new (static_cast<void *>(p)) U(std::forward<Args>(args)...); 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci template<typename U> 944514f5e3Sopenharmony_ci void destroy(U *p) // NOLINT(readability-identifier-naming) 954514f5e3Sopenharmony_ci { 964514f5e3Sopenharmony_ci if (p == nullptr) { 974514f5e3Sopenharmony_ci return; 984514f5e3Sopenharmony_ci } 994514f5e3Sopenharmony_ci p->~U(); 1004514f5e3Sopenharmony_ci } 1014514f5e3Sopenharmony_ci 1024514f5e3Sopenharmony_ci [[nodiscard]] void *Allocate(size_t size) 1034514f5e3Sopenharmony_ci { 1044514f5e3Sopenharmony_ci if (size == 0) { 1054514f5e3Sopenharmony_ci LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; 1064514f5e3Sopenharmony_ci UNREACHABLE(); 1074514f5e3Sopenharmony_ci } 1084514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 1094514f5e3Sopenharmony_ci void *ptr = malloc(size); 1104514f5e3Sopenharmony_ci if (ptr == nullptr) { 1114514f5e3Sopenharmony_ci LOG_ECMA_MEM(FATAL) << "malloc failed, size is: " << size; 1124514f5e3Sopenharmony_ci UNREACHABLE(); 1134514f5e3Sopenharmony_ci } 1144514f5e3Sopenharmony_ci return ptr; 1154514f5e3Sopenharmony_ci } 1164514f5e3Sopenharmony_ci 1174514f5e3Sopenharmony_ci template<typename S, typename... Args> 1184514f5e3Sopenharmony_ci [[nodiscard]] S *New(Args &&... args) 1194514f5e3Sopenharmony_ci { 1204514f5e3Sopenharmony_ci auto p = reinterpret_cast<void *>(Allocate(sizeof(S))); 1214514f5e3Sopenharmony_ci new (p) S(std::forward<Args>(args)...); 1224514f5e3Sopenharmony_ci return reinterpret_cast<S *>(p); 1234514f5e3Sopenharmony_ci } 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci template<class S> 1264514f5e3Sopenharmony_ci void Finalize(S *ptr) 1274514f5e3Sopenharmony_ci { 1284514f5e3Sopenharmony_ci ASSERT(ptr != nullptr); 1294514f5e3Sopenharmony_ci // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 1304514f5e3Sopenharmony_ci if constexpr (std::is_class_v<S>) { 1314514f5e3Sopenharmony_ci ptr->~S(); 1324514f5e3Sopenharmony_ci } 1334514f5e3Sopenharmony_ci Free(ptr); 1344514f5e3Sopenharmony_ci } 1354514f5e3Sopenharmony_ci 1364514f5e3Sopenharmony_ci [[nodiscard]] T *AllocArray(size_t size) 1374514f5e3Sopenharmony_ci { 1384514f5e3Sopenharmony_ci return static_cast<T *>(Allocate(size * sizeof(T))); 1394514f5e3Sopenharmony_ci } 1404514f5e3Sopenharmony_ci 1414514f5e3Sopenharmony_ci void Delete(T *ptr) 1424514f5e3Sopenharmony_ci { 1434514f5e3Sopenharmony_ci if (ptr == nullptr) { 1444514f5e3Sopenharmony_ci return; 1454514f5e3Sopenharmony_ci } 1464514f5e3Sopenharmony_ci // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 1474514f5e3Sopenharmony_ci if constexpr (std::is_class_v<T>) { 1484514f5e3Sopenharmony_ci ptr->~T(); 1494514f5e3Sopenharmony_ci } 1504514f5e3Sopenharmony_ci Free(ptr); 1514514f5e3Sopenharmony_ci } 1524514f5e3Sopenharmony_ci 1534514f5e3Sopenharmony_ci void Free(void *mem) 1544514f5e3Sopenharmony_ci { 1554514f5e3Sopenharmony_ci if (mem == nullptr) { 1564514f5e3Sopenharmony_ci return; 1574514f5e3Sopenharmony_ci } 1584514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 1594514f5e3Sopenharmony_ci free(mem); 1604514f5e3Sopenharmony_ci } 1614514f5e3Sopenharmony_ci}; 1624514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1634514f5e3Sopenharmony_ci 1644514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MEM_C_ADDRESS_ALLOCATOR_H