• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/map.h"
19 #include "ecmascript/platform/os.h"
20 
21 #if ECMASCRIPT_ENABLE_ZAP_MEM
22 #include "securec.h"
23 #endif
24 namespace panda::ecmascript {
AllocateArea(size_t capacity)25 Area *NativeAreaAllocator::AllocateArea(size_t capacity)
26 {
27     size_t headerSize = sizeof(Area);
28     if (capacity < headerSize) { // LOCV_EXCL_BR_LINE
29         LOG_ECMA_MEM(FATAL) << "capacity must have a size not less than sizeof Area.";
30         UNREACHABLE();
31     }
32     if (cachedArea_ != nullptr && capacity <= cachedArea_->GetSize()) {
33         auto result = cachedArea_;
34         cachedArea_ = nullptr;
35         return result;
36     }
37     // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
38     void *mem = malloc(capacity);
39     if (mem == nullptr) { // LOCV_EXCL_BR_LINE
40         LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << capacity
41                             << ", total allocated size = " << nativeMemoryUsage_.load(std::memory_order_relaxed);
42         UNREACHABLE();
43     }
44 #if ECMASCRIPT_ENABLE_ZAP_MEM
45     if (memset_s(mem, capacity, 0, capacity) != EOK) { // LOCV_EXCL_BR_LINE
46         LOG_FULL(FATAL) << "memset_s failed";
47         UNREACHABLE();
48     }
49 #endif
50     IncreaseNativeMemoryUsage(capacity);
51     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
52     uintptr_t begin = reinterpret_cast<uintptr_t>(mem) + headerSize;
53     capacity -= headerSize;
54     return new (mem) Area(begin, capacity);
55 }
56 
FreeArea(Area * area)57 void NativeAreaAllocator::FreeArea(Area *area)
58 {
59     if (area == nullptr) {
60         return;
61     }
62     if (cachedArea_ == nullptr && area->GetSize() <= MAX_CACHED_CHUNK_AREA_SIZE) {
63         cachedArea_ = area;
64         return;
65     }
66     auto size = area->GetSize() + sizeof(Area);
67     DecreaseNativeMemoryUsage(size);
68 #if ECMASCRIPT_ENABLE_ZAP_MEM
69     if (memset_s(area, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
70         LOG_FULL(FATAL) << "memset_s failed";
71         UNREACHABLE();
72     }
73 #endif
74     // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
75     free(reinterpret_cast<std::byte *>(area));
76 }
77 
Free(void * mem,size_t size)78 void NativeAreaAllocator::Free(void *mem, size_t size)
79 {
80     if (mem == nullptr) {
81         return;
82     }
83     DecreaseNativeMemoryUsage(size);
84 #if ECMASCRIPT_ENABLE_ZAP_MEM
85     if (memset_s(mem, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
86         LOG_FULL(FATAL) << "memset_s failed";
87         UNREACHABLE();
88     }
89 #endif
90     // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
91     free(mem);
92 }
93 
AllocateBuffer(size_t size)94 void *NativeAreaAllocator::AllocateBuffer(size_t size)
95 {
96     if (size == 0) { // LOCV_EXCL_BR_LINE
97         LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0";
98         UNREACHABLE();
99     }
100     // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
101     void *ptr = malloc(size);
102     if (ptr == nullptr) { // LOCV_EXCL_BR_LINE
103         LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << size
104                             << ", total allocated size = " << nativeMemoryUsage_.load(std::memory_order_relaxed);
105         UNREACHABLE();
106     }
107 #if ECMASCRIPT_ENABLE_ZAP_MEM
108     if (memset_s(ptr, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
109         LOG_FULL(FATAL) << "memset_s failed";
110         UNREACHABLE();
111     }
112 #endif
113     IncreaseNativeMemoryUsage(MallocUsableSize(ptr));
114     return ptr;
115 }
116 
FreeBuffer(void * mem)117 void NativeAreaAllocator::FreeBuffer(void *mem)
118 {
119     if (mem == nullptr) {
120         return;
121     }
122     size_t size = MallocUsableSize(mem);
123     DecreaseNativeMemoryUsage(size);
124 
125 #if ECMASCRIPT_ENABLE_ZAP_MEM
126     if (memset_s(mem, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
127         LOG_FULL(FATAL) << "memset_s failed";
128         UNREACHABLE();
129     }
130 #endif
131     // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
132     free(mem);
133 }
134 
NativeAreaPageMap(size_t size)135 void *NativeAreaAllocator::NativeAreaPageMap(size_t size)
136 {
137     if (size == 0) { // LOCV_EXCL_BR_LINE
138         LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0";
139         UNREACHABLE();
140     }
141     // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
142     size = AlignUp(size, PageSize());
143     void *ptr = PageMap(size, PAGE_PROT_READWRITE).GetMem();
144     PageTag(ptr, size, PageTagType::METHOD_LITERAL);
145 #if ECMASCRIPT_ENABLE_ZAP_MEM
146     if (memset_s(ptr, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
147         LOG_FULL(FATAL) << "memset_s failed";
148         UNREACHABLE();
149     }
150 #endif
151     IncreaseNativeMemoryUsage(size);
152     return ptr;
153 }
154 
NativeAreaPageUnmap(void * mem,size_t size)155 void NativeAreaAllocator::NativeAreaPageUnmap(void *mem, size_t size)
156 {
157     if (mem == nullptr) {
158         return;
159     }
160     size = AlignUp(size, PageSize());
161     DecreaseNativeMemoryUsage(size);
162 
163 #if ECMASCRIPT_ENABLE_ZAP_MEM
164     if (memset_s(mem, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
165         LOG_FULL(FATAL) << "memset_s failed";
166         UNREACHABLE();
167     }
168 #endif
169     // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
170     PageClearTag(mem, size);
171     PageUnmap(MemMap(mem, size));
172 }
173 
FreeBufferFunc(void * env,void * buffer,void * data)174 void NativeAreaAllocator::FreeBufferFunc([[maybe_unused]] void *env, void *buffer, void *data)
175 {
176     if (buffer == nullptr || data == nullptr) {
177         return;
178     }
179     NativeAreaAllocator* allocator = reinterpret_cast<NativeAreaAllocator*>(data);
180     allocator->FreeBuffer(buffer);
181 }
182 }  // namespace panda::ecmascript
183