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 ®ion_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 *> ®ions) 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 *> ®ions, 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