• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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 #ifndef PANDA_RUNTIME_MEM_INTERNAL_ALLOCATOR_H
16 #define PANDA_RUNTIME_MEM_INTERNAL_ALLOCATOR_H
17 
18 #include <vector>
19 
20 #include "libpandabase/concepts.h"
21 #include "libpandabase/mem/mmap_mem_pool-inl.h"
22 #include "libpandabase/mem/pool_manager.h"
23 #include "libpandabase/os/mutex.h"
24 #include "runtime/mem/freelist_allocator.h"
25 #include "runtime/mem/humongous_obj_allocator.h"
26 #include "runtime/mem/runslots_allocator.h"
27 
28 #ifdef TRACK_INTERNAL_ALLOCATIONS
29 #include "libpandabase/mem/alloc_tracker.h"
30 #endif  // TRACK_INTERNAL_ALLOCATIONS
31 
32 namespace panda::mem {
33 
34 namespace test {
35 class InternalAllocatorTest;
36 }  // namespace test
37 
38 template <typename AllocConfigT>
39 class MallocProxyAllocator;
40 class Allocator;
41 
42 enum class AllocScope {
43     GLOBAL,  // The allocation will be in global storage
44     LOCAL    // The allocation will be in thread-local storage
45 };
46 
47 enum class InternalAllocatorConfig {
48     PANDA_ALLOCATORS,  // Use panda allocators as internal allocator
49     MALLOC_ALLOCATOR   // Use malloc allocator as internal allocator
50 };
51 
52 class RawMemoryConfig;
53 class EmptyMemoryConfig;
54 
55 template <InternalAllocatorConfig Config = InternalAllocatorConfig::PANDA_ALLOCATORS>
56 class InternalAllocator {
57 #ifdef NDEBUG
58     using InternalAllocConfigT = EmptyMemoryConfig;
59 #else
60     using InternalAllocConfigT = RawMemoryConfig;
61 #endif
62 
63 public:
64     explicit InternalAllocator(MemStatsType *mem_stats);
65 
66     NO_COPY_SEMANTIC(InternalAllocator);
67     NO_MOVE_SEMANTIC(InternalAllocator);
68 
69     template <AllocScope AllocScopeT = AllocScope::GLOBAL>
70     [[nodiscard]] void *Alloc(size_t size, Alignment align = DEFAULT_ALIGNMENT);
71 
72     [[nodiscard]] void *AllocLocal(size_t size, Alignment align = DEFAULT_ALIGNMENT)
73     {
74         return Alloc<AllocScope::LOCAL>(size, align);
75     }
76 
77     template <class T>
78     [[nodiscard]] T *AllocArray(size_t size);
79 
80     template <class T>
81     [[nodiscard]] T *AllocArrayLocal(size_t size);
82 
83     template <typename T, typename... Args>
84     [[nodiscard]] std::enable_if_t<!std::is_array_v<T>, T *> New(Args &&... args);
85 
86     template <typename T>
87     [[nodiscard]] std::enable_if_t<is_unbounded_array_v<T>, std::remove_extent_t<T> *> New(size_t size);
88 
89     template <typename T>
90     void DeleteArray(T *data);
91 
92     void Free(void *ptr);
93 
94 #ifdef TRACK_INTERNAL_ALLOCATIONS
Dump()95     void Dump()
96     {
97         tracker_->Dump();
98     }
99 #endif  // TRACK_INTERNAL_ALLOCATIONS
100 
101     template <class T>
102     void Delete(T *ptr);
103 
104     ~InternalAllocator();
105 
106     /**
107      * \brief Iterates over memory pools used by this allocator.
108      * @tparam MemVisitor
109      * @param mem_visitor - function pointer or functor
110      */
111     template <typename MemVisitor>
112     void VisitAndRemoveAllPools(MemVisitor mem_visitor);
113 
114     /**
115      * \brief Visit memory pools that can be returned to the system in this allocator
116      * and remove them from the allocator structure.
117      * @tparam MemVisitor
118      * @param mem_visitor - function pointer or functor
119      */
120     template <typename MemVisitor>
121     void VisitAndRemoveFreePools(MemVisitor mem_visitor);
122 
123     using LocalSmallObjectAllocator = RunSlotsAllocator<InternalAllocConfigT, RunSlotsAllocatorLockConfig::DummyLock>;
124 
125     /**
126      * \brief Create and set up local internal allocator instance for fast small objects allocation
127      * @param allocator - a pointer to the allocator which will be used for local allocator instance storage
128      * @return - a pointer to the local internal allocator instance
129      */
130     static InternalAllocator::LocalSmallObjectAllocator *SetUpLocalInternalAllocator(Allocator *allocator);
131 
132     /**
133      * \brief Delete local internal allocator instance and return all pools to the system
134      * @param allocator - a pointer to the allocator which was used for local allocator instance storage
135      * @param local_allocator - a pointer to the local internal allocator instance
136      */
137     static void FinalizeLocalInternalAllocator(LocalSmallObjectAllocator *local_allocator, Allocator *allocator);
138 
139     /**
140      * \brief Return free memory pools to the system in local internal allocator
141      * and remove them from the allocator structure.
142      * @param local_allocator - a pointer to a local internal allocator instance
143      */
144     static void RemoveFreePoolsForLocalInternalAllocator(LocalSmallObjectAllocator *local_allocator);
145 
146     static void InitInternalAllocatorFromRuntime(Allocator *allocator);
147 
148     static Allocator *GetInternalAllocatorFromRuntime();
149 
150     static void ClearInternalAllocatorFromRuntime();
151 
152 private:
153 #ifdef TRACK_INTERNAL_ALLOCATIONS
154     os::memory::Mutex lock_;
155     MemStatsType *mem_stats_;
156     AllocTracker *tracker_ = nullptr;
157 #endif  // TRACK_INTERNAL_ALLOCATIONS
158     using RunSlotsAllocatorT = RunSlotsAllocator<InternalAllocConfigT>;
159     using FreeListAllocatorT = FreeListAllocator<InternalAllocConfigT>;
160     using HumongousObjAllocatorT = HumongousObjAllocator<InternalAllocConfigT>;
161     using MallocProxyAllocatorT = MallocProxyAllocator<InternalAllocConfigT>;
162     template <AllocScope AllocScopeT>
163     void *AllocViaPandaAllocators(size_t size, Alignment align);
164     void FreeViaPandaAllocators(void *ptr);
165     RunSlotsAllocatorT *runslots_allocator_ {nullptr};
166     FreeListAllocatorT *freelist_allocator_ {nullptr};
167     HumongousObjAllocatorT *humongous_allocator_ {nullptr};
168     MallocProxyAllocatorT *malloc_allocator_ {nullptr};
169     static Allocator *allocator_from_runtime;
170 
171     friend class test::InternalAllocatorTest;
172 };
173 
174 }  // namespace panda::mem
175 
176 #endif  // PANDA_RUNTIME_MEM_INTERNAL_ALLOCATOR_H
177