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