• 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/ark_collector/ark_collector.h"
17 #include "common_components/heap/verification.cpp"
18 #include "common_components/heap/heap_manager.h"
19 #include "common_components/tests/test_helper.h"
20 #include "common_interfaces/objects/base_object_operator.h"
21 
22 using namespace common;
23 namespace common::test {
24 class TestBaseObjectOperator : public common::BaseObjectOperatorInterfaces {
25 public:
IsValidObject(const BaseObject * object) const26     bool IsValidObject([[maybe_unused]] const BaseObject *object) const override { return enbaleValidObject_; }
ForEachRefField(const BaseObject * object,const common::RefFieldVisitor & visitor) const27     void ForEachRefField(const BaseObject *object, const common::RefFieldVisitor &visitor) const override {}
GetSize(const BaseObject * object) const28     size_t GetSize(const BaseObject *object) const override{ return size_; }
GetForwardingPointer(const BaseObject * object) const29     BaseObject *GetForwardingPointer(const BaseObject *object) const override { return nullptr; }
SetForwardingPointerAfterExclusive(BaseObject * object,BaseObject * fwdPtr)30     void SetForwardingPointerAfterExclusive(BaseObject *object, BaseObject *fwdPtr) override {}
SetValidObject(bool value)31     void SetValidObject(bool value) { enbaleValidObject_ = value; }
SetSize(size_t size)32     void SetSize(size_t size) { size_ = size; }
33 private:
34     bool enbaleValidObject_ = false;
35     size_t size_ = 0;
36 };
37 class VerificationTest : public common::test::BaseTestWithScope {
38 protected:
SetUpTestCase()39     static void SetUpTestCase()
40     {
41         BaseRuntime::GetInstance()->Init();
42     }
43 
TearDownTestCase()44     static void TearDownTestCase()
45     {
46         BaseRuntime::GetInstance()->Fini();
47     }
48 
SetUp()49     void SetUp() override
50     {
51         MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD);
52     }
53 
TearDown()54     void TearDown() override
55     {
56         MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD);
57     }
58 };
59 
HWTEST_F_L0(VerificationTest,GetObjectInfoTest)60 HWTEST_F_L0(VerificationTest, GetObjectInfoTest)
61 {
62     BaseObject* obj = nullptr;
63     std::string result = GetObjectInfo(obj);
64 
65     EXPECT_NE(result.find("address: 0x0"), std::string::npos);
66     EXPECT_NE(result.find("Skip: nullptr"), std::string::npos);
67     EXPECT_NE(result.find("Skip: Object is not in heap range"), std::string::npos);
68 }
69 
HWTEST_F_L0(VerificationTest,GetObjectInfoTest2)70 HWTEST_F_L0(VerificationTest, GetObjectInfoTest2)
71 {
72     BaseObject obj;
73     std::string result = GetObjectInfo(&obj);
74     EXPECT_NE(result.find("address: 0x"), std::string::npos);
75     EXPECT_NE(result.find("Skip: Object is not in heap range"), std::string::npos);
76 }
77 
HWTEST_F_L0(VerificationTest,GetRefInfoTest)78 HWTEST_F_L0(VerificationTest, GetRefInfoTest)
79 {
80     BaseObject oldObj;
81     RefField<false> oldField(&oldObj);
82     MAddress oldAddress = oldField.GetFieldValue();
83     std::string result = GetRefInfo(oldField);
84     EXPECT_NE(result.find("address: 0x"), std::string::npos);
85     EXPECT_NE(result.find("Skip: Object is not in heap range"), std::string::npos);
86 }
87 
HWTEST_F_L0(VerificationTest,VerifyRefImplTest2)88 HWTEST_F_L0(VerificationTest, VerifyRefImplTest2)
89 {
90     RegionSpace& theAllocator = reinterpret_cast<RegionSpace&>(Heap::GetHeap().GetAllocator());
91     uintptr_t addr = theAllocator.AllocOldRegion();
92     ASSERT_NE(addr, 0U);
93     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
94     RegionDesc* region = RegionDesc::GetRegionDescAt(reinterpret_cast<uintptr_t>(obj));
95     ASSERT_NE(region, nullptr);
96     region->SetRegionType(RegionDesc::RegionType::FROM_REGION);
97     RefField<false> field(obj);
98 
99     auto refObj = field.GetTargetObject();
100 
101     AfterForwardVisitor visitor;
102     visitor.VerifyRefImpl(obj, field);
103     ASSERT_FALSE(RegionSpace::IsMarkedObject(refObj));
104     ASSERT_FALSE(RegionSpace::IsResurrectedObject(refObj));
105 }
106 
HWTEST_F_L0(VerificationTest,VerifyRefImplTest3)107 HWTEST_F_L0(VerificationTest, VerifyRefImplTest3)
108 {
109     RegionSpace& theAllocator = reinterpret_cast<RegionSpace&>(Heap::GetHeap().GetAllocator());
110     uintptr_t addr = theAllocator.AllocOldRegion();
111     ASSERT_NE(addr, 0U);
112     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
113     RegionDesc* region = RegionDesc::GetRegionDescAt(reinterpret_cast<uintptr_t>(obj));
114     ASSERT_NE(region, nullptr);
115     region->SetRegionType(RegionDesc::RegionType::FULL_PINNED_REGION);
116     RefField<false> field(obj);
117 
118     auto refObj = field.GetTargetObject();
119 
120     ReadBarrierSetter visitor;
121     visitor.VerifyRefImpl(nullptr, field);
122     visitor.VerifyRefImpl(obj, field);
123     EXPECT_EQ(RegionDesc::RegionType::FULL_PINNED_REGION,
124         RegionDesc::GetRegionDescAt(reinterpret_cast<MAddress>(field.GetTargetObject()))->GetRegionType());
125 
126     region->SetRegionType(RegionDesc::RegionType::RECENT_PINNED_REGION);
127     visitor.VerifyRefImpl(obj, field);
128     EXPECT_EQ(RegionDesc::RegionType::RECENT_PINNED_REGION,
129         RegionDesc::GetRegionDescAt(reinterpret_cast<MAddress>(field.GetTargetObject()))->GetRegionType());
130 
131     region->SetRegionType(RegionDesc::RegionType::FIXED_PINNED_REGION);
132     visitor.VerifyRefImpl(obj, field);
133     EXPECT_EQ(RegionDesc::RegionType::FIXED_PINNED_REGION,
134         RegionDesc::GetRegionDescAt(reinterpret_cast<MAddress>(field.GetTargetObject()))->GetRegionType());
135 
136     region->SetRegionType(RegionDesc::RegionType::FULL_FIXED_PINNED_REGION);
137     visitor.VerifyRefImpl(obj, field);
138     EXPECT_EQ(RegionDesc::RegionType::FULL_FIXED_PINNED_REGION,
139         RegionDesc::GetRegionDescAt(reinterpret_cast<MAddress>(field.GetTargetObject()))->GetRegionType());
140 
141     region->SetRegionType(RegionDesc::RegionType::READ_ONLY_REGION);
142     auto oldRefValue = field.GetFieldValue();
143     visitor.VerifyRefImpl(obj, field);
144     auto newRefValue = field.GetFieldValue();
145     EXPECT_NE(oldRefValue, newRefValue);
146 }
147 
GetArkCollector()148 std::unique_ptr<ArkCollector> GetArkCollector()
149 {
150     CollectorResources &resources = Heap::GetHeap().GetCollectorResources();
151     Allocator &allocator = Heap::GetHeap().GetAllocator();
152 
153     return std::make_unique<ArkCollector>(allocator, resources);
154 }
155 
HWTEST_F_L0(VerificationTest,VerifyAfterMarkTest1)156 HWTEST_F_L0(VerificationTest, VerifyAfterMarkTest1)
157 {
158     Heap::GetHeap().SetGCPhase(GCPhase::GC_PHASE_POST_MARK);
159     std::unique_ptr<ArkCollector> arkCollector = GetArkCollector();
160     ASSERT_TRUE(arkCollector != nullptr);
161     WVerify verify;
162     verify.VerifyAfterMark(*arkCollector);
163     ASSERT_FALSE(MutatorManager::Instance().WorldStopped());
164 }
165 
HWTEST_F_L0(VerificationTest,VerifyAfterForwardTest1)166 HWTEST_F_L0(VerificationTest, VerifyAfterForwardTest1)
167 {
168     Heap::GetHeap().SetGCPhase(GCPhase::GC_PHASE_COPY);
169     std::unique_ptr<ArkCollector> arkCollector = GetArkCollector();
170     ASSERT_TRUE(arkCollector != nullptr);
171     WVerify verify;
172     verify.VerifyAfterForward(*arkCollector);
173     ASSERT_FALSE(MutatorManager::Instance().WorldStopped());
174 }
175 
HWTEST_F_L0(VerificationTest,VerifyAfterFixTest1)176 HWTEST_F_L0(VerificationTest, VerifyAfterFixTest1)
177 {
178     Heap::GetHeap().SetGCPhase(GCPhase::GC_PHASE_FIX);
179     std::unique_ptr<ArkCollector> arkCollector = GetArkCollector();
180     ASSERT_TRUE(arkCollector != nullptr);
181     WVerify verify;
182     verify.VerifyAfterFix(*arkCollector);
183     ASSERT_FALSE(MutatorManager::Instance().WorldStopped());
184 }
185 
HWTEST_F_L0(VerificationTest,EnableReadBarrierDFXTest1)186 HWTEST_F_L0(VerificationTest, EnableReadBarrierDFXTest1)
187 {
188     std::unique_ptr<ArkCollector> arkCollector = GetArkCollector();
189     ASSERT_TRUE(arkCollector != nullptr);
190     WVerify verify;
191     verify.EnableReadBarrierDFX(*arkCollector);
192     ASSERT_FALSE(MutatorManager::Instance().WorldStopped());
193 }
194 
HWTEST_F_L0(VerificationTest,DisableReadBarrierDFXTest1)195 HWTEST_F_L0(VerificationTest, DisableReadBarrierDFXTest1)
196 {
197     std::unique_ptr<ArkCollector> arkCollector = GetArkCollector();
198     ASSERT_TRUE(arkCollector != nullptr);
199     WVerify verify;
200     verify.DisableReadBarrierDFX(*arkCollector);
201     ASSERT_FALSE(MutatorManager::Instance().WorldStopped());
202 }
203 
HWTEST_F_L0(VerificationTest,GetObjectInfoTest3)204 HWTEST_F_L0(VerificationTest, GetObjectInfoTest3)
205 {
206     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::PINNED_OBJECT, true);
207     BaseObject *obj = reinterpret_cast<BaseObject *>(addr);
208     std::string result = GetObjectInfo(obj);
209     EXPECT_NE(result.find("address: 0x"), std::string::npos);
210     EXPECT_NE(result.find("Type: 0x"), std::string::npos);
211     EXPECT_NE(result.find("Base: 0x"), std::string::npos);
212     EXPECT_NE(result.find("Start: 0x"), std::string::npos);
213     EXPECT_NE(result.find("End: 0x"), std::string::npos);
214     EXPECT_NE(result.find("AllocPtr: 0x"), std::string::npos);
215     EXPECT_NE(result.find("MarkingLine: 0x"), std::string::npos);
216     EXPECT_NE(result.find("CopyLine: 0x"), std::string::npos);
217 }
218 
HWTEST_F_L0(VerificationTest,GetRefInfoTest2)219 HWTEST_F_L0(VerificationTest, GetRefInfoTest2)
220 {
221     RefField<false> field(nullptr);
222     uintptr_t taggedValue = 0x04;
223     field.SetFieldValue(static_cast<MAddress>(taggedValue));
224     std::string result = GetRefInfo(field);
225     EXPECT_NE(result.find("> Raw memory:"), std::string::npos);
226     EXPECT_NE(result.find("Skip: primitive"), std::string::npos);
227 }
228 
HWTEST_F_L0(VerificationTest,VerifyRefImplTest)229 HWTEST_F_L0(VerificationTest, VerifyRefImplTest)
230 {
231     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::PINNED_OBJECT, true);
232     BaseObject *obj = reinterpret_cast<BaseObject *>(addr);
233     RefField<false> oldField(obj);
234     TestBaseObjectOperator operatorImpl;
235     BaseObject::RegisterDynamic(&operatorImpl);
236     operatorImpl.SetValidObject(true);
237     Heap::GetHeap().SetGCReason(GCReason::GC_REASON_YOUNG);
238     operatorImpl.SetSize(BaseObject::BaseObjectSize());
239     AfterMarkVisitor visitor;
240     visitor.VerifyRefImpl(nullptr, oldField);
241     ASSERT_TRUE(Heap::GetHeap().GetGCReason() == GCReason::GC_REASON_YOUNG);
242     ASSERT_TRUE(Heap::IsTaggedObject(oldField.GetFieldValue()));
243 
244     AfterMarkVisitor<false> visitor1;
245     visitor1.VerifyRefImpl(nullptr, oldField);
246     ASSERT_TRUE(Heap::IsTaggedObject(oldField.GetFieldValue()));
247 }
248 
HWTEST_F_L0(VerificationTest,VerifyRefImplTest1)249 HWTEST_F_L0(VerificationTest, VerifyRefImplTest1)
250 {
251     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::PINNED_OBJECT, true);
252     BaseObject *obj = reinterpret_cast<BaseObject *>(addr);
253     RefField<false> oldField(obj);
254     TestBaseObjectOperator operatorImpl;
255     BaseObject::RegisterDynamic(&operatorImpl);
256     operatorImpl.SetValidObject(true);
257     Heap::GetHeap().SetGCReason(GCReason::GC_REASON_YOUNG);
258     operatorImpl.SetSize(BaseObject::BaseObjectSize());
259     AfterMarkVisitor visitor;
260     visitor.VerifyRefImpl(obj, oldField);
261     ASSERT_TRUE(Heap::GetHeap().GetGCReason() == GCReason::GC_REASON_YOUNG);
262     ASSERT_TRUE(Heap::IsTaggedObject(oldField.GetFieldValue()));
263 }
264 
265 static BaseObject* testObj = nullptr;
CustomVisitRoot(const RefFieldVisitor & visitorFunc)266 static void CustomVisitRoot(const RefFieldVisitor& visitorFunc)
267 {
268     RefField<> field(testObj);
269     visitorFunc(field);
270 }
HWTEST_F_L0(VerificationTest,IterateRemarked_VerifyAllRefs)271 HWTEST_F_L0(VerificationTest, IterateRemarked_VerifyAllRefs)
272 {
273     RegionSpace regionSpace;
274     VerifyIterator verify(regionSpace);
275     AfterForwardVisitor visitor;
276     std::unordered_set<BaseObject*> markSet;
277     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::PINNED_OBJECT, true);
278     testObj = reinterpret_cast<BaseObject*>(addr);
279     markSet.insert(testObj);
280 
281     verify.IterateRemarked<CustomVisitRoot>(visitor, markSet, true);
282     verify.IterateRemarked<CustomVisitRoot>(visitor, markSet, false);
283     EXPECT_EQ(markSet.size(), 1);
284     EXPECT_TRUE(markSet.find(testObj) != markSet.end());
285 }
286 } // namespace common::test
287