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#include "ecmascript/mem/native_area_allocator.h" 17 18#include "ecmascript/platform/os.h" 19 20#if ECMASCRIPT_ENABLE_ZAP_MEM 21#include "securec.h" 22#endif 23namespace panda::ecmascript { 24Area *NativeAreaAllocator::AllocateArea(size_t capacity) 25{ 26 size_t headerSize = sizeof(Area); 27 if (capacity < headerSize) { // LOCV_EXCL_BR_LINE 28 LOG_ECMA_MEM(FATAL) << "capacity must have a size not less than sizeof Area."; 29 UNREACHABLE(); 30 } 31 if (cachedArea_ != nullptr && capacity <= cachedArea_->GetSize()) { 32 auto result = cachedArea_; 33 cachedArea_ = nullptr; 34 return result; 35 } 36 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 37 void *mem = malloc(capacity); 38 if (mem == nullptr) { // LOCV_EXCL_BR_LINE 39 LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << capacity 40 << ", total allocated size = " << nativeMemoryUsage_.load(std::memory_order_relaxed); 41 UNREACHABLE(); 42 } 43#if ECMASCRIPT_ENABLE_ZAP_MEM 44 if (memset_s(mem, capacity, 0, capacity) != EOK) { // LOCV_EXCL_BR_LINE 45 LOG_FULL(FATAL) << "memset_s failed"; 46 UNREACHABLE(); 47 } 48#endif 49 IncreaseNativeMemoryUsage(capacity); 50 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 51 uintptr_t begin = reinterpret_cast<uintptr_t>(mem) + headerSize; 52 capacity -= headerSize; 53 return new (mem) Area(begin, capacity); 54} 55 56void NativeAreaAllocator::FreeArea(Area *area) 57{ 58 if (area == nullptr) { 59 return; 60 } 61 if (cachedArea_ == nullptr && area->GetSize() <= MAX_CACHED_CHUNK_AREA_SIZE) { 62 cachedArea_ = area; 63 return; 64 } 65 auto size = area->GetSize() + sizeof(Area); 66 DecreaseNativeMemoryUsage(size); 67#if ECMASCRIPT_ENABLE_ZAP_MEM 68 if (memset_s(area, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE 69 LOG_FULL(FATAL) << "memset_s failed"; 70 UNREACHABLE(); 71 } 72#endif 73 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 74 free(reinterpret_cast<std::byte *>(area)); 75} 76 77void NativeAreaAllocator::Free(void *mem, size_t size) 78{ 79 if (mem == nullptr) { 80 return; 81 } 82 DecreaseNativeMemoryUsage(size); 83#if ECMASCRIPT_ENABLE_ZAP_MEM 84 if (memset_s(mem, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE 85 LOG_FULL(FATAL) << "memset_s failed"; 86 UNREACHABLE(); 87 } 88#endif 89 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 90 free(mem); 91} 92 93void *NativeAreaAllocator::AllocateBuffer(size_t size) 94{ 95 if (size == 0) { // LOCV_EXCL_BR_LINE 96 LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; 97 UNREACHABLE(); 98 } 99 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 100 void *ptr = malloc(size); 101 if (ptr == nullptr) { // LOCV_EXCL_BR_LINE 102 LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << size 103 << ", total allocated size = " << nativeMemoryUsage_.load(std::memory_order_relaxed); 104 UNREACHABLE(); 105 } 106#if ECMASCRIPT_ENABLE_ZAP_MEM 107 if (memset_s(ptr, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE 108 LOG_FULL(FATAL) << "memset_s failed"; 109 UNREACHABLE(); 110 } 111#endif 112 IncreaseNativeMemoryUsage(MallocUsableSize(ptr)); 113 return ptr; 114} 115 116void NativeAreaAllocator::FreeBuffer(void *mem) 117{ 118 if (mem == nullptr) { 119 return; 120 } 121 size_t size = MallocUsableSize(mem); 122 DecreaseNativeMemoryUsage(size); 123 124#if ECMASCRIPT_ENABLE_ZAP_MEM 125 if (memset_s(mem, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE 126 LOG_FULL(FATAL) << "memset_s failed"; 127 UNREACHABLE(); 128 } 129#endif 130 // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) 131 free(mem); 132} 133 134void NativeAreaAllocator::FreeBufferFunc([[maybe_unused]] void *env, void *buffer, void *data) 135{ 136 if (buffer == nullptr || data == nullptr) { 137 return; 138 } 139 NativeAreaAllocator* allocator = reinterpret_cast<NativeAreaAllocator*>(data); 140 allocator->FreeBuffer(buffer); 141} 142} // namespace panda::ecmascript 143