• 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/idle_barrier.h"
17 #include "common_components/heap/ark_collector/tests/mock_barrier_collector.h"
18 #include "common_components/mutator/mutator_manager.h"
19 #include "common_components/tests/test_helper.h"
20 #include "common_components/heap/heap_manager.h"
21 #include "common_interfaces/base_runtime.h"
22 
23 using namespace common;
24 
25 namespace common::test {
26 class IdleBarrierTest : public common::test::BaseTestWithScope {
27 protected:
SetUpTestCase()28     static void SetUpTestCase()
29     {
30         BaseRuntime::GetInstance()->Init();
31     }
32 
TearDownTestCase()33     static void TearDownTestCase() {}
34 
SetUp()35     void SetUp() override
36     {
37         MutatorManager::Instance().CreateRuntimeMutator(ThreadType::ARK_PROCESSOR);
38     }
39 
TearDown()40     void TearDown() override
41     {
42         MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::ARK_PROCESSOR);
43     }
44 };
45 
HWTEST_F_L0(IdleBarrierTest,ReadStruct_TEST0)46 HWTEST_F_L0(IdleBarrierTest, ReadStruct_TEST0)
47 {
48     MockCollector collector;
49     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
50     ASSERT_TRUE(idleBarrier != nullptr);
51 
52     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
53     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
54     HeapAddress src = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
55     BaseObject* srcObj = reinterpret_cast<BaseObject*>(src);
56     srcObj->SetForwardState(BaseStateWord::ForwardState::FORWARDING);
57     HeapAddress dst = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
58     BaseObject* dstObj = reinterpret_cast<BaseObject*>(dst);
59     dstObj->SetForwardState(BaseStateWord::ForwardState::FORWARDED);
60     EXPECT_NE(dstObj->IsForwarding(), srcObj->IsForwarding());
61     idleBarrier->ReadStruct(dst, obj, src, sizeof(BaseObject));
62     EXPECT_EQ(dstObj->IsForwarding(), srcObj->IsForwarding());
63 }
64 
HWTEST_F_L0(IdleBarrierTest,AtomicWriteRefField_TEST0)65 HWTEST_F_L0(IdleBarrierTest, AtomicWriteRefField_TEST0)
66 {
67     MockCollector collector;
68     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
69     ASSERT_TRUE(idleBarrier != nullptr);
70 
71     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
72     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
73     constexpr size_t oldSize = 100;
74     oldObj->SetSizeForwarded(oldSize);
75     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
76     RefField<true> oldField(oldObj);
77     MAddress oldAddress = oldField.GetFieldValue();
78 
79     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
80     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
81     constexpr size_t newSize = 200;
82     newObj->SetSizeForwarded(newSize);
83     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
84     RefField<true> newField(newObj);
85     MAddress neWAddress = newField.GetFieldValue();
86     EXPECT_NE(oldAddress, neWAddress);
87 
88     idleBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed);
89     EXPECT_EQ(oldField.GetFieldValue(), neWAddress);
90 }
91 
HWTEST_F_L0(IdleBarrierTest,AtomicWriteRefField_TEST1)92 HWTEST_F_L0(IdleBarrierTest, AtomicWriteRefField_TEST1)
93 {
94     MockCollector collector;
95     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
96     ASSERT_TRUE(idleBarrier != nullptr);
97 
98     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
99     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
100     constexpr size_t oldSize = 100;
101     oldObj->SetSizeForwarded(oldSize);
102     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
103     RefField<true> oldField(oldObj);
104     MAddress oldAddress = oldField.GetFieldValue();
105 
106     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
107     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
108     constexpr size_t newSize = 200;
109     newObj->SetSizeForwarded(newSize);
110     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
111     RefField<true> newField(newObj);
112     MAddress neWAddress = newField.GetFieldValue();
113     EXPECT_NE(oldAddress, neWAddress);
114 
115     idleBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed);
116     EXPECT_EQ(oldField.GetFieldValue(), neWAddress);
117 }
118 
HWTEST_F_L0(IdleBarrierTest,AtomicSwapRefField_TEST0)119 HWTEST_F_L0(IdleBarrierTest, AtomicSwapRefField_TEST0)
120 {
121     MockCollector collector;
122     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
123     ASSERT_TRUE(idleBarrier != nullptr);
124 
125     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
126     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
127     constexpr size_t oldSize = 100;
128     oldObj->SetSizeForwarded(oldSize);
129     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
130     RefField<true> oldField(oldObj);
131     MAddress oldAddress = oldField.GetFieldValue();
132 
133     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
134     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
135     constexpr size_t newSize = 200;
136     newObj->SetSizeForwarded(newSize);
137     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
138     RefField<true> newField(newObj);
139     MAddress neWAddress = newField.GetFieldValue();
140     EXPECT_NE(oldAddress, neWAddress);
141 
142     BaseObject *retObj = idleBarrier->AtomicSwapRefField(oldObj, oldField, newObj, std::memory_order_relaxed);
143     ASSERT_TRUE(retObj != nullptr);
144     EXPECT_EQ(oldField.GetFieldValue(), newField.GetFieldValue());
145 }
146 
HWTEST_F_L0(IdleBarrierTest,CompareAndSwapRefField_TEST1)147 HWTEST_F_L0(IdleBarrierTest, CompareAndSwapRefField_TEST1)
148 {
149     MockCollector collector;
150     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
151     ASSERT_TRUE(idleBarrier != nullptr);
152 
153     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
154     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
155     constexpr size_t oldSize = 100;
156     oldObj->SetSizeForwarded(oldSize);
157     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
158     RefField<true> oldField(oldObj);
159 
160     bool result = idleBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, oldObj,
161         std::memory_order_seq_cst, std::memory_order_seq_cst);
162     ASSERT_TRUE(result);
163 }
164 
HWTEST_F_L0(IdleBarrierTest,CompareAndSwapRefField_TEST2)165 HWTEST_F_L0(IdleBarrierTest, CompareAndSwapRefField_TEST2)
166 {
167     MockCollector collector;
168     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
169     ASSERT_TRUE(idleBarrier != nullptr);
170 
171     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
172     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
173     constexpr size_t oldSize = 100;
174     oldObj->SetSizeForwarded(oldSize);
175     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
176     RefField<true> oldField(oldObj);
177     MAddress oldAddress = oldField.GetFieldValue();
178 
179     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
180     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
181     constexpr size_t newSize = 200;
182     newObj->SetSizeForwarded(newSize);
183     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
184     RefField<true> newField(newObj);
185     MAddress neWAddress = newField.GetFieldValue();
186     EXPECT_NE(oldAddress, neWAddress);
187 
188     bool result = idleBarrier->CompareAndSwapRefField(oldObj, newField, oldObj, newObj,
189         std::memory_order_seq_cst, std::memory_order_seq_cst);
190     ASSERT_FALSE(result);
191 }
192 
HWTEST_F_L0(IdleBarrierTest,WriteRefField_TEST0)193 HWTEST_F_L0(IdleBarrierTest, WriteRefField_TEST0)
194 {
195     MockCollector collector;
196     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
197     ASSERT_TRUE(idleBarrier != nullptr);
198 
199     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
200     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
201     constexpr size_t oldSize = 100;
202     oldObj->SetSizeForwarded(oldSize);
203     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
204     RefField<false> oldField(oldObj);
205     MAddress oldAddress = oldField.GetFieldValue();
206 
207     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
208     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
209     constexpr size_t newSize = 200;
210     newObj->SetSizeForwarded(newSize);
211     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
212     RefField<false> newField(newObj);
213     MAddress neWAddress = newField.GetFieldValue();
214     EXPECT_NE(oldAddress, neWAddress);
215 
216     idleBarrier->WriteRefField(oldObj, oldField, newObj);
217     EXPECT_EQ(oldField.GetFieldValue(), neWAddress);
218 }
219 
HWTEST_F_L0(IdleBarrierTest,WriteRefField_TEST1)220 HWTEST_F_L0(IdleBarrierTest, WriteRefField_TEST1)
221 {
222     MockCollector collector;
223     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
224     ASSERT_TRUE(idleBarrier != nullptr);
225 
226     constexpr uint64_t TAG_BITS_SHIFT = 48;
227     constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT;
228     constexpr uint64_t TAG_SPECIAL = 0x02ULL;
229     constexpr uint64_t TAG_BOOLEAN = 0x04ULL;
230     constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN;
231 
232     RefField<> field(MAddress(0));
233     BaseObject *obj = reinterpret_cast<BaseObject *>(TAG_HEAP_OBJECT_MASK);
234     idleBarrier->WriteRefField(obj, field, obj);
235     EXPECT_TRUE(obj != nullptr);
236 }
237 
HWTEST_F_L0(IdleBarrierTest,WriteBarrier_TEST1)238 HWTEST_F_L0(IdleBarrierTest, WriteBarrier_TEST1)
239 {
240     MockCollector collector;
241     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
242     ASSERT_TRUE(idleBarrier != nullptr);
243 
244     constexpr uint64_t TAG_BITS_SHIFT = 48;
245     constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT;
246     constexpr uint64_t TAG_SPECIAL = 0x02ULL;
247     constexpr uint64_t TAG_BOOLEAN = 0x04ULL;
248     constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN;
249 
250     RefField<> field(MAddress(0));
251     BaseObject *obj = reinterpret_cast<BaseObject *>(TAG_HEAP_OBJECT_MASK);
252     idleBarrier->WriteBarrier(obj, field, obj);
253     EXPECT_TRUE(obj != nullptr);
254 }
255 
HWTEST_F_L0(IdleBarrierTest,WriteBarrier_TEST2)256 HWTEST_F_L0(IdleBarrierTest, WriteBarrier_TEST2)
257 {
258     MockCollector collector;
259     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
260     ASSERT_TRUE(idleBarrier != nullptr);
261 
262     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
263     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
264     RefField<> field(obj);
265     idleBarrier->WriteBarrier(obj, field, obj);
266     EXPECT_TRUE(obj != nullptr);
267 }
268 
HWTEST_F_L0(IdleBarrierTest,WriteStruct_TEST0)269 HWTEST_F_L0(IdleBarrierTest, WriteStruct_TEST0)
270 {
271     MockCollector collector;
272     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
273     ASSERT_TRUE(idleBarrier != nullptr);
274 
275     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
276     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
277     HeapAddress src = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
278     BaseObject* srcObj = reinterpret_cast<BaseObject*>(src);
279     srcObj->SetForwardState(BaseStateWord::ForwardState::FORWARDING);
280     HeapAddress dst = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
281     BaseObject* dstObj = reinterpret_cast<BaseObject*>(dst);
282     dstObj->SetForwardState(BaseStateWord::ForwardState::FORWARDED);
283     EXPECT_NE(dstObj->IsForwarding(), srcObj->IsForwarding());
284     idleBarrier->WriteStruct(obj, dst, sizeof(BaseObject), src, sizeof(BaseObject));
285     EXPECT_EQ(dstObj->IsForwarding(), srcObj->IsForwarding());
286 }
287 
HWTEST_F_L0(IdleBarrierTest,CopyStructArray_TEST0)288 HWTEST_F_L0(IdleBarrierTest, CopyStructArray_TEST0)
289 {
290     MockCollector collector;
291     auto idleBarrier = std::make_unique<IdleBarrier>(collector);
292     ASSERT_TRUE(idleBarrier != nullptr);
293 
294     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
295     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
296     HeapAddress src = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
297     BaseObject* srcObj = reinterpret_cast<BaseObject*>(src);
298     srcObj->SetForwardState(BaseStateWord::ForwardState::FORWARDING);
299     HeapAddress dst = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
300     BaseObject* dstObj = reinterpret_cast<BaseObject*>(dst);
301     dstObj->SetForwardState(BaseStateWord::ForwardState::FORWARDED);
302     EXPECT_NE(dstObj->IsForwarding(), srcObj->IsForwarding());
303     idleBarrier->CopyStructArray(obj, dst, sizeof(BaseObject), obj, src, sizeof(BaseObject));
304     EXPECT_EQ(dstObj->IsForwarding(), srcObj->IsForwarding());
305 }
306 }  // namespace common::test
307