• 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/post_marking_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 PostMarkingBarrierTest : public ::testing::Test {
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(PostMarkingBarrierTest,ReadRefField_TEST1)46 HWTEST_F_L0(PostMarkingBarrierTest, ReadRefField_TEST1)
47 {
48     MockCollector collector;
49     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
50     ASSERT_TRUE(postMarkingBarrier != nullptr);
51 
52     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
53     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
54     RefField<false> field(obj);
55 
56     BaseObject *resultObj = postMarkingBarrier->ReadRefField(obj, field);
57     ASSERT_TRUE(resultObj != nullptr);
58     EXPECT_EQ(resultObj, obj);
59 }
60 
HWTEST_F_L0(PostMarkingBarrierTest,ReadRefField_TEST2)61 HWTEST_F_L0(PostMarkingBarrierTest, ReadRefField_TEST2)
62 {
63     MockCollector collector;
64     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
65     ASSERT_TRUE(postMarkingBarrier != nullptr);
66 
67     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
68     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
69     RefField<false> field(obj);
70 
71     BaseObject *resultObj = postMarkingBarrier->ReadRefField(nullptr, field);
72     ASSERT_TRUE(resultObj != nullptr);
73     EXPECT_EQ(resultObj, obj);
74 }
75 
HWTEST_F_L0(PostMarkingBarrierTest,ReadStaticRef_TEST1)76 HWTEST_F_L0(PostMarkingBarrierTest, ReadStaticRef_TEST1)
77 {
78     MockCollector collector;
79     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
80     ASSERT_TRUE(postMarkingBarrier != nullptr);
81 
82     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
83     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
84     RefField<false> field(obj);
85 
86     BaseObject *resultObj = postMarkingBarrier->ReadStaticRef(field);
87     ASSERT_TRUE(resultObj != nullptr);
88     EXPECT_EQ(resultObj, obj);
89 }
90 
HWTEST_F_L0(PostMarkingBarrierTest,ReadStringTableStaticRef_TEST1)91 HWTEST_F_L0(PostMarkingBarrierTest, ReadStringTableStaticRef_TEST1)
92 {
93     MockCollector collector;
94     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
95     ASSERT_TRUE(postMarkingBarrier != nullptr);
96 
97     RefField<false> field(nullptr);
98 
99     BaseObject* resultObj = postMarkingBarrier->ReadStringTableStaticRef(field);
100     ASSERT_TRUE(resultObj == nullptr);
101 }
102 
HWTEST_F_L0(PostMarkingBarrierTest,ReadStringTableStaticRef_TEST2)103 HWTEST_F_L0(PostMarkingBarrierTest, ReadStringTableStaticRef_TEST2)
104 {
105     MockCollector collector;
106     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
107     ASSERT_TRUE(postMarkingBarrier != nullptr);
108 
109     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
110     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
111     RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr);
112     regionInfo->SetRegionAllocPtr(addr - 1);
113     regionInfo->SetMarkingLine();
114     RefField<false> field(obj);
115 
116     BaseObject* resultObj = postMarkingBarrier->ReadStringTableStaticRef(field);
117     ASSERT_TRUE(resultObj != nullptr);
118 }
119 
HWTEST_F_L0(PostMarkingBarrierTest,ReadStringTableStaticRef_TEST3)120 HWTEST_F_L0(PostMarkingBarrierTest, ReadStringTableStaticRef_TEST3)
121 {
122     MockCollector collector;
123     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
124     ASSERT_TRUE(postMarkingBarrier != nullptr);
125 
126     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
127     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
128     RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr);
129     regionInfo->SetRegionType(RegionDesc::RegionType::ALIVE_REGION_FIRST);
130     RefField<false> field(obj);
131 
132     BaseObject* resultObj = postMarkingBarrier->ReadStringTableStaticRef(field);
133     ASSERT_TRUE(resultObj == nullptr);
134 }
135 
HWTEST_F_L0(PostMarkingBarrierTest,ReadStringTableStaticRef_TEST4)136 HWTEST_F_L0(PostMarkingBarrierTest, ReadStringTableStaticRef_TEST4)
137 {
138     MockCollector collector;
139     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
140     ASSERT_TRUE(postMarkingBarrier != nullptr);
141 
142     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
143     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
144     RefField<false> field(obj);
145 
146     Heap::GetHeap().SetGCReason(GC_REASON_YOUNG);
147     BaseObject* resultObj = postMarkingBarrier->ReadStringTableStaticRef(field);
148     ASSERT_TRUE(resultObj != nullptr);
149 }
150 
HWTEST_F_L0(PostMarkingBarrierTest,WriteRefField_TEST1)151 HWTEST_F_L0(PostMarkingBarrierTest, WriteRefField_TEST1)
152 {
153     MockCollector collector;
154     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
155     ASSERT_TRUE(postMarkingBarrier != nullptr);
156 
157     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
158     BaseObject* oldObj = reinterpret_cast<BaseObject*>(addr);
159     RefField<false> field(oldObj);
160     MAddress oldAddr = field.GetFieldValue();
161 
162     HeapAddress newObjAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
163     BaseObject* newObj = reinterpret_cast<BaseObject*>(newObjAddr);
164     postMarkingBarrier->WriteRefField(oldObj, field, newObj);
165     MAddress newAddr = field.GetFieldValue();
166 
167     EXPECT_NE(oldAddr, newAddr);
168     EXPECT_EQ(newAddr, reinterpret_cast<MAddress>(newObj));
169 }
170 
HWTEST_F_L0(PostMarkingBarrierTest,WriteBarrier_TEST1)171 HWTEST_F_L0(PostMarkingBarrierTest, WriteBarrier_TEST1)
172 {
173     MockCollector collector;
174     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
175     ASSERT_TRUE(postMarkingBarrier != nullptr);
176 
177     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
178     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
179     RefField<> field(obj);
180     postMarkingBarrier->WriteBarrier(obj, field, obj);
181     EXPECT_TRUE(obj != nullptr);
182 }
183 
HWTEST_F_L0(PostMarkingBarrierTest,WriteBarrier_TEST2)184 HWTEST_F_L0(PostMarkingBarrierTest, WriteBarrier_TEST2)
185 {
186     MockCollector collector;
187     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
188     ASSERT_TRUE(postMarkingBarrier != nullptr);
189 
190     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
191     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
192     RefField<> field(obj);
193     Heap::GetHeap().SetGCReason(GC_REASON_YOUNG);
194     postMarkingBarrier->WriteBarrier(obj, field, obj);
195     EXPECT_TRUE(obj != nullptr);
196 }
197 
HWTEST_F_L0(PostMarkingBarrierTest,ReadStruct_TEST1)198 HWTEST_F_L0(PostMarkingBarrierTest, ReadStruct_TEST1)
199 {
200     MockCollector collector;
201     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
202     ASSERT_TRUE(postMarkingBarrier != nullptr);
203 
204     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
205     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
206     HeapAddress src = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
207     BaseObject* srcObj = reinterpret_cast<BaseObject*>(src);
208     srcObj->SetForwardState(BaseStateWord::ForwardState::FORWARDING);
209     HeapAddress dst = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
210     BaseObject* dstObj = reinterpret_cast<BaseObject*>(dst);
211     dstObj->SetForwardState(BaseStateWord::ForwardState::FORWARDED);
212     EXPECT_NE(dstObj->IsForwarding(), srcObj->IsForwarding());
213     postMarkingBarrier->ReadStruct(dst, obj, src, sizeof(BaseObject));
214     EXPECT_EQ(dstObj->IsForwarding(), srcObj->IsForwarding());
215 }
216 
HWTEST_F_L0(PostMarkingBarrierTest,WriteStruct_TEST1)217 HWTEST_F_L0(PostMarkingBarrierTest, WriteStruct_TEST1)
218 {
219     MockCollector collector;
220     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
221     ASSERT_TRUE(postMarkingBarrier != nullptr);
222 
223     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
224     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
225     HeapAddress src = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
226     BaseObject* srcObj = reinterpret_cast<BaseObject*>(src);
227     srcObj->SetForwardState(BaseStateWord::ForwardState::FORWARDING);
228     HeapAddress dst = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
229     BaseObject* dstObj = reinterpret_cast<BaseObject*>(dst);
230     dstObj->SetForwardState(BaseStateWord::ForwardState::FORWARDED);
231     EXPECT_NE(dstObj->IsForwarding(), srcObj->IsForwarding());
232     postMarkingBarrier->WriteStruct(obj, dst, sizeof(BaseObject), src, sizeof(BaseObject));
233     EXPECT_EQ(dstObj->IsForwarding(), srcObj->IsForwarding());
234 }
235 
HWTEST_F_L0(PostMarkingBarrierTest,AtomicReadRefField_TEST1)236 HWTEST_F_L0(PostMarkingBarrierTest, AtomicReadRefField_TEST1)
237 {
238     MockCollector collector;
239     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
240     ASSERT_TRUE(postMarkingBarrier != nullptr);
241 
242     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
243     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
244     RefField<true> field(obj);
245 
246     BaseObject* result = postMarkingBarrier->AtomicReadRefField(obj, field, std::memory_order_seq_cst);
247     EXPECT_EQ(result, obj);
248 }
249 
HWTEST_F_L0(PostMarkingBarrierTest,AtomicWriteRefField_TEST1)250 HWTEST_F_L0(PostMarkingBarrierTest, AtomicWriteRefField_TEST1)
251 {
252     MockCollector collector;
253     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
254     ASSERT_TRUE(postMarkingBarrier != nullptr);
255 
256     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
257     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
258     constexpr size_t oldSize = 100;
259     oldObj->SetSizeForwarded(oldSize);
260     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
261     RefField<true> oldField(oldObj);
262     MAddress oldAddress = oldField.GetFieldValue();
263 
264     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
265     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
266     constexpr size_t newSize = 200;
267     newObj->SetSizeForwarded(newSize);
268     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
269 
270     postMarkingBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed);
271 
272     EXPECT_NE(oldField.GetFieldValue(), oldAddress);
273     EXPECT_EQ(oldField.GetFieldValue(), reinterpret_cast<MAddress>(newObj));
274 }
275 
HWTEST_F_L0(PostMarkingBarrierTest,AtomicWriteRefField_TEST2)276 HWTEST_F_L0(PostMarkingBarrierTest, AtomicWriteRefField_TEST2)
277 {
278     MockCollector collector;
279     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
280     ASSERT_TRUE(postMarkingBarrier != nullptr);
281 
282     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
283     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
284     constexpr size_t oldSize = 100;
285     oldObj->SetSizeForwarded(oldSize);
286     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
287     RefField<true> oldField(oldObj);
288     MAddress oldAddress = oldField.GetFieldValue();
289 
290     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
291     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
292     constexpr size_t newSize = 200;
293     newObj->SetSizeForwarded(newSize);
294     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
295 
296     postMarkingBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed);
297 
298     EXPECT_NE(oldField.GetFieldValue(), oldAddress);
299     EXPECT_EQ(oldField.GetFieldValue(), reinterpret_cast<MAddress>(newObj));
300 }
301 
HWTEST_F_L0(PostMarkingBarrierTest,AtomicSwapRefField_TEST1)302 HWTEST_F_L0(PostMarkingBarrierTest, AtomicSwapRefField_TEST1)
303 {
304     MockCollector collector;
305     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
306     ASSERT_TRUE(postMarkingBarrier != nullptr);
307 
308     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
309     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
310     RefField<true> field(oldObj);
311     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
312     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
313     BaseObject* result = postMarkingBarrier->AtomicSwapRefField(
314         oldObj, field, newObj, std::memory_order_relaxed);
315     EXPECT_EQ(result, oldObj);
316     EXPECT_EQ(field.GetFieldValue(), reinterpret_cast<MAddress>(newObj));
317 }
318 
HWTEST_F_L0(PostMarkingBarrierTest,CompareAndSwapRefField_TEST1)319 HWTEST_F_L0(PostMarkingBarrierTest, CompareAndSwapRefField_TEST1)
320 {
321     MockCollector collector;
322     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
323     ASSERT_TRUE(postMarkingBarrier != nullptr);
324 
325     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
326     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
327     constexpr size_t oldSize = 100;
328     oldObj->SetSizeForwarded(oldSize);
329     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
330     RefField<true> oldField(oldObj);
331     MAddress oldAddress = oldField.GetFieldValue();
332 
333     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
334     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
335     constexpr size_t newSize = 200;
336     newObj->SetSizeForwarded(newSize);
337     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
338     RefField<true> newField(newObj);
339     MAddress neWAddress = newField.GetFieldValue();
340     EXPECT_NE(oldAddress, neWAddress);
341 
342     bool result = postMarkingBarrier->CompareAndSwapRefField(
343         oldObj, oldField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst);
344     ASSERT_TRUE(result);
345     EXPECT_EQ(oldField.GetFieldValue(), neWAddress);
346 }
347 
HWTEST_F_L0(PostMarkingBarrierTest,CompareAndSwapRefField_TEST2)348 HWTEST_F_L0(PostMarkingBarrierTest, CompareAndSwapRefField_TEST2)
349 {
350     MockCollector collector;
351     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
352     ASSERT_TRUE(postMarkingBarrier != nullptr);
353 
354     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
355     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
356     constexpr size_t oldSize = 100;
357     oldObj->SetSizeForwarded(oldSize);
358     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
359     RefField<true> oldField(oldObj);
360 
361     MAddress initialAddress = oldField.GetFieldValue();
362 
363     bool result = postMarkingBarrier->CompareAndSwapRefField(
364         oldObj, oldField, oldObj, oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst);
365     ASSERT_TRUE(result);
366     EXPECT_EQ(oldField.GetFieldValue(), initialAddress);
367 }
368 
HWTEST_F_L0(PostMarkingBarrierTest,CompareAndSwapRefField_TEST3)369 HWTEST_F_L0(PostMarkingBarrierTest, CompareAndSwapRefField_TEST3)
370 {
371     MockCollector collector;
372     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
373     ASSERT_TRUE(postMarkingBarrier != nullptr);
374 
375     HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
376     BaseObject* oldObj = reinterpret_cast<BaseObject*>(oldAddr);
377     constexpr size_t oldSize = 100;
378     oldObj->SetSizeForwarded(oldSize);
379     EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize);
380     RefField<true> oldField(oldObj);
381     MAddress oldAddress = oldField.GetFieldValue();
382 
383     HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
384     BaseObject* newObj = reinterpret_cast<BaseObject*>(newAddr);
385     constexpr size_t newSize = 200;
386     newObj->SetSizeForwarded(newSize);
387     EXPECT_EQ(newObj->GetSizeForwarded(), newSize);
388     RefField<true> newField(newObj);
389     MAddress neWAddress = newField.GetFieldValue();
390     EXPECT_NE(oldAddress, neWAddress);
391 
392     bool result = postMarkingBarrier->CompareAndSwapRefField(oldObj, newField, oldObj, newObj,
393         std::memory_order_seq_cst, std::memory_order_seq_cst);
394     ASSERT_FALSE(result);
395 }
396 
HWTEST_F_L0(PostMarkingBarrierTest,CopyStructArray_TEST1)397 HWTEST_F_L0(PostMarkingBarrierTest, CopyStructArray_TEST1)
398 {
399     MockCollector collector;
400     auto postMarkingBarrier = std::make_unique<PostMarkingBarrier>(collector);
401     ASSERT_TRUE(postMarkingBarrier != nullptr);
402 
403     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
404     BaseObject* obj = reinterpret_cast<BaseObject*>(addr);
405     HeapAddress src = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
406     BaseObject* srcObj = reinterpret_cast<BaseObject*>(src);
407     srcObj->SetForwardState(BaseStateWord::ForwardState::FORWARDING);
408     HeapAddress dst = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
409     BaseObject* dstObj = reinterpret_cast<BaseObject*>(dst);
410     dstObj->SetForwardState(BaseStateWord::ForwardState::FORWARDED);
411     EXPECT_NE(dstObj->IsForwarding(), srcObj->IsForwarding());
412     postMarkingBarrier->CopyStructArray(obj, dst, sizeof(BaseObject), obj, src, sizeof(BaseObject));
413     EXPECT_EQ(dstObj->IsForwarding(), srcObj->IsForwarding());
414 }
415 }  // namespace common::test
416