• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #ifndef PANDA_LIBPANDABASE_MEM_STACK_LIKE_ALLOCATOR_H
16 #define PANDA_LIBPANDABASE_MEM_STACK_LIKE_ALLOCATOR_H
17 
18 #include "libpandabase/mem/mem.h"
19 #include "libpandabase/mem/pool_map.h"
20 
21 namespace ark::mem {
22 // Note: we only have 4GB of memory on arm32, so we need to limit the max size of the stack like allocator
23 // details can be found in #26461
24 #ifdef PANDA_TARGET_ARM32
25 static constexpr size_t STACK_LIKE_ALLOCATOR_DEFAUL_MAX_SIZE = 2_MB;
26 #else
27 static constexpr size_t STACK_LIKE_ALLOCATOR_DEFAUL_MAX_SIZE = 48_MB;
28 #endif
29 
30 //                                          Allocation flow looks like that:
31 //
32 //  1. Allocate big memory piece via mmap.
33 //  2. Allocate/Free memory in this preallocated memory piece.
34 //  3. Return nullptr if we reached the limit of created memory piece.
35 
36 template <Alignment ALIGNMENT = DEFAULT_FRAME_ALIGNMENT, size_t MAX_SIZE = STACK_LIKE_ALLOCATOR_DEFAUL_MAX_SIZE>
37 class StackLikeAllocator {
38 public:
39     explicit StackLikeAllocator(bool usePoolManager = true, SpaceType spaceType = SpaceType::SPACE_TYPE_FRAMES);
40     ~StackLikeAllocator();
41     NO_MOVE_SEMANTIC(StackLikeAllocator);
42     NO_COPY_SEMANTIC(StackLikeAllocator);
43 
44     template <bool USE_MEMSET = true>
45     [[nodiscard]] void *Alloc(size_t size);
46 
47     void Free(void *mem);
48 
49     /// @brief Returns true if address inside current allocator.
50     bool Contains(void *mem);
51 
GetAllocatorType()52     static constexpr AllocatorType GetAllocatorType()
53     {
54         return AllocatorType::STACK_LIKE_ALLOCATOR;
55     }
56 
GetAllocatedSize()57     size_t GetAllocatedSize() const
58     {
59         ASSERT(ToUintPtr(freePointer_) >= ToUintPtr(startAddr_));
60         return ToUintPtr(freePointer_) - ToUintPtr(startAddr_);
61     }
62 
SetReservedMemorySize(size_t size)63     void SetReservedMemorySize(size_t size)
64     {
65         ASSERT(GetFullMemorySize() >= size);
66         reservedEndAddr_ = ToVoidPtr(ToUintPtr(startAddr_) + size);
67     }
68 
UseWholeMemory()69     void UseWholeMemory()
70     {
71         endAddr_ = allocatedEndAddr_;
72     }
73 
ReserveMemory()74     void ReserveMemory()
75     {
76         ASSERT(reservedEndAddr_ != nullptr);
77         endAddr_ = reservedEndAddr_;
78     }
79 
GetFullMemorySize()80     size_t GetFullMemorySize() const
81     {
82         return ToUintPtr(allocatedEndAddr_) - ToUintPtr(startAddr_);
83     }
84 
85 private:
86     static constexpr size_t RELEASE_PAGES_SIZE = 256_KB;
87     static constexpr size_t RELEASE_PAGES_SHIFT = 18;
88     static_assert(RELEASE_PAGES_SIZE == (1U << RELEASE_PAGES_SHIFT));
89     static_assert(MAX_SIZE % GetAlignmentInBytes(ALIGNMENT) == 0);
90     void *startAddr_ {nullptr};
91     void *endAddr_ {nullptr};
92     void *freePointer_ {nullptr};
93     bool usePoolManager_ {false};
94     void *reservedEndAddr_ {nullptr};
95     void *allocatedEndAddr_ {nullptr};
96 };
97 }  // namespace ark::mem
98 
99 #endif  // PANDA_LIBPANDABASE_MEM_STACK_LIKE_ALLOCATOR_H
100