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_H 17 #define ECMASCRIPT_MEM_CHUNK_H 18 19 #include "ecmascript/common.h" 20 #include "ecmascript/log_wrapper.h" 21 #include "ecmascript/mem/ecma_list.h" 22 #include "ecmascript/mem/area.h" 23 24 namespace panda::ecmascript { 25 class NativeAreaAllocator; 26 27 class PUBLIC_API Chunk { 28 public: 29 static constexpr size_t MEM_ALIGN = 8U; 30 31 explicit Chunk(NativeAreaAllocator *allocator); 32 Chunk() = default; ~Chunk()33 ~Chunk() 34 { 35 ReleaseMemory(); 36 } 37 38 NO_COPY_SEMANTIC(Chunk); 39 NO_MOVE_SEMANTIC(Chunk); 40 Allocate(size_t size)41 [[nodiscard]] void *Allocate(size_t size) 42 { 43 if (size == 0) { 44 LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; 45 UNREACHABLE(); 46 } 47 uintptr_t result = ptr_; 48 size = AlignUp(size, MEM_ALIGN); 49 if (UNLIKELY(size > end_ - ptr_)) { 50 result = Expand(size); 51 } else { 52 ptr_ += size; 53 } 54 55 return reinterpret_cast<void *>(result); 56 } 57 58 template<class T> NewArray(size_t size)59 [[nodiscard]] T *NewArray(size_t size) 60 { 61 return static_cast<T *>(Allocate(size * sizeof(T))); 62 } 63 64 template<typename T, typename... Args> New(Args &&.... args)65 [[nodiscard]] T *New(Args &&... args) 66 { 67 auto p = reinterpret_cast<void *>(Allocate(sizeof(T))); 68 new (p) T(std::forward<Args>(args)...); 69 return reinterpret_cast<T *>(p); 70 } 71 72 template<class T> Delete(T *ptr)73 void Delete(T *ptr) 74 { 75 ASSERT(ptr != nullptr); 76 // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 77 if constexpr (std::is_class_v<T>) { 78 ptr->~T(); 79 } 80 Free(ptr); 81 } 82 Free([[maybe_unused]] void *mem)83 void Free([[maybe_unused]] void *mem) 84 { 85 // do nothing 86 } 87 88 protected: 89 uintptr_t ptr_ {0}; 90 uintptr_t end_ {0}; 91 92 Area *currentArea_ {nullptr}; 93 NativeAreaAllocator *allocator_ {nullptr}; 94 95 private: 96 uintptr_t Expand(size_t size); 97 Area *NewArea(size_t size); 98 void ReleaseMemory(); 99 100 EcmaList<Area> areaList_ {}; 101 }; 102 103 class PUBLIC_API ChunkObject { 104 public: operator new(size_t size, Chunk* chunk)105 void *operator new(size_t size, Chunk* chunk) 106 { 107 return chunk->Allocate(size); 108 } 109 operator delete([[maybe_unused]] void* ptr)110 void operator delete([[maybe_unused]] void* ptr) 111 { 112 UNREACHABLE(); 113 } 114 }; 115 } // namespace panda::ecmascript 116 117 #endif // ECMASCRIPT_MEM_CHUNK_H 118