1 /*
2 * Copyright (c) 2022 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/mem_map_allocator.h"
17 #include "ecmascript/platform/map.h"
18 #include "ecmascript/platform/os.h"
19
20 namespace panda::ecmascript {
GetInstance()21 MemMapAllocator *MemMapAllocator::GetInstance()
22 {
23 static MemMapAllocator *vmAllocator_ = new MemMapAllocator();
24 return vmAllocator_;
25 }
26
Allocate(size_t size,size_t alignment,bool regular,int prot)27 MemMap MemMapAllocator::Allocate(size_t size, size_t alignment, bool regular, int prot)
28 {
29 if (UNLIKELY(memMapTotalSize_ + size > capacity_)) {
30 LOG_GC(ERROR) << "memory map overflow";
31 return MemMap();
32 }
33
34 MemMap mem;
35 if (regular) {
36 mem = memMapPool_.GetMemFromCache(size);
37 if (mem.GetMem() != nullptr) {
38 memMapTotalSize_ += size;
39 PageProtect(mem.GetMem(), mem.GetSize(), prot);
40 PageTag(mem.GetMem(), size);
41 return mem;
42 }
43 mem = PageMap(REGULAR_REGION_MMAP_SIZE, PAGE_PROT_NONE, alignment);
44 memMapPool_.InsertMemMap(mem);
45 mem = memMapPool_.SplitMemFromCache(mem);
46 } else {
47 mem = memMapFreeList_.GetMemFromList(size);
48 }
49 if (mem.GetMem() != nullptr) {
50 PageProtect(mem.GetMem(), mem.GetSize(), prot);
51 PageTag(mem.GetMem(), mem.GetSize());
52 memMapTotalSize_ += mem.GetSize();
53 }
54 return mem;
55 }
56
Free(void * mem,size_t size,bool isRegular)57 void MemMapAllocator::Free(void *mem, size_t size, bool isRegular)
58 {
59 memMapTotalSize_ -= size;
60 PageTag(mem, size, true);
61 PageProtect(mem, size, PAGE_PROT_NONE);
62 PageRelease(mem, size);
63 if (isRegular) {
64 memMapPool_.AddMemToCache(mem, size);
65 } else {
66 memMapFreeList_.AddMemToList(MemMap(mem, size));
67 }
68 }
69
AdapterSuitablePoolCapacity()70 void MemMapAllocator::AdapterSuitablePoolCapacity()
71 {
72 size_t physicalSize = PhysicalSize();
73 capacity_ = std::max<size_t>(physicalSize / PHY_SIZE_MULTIPLE, MIN_MEM_POOL_CAPACITY);
74 if (capacity_ > LARGE_POOL_SIZE) {
75 capacity_ = std::max<size_t>(capacity_, STANDARD_POOL_SIZE);
76 } else if (capacity_ >= MEDIUM_POOL_SIZE) {
77 capacity_ = std::min<size_t>(capacity_, STANDARD_POOL_SIZE);
78 } else if (capacity_ >= LOW_POOL_SIZE) {
79 capacity_ = std::max<size_t>(capacity_, 128_MB);
80 }
81 LOG_GC(INFO) << "Ark Auto adapter memory pool capacity:" << capacity_;
82 }
83 } // namespace panda::ecmascript
84