1 /* 2 * Copyright (c) 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 16 #ifndef COMMON_COMPONENTS_HEAP_ARK_COLLECTOR_ARKCOLLECTOR_H 17 #define COMMON_COMPONENTS_HEAP_ARK_COLLECTOR_ARKCOLLECTOR_H 18 19 #include <unordered_map> 20 21 #include "common_components/heap/allocator/region_space.h" 22 #include "common_components/heap/collector/copy_data_manager.h" 23 #include "common_components/heap/collector/marking_collector.h" 24 #include "common_interfaces/base_runtime.h" 25 26 namespace common { 27 28 class CopyTable { 29 public: CopyTable(RegionSpace & space)30 explicit CopyTable(RegionSpace& space) : theSpace(space) {} 31 32 // if object is not relocated (forwarded or compacted), return nullptr. RouteObject(BaseObject * old,size_t size)33 BaseObject* RouteObject(BaseObject* old, size_t size) 34 { 35 BaseObject* toAddress = theSpace.RouteObject(old, size); 36 return toAddress; 37 } 38 GetForwardingPointer(BaseObject * old)39 BaseObject* GetForwardingPointer(BaseObject* old) 40 { 41 return old->GetForwardingPointer(); 42 } 43 44 RegionSpace& theSpace; 45 }; 46 47 enum class GCMode: uint8_t { 48 CMC = 0, 49 CONCURRENT_MARK = 1, 50 STW = 2 51 }; 52 53 class ArkCollector : public MarkingCollector { 54 public: ArkCollector(Allocator & allocator,CollectorResources & resources)55 explicit ArkCollector(Allocator& allocator, CollectorResources& resources) 56 : MarkingCollector(allocator, resources), fwdTable_(reinterpret_cast<RegionSpace&>(allocator)) 57 { 58 collectorType_ = CollectorType::SMOOTH_COLLECTOR; 59 } 60 61 ~ArkCollector() override = default; 62 Init(const RuntimeParam & param)63 void Init(const RuntimeParam& param) override 64 { 65 HeapBitmapManager::GetHeapBitmapManager().InitializeHeapBitmap(); 66 ASSERT(GetGCPhase() == GC_PHASE_IDLE); 67 Heap::GetHeap().InstallBarrier(GC_PHASE_IDLE); 68 #ifdef PANDA_TARGET_32 69 // cmc is not adapted for 32-bit systems 70 gcMode_ = GCMode::STW; 71 #else 72 if (param.gcParam.enableStwGC) { 73 gcMode_ = GCMode::STW; 74 } else { 75 gcMode_ = GCMode::CMC; 76 } 77 #endif 78 79 // force STW for RB DFX 80 #ifdef ENABLE_CMC_RB_DFX 81 gcMode_ = GCMode::STW; 82 #endif 83 } 84 Fini()85 void Fini() override 86 { 87 HeapBitmapManager::GetHeapBitmapManager().DestroyHeapBitmap(); 88 } 89 90 bool ShouldIgnoreRequest(GCRequest& request) override; 91 bool MarkObject(BaseObject* obj) const override; 92 93 MarkingRefFieldVisitor CreateMarkingObjectRefFieldsVisitor(WorkStack *workStack, WeakStack *weakStack) override; 94 void MarkingObjectRefFields(BaseObject *obj, MarkingRefFieldVisitor *data) override; 95 96 void FixObjectRefFields(BaseObject* obj) const override; 97 void FixRefField(BaseObject* obj, RefField<>& field) const; 98 99 BaseObject* ForwardObject(BaseObject* fromVersion) override; 100 IsOldPointer(RefField<> & ref)101 bool IsOldPointer(RefField<>& ref) const override { return false; } 102 IsCurrentPointer(RefField<> & ref)103 bool IsCurrentPointer(RefField<>& ref) const override { return false; } 104 AddRawPointerObject(BaseObject * obj)105 void AddRawPointerObject(BaseObject* obj) override 106 { 107 RegionSpace& space = reinterpret_cast<RegionSpace&>(theAllocator_); 108 space.AddRawPointerObject(obj); 109 } 110 RemoveRawPointerObject(BaseObject * obj)111 void RemoveRawPointerObject(BaseObject* obj) override 112 { 113 RegionSpace& space = reinterpret_cast<RegionSpace&>(theAllocator_); 114 space.RemoveRawPointerObject(obj); 115 } 116 117 BaseObject* ForwardUpdateRawRef(ObjectRef& ref); 118 IsFromObject(BaseObject * obj)119 bool IsFromObject(BaseObject* obj) const override 120 { 121 // filter const string object. 122 if (Heap::IsHeapAddress(obj)) { 123 RegionDesc::InlinedRegionMetaData *objMetaRegion = 124 RegionDesc::InlinedRegionMetaData::GetInlinedRegionMetaData(reinterpret_cast<uintptr_t>(obj)); 125 return objMetaRegion->IsFromRegion(); 126 } 127 128 return false; 129 } 130 131 bool IsUnmovableFromObject(BaseObject* obj) const override; 132 133 // this is called when caller assures from-object/from-region still exists. GetForwardingPointer(BaseObject * fromObj)134 BaseObject* GetForwardingPointer(BaseObject* fromObj) { return fwdTable_.GetForwardingPointer(fromObj); } 135 FindToVersion(BaseObject * obj)136 BaseObject* FindToVersion(BaseObject* obj) const override 137 { 138 return const_cast<ArkCollector*>(this)->fwdTable_.GetForwardingPointer(obj); 139 } 140 141 void SetGCThreadQosPriority(common::PriorityMode mode); 142 143 BaseObject* CopyObjectImpl(BaseObject* obj); 144 BaseObject* CopyObjectAfterExclusive(BaseObject* obj) override; 145 146 BaseObject* TryForwardObject(BaseObject* fromVersion); 147 148 bool TryUntagRefField(BaseObject* obj, RefField<>& field, BaseObject*& target) const override; 149 bool TryUpdateRefField(BaseObject* obj, RefField<>& field, BaseObject*& newRef) const override; 150 bool TryForwardRefField(BaseObject* obj, RefField<>& field, BaseObject*& newRef) const override; 151 GetAndTryTagRefField(BaseObject * target)152 RefField<> GetAndTryTagRefField(BaseObject* target) const override 153 { 154 if (IsFromObject(target)) { 155 return RefField<>(target); 156 } else { 157 return RefField<>(target); 158 } 159 } 160 161 protected: CollectLargeGarbage()162 void CollectLargeGarbage() 163 { 164 COMMON_PHASE_TIMER("Collect large garbage"); 165 RegionSpace& space = reinterpret_cast<RegionSpace&>(theAllocator_); 166 GCStats& stats = GetGCStats(); 167 stats.largeSpaceSize = space.LargeObjectSize(); 168 stats.largeGarbageSize = space.CollectLargeGarbage(); 169 stats.collectedBytes += stats.largeGarbageSize; 170 } 171 CollectPinnedGarbage()172 void CollectPinnedGarbage() 173 { 174 RegionSpace& space = reinterpret_cast<RegionSpace&>(theAllocator_); 175 GCStats& stats = GetGCStats(); 176 stats.pinnedSpaceSize = space.PinnedSpaceSize(); 177 stats.collectedBytes += stats.pinnedGarbageSize; 178 } 179 180 void CollectSmallSpace(); 181 void ClearAllGCInfo(); 182 183 void DoGarbageCollection() override; 184 void ProcessStringTable() override; 185 186 void ProcessFinalizers() override; 187 188 private: 189 friend class RemarkAndPreforwardVisitor; 190 template<bool copy> 191 bool TryUpdateRefFieldImpl(BaseObject* obj, RefField<>& ref, BaseObject*& oldRef, BaseObject*& newRef) const; 192 193 enum class EnumRootsPolicy { 194 NO_STW_AND_NO_FLIP_MUTATOR, 195 STW_AND_NO_FLIP_MUTATOR, 196 STW_AND_FLIP_MUTATOR, 197 }; 198 199 template <EnumRootsPolicy policy> 200 CArrayList<BaseObject *> EnumRoots(); 201 202 template <void (&rootsVisitFunc)(const common::RefFieldVisitor &)> EnumRootsImpl(const common::RefFieldVisitor & visitor)203 void EnumRootsImpl(const common::RefFieldVisitor &visitor) 204 { 205 // assemble garbage candidates. 206 reinterpret_cast<RegionSpace &>(theAllocator_).AssembleGarbageCandidates(); 207 reinterpret_cast<RegionSpace &>(theAllocator_).PrepareMarking(); 208 209 COMMON_PHASE_TIMER("enum roots & update old pointers within"); 210 TransitionToGCPhase(GCPhase::GC_PHASE_ENUM, true); 211 212 rootsVisitFunc(visitor); 213 } 214 CArrayList<CArrayList<BaseObject *>> EnumRootsFlip(STWParam& param, const common::RefFieldVisitor &visitor); 215 216 void MarkingHeap(const CArrayList<BaseObject *> &collectedRoots); 217 void PostMarking(); 218 void RemarkAndPreforwardStaticRoots(WorkStack& workStack) override; 219 void ParallelRemarkAndPreforward(WorkStack& workStack); 220 void Preforward(); 221 void ConcurrentPreforward(); 222 223 void PreforwardConcurrentRoots(); 224 void PreforwardStaticWeakRoots(); 225 void PreforwardConcurrencyModelRoots(); 226 227 void PrepareFix(); 228 void ParallelFixHeap(); 229 void FixHeap(); // roots and ref-fields 230 WeakRefFieldVisitor GetWeakRefFieldVisitor(); 231 RefFieldVisitor GetPrefowardRefFieldVisitor(); 232 void PreforwardFlip(); 233 234 CopyTable fwdTable_; 235 236 GCMode gcMode_ = GCMode::CMC; 237 }; 238 } // namespace common 239 240 #endif // COMMON_COMPONENTS_HEAP_ARK_COLLECTOR_ARKCOLLECTOR_H 241