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_CHUNK_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_MEM_CHUNK_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/common.h" 204514f5e3Sopenharmony_ci#include "ecmascript/log_wrapper.h" 214514f5e3Sopenharmony_ci#include "ecmascript/mem/ecma_list.h" 224514f5e3Sopenharmony_ci#include "ecmascript/mem/area.h" 234514f5e3Sopenharmony_ci 244514f5e3Sopenharmony_cinamespace panda::ecmascript { 254514f5e3Sopenharmony_ciclass NativeAreaAllocator; 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_ciclass PUBLIC_API Chunk { 284514f5e3Sopenharmony_cipublic: 294514f5e3Sopenharmony_ci static constexpr size_t MEM_ALIGN = 8U; 304514f5e3Sopenharmony_ci 314514f5e3Sopenharmony_ci explicit Chunk(NativeAreaAllocator *allocator); 324514f5e3Sopenharmony_ci Chunk() = default; 334514f5e3Sopenharmony_ci ~Chunk() 344514f5e3Sopenharmony_ci { 354514f5e3Sopenharmony_ci ReleaseMemory(); 364514f5e3Sopenharmony_ci } 374514f5e3Sopenharmony_ci 384514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(Chunk); 394514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(Chunk); 404514f5e3Sopenharmony_ci 414514f5e3Sopenharmony_ci [[nodiscard]] void *Allocate(size_t size) 424514f5e3Sopenharmony_ci { 434514f5e3Sopenharmony_ci if (size == 0) { 444514f5e3Sopenharmony_ci LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; 454514f5e3Sopenharmony_ci UNREACHABLE(); 464514f5e3Sopenharmony_ci } 474514f5e3Sopenharmony_ci uintptr_t result = ptr_; 484514f5e3Sopenharmony_ci size = AlignUp(size, MEM_ALIGN); 494514f5e3Sopenharmony_ci if (UNLIKELY(size > end_ - ptr_)) { 504514f5e3Sopenharmony_ci result = Expand(size); 514514f5e3Sopenharmony_ci } else { 524514f5e3Sopenharmony_ci ptr_ += size; 534514f5e3Sopenharmony_ci } 544514f5e3Sopenharmony_ci 554514f5e3Sopenharmony_ci return reinterpret_cast<void *>(result); 564514f5e3Sopenharmony_ci } 574514f5e3Sopenharmony_ci 584514f5e3Sopenharmony_ci template<class T> 594514f5e3Sopenharmony_ci [[nodiscard]] T *NewArray(size_t size) 604514f5e3Sopenharmony_ci { 614514f5e3Sopenharmony_ci return static_cast<T *>(Allocate(size * sizeof(T))); 624514f5e3Sopenharmony_ci } 634514f5e3Sopenharmony_ci 644514f5e3Sopenharmony_ci template<typename T, typename... Args> 654514f5e3Sopenharmony_ci [[nodiscard]] T *New(Args &&... args) 664514f5e3Sopenharmony_ci { 674514f5e3Sopenharmony_ci auto p = reinterpret_cast<void *>(Allocate(sizeof(T))); 684514f5e3Sopenharmony_ci new (p) T(std::forward<Args>(args)...); 694514f5e3Sopenharmony_ci return reinterpret_cast<T *>(p); 704514f5e3Sopenharmony_ci } 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_ci template<class T> 734514f5e3Sopenharmony_ci void Delete(T *ptr) 744514f5e3Sopenharmony_ci { 754514f5e3Sopenharmony_ci ASSERT(ptr != nullptr); 764514f5e3Sopenharmony_ci // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 774514f5e3Sopenharmony_ci if constexpr (std::is_class_v<T>) { 784514f5e3Sopenharmony_ci ptr->~T(); 794514f5e3Sopenharmony_ci } 804514f5e3Sopenharmony_ci Free(ptr); 814514f5e3Sopenharmony_ci } 824514f5e3Sopenharmony_ci 834514f5e3Sopenharmony_ci void Free([[maybe_unused]] void *mem) 844514f5e3Sopenharmony_ci { 854514f5e3Sopenharmony_ci // do nothing 864514f5e3Sopenharmony_ci } 874514f5e3Sopenharmony_ci 884514f5e3Sopenharmony_ciprotected: 894514f5e3Sopenharmony_ci uintptr_t ptr_ {0}; 904514f5e3Sopenharmony_ci uintptr_t end_ {0}; 914514f5e3Sopenharmony_ci 924514f5e3Sopenharmony_ci Area *currentArea_ {nullptr}; 934514f5e3Sopenharmony_ci NativeAreaAllocator *allocator_ {nullptr}; 944514f5e3Sopenharmony_ci 954514f5e3Sopenharmony_ciprivate: 964514f5e3Sopenharmony_ci uintptr_t Expand(size_t size); 974514f5e3Sopenharmony_ci Area *NewArea(size_t size); 984514f5e3Sopenharmony_ci void ReleaseMemory(); 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_ci EcmaList<Area> areaList_ {}; 1014514f5e3Sopenharmony_ci}; 1024514f5e3Sopenharmony_ci 1034514f5e3Sopenharmony_ciclass PUBLIC_API ChunkObject { 1044514f5e3Sopenharmony_cipublic: 1054514f5e3Sopenharmony_ci void *operator new(size_t size, Chunk* chunk) 1064514f5e3Sopenharmony_ci { 1074514f5e3Sopenharmony_ci return chunk->Allocate(size); 1084514f5e3Sopenharmony_ci } 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_ci void operator delete([[maybe_unused]] void* ptr) 1114514f5e3Sopenharmony_ci { 1124514f5e3Sopenharmony_ci UNREACHABLE(); 1134514f5e3Sopenharmony_ci } 1144514f5e3Sopenharmony_ci}; 1154514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1164514f5e3Sopenharmony_ci 1174514f5e3Sopenharmony_ci#endif // ECMASCRIPT_MEM_CHUNK_H 118