• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 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 #ifndef PANDA_RUNTIME_MEM_GC_G1_G1_EVACUATE_REGIONS_WORKER_STATE_H
16 #define PANDA_RUNTIME_MEM_GC_G1_G1_EVACUATE_REGIONS_WORKER_STATE_H
17 
18 #include "runtime/mem/lock_config_helper.h"
19 #include "runtime/include/coretypes/tagged_value.h"
20 #include "runtime/mark_word.h"
21 #include "runtime/include/mem/panda_containers.h"
22 #include "runtime/mem/gc/g1/g1-object-pointer-handlers.h"
23 
24 namespace ark::mem {
25 template <typename LanguageConfig>
26 class G1GC;
27 
28 template <MTModeT MODE>
29 class ObjectAllocatorG1;
30 
31 class CardTable;
32 
33 class SharedState;
34 
35 /// Data and methods to evacuate live objects by one worker.
36 template <typename LanguageConfig>
37 class G1EvacuateRegionsWorkerState {
38 public:
39     using Ref = typename ObjectReference<LanguageConfig::LANG_TYPE>::Type;
40 
41     G1EvacuateRegionsWorkerState(G1GC<LanguageConfig> *gc, uint id, PandaVector<Ref> *queue, SharedState *shared);
42 
GetId()43     uint GetId() const
44     {
45         return id_;
46     };
47 
ProcessQueue()48     void ProcessQueue()
49     {
50         while (!queue_->empty()) {
51             Ref p = queue_->back();
52             queue_->pop_back();
53             ProcessRef(p);
54         }
55     }
56 
PushToQueue(Ref p)57     void PushToQueue(Ref p)
58     {
59         queue_->push_back(p);
60     }
61 
62     /// Evacuate single live object, traverse its fields and enqueue found references to the queue_
63     ObjectHeader *Evacuate(ObjectHeader *obj, MarkWord markWord);
64 
GetGC()65     G1GC<LanguageConfig> *GetGC()
66     {
67         return gc_;
68     }
69 
GetCopiedBytesYoung()70     size_t GetCopiedBytesYoung() const
71     {
72         return copiedBytesYoung_;
73     }
74 
GetCopiedObjectsYoung()75     size_t GetCopiedObjectsYoung() const
76     {
77         return copiedObjectsYoung_;
78     }
79 
GetCopiedBytesOld()80     size_t GetCopiedBytesOld() const
81     {
82         return copiedBytesOld_;
83     }
84 
GetCopiedObjectsOld()85     size_t GetCopiedObjectsOld() const
86     {
87         return copiedObjectsOld_;
88     }
89 
GetLiveBytes()90     size_t GetLiveBytes() const
91     {
92         return liveBytes_;
93     }
94 
GetRegionTo()95     Region *GetRegionTo()
96     {
97         return regionTo_;
98     }
99 
GetShared()100     SharedState *GetShared()
101     {
102         return shared_;
103     }
104 
IsSameRegion(void * ref,void * obj)105     bool IsSameRegion(void *ref, void *obj) const
106     {
107         return ark::mem::IsSameRegion(ref, obj, regionSizeBits_);
108     }
109 
EnqueueCard(void * p)110     void EnqueueCard(void *p)
111     {
112         auto *card = cardTable_->GetCardPtr(ToUintPtr(p));
113         if (card != latestCard_) {
114             cardQueue_.insert(card);
115             latestCard_ = card;
116         }
117     }
118 
119     template <typename Visitor>
VisitCards(Visitor visitor)120     void VisitCards(Visitor visitor)
121     {
122         for (auto *card : cardQueue_) {
123             visitor(card);
124         }
125     }
126 
GetTaskStart()127     uint64_t GetTaskStart() const
128     {
129         return taskStart_;
130     }
131 
GetTaskEnd()132     uint64_t GetTaskEnd() const
133     {
134         return taskEnd_;
135     }
136 
DumpStat()137     void DumpStat() const
138     {
139         LOG(INFO, GC) << "=== Worker #" << GetId();
140         LOG(INFO, GC) << "non heap roots scan duration " << ark::helpers::TimeConverter(scanNonHeapRootsDuration_);
141         LOG(INFO, GC) << "added refs from non heap roots " << addNonHeapRootsRefsCount_;
142         LOG(INFO, GC) << "remset scan duration " << ark::helpers::TimeConverter(scanRemsetDuration_);
143         LOG(INFO, GC) << "remset count " << remsetCount_;
144         LOG(INFO, GC) << "added refs from remset " << foundRemsetRefsCount_;
145         LOG(INFO, GC) << "reenque cards " << reenqueueCardsCount_;
146         LOG(INFO, GC) << "evacuation duration " << ark::helpers::TimeConverter(evacuationDuration_);
147         LOG(INFO, GC) << "evacuation add cards " << evacuationAddCardsCount_;
148     }
149 
Work()150     void Work()
151     {
152         StartWork();
153 
154         Init();
155         EvacuateNonHeapRoots();
156         ScanRemset();
157         EvacuateLiveObjects();
158 
159         EndWork();
160     }
161 
162 private:
163     void StartWork();
Init()164     void Init()
165     {
166         constexpr size_t RESERVED_SIZE = 200000;
167         queue_->reserve(RESERVED_SIZE);
168         regionTo_ = GetNextRegion();
169     }
170 
171     void EndWork();
172     void EvacuateNonHeapRoots();
173     void ScanRemset();
174     template <typename Visitor>
175     void IterateRefsInMemRange(const MemRange &memRange, Region *region, Visitor *visitor);
176     void EvacuateLiveObjects();
177 
GetNextRegion()178     Region *GetNextRegion()
179     {
180         auto *region = objectAllocator_->template PopFromOldRegionQueue<true>();
181         if (region != nullptr) {
182             return region;
183         }
184         return CreateNewRegion();
185     }
186 
CreateNewRegion()187     Region *CreateNewRegion()
188     {
189         return objectAllocator_->template CreateAndSetUpNewOldRegion<true>();
190     }
191 
192     void ProcessRef(Ref p);
193 
194     ObjectHeader *SetForwardAddress(ObjectHeader *src, ObjectHeader *dst, MarkWord markWord);
195 
196     G1GC<LanguageConfig> *gc_;
197     ObjectAllocatorG1<LanguageConfig::MT_MODE> *objectAllocator_;
198     CardTable *cardTable_;
199     size_t regionSizeBits_;
200     uint id_;
201     SharedState *shared_;
202     PandaVector<Ref> *queue_;
203     EvacuationObjectPointerHandler<LanguageConfig> evacuationObjectPointerHandler_;
204 
205     PandaSet<CardTable::CardPtr> cardQueue_;
206     CardTable::CardPtr latestCard_ {nullptr};
207 
208     uint64_t taskStart_ {0};
209     uint64_t taskEnd_ {0};
210 
211     size_t copiedBytesYoung_ {0};
212     size_t copiedObjectsYoung_ {0};
213     size_t copiedBytesOld_ {0};
214     size_t copiedObjectsOld_ {0};
215     size_t liveBytes_ {0};
216     Region *regionTo_ {nullptr};
217 
218     uint64_t scanNonHeapRootsDuration_ {0};
219     uint64_t addNonHeapRootsRefsCount_ {0};
220 
221     uint64_t scanRemsetDuration_ {0};
222     uint64_t foundRemsetRefsCount_ {0};
223     uint64_t remsetCount_ {0};
224 
225     uint64_t evacuationDuration_ {0};
226     uint64_t reenqueueCardsCount_ {0};
227     uint64_t evacuationAddCardsCount_ {0};
228 };
229 
230 /// Common data which is shared between workers.
231 class SharedState {
232 public:
SharedState(Thread * gcThread,size_t workersCount,RemSet<> * remset)233     SharedState(Thread *gcThread, size_t workersCount, RemSet<> *remset)
234         : gcThread_(gcThread), workersCount_(workersCount), remset_(remset)
235     {
236     }
237 
GetGcThread()238     Thread *GetGcThread() const
239     {
240         return gcThread_;
241     }
242 
GetWorkersCount()243     size_t GetWorkersCount() const
244     {
245         return workersCount_;
246     }
247 
GetRemset()248     RemSet<> *GetRemset() const
249     {
250         return remset_;
251     }
252 
253     /// Counter which can be used to distribute remset processing between workers
GetRemsetCounter()254     std::atomic<size_t> &GetRemsetCounter()
255     {
256         return remsetCounter_;
257     }
258 
259 private:
260     Thread *gcThread_;
261     size_t workersCount_;
262     std::atomic<size_t> remsetCounter_ {};
263     RemSet<> *remset_;
264 };
265 
266 }  // namespace ark::mem
267 #endif
268