• 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 
16 #ifndef RUNTIME_MEM_GC_G1_G1_ALLOCATOR_H
17 #define RUNTIME_MEM_GC_G1_G1_ALLOCATOR_H
18 
19 #include "runtime/include/mem/allocator.h"
20 #include "runtime/mem/region_allocator.h"
21 #include "runtime/mem/region_allocator-inl.h"
22 #include "runtime/mem/gc/g1/g1-allocator_constants.h"
23 
24 namespace panda::mem {
25 class ObjectAllocConfigWithCrossingMap;
26 class ObjectAllocConfig;
27 class TLAB;
28 
29 template <MTModeT MT_MODE = MT_MODE_MULTI>
30 class ObjectAllocatorG1 final : public ObjectAllocatorGenBase {
31     static constexpr size_t TLAB_SIZE = 4_KB;  // TLAB size for young gen
32 
33     using ObjectAllocator = RegionAllocator<ObjectAllocConfig>;
34     using NonMovableAllocator = RegionNonmovableAllocator<ObjectAllocConfig, RegionAllocatorLockConfig::CommonLock,
35                                                           FreeListAllocator<ObjectAllocConfig>>;
36     using HumongousObjectAllocator =
37         RegionHumongousAllocator<ObjectAllocConfig>;  // Allocator used for humongous objects
38 
39     // REGION_SIZE should not change here.
40     // If it is necessary to change this value, it must be done through changes to G1_REGION_SIZE
41     static constexpr size_t REGION_SIZE = mem::G1_REGION_SIZE;
42     static_assert(REGION_SIZE == mem::G1_REGION_SIZE);
43 
44 public:
45     NO_MOVE_SEMANTIC(ObjectAllocatorG1);
46     NO_COPY_SEMANTIC(ObjectAllocatorG1);
47 
48     explicit ObjectAllocatorG1(MemStatsType *memStats, bool createPygoteSpaceAllocator);
49 
50     ~ObjectAllocatorG1() final = default;
51 
52     void *Allocate(size_t size, Alignment align, [[maybe_unused]] panda::ManagedThread *thread,
53                    ObjMemInitPolicy objInit) final;
54 
55     void *AllocateNonMovable(size_t size, Alignment align, [[maybe_unused]] panda::ManagedThread *thread,
56                              ObjMemInitPolicy objInit) final;
57 
58     void PinObject(ObjectHeader *object) final;
59 
60     void UnpinObject(ObjectHeader *object) final;
61 
62     void VisitAndRemoveAllPools(const MemVisitor &memVisitor) final;
63 
64     void VisitAndRemoveFreePools(const MemVisitor &memVisitor) final;
65 
66     void IterateOverYoungObjects(const ObjectVisitor &objectVisitor) final;
67 
68     size_t GetMaxYoungRegionsCount();
69 
70     PandaVector<Region *> GetYoungRegions();
71 
72     PandaVector<Region *> GetMovableRegions();
73 
74     PandaVector<Region *> GetAllRegions();
75 
76     /// Returns a vector which contains non-movable and humongous regions
77     PandaVector<Region *> GetNonRegularRegions();
78 
79     void IterateOverTenuredObjects(const ObjectVisitor &objectVisitor) final;
80 
81     void IterateOverHumongousObjects(const ObjectVisitor &objectVisitor);
82 
83     void IterateOverObjects(const ObjectVisitor &objectVisitor) final;
84 
85     /// @brief iterates all objects in object allocator
86     void IterateRegularSizeObjects(const ObjectVisitor &objectVisitor) final;
87 
88     /// @brief iterates objects in all allocators except object allocator
89     void IterateNonRegularSizeObjects(const ObjectVisitor &objectVisitor) final;
90 
91     void FreeObjectsMovedToPygoteSpace() final;
92 
Collect(const GCObjectVisitor & gcObjectVisitor,GCCollectMode collectMode)93     void Collect(const GCObjectVisitor &gcObjectVisitor, GCCollectMode collectMode) final
94     {
95         (void)gcObjectVisitor;
96         (void)collectMode;
97         UNREACHABLE();
98     }
99 
100     /**
101      * Collect non regular regions (i.e. remove dead objects from Humongous and NonMovable regions
102      * and remove empty regions).
103      */
104     void CollectNonRegularRegions(const RegionsVisitor &regionVisitor, const GCObjectVisitor &gcObjectVisitor);
105 
106     size_t GetRegularObjectMaxSize() final;
107 
108     size_t GetLargeObjectMaxSize() final;
109 
110     bool IsObjectInYoungSpace(const ObjectHeader *obj) final;
111 
112     bool IsIntersectedWithYoung(const MemRange &memRange) final;
113 
114     bool HasYoungSpace() final;
115 
116     const std::vector<MemRange> &GetYoungSpaceMemRanges() final;
117 
118     template <bool INCLUDE_CURRENT_REGION>
GetTopGarbageRegions()119     PandaPriorityQueue<std::pair<uint32_t, Region *>> GetTopGarbageRegions()
120     {
121         return objectAllocator_->template GetTopGarbageRegions<INCLUDE_CURRENT_REGION>();
122     }
123 
124     std::vector<MarkBitmap *> &GetYoungSpaceBitmaps() final;
125 
ReserveRegionIfNeeded()126     void ReserveRegionIfNeeded()
127     {
128         objectAllocator_->ReserveRegionIfNeeded();
129     }
130 
ReleaseReservedRegion()131     void ReleaseReservedRegion()
132     {
133         objectAllocator_->ReleaseReservedRegion();
134     }
135 
136     void ResetYoungAllocator() final;
137 
138     template <RegionFlag REGIONS_TYPE, RegionSpace::ReleaseRegionsPolicy REGIONS_RELEASE_POLICY,
139               OSPagesPolicy OS_PAGES_POLICY, bool NEED_LOCK, typename Container>
ResetRegions(const Container & regions)140     void ResetRegions(const Container &regions)
141     {
142         objectAllocator_->ResetSeveralSpecificRegions<REGIONS_TYPE, REGIONS_RELEASE_POLICY, OS_PAGES_POLICY, NEED_LOCK>(
143             regions);
144     }
145 
146     TLAB *CreateNewTLAB(panda::ManagedThread *thread) final;
147 
148     size_t GetTLABMaxAllocSize() final;
149 
IsTLABSupported()150     bool IsTLABSupported() final
151     {
152         return true;
153     }
154 
155     void IterateOverObjectsInRange(MemRange memRange, const ObjectVisitor &objectVisitor) final;
156 
157     bool ContainObject(const ObjectHeader *obj) const final;
158 
159     bool IsLive(const ObjectHeader *obj) final;
160 
VerifyAllocatorStatus()161     size_t VerifyAllocatorStatus() final
162     {
163         LOG(FATAL, ALLOC) << "Not implemented";
164         return 0;
165     }
166 
AllocateLocal(size_t size,Alignment align,panda::ManagedThread * thread)167     [[nodiscard]] void *AllocateLocal([[maybe_unused]] size_t size, [[maybe_unused]] Alignment align,
168                                       [[maybe_unused]] panda::ManagedThread *thread) final
169     {
170         LOG(FATAL, ALLOC) << "ObjectAllocatorGen: AllocateLocal not supported";
171         return nullptr;
172     }
173 
174     bool IsObjectInNonMovableSpace(const ObjectHeader *obj) final;
175 
176     void UpdateSpaceData() final;
177 
178     void CompactYoungRegions(const GCObjectVisitor &deathChecker, const ObjectVisitorEx &moveChecker);
179 
180     template <RegionFlag REGION_TYPE, bool USE_MARKBITMAP = false>
CompactRegion(Region * region,const GCObjectVisitor & deathChecker,const ObjectVisitorEx & moveChecker)181     void CompactRegion(Region *region, const GCObjectVisitor &deathChecker, const ObjectVisitorEx &moveChecker)
182     {
183         objectAllocator_->template CompactSpecificRegion<REGION_TYPE, RegionFlag::IS_OLD, USE_MARKBITMAP>(
184             region, deathChecker, moveChecker);
185     }
186 
187     template <bool USE_MARKBITMAP>
PromoteYoungRegion(Region * region,const GCObjectVisitor & deathChecker,const ObjectVisitor & promotionChecker)188     void PromoteYoungRegion(Region *region, const GCObjectVisitor &deathChecker, const ObjectVisitor &promotionChecker)
189     {
190         ASSERT(region->HasFlag(RegionFlag::IS_EDEN));
191         objectAllocator_->template PromoteYoungRegion<USE_MARKBITMAP>(region, deathChecker, promotionChecker);
192     }
193 
194     void CompactTenuredRegions(const PandaVector<Region *> &regions, const GCObjectVisitor &deathChecker,
195                                const ObjectVisitorEx &moveChecker);
196 
ClearCurrentTenuredRegion()197     void ClearCurrentTenuredRegion()
198     {
199         objectAllocator_->template ClearCurrentRegion<IS_OLD>();
200     }
201 
GetRegionSize()202     static constexpr size_t GetRegionSize()
203     {
204         return REGION_SIZE;
205     }
206 
HaveTenuredSize(size_t numRegions)207     bool HaveTenuredSize(size_t numRegions) const
208     {
209         return objectAllocator_->GetSpace()->GetPool()->HaveTenuredSize(numRegions * ObjectAllocator::REGION_SIZE);
210     }
211 
HaveFreeRegions(size_t numRegions)212     bool HaveFreeRegions(size_t numRegions) const
213     {
214         return objectAllocator_->GetSpace()->GetPool()->HaveFreeRegions(numRegions, ObjectAllocator::REGION_SIZE);
215     }
216 
GetYoungAllocMaxSize()217     static constexpr size_t GetYoungAllocMaxSize()
218     {
219         // NOTE(dtrubenkov): FIX to more meaningful value
220         return ObjectAllocator::GetMaxRegularObjectSize();
221     }
222 
223     template <RegionFlag REGION_TYPE, OSPagesPolicy OS_PAGES_POLICY>
ReleaseEmptyRegions()224     void ReleaseEmptyRegions()
225     {
226         objectAllocator_->ReleaseEmptyRegions<REGION_TYPE, OS_PAGES_POLICY>();
227     }
228 
SetDesiredEdenLength(size_t edenLength)229     void SetDesiredEdenLength(size_t edenLength)
230     {
231         objectAllocator_->SetDesiredEdenLength(edenLength);
232     }
233 
234 private:
235     Alignment CalculateAllocatorAlignment(size_t align) final;
236 
237     PandaUniquePtr<ObjectAllocator> objectAllocator_ {nullptr};
238     PandaUniquePtr<NonMovableAllocator> nonmovableAllocator_ {nullptr};
239     PandaUniquePtr<HumongousObjectAllocator> humongousObjectAllocator_ {nullptr};
240     MemStatsType *memStats_ {nullptr};
241 
242     void *AllocateTenured(size_t size) final;
243 
244     void *AllocateTenuredWithoutLocks(size_t size) final;
245 
246     friend class AllocTypeConfigG1;
247 };
248 
249 }  // namespace panda::mem
250 
251 #endif  // RUNTIME_MEM_GC_G1_G1_ALLOCATOR_H
252