• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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