• 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_TASK_H
16 #define PANDA_RUNTIME_MEM_GC_G1_G1_EVACUATE_REGIONS_TASK_H
17 
18 #include "runtime/mem/gc/workers/gc_workers_tasks.h"
19 #include "runtime/mem/gc/g1/g1-evacuate-regions-worker-state-inl.h"
20 
21 namespace ark::mem {
22 
23 class GcThreadScope {
24 public:
GcThreadScope(Thread * gcThread)25     explicit GcThreadScope(Thread *gcThread) : previous_(Thread::GetCurrent())
26     {
27         Thread::SetCurrent(gcThread);
28     }
29 
~GcThreadScope()30     ~GcThreadScope()
31     {
32         Thread::SetCurrent(previous_);
33     }
34 
35     DEFAULT_COPY_SEMANTIC(GcThreadScope);
36     DEFAULT_MOVE_SEMANTIC(GcThreadScope);
37 
38 private:
39     Thread *previous_;
40 };
41 
42 template <typename LanguageConfig>
43 class G1EvacuateRegionsTask : public GCWorkersTask {
44 public:
G1EvacuateRegionsTask(G1EvacuateRegionsWorkerState<LanguageConfig> * state)45     explicit G1EvacuateRegionsTask(G1EvacuateRegionsWorkerState<LanguageConfig> *state)
46         : GCWorkersTask(GCWorkersTaskTypes::TASK_EVACUATE_REGIONS, state)
47     {
48     }
49 
50     DEFAULT_COPY_SEMANTIC(G1EvacuateRegionsTask);
51     DEFAULT_MOVE_SEMANTIC(G1EvacuateRegionsTask);
52     ~G1EvacuateRegionsTask() = default;
53 
Work()54     void Work()
55     {
56         GcThreadScope gcThreadScope(GetState()->GetShared()->GetGcThread());
57         GetState()->Work();
58     }
59 
60 private:
GetState()61     G1EvacuateRegionsWorkerState<LanguageConfig> *GetState() const
62     {
63         return static_cast<G1EvacuateRegionsWorkerState<LanguageConfig> *>(storage_);
64     }
65 };
66 
67 template <class LanguageConfig>
68 class ParallelCompactionTask {
69 public:
ParallelCompactionTask(G1GC<LanguageConfig> * gc,ObjectAllocatorG1<LanguageConfig::MT_MODE> * objectAllocator,RemSet<> * remset,const CollectionSet & collectionSet)70     ParallelCompactionTask(G1GC<LanguageConfig> *gc, ObjectAllocatorG1<LanguageConfig::MT_MODE> *objectAllocator,
71                            RemSet<> *remset, const CollectionSet &collectionSet)
72         : gc_(gc),
73           internalAllocator_(gc->GetInternalAllocator()),
74           objectAllocator_(objectAllocator),
75           shared_(Thread::GetCurrent(), gc->GetSettings()->GCWorkersCount(), remset),
76           queues_(shared_.GetWorkersCount())
77     {
78         for (auto *region : collectionSet) {
79             auto allocated = region->GetAllocatedBytes();
80             if (region->HasFlag(RegionFlag::IS_EDEN)) {
81                 allocatedBytesYoung_ += allocated;
82             } else {
83                 allocatedBytesOld_ += allocated;
84             }
85         }
86     }
87 
88     NO_COPY_SEMANTIC(ParallelCompactionTask);
89     NO_MOVE_SEMANTIC(ParallelCompactionTask);
90 
~ParallelCompactionTask()91     ~ParallelCompactionTask()
92     {
93         for (auto *state : workerStates_) {
94             internalAllocator_->Delete(state);
95         }
96     }
97 
Run()98     void Run()
99     {
100         Submit();
101         gc_->GetWorkersTaskPool()->WaitUntilTasksEnd();
102         LOG_IF(gc_->GetSettings()->LogDetailedGCInfoEnabled(), INFO, GC)
103             << "Waited all workers for "
104             << ark::helpers::TimeConverter(ark::time::GetCurrentTimeInNanos() - beforeSubmitTime_);
105     }
106 
FlushDirtyCards(GCG1BarrierSet::ThreadLocalCardQueues * queue)107     void FlushDirtyCards(GCG1BarrierSet::ThreadLocalCardQueues *queue)
108     {
109         for (auto *state : workerStates_) {
110             state->VisitCards([queue](auto *card) {
111                 if (!card->IsMarked()) {
112                     card->Mark();
113                     queue->push_back(card);
114                 }
115             });
116         }
117     }
118 
Finish()119     void Finish()
120     {
121         for (auto *state : workerStates_) {
122             state->GetRegionTo()->SetLiveBytes(state->GetRegionTo()->GetLiveBytes() + state->GetLiveBytes());
123             objectAllocator_->template PushToOldRegionQueue<true>(state->GetRegionTo());
124 
125             copiedBytesYoung_ += state->GetCopiedBytesYoung();
126             copiedObjectsYoung_ += state->GetCopiedObjectsYoung();
127 
128             copiedBytesOld_ += state->GetCopiedBytesOld();
129             copiedObjectsOld_ += state->GetCopiedObjectsOld();
130         }
131 
132         if (gc_->GetSettings()->LogDetailedGCInfoEnabled()) {
133             DumpStats();
134         }
135     }
136 
GetCopiedBytesYoung()137     size_t GetCopiedBytesYoung() const
138     {
139         return copiedBytesYoung_;
140     }
141 
GetCopiedObjectsYoung()142     size_t GetCopiedObjectsYoung() const
143     {
144         return copiedObjectsYoung_;
145     }
146 
GetCopiedBytesOld()147     size_t GetCopiedBytesOld() const
148     {
149         return copiedBytesOld_;
150     }
151 
GetCopiedObjectsOld()152     size_t GetCopiedObjectsOld() const
153     {
154         return copiedObjectsOld_;
155     }
156 
GetFreedBytesYoung()157     size_t GetFreedBytesYoung() const
158     {
159         return allocatedBytesYoung_ - copiedBytesYoung_;
160     }
161 
GetFreedBytesOld()162     size_t GetFreedBytesOld() const
163     {
164         return allocatedBytesOld_ - copiedBytesOld_;
165     }
166 
167 private:
168     using TaskQueue = PandaVector<typename ObjectReference<LanguageConfig::LANG_TYPE>::Type>;
169 
Submit()170     void Submit()
171     {
172         beforeSubmitTime_ = ark::time::GetCurrentTimeInNanos();
173         auto workersCount = shared_.GetWorkersCount();
174         for (size_t i = 0; i < workersCount; i++) {
175             auto *state = internalAllocator_->template New<G1EvacuateRegionsWorkerState<LanguageConfig>>(
176                 gc_, i, &queues_[i], &shared_);
177             bool added = gc_->GetWorkersTaskPool()->AddTask(G1EvacuateRegionsTask(state));
178             if (!added) {
179                 LOG(INFO, GC) << "Not enough workers to add task #" << i;
180                 state->Work();
181             }
182             workerStates_.push_back(state);
183         }
184     }
185 
DumpStats()186     void DumpStats() const
187     {
188         for (auto *state : workerStates_) {
189             LOG(INFO, GC) << "Worker #" << state->GetId() << " started +"
190                           << ark::helpers::TimeConverter(state->GetTaskStart() - beforeSubmitTime_);
191             LOG(INFO, GC) << "Worker #" << state->GetId() << " finished +"
192                           << ark::helpers::TimeConverter(state->GetTaskEnd() - beforeSubmitTime_);
193             LOG(INFO, GC) << "Worker #" << state->GetId() << " duration "
194                           << ark::helpers::TimeConverter(state->GetTaskEnd() - state->GetTaskStart());
195             state->DumpStat();
196         }
197     }
198 
199     G1GC<LanguageConfig> *gc_;
200     InternalAllocatorPtr internalAllocator_;
201     ObjectAllocatorG1<LanguageConfig::MT_MODE> *objectAllocator_;
202     PandaVector<G1EvacuateRegionsWorkerState<LanguageConfig> *> workerStates_;
203     SharedState shared_;
204     PandaVector<TaskQueue> queues_;
205 
206     uint64_t beforeSubmitTime_ {0};
207     size_t allocatedBytesYoung_ {0};
208     size_t allocatedBytesOld_ {0};
209 
210     size_t copiedBytesYoung_ {0};
211     size_t copiedObjectsYoung_ {0};
212     size_t copiedBytesOld_ {0};
213     size_t copiedObjectsOld_ {0};
214 };
215 
216 }  // namespace ark::mem
217 #endif
218