• 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 #ifndef COMMON_COMPONENTS_HEAP_SPACE_OLD_SPACE_H
16 #define COMMON_COMPONENTS_HEAP_SPACE_OLD_SPACE_H
17 
18 #include "common_components/heap/allocator/region_manager.h"
19 #include "common_components/heap/space/regional_space.h"
20 #include "common_components/heap/space/from_space.h"
21 #include "common_components/heap/space/to_space.h"
22 #include "common_components/mutator/mutator.h"
23 #include "common_components/heap/allocator/fix_heap.h"
24 #if defined(COMMON_SANITIZER_SUPPORT)
25 #include "common_components/base/asan_interface.h"
26 #endif
27 
28 namespace common {
29 // regions for small-sized movable objects, which may be moved during gc.
30 class OldSpace : public RegionalSpace {
31 public:
OldSpace(RegionManager & regionManager)32     OldSpace(RegionManager& regionManager)
33         : RegionalSpace(regionManager),
34           tlOldRegionList_("thread-local old regions"),
35           recentFullOldRegionList_("recent full old regions"),
36           oldRegionList_("old regions") {}
37 
38     void DumpRegionStats() const;
39 
AddThreadLocalRegion(RegionDesc * region)40     void AddThreadLocalRegion(RegionDesc* region)
41     {
42         tlOldRegionList_.PrependRegion(region, RegionDesc::RegionType::THREAD_LOCAL_OLD_REGION);
43     }
44 
CollectFixTasks(FixHeapTaskList & taskList)45     void CollectFixTasks(FixHeapTaskList &taskList)
46     {
47         if (Heap::GetHeap().GetGCReason() == GC_REASON_YOUNG) {
48             FixHeapWorker::CollectFixHeapTasks(taskList, oldRegionList_, FIX_OLD_REGION);
49             std::lock_guard<std::mutex> lock(lock_);
50             FixHeapWorker::CollectFixHeapTasks(taskList, tlOldRegionList_, FIX_RECENT_OLD_REGION);
51             FixHeapWorker::CollectFixHeapTasks(taskList, recentFullOldRegionList_, FIX_RECENT_OLD_REGION);
52         } else {
53             FixHeapWorker::CollectFixHeapTasks(taskList, oldRegionList_, FIX_REGION);
54             std::lock_guard<std::mutex> lock(lock_);
55             FixHeapWorker::CollectFixHeapTasks(taskList, tlOldRegionList_, FIX_RECENT_REGION);
56             FixHeapWorker::CollectFixHeapTasks(taskList, recentFullOldRegionList_, FIX_RECENT_REGION);
57         }
58     }
59 
AssembleGarbageCandidates(FromSpace & fromSpace)60     void AssembleGarbageCandidates(FromSpace& fromSpace)
61     {
62         fromSpace.AssembleGarbageCandidates(oldRegionList_);
63     }
64 
GetAllocatedSize()65     size_t GetAllocatedSize() const
66     {
67         return tlOldRegionList_.GetAllocatedSize(false) + recentFullOldRegionList_.GetAllocatedSize() +
68                oldRegionList_.GetAllocatedSize();
69     }
70 
GetUsedUnitCount()71     size_t GetUsedUnitCount() const
72     {
73         return tlOldRegionList_.GetRegionCount() + recentFullOldRegionList_.GetRegionCount() +
74                oldRegionList_.GetUnitCount();
75     }
76 
PromoteRegionList(RegionList & list)77     void PromoteRegionList(RegionList& list)
78     {
79         oldRegionList_.MergeRegionList(list, RegionDesc::RegionType::OLD_REGION);
80     }
81 
AssembleRecentFull()82     void AssembleRecentFull()
83     {
84         oldRegionList_.MergeRegionList(recentFullOldRegionList_, RegionDesc::RegionType::OLD_REGION);
85     }
86 
ClearRSet()87     void ClearRSet()
88     {
89         ClearRSet(tlOldRegionList_.GetHeadRegion());
90         ClearRSet(recentFullOldRegionList_.GetHeadRegion());
91         ClearRSet(oldRegionList_.GetHeadRegion());
92     }
93 
ClearAllGCInfo()94     void ClearAllGCInfo()
95     {
96         ClearGCInfo(oldRegionList_);
97         std::lock_guard<std::mutex> lock(lock_);
98         ClearGCInfo(tlOldRegionList_);
99         ClearGCInfo(recentFullOldRegionList_);
100     }
101 
MarkRememberSet(const std::function<void (BaseObject *)> & func)102     void MarkRememberSet(const std::function<void(BaseObject*)>& func)
103     {
104         auto visitFunc = [&func](RegionDesc* region) {
105             region->VisitRememberSet(func);
106         };
107 
108         auto visitRecentFunc = [&func](RegionDesc* region) {
109             region->VisitRememberSetBeforeMarking(func);
110         };
111 
112         // Need to visit objects allocated before current GC iteration, markingline is used to distinguish them.
113         tlOldRegionList_.VisitAllRegions(visitRecentFunc);
114         recentFullOldRegionList_.VisitAllRegions(visitRecentFunc);
115         oldRegionList_.VisitAllRegions(visitFunc);
116     }
117 
AddFullRegion(RegionDesc * region)118     void AddFullRegion(RegionDesc *region)
119     {
120         recentFullOldRegionList_.PrependRegion(region, RegionDesc::RegionType::OLD_REGION);
121     }
122 
HandleFullThreadLocalRegion(RegionDesc * region)123     void HandleFullThreadLocalRegion(RegionDesc* region)
124     {
125         std::lock_guard<std::mutex> lock(lock_);
126         ASSERT_LOGF(region->GetRegionType() == RegionDesc::RegionType::THREAD_LOCAL_OLD_REGION,
127                     "not thread local old region");
128         tlOldRegionList_.DeleteRegion(region);
129         recentFullOldRegionList_.PrependRegion(region, RegionDesc::RegionType::OLD_REGION);
130     }
131 
132 private:
ClearGCInfo(RegionList & list)133     void ClearGCInfo(RegionList& list)
134     {
135         RegionList tmp("temp region list");
136         list.CopyListTo(tmp);
137         tmp.VisitAllRegions([](RegionDesc* region) {
138             region->ClearMarkingCopyLine();
139             region->ClearLiveInfo();
140             region->ResetMarkBit();
141         });
142     }
143 
ClearRSet(RegionDesc * region)144     void ClearRSet(RegionDesc* region)
145     {
146         while (region != nullptr) {
147             region->ClearRSet();
148             region = region->GetNextRegion();
149         }
150     }
151     // Used to exclude the promotion of TLS regions during the ClearGCInfo phase
152     // This is necessary when the mutator can promote TL to recentFull while the GC is performing ClearGC
153     std::mutex lock_;
154 
155     // regions for thread-local allocation.
156     // regions in this list are already used for allocation but not full yet.
157     RegionList tlOldRegionList_;
158 
159     // recentFullRegionList is a list of regions which become full .
160     RegionList recentFullOldRegionList_;
161 
162     RegionList oldRegionList_;
163 };
164 } // namespace common
165 #endif // COMMON_COMPONENTS_HEAP_SPACE_OLD_SPACE_H
166