• 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 #include "common_components/heap/collector/marking_collector.h"
17 #include "common_components/heap/heap_manager.h"
18 #include "common_components/heap/ark_collector/ark_collector.h"
19 #include "common_components/mutator/mutator_manager.h"
20 #include "common_components/tests/test_helper.h"
21 #include <cstdint>
22 
23 using namespace common;
24 
25 namespace common::test {
26 class MarkingCollectorTest : public common::test::BaseTestWithScope {
27 protected:
SetUpTestCase()28     static void SetUpTestCase()
29     {
30         BaseRuntime::GetInstance()->Init();
31     }
32 
TearDownTestCase()33     static void TearDownTestCase()
34     {
35         BaseRuntime::GetInstance()->Fini();
36     }
SetUp()37     void SetUp() override
38     {
39         MutatorManager::Instance().CreateRuntimeMutator(ThreadType::ARK_PROCESSOR);
40     }
41 
TearDown()42     void TearDown() override
43     {
44         MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::ARK_PROCESSOR);
45     }
46 
47     StaticRootTable rootTable_;
ContainsRoot(StaticRootTable & table,const StaticRootTable::StaticRootArray * array,uint32_t size)48     bool ContainsRoot(StaticRootTable& table, const StaticRootTable::StaticRootArray* array, uint32_t size)
49     {
50         bool found = false;
51         auto visitor = [&found, array, size](RefField<>& root) {
52             for (uint32_t i = 0; i < size; ++i) {
53                 if (&root == array->content[i]) {
54                     found = true;
55                     return;
56                 }
57             }
58         };
59         table.VisitRoots(visitor);
60         return found;
61     }
62     class TableMarkingCollctor : public MarkingCollector {
63     public:
64         using MarkingCollector::SetGCReason;
65         using MarkingCollector::MarkingRoots;
66         using MarkingCollector::PushRootToWorkStack;
67         using MarkingCollector::UpdateNativeThreshold;
68     };
69 };
70 
HWTEST_F_L0(MarkingCollectorTest,RunGarbageCollection)71 HWTEST_F_L0(MarkingCollectorTest, RunGarbageCollection)
72 {
73     MarkingCollector& collector = reinterpret_cast<MarkingCollector&>(Heap::GetHeap().GetCollector());
74     Heap::GetHeap().SetGCReason(GCReason::GC_REASON_YOUNG);
75     collector.RunGarbageCollection(0, GCReason::GC_REASON_USER, common::GC_TYPE_FULL);
76     ASSERT_FALSE(Heap::GetHeap().GetCollector().GetGCStats().isYoungGC());
77 
78     Heap::GetHeap().SetGCReason(GCReason::GC_REASON_BACKUP);
79     collector.RunGarbageCollection(0, GCReason::GC_REASON_OOM, common::GC_TYPE_FULL);
80     ASSERT_FALSE(Heap::GetHeap().GetCollector().GetGCStats().isYoungGC());
81 }
82 
HWTEST_F_L0(MarkingCollectorTest,RunGarbageCollectionTest2)83 HWTEST_F_L0(MarkingCollectorTest, RunGarbageCollectionTest2)
84 {
85     MarkingCollector& collector = reinterpret_cast<MarkingCollector&>(Heap::GetHeap().GetCollector());
86     Heap::GetHeap().SetGCReason(GCReason::GC_REASON_YOUNG);
87     collector.RunGarbageCollection(0, GCReason::GC_REASON_YOUNG, common::GC_TYPE_FULL);
88     ASSERT_TRUE(Heap::GetHeap().GetCollector().GetGCStats().isYoungGC());
89 }
90 
HWTEST_F_L0(MarkingCollectorTest,UpdateNativeThresholdTest)91 HWTEST_F_L0(MarkingCollectorTest, UpdateNativeThresholdTest)
92 {
93     TableMarkingCollctor& collector = reinterpret_cast<TableMarkingCollctor&>(Heap::GetHeap().GetCollector());
94     GCParam gcParam;
95     gcParam.minGrowBytes = 1024;
96     Heap::GetHeap().SetNativeHeapThreshold(512);
97     auto oldThreshold = Heap::GetHeap().GetNativeHeapThreshold();
98     collector.UpdateNativeThreshold(gcParam);
99     auto newThreshold = Heap::GetHeap().GetNativeHeapThreshold();
100     EXPECT_NE(newThreshold, oldThreshold);
101 }
102 
HWTEST_F_L0(MarkingCollectorTest,UpdateNativeThresholdTest2)103 HWTEST_F_L0(MarkingCollectorTest, UpdateNativeThresholdTest2)
104 {
105     TableMarkingCollctor& collector = reinterpret_cast<TableMarkingCollctor&>(Heap::GetHeap().GetCollector());
106     Heap::GetHeap().NotifyNativeAllocation(1100 * MB);
107 
108     GCParam param;
109     collector.UpdateNativeThreshold(param);
110     ASSERT_TRUE(Heap::GetHeap().GetNotifiedNativeSize() > MAX_NATIVE_SIZE_INC);
111 }
112 
HWTEST_F_L0(MarkingCollectorTest,MarkingRootsTest)113 HWTEST_F_L0(MarkingCollectorTest, MarkingRootsTest)
114 {
115     TableMarkingCollctor& collector = reinterpret_cast<TableMarkingCollctor&>(Heap::GetHeap().GetCollector());
116     CArrayList<BaseObject *> roots;
117     RegionSpace& theAllocator = reinterpret_cast<RegionSpace&>(Heap::GetHeap().GetAllocator());
118     uintptr_t addr = theAllocator.AllocOldRegion();
119     ASSERT_NE(addr, 0);
120     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
121     RegionDesc* region = RegionDesc::GetRegionDescAt(addr);
122     region->SetRegionType(RegionDesc::RegionType::OLD_REGION);
123     Heap::GetHeap().SetGCReason(GC_REASON_YOUNG);
124     collector.SetGCReason(GC_REASON_YOUNG);
125 
126     roots.push_back(obj);
127     collector.MarkingRoots(roots);
128     ASSERT_TRUE(region->IsInOldSpace());
129 }
130 
HWTEST_F_L0(MarkingCollectorTest,PushRootToWorkStackTest)131 HWTEST_F_L0(MarkingCollectorTest, PushRootToWorkStackTest)
132 {
133     TableMarkingCollctor& collector = reinterpret_cast<TableMarkingCollctor&>(Heap::GetHeap().GetCollector());
134     RegionSpace& theAllocator = reinterpret_cast<RegionSpace&>(Heap::GetHeap().GetAllocator());
135     uintptr_t addr = theAllocator.AllocOldRegion();
136     ASSERT_NE(addr, 0);
137     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
138     RootSet roots;
139     RegionDesc* region = RegionDesc::GetRegionDescAt(addr);
140     region->SetRegionType(RegionDesc::RegionType::RECENT_LARGE_REGION);
141     collector.SetGCReason(GC_REASON_NATIVE);
142     region->MarkObject(obj);
143     bool result = collector.PushRootToWorkStack(&roots, obj);
144     ASSERT_FALSE(result);
145 
146     region->SetRegionType(RegionDesc::RegionType::RECENT_LARGE_REGION);
147     collector.SetGCReason(GC_REASON_YOUNG);
148     result = collector.PushRootToWorkStack(&roots, obj);
149     ASSERT_FALSE(result);
150 
151     region->SetRegionType(RegionDesc::RegionType::OLD_REGION);
152     collector.SetGCReason(GC_REASON_NATIVE);
153     result = collector.PushRootToWorkStack(&roots, obj);
154     ASSERT_FALSE(result);
155 }
156 }