• 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 MTMode = 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 *mem_stats, bool create_pygote_space_allocator);
49 
50     ~ObjectAllocatorG1() final = default;
51 
52     void *Allocate(size_t size, Alignment align, [[maybe_unused]] panda::ManagedThread *thread) final;
53 
54     void *AllocateNonMovable(size_t size, Alignment align, [[maybe_unused]] panda::ManagedThread *thread) final;
55 
56     void VisitAndRemoveAllPools(const MemVisitor &mem_visitor) final;
57 
58     void VisitAndRemoveFreePools(const MemVisitor &mem_visitor) final;
59 
60     void IterateOverYoungObjects(const ObjectVisitor &object_visitor) final;
61 
62     PandaVector<Region *> GetYoungRegions();
63 
64     PandaVector<Region *> GetMovableRegions();
65 
66     PandaVector<Region *> GetAllRegions();
67 
68     /**
69      * Returns a vector which contains non-movable and humongous regions
70      */
71     PandaVector<Region *> GetNonRegularRegions();
72 
73     void IterateOverTenuredObjects(const ObjectVisitor &object_visitor) final;
74 
75     void IterateOverHumongousObjects(const ObjectVisitor &object_visitor);
76 
77     void IterateOverObjects(const ObjectVisitor &object_visitor) final;
78 
79     /**
80      * \brief iterates all objects in object allocator
81      */
82     void IterateRegularSizeObjects(const ObjectVisitor &object_visitor) final;
83 
84     /**
85      * \brief iterates objects in all allocators except object allocator
86      */
87     void IterateNonRegularSizeObjects(const ObjectVisitor &object_visitor) final;
88 
89     void FreeObjectsMovedToPygoteSpace() final;
90 
Collect(const GCObjectVisitor & gc_object_visitor,GCCollectMode collect_mode)91     void Collect(const GCObjectVisitor &gc_object_visitor, GCCollectMode collect_mode) final
92     {
93         (void)gc_object_visitor;
94         (void)collect_mode;
95         UNREACHABLE();
96     }
97 
98     /**
99      * Collect non regular regions (i.e. remove dead objects from Humongous and NonMovable regions
100      * and remove empty regions).
101      */
102     void CollectNonRegularRegions(const RegionsVisitor &region_visitor, const GCObjectVisitor &gc_object_visitor);
103 
104     size_t GetRegularObjectMaxSize() final;
105 
106     size_t GetLargeObjectMaxSize() final;
107 
108     bool IsAddressInYoungSpace(uintptr_t address) final;
109 
110     bool IsIntersectedWithYoung(const MemRange &mem_range) final;
111 
112     bool HasYoungSpace() final;
113 
114     const std::vector<MemRange> &GetYoungSpaceMemRanges() final;
115 
116     template <bool include_current_region>
GetTopGarbageRegions(size_t region_count)117     PandaVector<Region *> GetTopGarbageRegions(size_t region_count)
118     {
119         return object_allocator_->template GetTopGarbageRegions<include_current_region>(region_count);
120     }
121 
122     std::vector<MarkBitmap *> &GetYoungSpaceBitmaps() final;
123 
124     void ResetYoungAllocator() final;
125 
126     template <RegionFlag regions_type>
ResetRegions(const PandaVector<Region * > & regions)127     void ResetRegions(const PandaVector<Region *> &regions)
128     {
129         object_allocator_->ResetSeveralSpecificRegions<regions_type>(regions);
130     }
131 
132     TLAB *CreateNewTLAB(panda::ManagedThread *thread) final;
133 
134     size_t GetTLABMaxAllocSize() final;
135 
IsTLABSupported()136     bool IsTLABSupported() final
137     {
138         return true;
139     }
140 
141     void IterateOverObjectsInRange(MemRange mem_range, const ObjectVisitor &object_visitor) final;
142 
143     bool ContainObject(const ObjectHeader *obj) const final;
144 
145     bool IsLive(const ObjectHeader *obj) final;
146 
VerifyAllocatorStatus()147     size_t VerifyAllocatorStatus() final
148     {
149         LOG(FATAL, ALLOC) << "Not implemented";
150         return 0;
151         // TODO(yyang): add verify for large/humongous allocator
152     }
153 
AllocateLocal(size_t size,Alignment align,panda::ManagedThread * thread)154     [[nodiscard]] void *AllocateLocal([[maybe_unused]] size_t size, [[maybe_unused]] Alignment align,
155                                       [[maybe_unused]] panda::ManagedThread *thread) final
156     {
157         LOG(FATAL, ALLOC) << "ObjectAllocatorGen: AllocateLocal not supported";
158         return nullptr;
159     }
160 
161     bool IsObjectInNonMovableSpace(const ObjectHeader *obj) final;
162 
163     void UpdateSpaceData() final;
164 
165     void CompactYoungRegions(const GCObjectVisitor &death_checker, const ObjectVisitorEx &move_checker);
166 
167     template <RegionFlag region_type, bool use_markbitmap = false>
CompactRegion(Region * region,const GCObjectVisitor & death_checker,const ObjectVisitorEx & move_checker)168     void CompactRegion(Region *region, const GCObjectVisitor &death_checker, const ObjectVisitorEx &move_checker)
169     {
170         object_allocator_->template CompactSpecificRegion<region_type, RegionFlag::IS_OLD, use_markbitmap>(
171             region, death_checker, move_checker);
172     }
173 
174     void PromoteYoungRegion(Region *region, const GCObjectVisitor &death_checker,
175                             const ObjectVisitor &promotion_checker);
176 
177     void CompactTenuredRegions(const PandaVector<Region *> &regions, const GCObjectVisitor &death_checker,
178                                const ObjectVisitorEx &move_checker);
179 
180     void ClearCurrentRegion();
181 
GetRegionSize()182     static constexpr size_t GetRegionSize()
183     {
184         return REGION_SIZE;
185     }
186 
HaveTenuredSize(size_t num_regions)187     bool HaveTenuredSize(size_t num_regions) const
188     {
189         return object_allocator_->GetSpace()->GetPool()->HaveTenuredSize(num_regions * ObjectAllocator::REGION_SIZE);
190     }
191 
HaveFreeRegions(size_t num_regions)192     bool HaveFreeRegions(size_t num_regions) const
193     {
194         return object_allocator_->GetSpace()->GetPool()->HaveFreeRegions(num_regions, ObjectAllocator::REGION_SIZE);
195     }
196 
GetYoungAllocMaxSize()197     static constexpr size_t GetYoungAllocMaxSize()
198     {
199         // TODO(dtrubenkov): FIX to more meaningful value
200         return ObjectAllocator::GetMaxRegularObjectSize();
201     }
202 
203 private:
204     PandaUniquePtr<ObjectAllocator> object_allocator_ {nullptr};
205     PandaUniquePtr<NonMovableAllocator> nonmovable_allocator_ {nullptr};
206     PandaUniquePtr<HumongousObjectAllocator> humongous_object_allocator_ {nullptr};
207     MemStatsType *mem_stats_ {nullptr};
208 
209     void *AllocateTenured(size_t size) final;
210 
211     void *AllocateTenuredWithoutLocks(size_t size) final;
212 
213     friend class AllocTypeConfigG1;
214 };
215 
216 }  // namespace panda::mem
217 
218 #endif  // RUNTIME_MEM_GC_G1_G1_ALLOCATOR_H
219