• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/heap_region_allocator.h"
17 
18 #include "ecmascript/mem/mark_stack.h"
19 #include "ecmascript/mem/mem_map_allocator.h"
20 #include "ecmascript/mem/region.h"
21 #include "ecmascript/mem/space-inl.h"
22 #include "ecmascript/platform/map.h"
23 
24 namespace panda::ecmascript {
25 constexpr size_t PANDA_POOL_ALIGNMENT_IN_BYTES = 256_KB;
26 
AllocateAlignedRegion(Space * space,size_t capacity,JSThread * thread)27 Region *HeapRegionAllocator::AllocateAlignedRegion(Space *space, size_t capacity, JSThread* thread)
28 {
29     if (capacity == 0) {
30         LOG_ECMA_MEM(FATAL) << "capacity must have a size bigger than 0";
31         UNREACHABLE();
32     }
33     RegionSpaceFlag flags = space->GetRegionFlag();
34     bool isRegular = (flags != RegionSpaceFlag::IN_HUGE_OBJECT_SPACE);
35     bool isMachineCode = (flags == RegionSpaceFlag::IN_MACHINE_CODE_SPACE);
36     auto pool = MemMapAllocator::GetInstance()->Allocate(capacity, DEFAULT_REGION_SIZE, isRegular, isMachineCode);
37     void *mapMem = pool.GetMem();
38     if (mapMem == nullptr) {
39         LOG_ECMA_MEM(FATAL) << "pool is empty " << annoMemoryUsage_.load(std::memory_order_relaxed);
40         UNREACHABLE();
41     }
42 #if ECMASCRIPT_ENABLE_ZAP_MEM
43     if (memset_s(mapMem, capacity, 0, capacity) != EOK) {
44         LOG_FULL(FATAL) << "memset_s failed";
45         UNREACHABLE();
46     }
47 #endif
48     IncreaseAnnoMemoryUsage(capacity);
49 
50     uintptr_t mem = ToUintPtr(mapMem);
51     // Check that the address is 256K byte aligned
52     LOG_ECMA_IF(AlignUp(mem, PANDA_POOL_ALIGNMENT_IN_BYTES) != mem, FATAL) << "region not align by 256KB";
53 
54     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
55     uintptr_t begin = AlignUp(mem + sizeof(Region), static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION));
56     uintptr_t end = mem + capacity;
57 
58     return new (ToVoidPtr(mem)) Region(thread, mem, begin, end, flags);
59 }
60 
FreeRegion(Region * region)61 void HeapRegionAllocator::FreeRegion(Region *region)
62 {
63     auto size = region->GetCapacity();
64     bool isRegular = !(region->InHugeObjectSpace());
65     auto allocateBase = region->GetAllocateBase();
66 
67     DecreaseAnnoMemoryUsage(size);
68     region->Invalidate();
69     region->ClearMembers();
70 #if ECMASCRIPT_ENABLE_ZAP_MEM
71     if (memset_s(ToVoidPtr(allocateBase), size, INVALID_VALUE, size) != EOK) {
72         LOG_FULL(FATAL) << "memset_s failed";
73         UNREACHABLE();
74     }
75 #endif
76     MemMapAllocator::GetInstance()->Free(ToVoidPtr(allocateBase), size, isRegular);
77 }
78 }  // namespace panda::ecmascript
79