• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-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 
16 #ifndef PANDA_RUNTIME_MEM_GC_GC_WORKERS_TASKS_H
17 #define PANDA_RUNTIME_MEM_GC_GC_WORKERS_TASKS_H
18 
19 #include "runtime/mem/gc/g1/ref_updater.h"
20 #include "runtime/mem/gc/gc_root.h"
21 #include "runtime/thread_pool_queue.h"
22 #include "libpandabase/utils/range.h"
23 
24 namespace ark::mem {
25 
26 enum class GCWorkersTaskTypes : uint32_t {
27     TASK_EMPTY,
28     TASK_MARKING,
29     TASK_REMARK,
30     TASK_FULL_MARK,
31     TASK_REGION_COMPACTING,
32     TASK_RETURN_FREE_PAGES_TO_OS,
33     TASK_UPDATE_REMSET_REFS,
34     TASK_ENQUEUE_REMSET_REFS,
35     TASK_EVACUATE_REGIONS,
36 };
37 
GCWorkersTaskTypesToString(GCWorkersTaskTypes type)38 constexpr const char *GCWorkersTaskTypesToString(GCWorkersTaskTypes type)
39 {
40     switch (type) {
41         case GCWorkersTaskTypes::TASK_EMPTY:
42             return "Empty task";
43         case GCWorkersTaskTypes::TASK_MARKING:
44             return "Marking task";
45         case GCWorkersTaskTypes::TASK_REMARK:
46             return "Remark task";
47         case GCWorkersTaskTypes::TASK_FULL_MARK:
48             return "Marking task for full collection";
49         case GCWorkersTaskTypes::TASK_REGION_COMPACTING:
50             return "Region compacting task";
51         case GCWorkersTaskTypes::TASK_RETURN_FREE_PAGES_TO_OS:
52             return "Return free pages to the OS";
53         case GCWorkersTaskTypes::TASK_UPDATE_REMSET_REFS:
54             return "Update remset references task";
55         case GCWorkersTaskTypes::TASK_ENQUEUE_REMSET_REFS:
56             return "Enqueue remset references task";
57         case GCWorkersTaskTypes::TASK_EVACUATE_REGIONS:
58             return "Evacuate regions task";
59         default:
60             return "Unknown task";
61     }
62 }
63 
64 class GCWorkersTask : public TaskInterface {
65 public:
taskType_(type)66     explicit GCWorkersTask(GCWorkersTaskTypes type = GCWorkersTaskTypes::TASK_EMPTY) : taskType_(type)
67     {
68         ASSERT(type == GCWorkersTaskTypes::TASK_EMPTY || type == GCWorkersTaskTypes::TASK_RETURN_FREE_PAGES_TO_OS);
69     }
70 
71     ~GCWorkersTask() = default;
72     DEFAULT_COPY_SEMANTIC(GCWorkersTask);
73     DEFAULT_MOVE_SEMANTIC(GCWorkersTask);
74 
IsEmpty()75     bool IsEmpty() const
76     {
77         return taskType_ == GCWorkersTaskTypes::TASK_EMPTY;
78     }
79 
80     template <class GCWorkersTaskT>
Cast()81     std::enable_if_t<std::is_base_of_v<GCWorkersTask, GCWorkersTaskT>, GCWorkersTaskT *> Cast() const
82     {
83         return static_cast<GCWorkersTaskT *>(const_cast<GCWorkersTask *>(this));
84     }
85 
86     template <class GCWorkersTaskT>
87     std::enable_if_t<!std::is_base_of_v<GCWorkersTask, GCWorkersTaskT>, GCWorkersTaskT *> Cast() const = delete;
88 
GetType()89     GCWorkersTaskTypes GetType() const
90     {
91         return taskType_;
92     }
93 
94 private:
95     GCWorkersTaskTypes taskType_;
96 
97 protected:
98     using StorageType = void *;
99 
GCWorkersTask(GCWorkersTaskTypes type,StorageType taskStorageData)100     GCWorkersTask(GCWorkersTaskTypes type, StorageType taskStorageData) : taskType_(type), storage_(taskStorageData)
101     {
102         ASSERT(storage_ != nullptr);
103     }
104 
105     StorageType storage_ {nullptr};  // NOLINT(misc-non-private-member-variables-in-classes)
106 };
107 
108 class GCMarkWorkersTask : public GCWorkersTask {
109 public:
110     using StackType = GCMarkingStackType;
GCMarkWorkersTask(GCWorkersTaskTypes type,StackType * markingStack)111     GCMarkWorkersTask(GCWorkersTaskTypes type, StackType *markingStack) : GCWorkersTask(type, markingStack)
112     {
113         ASSERT(type == GCWorkersTaskTypes::TASK_MARKING || type == GCWorkersTaskTypes::TASK_REMARK ||
114                type == GCWorkersTaskTypes::TASK_FULL_MARK);
115     }
116     DEFAULT_COPY_SEMANTIC(GCMarkWorkersTask);
117     DEFAULT_MOVE_SEMANTIC(GCMarkWorkersTask);
118     ~GCMarkWorkersTask() = default;
119 
GetMarkingStack()120     StackType *GetMarkingStack() const
121     {
122         return static_cast<StackType *>(storage_);
123     }
124 };
125 
126 class Region;
127 
128 class GCRegionCompactWorkersTask : public GCWorkersTask {
129 public:
130     using RegionDataType = std::pair<Region *, ObjectVisitor>;
131 
GCRegionCompactWorkersTask(RegionDataType * regionData)132     explicit GCRegionCompactWorkersTask(RegionDataType *regionData)
133         : GCWorkersTask(GCWorkersTaskTypes::TASK_REGION_COMPACTING, regionData)
134     {
135     }
136     DEFAULT_COPY_SEMANTIC(GCRegionCompactWorkersTask);
137     DEFAULT_MOVE_SEMANTIC(GCRegionCompactWorkersTask);
138     ~GCRegionCompactWorkersTask() = default;
139 
GetRegionData()140     RegionDataType *GetRegionData() const
141     {
142         return static_cast<RegionDataType *>(storage_);
143     }
144 };
145 
146 template <bool VECTOR>
147 class GCUpdateRefsWorkersTask : public GCWorkersTask {
148 public:
149     using MovedObjectsRange = std::conditional_t<VECTOR, Range<PandaVector<ObjectHeader *>::iterator>,
150                                                  Range<PandaDeque<ObjectHeader *>::iterator>>;
151     // We need this to evenly split moved objects vector to ranges for gc workers
152     static constexpr int RANGE_SIZE = 4096;
153 
GCUpdateRefsWorkersTask(MovedObjectsRange * movedObjects)154     explicit GCUpdateRefsWorkersTask(MovedObjectsRange *movedObjects)
155         : GCWorkersTask(GCWorkersTaskTypes::TASK_ENQUEUE_REMSET_REFS, movedObjects)
156     {
157     }
158     DEFAULT_COPY_SEMANTIC(GCUpdateRefsWorkersTask);
159     DEFAULT_MOVE_SEMANTIC(GCUpdateRefsWorkersTask);
160     ~GCUpdateRefsWorkersTask() = default;
161 
GetMovedObjectsRange()162     MovedObjectsRange *GetMovedObjectsRange() const
163     {
164         return static_cast<MovedObjectsRange *>(storage_);
165     }
166 };
167 
168 }  // namespace ark::mem
169 
170 #endif  // PANDA_RUNTIME_MEM_GC_GC_WORKERS_TASKS_H
171