diff --git a/BUILD.gn b/BUILD.gn index 950996df5bccf51d0279ab165487a5379c8c6a9a..df72eda355352c96153185fc4ebb72e135980925 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -164,10 +164,11 @@ group("common_components_js_unittest") { "common_components/heap/barrier/tests:unittest", #"common_components/heap/collector/tests:unittest", - #"common_components/heap/w_collector/tests:unittest", + "common_components/heap/w_collector/tests:unittest", "common_components/mutator/tests:unittest", "common_components/objects/tests:unittest", "common_components/thread/tests:unittest", + "common_components/log/tests:unittest", ] } } @@ -185,10 +186,11 @@ group("common_components_unittest") { "common_components/heap/barrier/tests:host_unittest", #"common_components/heap/collector/tests:host_unittest", - #"common_components/heap/w_collector/tests:host_unittest", + "common_components/heap/w_collector/tests:host_unittest", "common_components/mutator/tests:host_unittest", "common_components/objects/tests:host_unittest", "common_components/thread/tests:host_unittest", + "common_components/log/tests:host_unittest", ] } } diff --git a/common_components/BUILD.gn b/common_components/BUILD.gn index 9b7b13bc107f75acb0bfd61e288e4d4bbbc72cb7..71f085ee7f9bd9e9b02937e1af1f5910b9db55ed 100755 --- a/common_components/BUILD.gn +++ b/common_components/BUILD.gn @@ -410,11 +410,13 @@ ohos_shared_library("libark_common_components_test") { if (!ark_standalone_build) { public_external_deps = [ "zlib:libz", + "bounds_checking_function:libsec_shared", ] public_external_deps += hiviewdfx_ext_deps } else { external_deps += [ "zlib:libz", + "bounds_checking_function:libsec_shared", ] external_deps += hiviewdfx_ext_deps } diff --git a/common_components/heap/allocator/tests/BUILD.gn b/common_components/heap/allocator/tests/BUILD.gn index a388033a486692e3e6f504372180fbfeaa027641..5acba71f6e2fabafcfebe26ac448b6791542e237 100755 --- a/common_components/heap/allocator/tests/BUILD.gn +++ b/common_components/heap/allocator/tests/BUILD.gn @@ -91,7 +91,6 @@ host_unittest_action("Region_Space_Test") { sources = [ # test file - "treap_test.cpp", "region_space_test.cpp", ] @@ -139,10 +138,10 @@ group("unittest") { # deps file deps = [ ":Allocator_Test", - ":Region_Manager_Test", ":Treap_Test", ":Region_Space_Test", ":Heap_Allocator_Test", + ":Region_Manager_Test" ] } @@ -152,9 +151,9 @@ group("host_unittest") { # deps file deps = [ ":Allocator_TestAction", - ":Region_Manager_TestAction", ":Treap_TestAction", ":Region_Space_TestAction", - ":Heap_Allocator_Test", + ":Heap_Allocator_TestAction", + ":Region_Manager_TestAction" ] } diff --git a/common_components/heap/allocator/tests/region_manager_test.cpp b/common_components/heap/allocator/tests/region_manager_test.cpp index 6d1661bde23af81f0c5a3ea7d7fa2427411f0c31..07b15d7c6d6174ba979a0b44576822d17487d392 100755 --- a/common_components/heap/allocator/tests/region_manager_test.cpp +++ b/common_components/heap/allocator/tests/region_manager_test.cpp @@ -20,7 +20,6 @@ #include "common_components/heap/heap_manager.h" #include "common_components/tests/test_helper.h" #include -#include using namespace common; @@ -316,4 +315,117 @@ HWTEST_F_L0(RegionManagerTest, AllocPinnedFromFreeList) manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); EXPECT_EQ(manager.AllocPinnedFromFreeList(0), 0); } + +HWTEST_F_L0(RegionManagerTest, FixAllRegionLists) +{ + Heap::GetHeap().SetGCReason(GCReason::GC_REASON_YOUNG); + RegionManager manager; + manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); + manager.FixAllRegionLists(); + EXPECT_EQ(Heap::GetHeap().GetGCReason(), GCReason::GC_REASON_YOUNG); +} + +HWTEST_F_L0(RegionManagerTest, AllocReadOnly1) +{ + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + RegionManager manager; + manager.ClearAllGCInfo(); + ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); + uintptr_t ret = manager.AllocReadOnly(sizeof(RegionDesc), false); + EXPECT_EQ(ret, 0); +} + +HWTEST_F_L0(RegionManagerTest, AllocReadOnly2) +{ + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_MARK); + RegionManager manager; + manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); + manager.ClearAllGCInfo(); + ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); + uintptr_t ret = manager.AllocReadOnly(sizeof(RegionDesc), false); + RegionDesc* region = RegionDesc::GetRegionDescAt(ret); + EXPECT_NE(ret, 0); + EXPECT_EQ(region->GetTraceLine(), region->GetRegionStart()); + EXPECT_EQ(region->GetCopyLine(), std::numeric_limits::max()); + EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); +} + +HWTEST_F_L0(RegionManagerTest, AllocReadOnly3) +{ + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_POST_MARK); + RegionManager manager; + manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); + manager.ClearAllGCInfo(); + ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); + uintptr_t ret = manager.AllocReadOnly(sizeof(RegionDesc), false); + RegionDesc* region = RegionDesc::GetRegionDescAt(ret); + EXPECT_NE(ret, 0); + EXPECT_EQ(region->GetTraceLine(), region->GetRegionStart()); + EXPECT_EQ(region->GetCopyLine(), std::numeric_limits::max()); + EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); +} + +HWTEST_F_L0(RegionManagerTest, AllocReadOnly4) +{ + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_PRECOPY); + RegionManager manager; + manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); + manager.ClearAllGCInfo(); + ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); + uintptr_t ret = manager.AllocReadOnly(sizeof(RegionDesc), false); + RegionDesc* region = RegionDesc::GetRegionDescAt(ret); + EXPECT_NE(ret, 0); + EXPECT_EQ(region->GetCopyLine(), region->GetRegionStart()); + EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); +} + +HWTEST_F_L0(RegionManagerTest, AllocReadOnly5) +{ + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_COPY); + RegionManager manager; + manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); + manager.ClearAllGCInfo(); + ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); + uintptr_t ret = manager.AllocReadOnly(sizeof(RegionDesc), false); + RegionDesc* region = RegionDesc::GetRegionDescAt(ret); + EXPECT_NE(ret, 0); + EXPECT_EQ(region->GetCopyLine(), region->GetRegionStart()); + EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); +} + +HWTEST_F_L0(RegionManagerTest, AllocReadOnly6) +{ + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_FIX); + RegionManager manager; + manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); + manager.ClearAllGCInfo(); + ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); + uintptr_t ret = manager.AllocReadOnly(sizeof(RegionDesc), false); + RegionDesc* region = RegionDesc::GetRegionDescAt(ret); + EXPECT_NE(ret, 0); + EXPECT_EQ(region->GetCopyLine(), region->GetRegionStart()); + EXPECT_EQ(region->GetFixLine(), region->GetRegionStart()); +} + +HWTEST_F_L0(RegionManagerTest, AllocReadOnly7) +{ + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_UNDEF); + RegionManager manager; + manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); + manager.ClearAllGCInfo(); + ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); + uintptr_t ret = manager.AllocReadOnly(sizeof(RegionDesc), false); + RegionDesc* region = RegionDesc::GetRegionDescAt(ret); + EXPECT_NE(ret, 0); + EXPECT_EQ(region->GetTraceLine(), std::numeric_limits::max()); + EXPECT_EQ(region->GetCopyLine(), std::numeric_limits::max()); + EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); +} } diff --git a/common_components/heap/allocator/tests/region_space_test.cpp b/common_components/heap/allocator/tests/region_space_test.cpp index 9da265969874c352ebe146a7ec2030ce87160917..1d62c2afc55b1419c1ec6027818a12383323d82e 100755 --- a/common_components/heap/allocator/tests/region_space_test.cpp +++ b/common_components/heap/allocator/tests/region_space_test.cpp @@ -56,6 +56,10 @@ protected: ASSERT_NE(mutator_, nullptr); mutator_->InitTid(); ThreadLocal::GetThreadLocalData()->mutator = mutator_; + BaseRuntime::GetInstance()->GetHeapParam().regionSize = 64; // 64:region size + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + RegionManager& regionManager = theAllocator.GetRegionManager(); + regionManager.SetMaxUnitCountForRegion(); } void TearDown() override diff --git a/common_components/heap/barrier/tests/barrier_test.cpp b/common_components/heap/barrier/tests/barrier_test.cpp index d78a62b39bed28db45bf1ebd3b6dc962bd630ef7..46d7a33bb96c30df78d8aab3917a72bcf7092000 100644 --- a/common_components/heap/barrier/tests/barrier_test.cpp +++ b/common_components/heap/barrier/tests/barrier_test.cpp @@ -106,7 +106,6 @@ protected: } }; - HWTEST_F_L0(BarrierTest, ReadRefField_ReturnsExpectedValue) { uint64_t value = reinterpret_cast(dummyObj.get()); RefField field(value); @@ -115,7 +114,6 @@ HWTEST_F_L0(BarrierTest, ReadRefField_ReturnsExpectedValue) { EXPECT_EQ(result, dummyObj.get()); } - HWTEST_F_L0(BarrierTest, WriteRefField_SetsTargetObject) { uint64_t initValue = 0; RefField field(initValue); @@ -125,7 +123,6 @@ HWTEST_F_L0(BarrierTest, WriteRefField_SetsTargetObject) { EXPECT_EQ(field.GetTargetObject(), newRef); } - HWTEST_F_L0(BarrierTest, WriteStaticRef_SetsTargetObject) { uint64_t initValue = 0; RefField field(initValue); @@ -135,7 +132,6 @@ HWTEST_F_L0(BarrierTest, WriteStaticRef_SetsTargetObject) { EXPECT_EQ(field.GetTargetObject(), newRef); } - HWTEST_F_L0(BarrierTest, AtomicWriteRefField_UpdatesWithMemoryOrder) { uint64_t initValue = 0; RefField field(initValue); @@ -145,7 +141,6 @@ HWTEST_F_L0(BarrierTest, AtomicWriteRefField_UpdatesWithMemoryOrder) { EXPECT_EQ(field.GetTargetObject(std::memory_order_relaxed), newRef); } - HWTEST_F_L0(BarrierTest, CompareAndSwapRefField_WorksWithSuccessAndFailure) { uint64_t initValue = 0; RefField field(initValue); @@ -156,4 +151,101 @@ HWTEST_F_L0(BarrierTest, CompareAndSwapRefField_WorksWithSuccessAndFailure) { std::memory_order_seq_cst, std::memory_order_relaxed); EXPECT_TRUE(result); EXPECT_EQ(field.GetTargetObject(std::memory_order_relaxed), newRef); +} + +HWTEST_F_L0(BarrierTest, WriteStruct_HandlesDifferentLengths) { + size_t srcBufferSize = 512; + size_t dstBufferSize = 1024; + char* srcBuffer = new char[srcBufferSize]; + char* dstBuffer = new char[dstBufferSize]; + + for (size_t i = 0; i < srcBufferSize; ++i) { + srcBuffer[i] = static_cast(i % 256); + } + + barrier.WriteStruct(nullptr, reinterpret_cast(dstBuffer), dstBufferSize, + reinterpret_cast(srcBuffer), srcBufferSize); + + EXPECT_EQ(memcmp(dstBuffer, srcBuffer, srcBufferSize), 0); + + for (size_t i = srcBufferSize; i < dstBufferSize; ++i) { + EXPECT_EQ(dstBuffer[i], 0); + } + + delete[] srcBuffer; + delete[] dstBuffer; +} + +HWTEST_F_L0(BarrierTest, ReadStaticRef_ReturnsExpectedValue) { + uint64_t value = reinterpret_cast(dummyObj.get()); + RefField field(value); + + BaseObject* result = barrier.ReadStaticRef(field); + EXPECT_EQ(result, dummyObj.get()); +} + +HWTEST_F_L0(BarrierTest, AtomicSwapRefField_ExchangesCorrectly) { + uint64_t initValue = reinterpret_cast(dummyObj.get()); + RefField field(initValue); + BaseObject* newRef = reinterpret_cast(0x1234567890); + BaseObject* oldValue = barrier.AtomicSwapRefField(nullptr, field, newRef, std::memory_order_seq_cst); + + EXPECT_EQ(oldValue, dummyObj.get()); + EXPECT_EQ(field.GetTargetObject(std::memory_order_relaxed), newRef); +} + +HWTEST_F_L0(BarrierTest, AtomicReadRefField_ReadsCorrectly) { + uint64_t initValue = reinterpret_cast(dummyObj.get()); + RefField field(initValue); + + BaseObject* value = barrier.AtomicReadRefField(nullptr, field, std::memory_order_seq_cst); + + EXPECT_EQ(value, dummyObj.get()); +} + +HWTEST_F_L0(BarrierTest, CopyStructArray_CopiesDataCorrectly) { + constexpr size_t arraySize = 100; + char* srcBuffer = new char[arraySize]; + char* dstBuffer = new char[arraySize]; + + for (size_t i = 0; i < arraySize; ++i) { + srcBuffer[i] = static_cast(i % 256); + } + + BaseObject srcObj; + BaseObject dstObj; + + HeapAddress srcFieldAddr = reinterpret_cast(srcBuffer); + HeapAddress dstFieldAddr = reinterpret_cast(dstBuffer); + + barrier.CopyStructArray(&dstObj, dstFieldAddr, arraySize, &srcObj, srcFieldAddr, arraySize); + + EXPECT_EQ(memcmp(dstBuffer, srcBuffer, arraySize), 0); + + delete[] srcBuffer; + delete[] dstBuffer; +} + +HWTEST_F_L0(BarrierTest, ReadStruct_ReadsCorrectly) { + struct TestStruct { + int a; + double b; + }; + + TestStruct* initValue = new TestStruct{42, 3.14}; + RefField field(reinterpret_cast(initValue)); + + char dstBuffer[sizeof(TestStruct)]; + HeapAddress dstAddr = reinterpret_cast(dstBuffer); + + BaseObject dummyObj; + HeapAddress srcAddr = reinterpret_cast(field.GetTargetObject()); + + barrier.ReadStruct(dstAddr, &dummyObj, srcAddr, sizeof(TestStruct)); + + TestStruct* result = reinterpret_cast(dstBuffer); + EXPECT_EQ(result->a, initValue->a); + EXPECT_EQ(result->b, initValue->b); + + delete initValue; } \ No newline at end of file diff --git a/common_components/heap/collector/tests/BUILD.gn b/common_components/heap/collector/tests/BUILD.gn index 95fb9e2968b2dcb2aee64333b06a1a2cb686896e..20a34d4289709824629fe2663dcf71b8349d9011 100755 --- a/common_components/heap/collector/tests/BUILD.gn +++ b/common_components/heap/collector/tests/BUILD.gn @@ -21,7 +21,7 @@ host_unittest_action("Collector_Test") { sources = [ # test file "collector_resources_test.cpp", - "finalizer_processor_test.cpp", + # "finalizer_processor_test.cpp", ] configs = [ diff --git a/common_components/heap/collector/tests/collector_resources_test.cpp b/common_components/heap/collector/tests/collector_resources_test.cpp index c05a505ae9ecf5fac640edba6548a8b9c29ba3fc..e5c41750fcb1344b801a23067148d3fb5d8e0aba 100755 --- a/common_components/heap/collector/tests/collector_resources_test.cpp +++ b/common_components/heap/collector/tests/collector_resources_test.cpp @@ -49,4 +49,43 @@ HWTEST_F_L0(CollectorResourcesTest, RequestHeapDumpTest) { GCTask::GCTaskType::GC_TASK_INVALID); EXPECT_TRUE(Heap::GetHeap().IsGCEnabled()); } + +HWTEST_F_L0(CollectorResourcesTest, RequestGC) { + GCRequest gcRequests = { GC_REASON_BACKUP, "backup", true, false, 0, 0 }; + Heap::GetHeap().EnableGC(false); + EXPECT_TRUE(!Heap::GetHeap().GetCollectorResources().IsGCActive()); + GCReason reason = gcRequests.reason; + Heap::GetHeap().GetCollectorResources().RequestGC(reason, true); +} + +HWTEST_F_L0(CollectorResourcesTest, RequestGCAndWaitTest) { + GCRequest gcRequests = { GC_REASON_USER, "user", false, false, 0, 0 }; + GCReason reason = gcRequests.reason; + Heap::GetHeap().EnableGC(true); + EXPECT_TRUE(Heap::GetHeap().GetCollectorResources().IsGCActive()); + Heap::GetHeap().GetCollectorResources().RequestGC(reason, false); + EXPECT_TRUE(!gcRequests.IsSyncGC()); +} + +HWTEST_F_L0(CollectorResourcesTest, GetGCThreadCountTest0) { + uint32_t res = Heap::GetHeap().GetCollectorResources().GetGCThreadCount(false); + EXPECT_EQ(res, 2u); +} + +HWTEST_F_L0(CollectorResourcesTest, GetGCThreadCountTest1) { + Heap::GetHeap().GetCollectorResources().Fini(); + uint32_t res = Heap::GetHeap().GetCollectorResources().GetGCThreadCount(false); + EXPECT_EQ(res, 1u); +} + +HWTEST_F_L0(CollectorResourcesTest, StartRuntimeThreadsTest) { + Heap::GetHeap().GetCollectorResources().Fini(); + Heap::GetHeap().GetCollectorResources().StartRuntimeThreads(); + EXPECT_TRUE(Heap::GetHeap().GetCollectorResources().GetFinalizerProcessor().IsRunning()); +} + +HWTEST_F_L0(CollectorResourcesTest, StopRuntimeThreadsTest) { + Heap::GetHeap().GetCollectorResources().StopRuntimeThreads(); + EXPECT_FALSE(Heap::GetHeap().GetCollectorResources().GetFinalizerProcessor().IsRunning()); +} } // namespace common::test \ No newline at end of file diff --git a/common_components/heap/collector/tests/gc_request_test.cpp b/common_components/heap/collector/tests/gc_request_test.cpp index 19324a4a059767e8e081a6aa30a97f0a6478759b..5ceccb73318c16e9ba1dfd7562dea1a3bddf7882 100644 --- a/common_components/heap/collector/tests/gc_request_test.cpp +++ b/common_components/heap/collector/tests/gc_request_test.cpp @@ -21,141 +21,129 @@ using namespace common; -uint64_t fakeCurrentTime = 0; - namespace common { -uint64_t TimeUtil::NanoSeconds() -{ - return fakeCurrentTime; -} -} // namespace panda - class GCRequestTest : public common::test::BaseTestWithScope { -protected: - void SetUp() override - { - fakeCurrentTime = 0; - } - - void SetPrevRequestTime(GCRequest& req, uint64_t time) - { - req.SetPrevRequestTime(time); - } - - void SetMinInterval(GCRequest& req, uint64_t intervalNs) - { - req.SetMinInterval(intervalNs); - } }; -void SetLastGCFinishTime(uint64_t time) -{ - GCStats::SetPrevGCFinishTime(time); +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Heu_Test1) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCStats::SetPrevGCFinishTime(now); + GCRequest req = { GC_REASON_HEU, "heuristic", false, true, 0, 0 }; + req.SetMinInterval(now + 1000); + + bool result = req.ShouldBeIgnored(); + EXPECT_TRUE(result); } +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Heu_Test2) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCStats::SetPrevGCFinishTime(1000); + GCRequest req = { GC_REASON_HEU, "heuristic", false, true, 0, 0 }; + req.SetMinInterval(1000); -bool ShouldBeIgnoredWithReason(GCReason reason, uint64_t minIntervalNs, uint64_t prevReqTime, uint64_t now, - uint64_t lastGCFinishTime = 0) -{ - fakeCurrentTime = now; - SetLastGCFinishTime(lastGCFinishTime); + bool result = req.ShouldBeIgnored(); + EXPECT_FALSE(result); +} - GCRequest req = { - reason, - "", // name - false, // isSync - false, // isConcurrent - minIntervalNs, - prevReqTime - }; +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Young_Test1) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCStats::SetPrevGCFinishTime(now); + GCRequest req = { GC_REASON_YOUNG, "young", false, true, 0, 0 }; + req.SetMinInterval(now + 1000); - return req.ShouldBeIgnored(); + bool result = req.ShouldBeIgnored(); + EXPECT_TRUE(result); } +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Young_Test2) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCStats::SetPrevGCFinishTime(1000); + GCRequest req = { GC_REASON_YOUNG, "young", false, true, 0, 0 }; + req.SetMinInterval(1000); -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Heu_ReturnsTrue_IfFrequent) { - bool result = ShouldBeIgnoredWithReason( - GC_REASON_HEU, - 1000, // minIntervalNs - fakeCurrentTime - 500, // prevReqTime < now - minInterval - fakeCurrentTime - ); + bool result = req.ShouldBeIgnored(); EXPECT_FALSE(result); } -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Native_ReturnsTrue_IfFrequent) { - bool result = ShouldBeIgnoredWithReason( - GC_REASON_NATIVE, - 1000, - fakeCurrentTime - 500, - fakeCurrentTime, - fakeCurrentTime - 500 // lastGCFinishTime - ); - EXPECT_FALSE(result); +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Native_Test1) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCStats::SetPrevGCFinishTime(now); + GCRequest req = { GC_REASON_NATIVE, "native", false, true, 0, 0 }; + req.SetMinInterval(now + 1000); + + bool result = req.ShouldBeIgnored(); + EXPECT_TRUE(result); } -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Native_ReturnsFalse_IfNotFrequent) { - bool result = ShouldBeIgnoredWithReason( - GC_REASON_NATIVE, - 1000, - fakeCurrentTime - 1500, - fakeCurrentTime, - fakeCurrentTime - 1500 - ); +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Native_Test2) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCStats::SetPrevGCFinishTime(1000); + GCRequest req = { GC_REASON_NATIVE, "native", false, true, 0, 0 }; + req.SetMinInterval(1000); + + bool result = req.ShouldBeIgnored(); EXPECT_FALSE(result); } -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_OOM_ReturnsTrue_IfFrequent) { - bool result = ShouldBeIgnoredWithReason( - GC_REASON_OOM, - 1000, - fakeCurrentTime - 500, - fakeCurrentTime - ); +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Oom_Test1) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCRequest req = { GC_REASON_OOM, "oom", false, true, 0, 0 }; + req.SetMinInterval(now + 1000); + req.SetPrevRequestTime(now); + + bool result = req.ShouldBeIgnored(); EXPECT_TRUE(result); } -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_OOM_ReturnsFalse_IfNotFrequent) { - bool result = ShouldBeIgnoredWithReason( - GC_REASON_OOM, - 1000, - fakeCurrentTime - 1500, - fakeCurrentTime - ); +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Oom_Test2) { + GCRequest req = { GC_REASON_OOM, "oom", false, true, 0, 0 }; + req.SetMinInterval(0); + req.SetPrevRequestTime(1000); + + bool result = req.ShouldBeIgnored(); + EXPECT_FALSE(result); +} + +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Oom_Test3) { + GCRequest req = { GC_REASON_OOM, "oom", false, true, 0, 0 }; + req.SetMinInterval(1000); + req.SetPrevRequestTime(1000); + + bool result = req.ShouldBeIgnored(); EXPECT_FALSE(result); } -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Force_ReturnsTrue_IfFrequent) { - bool result = ShouldBeIgnoredWithReason( - GC_REASON_FORCE, - 1000, - fakeCurrentTime - 500, - fakeCurrentTime - ); +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Force_Test1) { + int64_t now = static_cast(TimeUtil::NanoSeconds()); + GCRequest req = { GC_REASON_FORCE, "force", false, true, 0, 0 }; + req.SetMinInterval(now + 1000); + req.SetPrevRequestTime(now); + + bool result = req.ShouldBeIgnored(); EXPECT_TRUE(result); } -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Force_ReturnsFalse_IfNotFrequent) { - bool result = ShouldBeIgnoredWithReason( - GC_REASON_FORCE, - 1000, - fakeCurrentTime - 1500, - fakeCurrentTime - ); +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Force_Test2) { + GCRequest req = { GC_REASON_FORCE, "force", false, true, 0, 0 }; + req.SetMinInterval(0); + req.SetPrevRequestTime(1000); + + bool result = req.ShouldBeIgnored(); EXPECT_FALSE(result); } -HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_User_ReturnsFalse) { - fakeCurrentTime = 1000; +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_Force_Test3) { + GCRequest req = { GC_REASON_FORCE, "force", false, true, 0, 0 }; + req.SetMinInterval(1000); + req.SetPrevRequestTime(1000); - GCRequest req = { - GC_REASON_USER, - "", - false, - false, - 0, - 0 - }; + bool result = req.ShouldBeIgnored(); + EXPECT_FALSE(result); +} - EXPECT_FALSE(req.ShouldBeIgnored()); -} \ No newline at end of file +HWTEST_F_L0(GCRequestTest, ShouldBeIgnored_User_Test1) { + GCRequest req = { GC_REASON_USER, "user", false, true, 0, 0 }; + bool result = req.ShouldBeIgnored(); + EXPECT_FALSE(result); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/heap/collector/tests/task_queue_test.cpp b/common_components/heap/collector/tests/task_queue_test.cpp index 9d2bd3a063bae26bd0104c546fc9ff8d60f614fe..e90a061577b8fd78fe238622bdf26da848d9e200 100644 --- a/common_components/heap/collector/tests/task_queue_test.cpp +++ b/common_components/heap/collector/tests/task_queue_test.cpp @@ -15,218 +15,99 @@ #include "common_components/heap/collector/task_queue.h" #include "common_components/heap/collector/collector_proxy.h" - +#include "common_components/heap/collector/gc_request.h" #include "common_components/tests/test_helper.h" -using namespace common; - -// ==================== Mock Classes ==================== - -class MockCollectorProxy : public CollectorProxy { +namespace common { +class StubAllocator : public Allocator { public: - explicit MockCollectorProxy(Allocator& allocator, CollectorResources& resources) - : CollectorProxy(allocator, resources), runCalled_(false), - lastGcIndex_(0), lastReason_(GC_REASON_INVALID) {} - - void RunGarbageCollection(uint64_t gcIndex, GCReason reason) override - { - runCalled_ = true; - lastGcIndex_ = gcIndex; - lastReason_ = reason; - } - - bool WasRunCalled() const - { - return runCalled_; - } - uint64_t GetLastGcIndex() const - { - return lastGcIndex_; - } - GCReason GetLastReason() const - { - return lastReason_; - } - - void Reset() - { - runCalled_ = false; - lastGcIndex_ = 0; - lastReason_ = GC_REASON_INVALID; - } - -private: - mutable bool runCalled_; - uint64_t lastGcIndex_; - GCReason lastReason_; -}; - -constexpr size_t DEFAULT_MAX_CAPACITY_SIZE = 10 * 1024 * 1024; -constexpr size_t DEFAULT_CAPACITY_SIZE = 5 * 1024 * 1024; - -class TestAllocator : public Allocator { -public: - HeapAddress Allocate(size_t size, AllocType type) override - { - return 0; - } - HeapAddress AllocateNoGC(size_t size, AllocType type) override - { - return 0; - } - bool ForEachObject(const std::function& callback, bool safe) const override - { - return true; - } - size_t ReclaimGarbageMemory(bool releaseAll) override - { - return 0; - } - void FeedHungryBuffers() override {} - size_t LargeObjectSize() const override - { - return 0; - } - size_t GetAllocatedBytes() const override - { - return 0; - } + HeapAddress Allocate(size_t size, AllocType allocType) override { return 0; } + HeapAddress AllocateNoGC(size_t size, AllocType allocType) override { return 0; } + bool ForEachObject(const std::function&, bool safe) const override { return true; } + size_t ReclaimGarbageMemory(bool releaseAll) override { return 0; } + size_t LargeObjectSize() const override { return 0; } + size_t GetAllocatedBytes() const override { return 0; } void Init(const RuntimeParam& param) override {} - - size_t GetMaxCapacity() const override - { - return DEFAULT_MAX_CAPACITY_SIZE; - } - size_t GetCurrentCapacity() const override - { - return DEFAULT_CAPACITY_SIZE; - } - size_t GetUsedPageSize() const override - { - return 0; - } - HeapAddress GetSpaceStartAddress() const override - { - return 0; - } - HeapAddress GetSpaceEndAddress() const override - { - return 0; - } - + size_t GetMaxCapacity() const override { return 0; } + size_t GetCurrentCapacity() const override { return 0; } + size_t GetUsedPageSize() const override { return 0; } + HeapAddress GetSpaceStartAddress() const override { return 0; } + HeapAddress GetSpaceEndAddress() const override { return 0; } #ifndef NDEBUG bool IsHeapObject(HeapAddress) const override { return false; } #endif + void FeedHungryBuffers() override {} }; -class TestCollectorResources : public CollectorResources { +class StubCollectorProxy : public CollectorProxy { public: - explicit TestCollectorResources(CollectorProxy& proxy) : CollectorResources(proxy) {} - void Init() {} - void Fini() {} -}; + explicit StubCollectorProxy(Allocator& allocator, CollectorResources& resources) + : CollectorProxy(allocator, resources) {} -// ==================== Fix: Use correct GCTask interface ==================== + void RunGarbageCollection(uint64_t gcIndex, GCReason reason) override {} +}; +} -class MockGCTask : public GCTask { +namespace common { +class DummyCollectorProxy : public CollectorProxy { public: - explicit MockGCTask(GCTaskType type, uint64_t index, GCReason reason) - : GCTask(type), taskIndex_(index), gcReason_(reason) {} - - uint64_t GetGCIndex() const - { - return taskIndex_; - } - GCReason GetGCReason() const - { - return gcReason_; - } - - bool Execute(void* owner) override - { - if (owner == nullptr) { - return false; - } - - auto* proxy = reinterpret_cast(owner); - switch (GetTaskType()) { - case GCTaskType::GC_TASK_TERMINATE_GC: - return false; - case GCTaskType::GC_TASK_INVOKE_GC: - proxy->RunGarbageCollection(taskIndex_, gcReason_); - return true; - default: - return true; - } - } - -private: - uint64_t taskIndex_; - GCReason gcReason_; + explicit DummyCollectorProxy(Allocator& alloc, CollectorResources& res) + : CollectorProxy(alloc, res) {} + void RunGarbageCollection(uint64_t gcIndex, GCReason reason) override {} }; -// ==================== Test Fixture ==================== +class DummyCollectorResources : public CollectorResources { +private: + DummyCollectorProxy proxy_; -// class GCRunnerTest : public BaseTestWithScope { +public: + explicit DummyCollectorResources(Allocator& alloc) + : CollectorResources(proxy_), + proxy_(alloc, *this) {} +}; +} namespace common::test { class GCRunnerTest : public common::test::BaseTestWithScope { protected: void SetUp() override { - resources_.reset(new TestCollectorResources(proxy_)); - mockProxy_ = new MockCollectorProxy(allocator_, *resources_); + allocator_ = std::make_unique(); + dummyResources_ = std::make_unique(*allocator_); + proxy_ = std::make_unique(*allocator_, *dummyResources_); + proxyStorage_ = std::make_unique(*allocator_, *dummyResources_); } void TearDown() override { - delete mockProxy_; - mockProxy_ = nullptr; - resources_.reset(); + proxyStorage_.reset(); + dummyResources_.reset(); + proxy_.reset(); + allocator_.reset(); } - TestAllocator allocator_; - std::unique_ptr resources_; - MockCollectorProxy* mockProxy_; - CollectorProxy proxy_{allocator_, *resources_}; + std::unique_ptr allocator_; + std::unique_ptr proxy_; + std::unique_ptr proxyStorage_; + std::unique_ptr dummyResources_; }; -// ==================== Test Cases ==================== - -/** - * @tc.name: GCRunner_Execute_Terminate - * @tc.desc: Test GC_TASK_TERMINATE_GC task type. - * @tc.type: FUNC - */ -HWTEST_F_L0(GCRunnerTest, Execute_Terminate) { - // Arrange - MockGCTask task(GCTask::GCTaskType::GC_TASK_TERMINATE_GC, 0, GC_REASON_INVALID); - - // Act - bool result = task.Execute(mockProxy_); - - // Assert - EXPECT_FALSE(result); // Should return false to terminate thread +HWTEST_F_L0(GCRunnerTest, Execute_TerminateGC) { + common::GCRunner runner(common::GCTask::GCTaskType::GC_TASK_TERMINATE_GC); + bool result = runner.Execute(proxyStorage_.get()); + EXPECT_FALSE(result); } -/** - * @tc.name: GCRunner_Execute_InvokeGC - * @tc.desc: Test GC_TASK_INVOKE_GC triggers RunGarbageCollection. - * @tc.type: FUNC - */ HWTEST_F_L0(GCRunnerTest, Execute_InvokeGC) { - // Arrange - mockProxy_->Reset(); - - MockGCTask task(GCTask::GCTaskType::GC_TASK_INVOKE_GC, 123, GC_REASON_FORCE); - - // Act - bool result = task.Execute(mockProxy_); + common::GCRunner runner(common::GCTask::GCTaskType::GC_TASK_INVOKE_GC, GC_REASON_BACKUP); + bool result = runner.Execute(proxyStorage_.get()); + EXPECT_TRUE(result); +} - // Assert - EXPECT_TRUE(result); // Thread should continue - EXPECT_TRUE(mockProxy_->WasRunCalled()); - EXPECT_EQ(mockProxy_->GetLastGcIndex(), 123U); - EXPECT_EQ(mockProxy_->GetLastReason(), GC_REASON_FORCE); +HWTEST_F_L0(GCRunnerTest, Execute_InvalidTaskType) { + common::GCRunner runner(static_cast( + static_cast(common::GCTask::GCTaskType::GC_TASK_DUMP_HEAP_IDE) + 1)); + bool result = runner.Execute(proxyStorage_.get()); + EXPECT_TRUE(result); } -} \ No newline at end of file +} // namespace common::test diff --git a/common_components/heap/w_collector/copy_barrier.cpp b/common_components/heap/w_collector/copy_barrier.cpp index b09ac3ad8db40b30dbd039a86d79186d2deea397..1a5d3eef90f1c08535a39862e2cd18934f7007d9 100755 --- a/common_components/heap/w_collector/copy_barrier.cpp +++ b/common_components/heap/w_collector/copy_barrier.cpp @@ -80,7 +80,7 @@ BaseObject* CopyBarrier::ReadStringTableStaticRef(RefField& field) const void CopyBarrier::ReadStruct(HeapAddress dst, BaseObject* obj, HeapAddress src, size_t size) const { CHECK_CC(!Heap::IsHeapAddress(dst)); - if (obj != nullptr) { + if (obj != nullptr) { //LCOV_EXCL_BR_LINE obj->ForEachRefInStruct( [this, obj](RefField& field) { BaseObject* target = ReadRefField(obj, field); @@ -104,10 +104,10 @@ void CopyBarrier::AtomicWriteRefField(BaseObject* obj, RefField& field, Ba { RefField<> newField(newRef); field.SetFieldValue(newField.GetFieldValue(), order); - if (obj != nullptr) { + if (obj != nullptr) { //LCOV_EXCL_BR_LINE DLOG(FBARRIER, "atomic write obj %p<%p>(%zu) ref@%p: %#zx", obj, obj->GetTypeInfo(), obj->GetSize(), &field, newField.GetFieldValue()); - } else { + } else { //LCOV_EXCL_BR_LINE DLOG(FBARRIER, "atomic write static ref@%p: %#zx", &field, newField.GetFieldValue()); } } @@ -129,9 +129,9 @@ bool CopyBarrier::CompareAndSwapRefField(BaseObject* obj, RefField& field, HeapAddress oldFieldValue = field.GetFieldValue(std::memory_order_seq_cst); RefField oldField(oldFieldValue); BaseObject* oldVersion = ReadRefField(nullptr, oldField); - while (oldVersion == oldRef) { + while (oldVersion == oldRef) { //LCOV_EXCL_BR_LINE RefField<> newField(newRef); - if (field.CompareExchange(oldFieldValue, newField.GetFieldValue(), succOrder, failOrder)) { + if (field.CompareExchange(oldFieldValue, newField.GetFieldValue(), succOrder, failOrder)) { //LCOV_EXCL_BR_LINE return true; } oldFieldValue = field.GetFieldValue(std::memory_order_seq_cst); diff --git a/common_components/heap/w_collector/tests/BUILD.gn b/common_components/heap/w_collector/tests/BUILD.gn index 300f6daa0b1dcc2c5899d092818445821ff393a1..c4bd6cd11ee10d3aa9a2599cd6832bac2241de5f 100755 --- a/common_components/heap/w_collector/tests/BUILD.gn +++ b/common_components/heap/w_collector/tests/BUILD.gn @@ -15,14 +15,172 @@ import("//arkcompiler/ets_runtime/common_components/tests/test_helper.gni") module_output_path = "ets_runtime" -host_unittest_action("W_Collector_Test") { +host_unittest_action("Copy_Barrier_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "copy_barrier_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +host_unittest_action("Enum_Barrier_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "enum_barrier_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +host_unittest_action("Idle_Barrier_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "idle_barrier_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +host_unittest_action("Post_Trace_Barrier_Test") { module_out_path = module_output_path sources = [ # test file "post_trace_barrier_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +host_unittest_action("Preforward_Barrier_Test") { + module_out_path = module_output_path + + sources = [ + # test file "preforward_barrier_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +host_unittest_action("Remark_Barrier_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "remark_barrier_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +host_unittest_action("Trace_Barrier_Test") { + module_out_path = module_output_path + + sources = [ + # test file "trace_barrier_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +host_unittest_action("W_Collector_Test") { + module_out_path = module_output_path + + sources = [ + # test file "w_collector_test.cpp", ] @@ -46,6 +204,13 @@ group("unittest") { # deps file deps = [ + ":Copy_Barrier_Test", + ":Enum_Barrier_Test", + ":Idle_Barrier_Test", + ":Post_Trace_Barrier_Test", + ":Preforward_Barrier_Test", + ":Remark_Barrier_Test", + ":Trace_Barrier_Test", ":W_Collector_Test", ] } @@ -55,6 +220,13 @@ group("host_unittest") { # deps file deps = [ + ":Copy_Barrier_TestAction", + ":Enum_Barrier_TestAction", + ":Idle_Barrier_TestAction", + ":Post_Trace_Barrier_TestAction", + ":Preforward_Barrier_TestAction", + ":Remark_Barrier_TestAction", + ":Trace_Barrier_TestAction", ":W_Collector_TestAction", ] } \ No newline at end of file diff --git a/common_components/heap/w_collector/tests/copy_barrier_test.cpp b/common_components/heap/w_collector/tests/copy_barrier_test.cpp index 440c86c1007c07455f208f65061a55194f05f14b..df5e3a24dea4816effd3c3f0fb1fb093cf933d7e 100755 --- a/common_components/heap/w_collector/tests/copy_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/copy_barrier_test.cpp @@ -14,34 +14,192 @@ */ #include "common_components/heap/w_collector/copy_barrier.h" -#include "common_components/heap/heap.h" +#include "common_components/heap/w_collector/tests/mock_barrier_collector.h" +#include "common_components/mutator/mutator_manager.h" #include "common_components/tests/test_helper.h" +#include "common_components/heap/heap_manager.h" +#include "common_interfaces/base_runtime.h" using namespace common; namespace common::test { class CopyBarrierTest : public common::test::BaseTestWithScope { +protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() {} + + void SetUp() override + { + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); + } + + void TearDown() override + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } }; -HWTEST_F_L0(CopyBarrierTest, ReadStruct_TEST1) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST1) +{ + MockCollector collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = copyBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST2) +{ + MockCollector collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = copyBarrier->ReadRefField(nullptr, field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST3) +{ + MockCollector collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj, true); + + BaseObject* resultObj = copyBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + constexpr uint64_t TAG_WEAK = 0x01ULL; + BaseObject* newObj = reinterpret_cast(reinterpret_cast(obj) | TAG_WEAK); + EXPECT_EQ(resultObj, newObj); +} + +HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST4) +{ + MockCollectorUnmovableTest collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = copyBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST5) +{ + MockCollectorUnmovableTest collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj, true); + + BaseObject* resultObj = copyBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + constexpr uint64_t TAG_WEAK = 0x01ULL; + BaseObject* newObj = reinterpret_cast(reinterpret_cast(obj) | TAG_WEAK); + EXPECT_EQ(resultObj, newObj); +} + + +HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST6) +{ + MockCollectorForwardTest collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = copyBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj == nullptr); +} + +HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST7) +{ + MockCollectorForwardTest collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj, true); + + BaseObject* resultObj = copyBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); +} + +HWTEST_F_L0(CopyBarrierTest, ReadStaticRef_TEST1) +{ + MockCollector collector; auto copyBarrier = std::make_unique(collector); ASSERT_TRUE(copyBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = copyBarrier->ReadStaticRef(field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(CopyBarrierTest, ReadStringTableStaticRef_TEST1) +{ + MockCollector collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + RefField field(nullptr); + + BaseObject* resultObj = copyBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + +HWTEST_F_L0(CopyBarrierTest, ReadStruct_TEST1) +{ + MockCollector collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; uint8_t dstBuffer[size] = {}; srcBuffer[0] = 1; HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - copyBarrier->ReadStruct(dst, &obj, src, size); + copyBarrier->ReadStruct(dst, obj, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } -HWTEST_F_L0(CopyBarrierTest, ReadStruct_TEST2) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(CopyBarrierTest, ReadStruct_TEST2) +{ + MockCollector collector; auto copyBarrier = std::make_unique(collector); ASSERT_TRUE(copyBarrier != nullptr); @@ -56,103 +214,129 @@ HWTEST_F_L0(CopyBarrierTest, ReadStruct_TEST2) { EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } -HWTEST_F_L0(CopyBarrierTest, AtomicWriteRefField_TEST1) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(CopyBarrierTest, AtomicWriteRefField_TEST1) +{ + MockCollector collector; auto copyBarrier = std::make_unique(collector); ASSERT_TRUE(copyBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - copyBarrier->AtomicWriteRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); + copyBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } -HWTEST_F_L0(CopyBarrierTest, AtomicWriteRefField_TEST2) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(CopyBarrierTest, AtomicWriteRefField_TEST2) +{ + MockCollector collector; auto copyBarrier = std::make_unique(collector); ASSERT_TRUE(copyBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - copyBarrier->AtomicWriteRefField(nullptr, oldField, &newObj, std::memory_order_relaxed); + copyBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } -HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST1) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(CopyBarrierTest, CompareAndSwapRefField_TEST1) +{ + MockCollector collector; auto copyBarrier = std::make_unique(collector); ASSERT_TRUE(copyBarrier != nullptr); - BaseObject obj; - RefField field(&obj); - - BaseObject* resultObj = copyBarrier->ReadRefField(&obj, field); - ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + bool result = copyBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, newObj, + std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_TRUE(result); } -HWTEST_F_L0(CopyBarrierTest, ReadRefField_TEST2) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(CopyBarrierTest, CompareAndSwapRefField_TEST2) +{ + MockCollector collector; auto copyBarrier = std::make_unique(collector); ASSERT_TRUE(copyBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); - BaseObject* resultObj = copyBarrier->ReadRefField(nullptr, field); - ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + bool result = copyBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, oldObj, + std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_TRUE(result); } -HWTEST_F_L0(CopyBarrierTest, ReadStaticRef_TEST1) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(CopyBarrierTest, CompareAndSwapRefField_TEST3) +{ + MockCollector collector; auto copyBarrier = std::make_unique(collector); ASSERT_TRUE(copyBarrier != nullptr); - BaseObject obj; - RefField field(&obj); - - BaseObject* resultObj = copyBarrier->ReadStaticRef(field); - ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); -} - -HWTEST_F_L0(CopyBarrierTest, AtomicReadRefField_TEST1) { - Collector& collector = Heap::GetHeap().GetCollector(); - auto copyBarrier = std::make_unique(collector); - ASSERT_TRUE(copyBarrier != nullptr); + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); - BaseObject obj; - RefField field(&obj); + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); - BaseObject* resultObj = nullptr; - resultObj = copyBarrier->AtomicReadRefField(&obj, field, std::memory_order_seq_cst); - ASSERT_TRUE(resultObj != nullptr); + bool result = copyBarrier->CompareAndSwapRefField(oldObj, newField, oldObj, newObj, + std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_FALSE(result); } } // namespace common::test \ No newline at end of file diff --git a/common_components/heap/w_collector/tests/enum_barrier_test.cpp b/common_components/heap/w_collector/tests/enum_barrier_test.cpp index e771b6bcac3df30714736bbd33a948d55430ee9d..045895b21834cd55723de20df84cb0ea91beac80 100755 --- a/common_components/heap/w_collector/tests/enum_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/enum_barrier_test.cpp @@ -13,266 +13,400 @@ * limitations under the License. */ -#include "common_components/heap/heap.h" #include "common_components/heap/w_collector/enum_barrier.h" +#include "common_components/heap/w_collector/tests/mock_barrier_collector.h" +#include "common_components/mutator/mutator_manager.h" #include "common_components/tests/test_helper.h" +#include "common_components/heap/heap_manager.h" +#include "common_interfaces/base_runtime.h" using namespace common; namespace common::test { class EnumBarrierTest : public common::test::BaseTestWithScope { protected: - void SetUp() override + static void SetUpTestCase() { - Collector& collector = Heap::GetHeap().GetCollector(); - enumBarrier_ = std::make_unique(collector); + BaseRuntime::GetInstance()->Init(); } - void TearDown() override {} + static void TearDownTestCase() {} + + void SetUp() override + { + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); + } - std::unique_ptr enumBarrier_ {nullptr}; + void TearDown() override + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } }; -HWTEST_F_L0(EnumBarrierTest, ReadRefField_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, ReadRefField_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject* resultObj = enumBarrier_->ReadRefField(&obj, field); + BaseObject* resultObj = enumBarrier->ReadRefField(obj, field); ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + EXPECT_EQ(resultObj, obj); } -HWTEST_F_L0(EnumBarrierTest, ReadRefField_TEST2) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, ReadRefField_TEST2) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject* resultObj = enumBarrier_->ReadRefField(nullptr, field); + BaseObject* resultObj = enumBarrier->ReadRefField(nullptr, field); ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + EXPECT_EQ(resultObj, obj); } -HWTEST_F_L0(EnumBarrierTest, ReadStaticRef_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, ReadStaticRef_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject* resultObj = enumBarrier_->ReadStaticRef(field); + BaseObject* resultObj = enumBarrier->ReadStaticRef(field); ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(EnumBarrierTest, WriteRefField_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(addr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField field(oldObj); + MAddress oldAddress = field.GetFieldValue(); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + enumBarrier->WriteRefField(oldObj, field, newObj); + MAddress newAddress = field.GetFieldValue(); + EXPECT_NE(newAddress, oldAddress); } -HWTEST_F_L0(EnumBarrierTest, WriteRefField_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, WriteRefField_TEST2) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField field(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField field(nullptr); MAddress oldAddress = field.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - enumBarrier_->WriteRefField(&oldObj, field, &newObj); - enumBarrier_->WriteBarrier(&oldObj, field, &newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + enumBarrier->WriteRefField(oldObj, field, newObj); MAddress newAddress = field.GetFieldValue(); EXPECT_NE(newAddress, oldAddress); } -HWTEST_F_L0(EnumBarrierTest, ReadStruct_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, WriteBarrier_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); + +#ifndef ARK_USE_SATB_BARRIER + constexpr uint64_t TAG_BITS_SHIFT = 48; + constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT; + constexpr uint64_t TAG_SPECIAL = 0x02ULL; + constexpr uint64_t TAG_BOOLEAN = 0x04ULL; + constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN; + + RefField<> field(MAddress(0)); + enumBarrier->WriteBarrier(nullptr, field, nullptr); + BaseObject *obj = reinterpret_cast(TAG_HEAP_OBJECT_MASK); + enumBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +#endif +} + +HWTEST_F_L0(EnumBarrierTest, WriteBarrier_TEST2) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); + +#ifdef ARK_USE_SATB_BARRIER + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField normalField(obj); + enumBarrier->WriteBarrier(obj, normalField, obj); + EXPECT_TRUE(obj != nullptr); + + HeapAddress weakAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* weakObj = reinterpret_cast(weakAddr); + RefField weakField(MAddress(0)); + enumBarrier->WriteBarrier(&weakObj, weakField, &weakObj); + EXPECT_TRUE(weakObj != nullptr); + + HeapAddress nonTaggedAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* nonTaggedObj = reinterpret_cast(nonTaggedAddr); + RefField nonTaggedField(&nonTaggedObj); + enumBarrier->WriteBarrier(nullptr, nonTaggedField, &nonTaggedObj); + EXPECT_TRUE(nonTaggedObj != nullptr); +#endif +} + +HWTEST_F_L0(EnumBarrierTest, ReadStruct_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; uint8_t dstBuffer[size] = {}; srcBuffer[0] = 1; HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - enumBarrier_->ReadStruct(dst, &obj, src, size); + enumBarrier->ReadStruct(dst, obj, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } -HWTEST_F_L0(EnumBarrierTest, WriteStaticRef_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, WriteStruct_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; - constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField field(&oldObj); - MAddress oldAddress = field.GetFieldValue(); - - BaseObject newObj; - constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - enumBarrier_->WriteStaticRef(field, &newObj); - MAddress newAddress = field.GetFieldValue(); - EXPECT_NE(newAddress, oldAddress); + auto objPtr = std::make_unique(); + constexpr size_t size = 16; + auto srcBuffer = std::make_unique(size); + auto dstBuffer = std::make_unique(size); + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer.get()); + HeapAddress dst = reinterpret_cast(dstBuffer.get()); + enumBarrier->WriteStruct(objPtr.get(), dst, size, src, size); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } -HWTEST_F_L0(EnumBarrierTest, WriteStruct_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, WriteStruct_TEST2) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - auto objPtr = std::make_unique(); constexpr size_t size = 16; auto srcBuffer = std::make_unique(size); auto dstBuffer = std::make_unique(size); srcBuffer[0] = 1; HeapAddress src = reinterpret_cast(srcBuffer.get()); HeapAddress dst = reinterpret_cast(dstBuffer.get()); - enumBarrier_->WriteStruct(objPtr.get(), dst, size, src, size); + enumBarrier->WriteStruct(nullptr, dst, size, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } -HWTEST_F_L0(EnumBarrierTest, AtomicReadRefField_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, AtomicReadRefField_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 100; - obj.SetSizeForwarded(size); - EXPECT_EQ(obj.GetSizeForwarded(), size); - RefField field(&obj); + obj->SetSizeForwarded(size); + EXPECT_EQ(obj->GetSizeForwarded(), size); + RefField field(obj); BaseObject* resultObj = nullptr; - resultObj = enumBarrier_->AtomicReadRefField(&obj, field, std::memory_order_seq_cst); + resultObj = enumBarrier->AtomicReadRefField(obj, field, std::memory_order_seq_cst); ASSERT_TRUE(resultObj != nullptr); } -HWTEST_F_L0(EnumBarrierTest, AtomicWriteRefField_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, AtomicWriteRefField_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - enumBarrier_->AtomicWriteRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); + enumBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } -HWTEST_F_L0(EnumBarrierTest, AtomicWriteRefField_TEST2) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, AtomicWriteRefField_TEST2) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - enumBarrier_->AtomicWriteRefField(nullptr, oldField, &newObj, std::memory_order_relaxed); + enumBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } -HWTEST_F_L0(EnumBarrierTest, AtomicSwapRefField_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, AtomicSwapRefField_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); BaseObject* resultObj = nullptr; - resultObj = enumBarrier_->AtomicSwapRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); + resultObj = enumBarrier->AtomicSwapRefField(oldObj, oldField, newObj, std::memory_order_relaxed); ASSERT_TRUE(resultObj != nullptr); EXPECT_EQ(oldField.GetFieldValue(), newField.GetFieldValue()); } -HWTEST_F_L0(EnumBarrierTest, CompareAndSwapRefField_TEST1) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, CompareAndSwapRefField_TEST1) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - - bool result = enumBarrier_->CompareAndSwapRefField(&oldObj, oldField, &oldObj, &newObj, + bool result = enumBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); - ASSERT_FALSE(result); + ASSERT_TRUE(result); } -HWTEST_F_L0(EnumBarrierTest, CompareAndSwapRefField_TEST2) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, CompareAndSwapRefField_TEST2) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); - bool result = enumBarrier_->CompareAndSwapRefField(&oldObj, oldField, &oldObj, &oldObj, + bool result = enumBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_TRUE(result); } -HWTEST_F_L0(EnumBarrierTest, CompareAndSwapRefField_TEST3) { - ASSERT_TRUE(enumBarrier_ != nullptr); +HWTEST_F_L0(EnumBarrierTest, CompareAndSwapRefField_TEST3) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - bool result = enumBarrier_->CompareAndSwapRefField(&oldObj, newField, &oldObj, &newObj, + bool result = enumBarrier->CompareAndSwapRefField(oldObj, newField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_FALSE(result); } diff --git a/common_components/heap/w_collector/tests/idle_barrier_test.cpp b/common_components/heap/w_collector/tests/idle_barrier_test.cpp index 989a8583aa5d30b644b19569aadbea1293a94a78..a799ead11920d542bf820bf6333fe35745031a5c 100755 --- a/common_components/heap/w_collector/tests/idle_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/idle_barrier_test.cpp @@ -14,209 +14,217 @@ */ #include "common_components/heap/w_collector/idle_barrier.h" -#include "common_components/heap/heap.h" +#include "common_components/heap/w_collector/tests/mock_barrier_collector.h" +#include "common_components/mutator/mutator_manager.h" #include "common_components/tests/test_helper.h" +#include "common_components/heap/heap_manager.h" +#include "common_interfaces/base_runtime.h" using namespace common; namespace common::test { class IdleBarrierTest : public common::test::BaseTestWithScope { +protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() {} + + void SetUp() override + { + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); + } + + void TearDown() override + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } }; HWTEST_F_L0(IdleBarrierTest, ReadStruct_TEST0) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; uint8_t dstBuffer[size] = {}; srcBuffer[0] = 1; HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - idleBarrier->ReadStruct(dst, &obj, src, size); + idleBarrier->ReadStruct(dst, obj, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } HWTEST_F_L0(IdleBarrierTest, AtomicWriteRefField_TEST0) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - idleBarrier->AtomicWriteRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); + idleBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } -HWTEST_F_L0(IdleBarrierTest, AtomicWriteRefField_TEST1) { - Collector& collector = Heap::GetHeap().GetCollector(); +HWTEST_F_L0(IdleBarrierTest, AtomicWriteRefField_TEST1) +{ + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - idleBarrier->AtomicWriteRefField(nullptr, oldField, &newObj, std::memory_order_relaxed); + idleBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } HWTEST_F_L0(IdleBarrierTest, AtomicSwapRefField_TEST0) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - BaseObject *retObj = idleBarrier->AtomicSwapRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); + BaseObject *retObj = idleBarrier->AtomicSwapRefField(oldObj, oldField, newObj, std::memory_order_relaxed); ASSERT_TRUE(retObj != nullptr); EXPECT_EQ(oldField.GetFieldValue(), newField.GetFieldValue()); } -HWTEST_F_L0(IdleBarrierTest, CompareAndSwapRefField_TEST0) -{ - Collector& collector = Heap::GetHeap().GetCollector(); - auto idleBarrier = std::make_unique(collector); - ASSERT_TRUE(idleBarrier != nullptr); - - BaseObject oldObj; - constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); - MAddress oldAddress = oldField.GetFieldValue(); - - BaseObject newObj; - constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); - MAddress neWAddress = newField.GetFieldValue(); - EXPECT_NE(oldAddress, neWAddress); - - bool result = idleBarrier->CompareAndSwapRefField(&oldObj, oldField, &oldObj, &newObj, - std::memory_order_seq_cst, std::memory_order_seq_cst); - ASSERT_FALSE(result); -} - HWTEST_F_L0(IdleBarrierTest, CompareAndSwapRefField_TEST1) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); - bool result = idleBarrier->CompareAndSwapRefField(&oldObj, oldField, &oldObj, &oldObj, + bool result = idleBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_TRUE(result); } HWTEST_F_L0(IdleBarrierTest, CompareAndSwapRefField_TEST2) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - bool result = idleBarrier->CompareAndSwapRefField(&oldObj, newField, &oldObj, &newObj, + bool result = idleBarrier->CompareAndSwapRefField(oldObj, newField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_FALSE(result); } HWTEST_F_L0(IdleBarrierTest, WriteRefField_TEST0) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - idleBarrier->WriteRefField(&oldObj, oldField, &newObj); + idleBarrier->WriteRefField(oldObj, oldField, newObj); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } HWTEST_F_L0(IdleBarrierTest, WriteStruct_TEST0) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; uint8_t dstBuffer[size] = {}; @@ -224,48 +232,28 @@ HWTEST_F_L0(IdleBarrierTest, WriteStruct_TEST0) HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - idleBarrier->WriteStruct(&obj, dst, size, src, size); + idleBarrier->WriteStruct(obj, dst, size, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } -HWTEST_F_L0(IdleBarrierTest, WriteStaticRef_TEST0) -{ - Collector& collector = Heap::GetHeap().GetCollector(); - auto idleBarrier = std::make_unique(collector); - ASSERT_TRUE(idleBarrier != nullptr); - - BaseObject oldObj; - constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField field(&oldObj); - MAddress oldAddress = field.GetFieldValue(); - - BaseObject newObj; - constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - idleBarrier->WriteStaticRef(field, &newObj); - MAddress newAddress = field.GetFieldValue(); - EXPECT_NE(newAddress, oldAddress); -} - HWTEST_F_L0(IdleBarrierTest, CopyStructArray_TEST0) { - Collector& collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto idleBarrier = std::make_unique(collector); ASSERT_TRUE(idleBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; @@ -274,7 +262,7 @@ HWTEST_F_L0(IdleBarrierTest, CopyStructArray_TEST0) HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - idleBarrier->CopyStructArray(&oldObj, dst, size, &newObj, src, size); + idleBarrier->CopyStructArray(oldObj, dst, size, newObj, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } diff --git a/common_components/heap/w_collector/tests/mock_barrier_collector.h b/common_components/heap/w_collector/tests/mock_barrier_collector.h new file mode 100755 index 0000000000000000000000000000000000000000..3688b6dbd5450ed6dd4e88519dc049b4986dc679 --- /dev/null +++ b/common_components/heap/w_collector/tests/mock_barrier_collector.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMMON_COMPONENTS_HEAP_W_COLLECTOR_MOCK_BARRIER_COLLECTOR_H +#define COMMON_COMPONENTS_HEAP_W_COLLECTOR_MOCK_BARRIER_COLLECTOR_H + +#include "common_components/heap/collector/collector.h" + +namespace common { +class MockCollector : public Collector { +public: + void Init(const RuntimeParam& param) override {} + void RunGarbageCollection(uint64_t, GCReason) override {} + BaseObject* ForwardObject(BaseObject*) override + { + return nullptr; + } + bool ShouldIgnoreRequest(GCRequest&) override + { + return false; + } + bool IsFromObject(BaseObject*) const override + { + return false; + } + bool IsUnmovableFromObject(BaseObject*) const override + { + return false; + } + BaseObject* FindToVersion(BaseObject*) const override + { + return nullptr; + } + + bool TryUpdateRefField(BaseObject* obj, RefField<>& field, BaseObject*& toVersion) const override + { + toVersion = reinterpret_cast(field.GetFieldValue()); + return true; + } + + bool TryForwardRefField(BaseObject*, RefField<>&, BaseObject*&) const override + { + return false; + } + bool TryUntagRefField(BaseObject*, RefField<>&, BaseObject*&) const override + { + return false; + } + RefField<> GetAndTryTagRefField(BaseObject*) const override + { + return RefField<>(nullptr); + } + bool IsOldPointer(RefField<>&) const override + { + return false; + } + bool IsCurrentPointer(RefField<>&) const override + { + return false; + } + void AddRawPointerObject(BaseObject*) override {} + void RemoveRawPointerObject(BaseObject*) override {} +}; + +class MockCollectorUnmovableTest : public MockCollector { +public: + bool IsFromObject(BaseObject*) const override + { + return true; + } + bool IsUnmovableFromObject(BaseObject*) const override + { + return true; + } +}; + +class MockCollectorForwardTest : public MockCollector { +public: + bool IsFromObject(BaseObject*) const override + { + return true; + } + bool TryForwardRefField(BaseObject*, RefField<>&, BaseObject*&) const override + { + return true; + } +}; +} // namespace common + +#endif // COMMON_COMPONENTS_HEAP_W_COLLECTOR_MOCK_BARRIER_COLLECTOR_H \ No newline at end of file diff --git a/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp b/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp index d51db25d4009a8b687b06b53fbaccd958bdf7367..7b7eb4221a98491ac2dfb94db2af7835ca385437 100755 --- a/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp @@ -13,298 +13,329 @@ * limitations under the License. */ -#include "common_components/heap/heap.h" #include "common_components/heap/w_collector/post_trace_barrier.h" +#include "common_components/heap/w_collector/tests/mock_barrier_collector.h" +#include "common_components/mutator/mutator_manager.h" #include "common_components/tests/test_helper.h" +#include "common_components/heap/heap_manager.h" +#include "common_interfaces/base_runtime.h" using namespace common; namespace common::test { class PostTraceBarrierTest : public ::testing::Test { protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() {} + void SetUp() override { - Collector &collector = Heap::GetHeap().GetCollector(); - postTraceBarrier_ = std::make_unique(collector); + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); } void TearDown() override - {} - - std::unique_ptr postTraceBarrier_{nullptr}; + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } }; HWTEST_F_L0(PostTraceBarrierTest, ReadRefField_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject *resultObj = postTraceBarrier_->ReadRefField(&obj, field); + BaseObject *resultObj = postTraceBarrier->ReadRefField(obj, field); ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + EXPECT_EQ(resultObj, obj); } HWTEST_F_L0(PostTraceBarrierTest, ReadRefField_TEST2) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject *resultObj = postTraceBarrier_->ReadRefField(nullptr, field); + BaseObject *resultObj = postTraceBarrier->ReadRefField(nullptr, field); ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + EXPECT_EQ(resultObj, obj); } HWTEST_F_L0(PostTraceBarrierTest, ReadStaticRef_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject *resultObj = postTraceBarrier_->ReadStaticRef(field); + BaseObject *resultObj = postTraceBarrier->ReadStaticRef(field); ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + EXPECT_EQ(resultObj, obj); } -HWTEST_F_L0(PostTraceBarrierTest, WriteRefField_TEST1) +HWTEST_F_L0(PostTraceBarrierTest, ReadStringTableStaticRef_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject oldObj; - constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField field(&oldObj); - MAddress oldAddress = field.GetFieldValue(); + RefField field(nullptr); - BaseObject newObj; - constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - postTraceBarrier_->WriteRefField(&oldObj, field, &newObj); - postTraceBarrier_->WriteBarrier(&oldObj, field, &newObj); - MAddress newAddress = field.GetFieldValue(); - EXPECT_NE(newAddress, oldAddress); + BaseObject* resultObj = postTraceBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + +HWTEST_F_L0(PostTraceBarrierTest, WriteRefField_TEST1) +{ + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(addr); + RefField field(oldObj); + MAddress oldAddr = field.GetFieldValue(); + + HeapAddress newObjAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newObjAddr); + postTraceBarrier->WriteRefField(oldObj, field, newObj); + MAddress newAddr = field.GetFieldValue(); + + EXPECT_NE(oldAddr, newAddr); + EXPECT_EQ(newAddr, reinterpret_cast(newObj)); } HWTEST_F_L0(PostTraceBarrierTest, ReadStruct_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; uint8_t dstBuffer[size] = {}; srcBuffer[0] = 1; HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - postTraceBarrier_->ReadStruct(dst, &obj, src, size); + postTraceBarrier->ReadStruct(dst, obj, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } -HWTEST_F_L0(PostTraceBarrierTest, WriteStaticRef_TEST1) -{ - ASSERT_TRUE(postTraceBarrier_ != nullptr); - - BaseObject oldObj; - constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField field(&oldObj); - MAddress oldAddress = field.GetFieldValue(); - - BaseObject newObj; - constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - postTraceBarrier_->WriteStaticRef(field, &newObj); - MAddress newAddress = field.GetFieldValue(); - EXPECT_NE(newAddress, oldAddress); -} - HWTEST_F_L0(PostTraceBarrierTest, WriteStruct_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; uint8_t dstBuffer[size] = {}; srcBuffer[0] = 1; HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - postTraceBarrier_->WriteStruct(&obj, dst, size, src, size); + postTraceBarrier->WriteStruct(obj, dst, size, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } HWTEST_F_L0(PostTraceBarrierTest, AtomicReadRefField_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject obj; - constexpr size_t size = 100; - obj.SetSizeForwarded(size); - EXPECT_EQ(obj.GetSizeForwarded(), size); - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject *resultObj = nullptr; - resultObj = postTraceBarrier_->AtomicReadRefField(&obj, field, std::memory_order_seq_cst); - ASSERT_TRUE(resultObj != nullptr); + BaseObject* result = postTraceBarrier->AtomicReadRefField(obj, field, std::memory_order_seq_cst); + EXPECT_EQ(result, obj); } HWTEST_F_L0(PostTraceBarrierTest, AtomicWriteRefField_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); - MAddress neWAddress = newField.GetFieldValue(); - EXPECT_NE(oldAddress, neWAddress); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); - postTraceBarrier_->AtomicWriteRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); - EXPECT_EQ(oldField.GetFieldValue(), neWAddress); + postTraceBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed); + + EXPECT_NE(oldField.GetFieldValue(), oldAddress); + EXPECT_EQ(oldField.GetFieldValue(), reinterpret_cast(newObj)); } HWTEST_F_L0(PostTraceBarrierTest, AtomicWriteRefField_TEST2) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); - MAddress neWAddress = newField.GetFieldValue(); - EXPECT_NE(oldAddress, neWAddress); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); - postTraceBarrier_->AtomicWriteRefField(nullptr, oldField, &newObj, std::memory_order_relaxed); - EXPECT_EQ(oldField.GetFieldValue(), neWAddress); + postTraceBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed); + + EXPECT_NE(oldField.GetFieldValue(), oldAddress); + EXPECT_EQ(oldField.GetFieldValue(), reinterpret_cast(newObj)); } HWTEST_F_L0(PostTraceBarrierTest, AtomicSwapRefField_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); - - BaseObject oldObj; - constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); - MAddress oldAddress = oldField.GetFieldValue(); - - BaseObject newObj; - constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); - MAddress neWAddress = newField.GetFieldValue(); - EXPECT_NE(oldAddress, neWAddress); - - BaseObject *resultObj = nullptr; - resultObj = postTraceBarrier_->AtomicSwapRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); - ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(oldField.GetFieldValue(), newField.GetFieldValue()); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + RefField field(oldObj); + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + BaseObject* result = postTraceBarrier->AtomicSwapRefField( + oldObj, field, newObj, std::memory_order_relaxed); + EXPECT_EQ(result, oldObj); + EXPECT_EQ(field.GetFieldValue(), reinterpret_cast(newObj)); } HWTEST_F_L0(PostTraceBarrierTest, CompareAndSwapRefField_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - bool result = postTraceBarrier_->CompareAndSwapRefField( - &oldObj, oldField, &oldObj, &newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + bool result = postTraceBarrier->CompareAndSwapRefField( + oldObj, oldField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_TRUE(result); + EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } HWTEST_F_L0(PostTraceBarrierTest, CompareAndSwapRefField_TEST2) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + + MAddress initialAddress = oldField.GetFieldValue(); - bool result = postTraceBarrier_->CompareAndSwapRefField( - &oldObj, oldField, &oldObj, &oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + bool result = postTraceBarrier->CompareAndSwapRefField( + oldObj, oldField, oldObj, oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_TRUE(result); + EXPECT_EQ(oldField.GetFieldValue(), initialAddress); } HWTEST_F_L0(PostTraceBarrierTest, CompareAndSwapRefField_TEST3) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - bool result = postTraceBarrier_->CompareAndSwapRefField( - &oldObj, newField, &oldObj, &newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + bool result = postTraceBarrier->CompareAndSwapRefField(oldObj, newField, oldObj, newObj, + std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_FALSE(result); } HWTEST_F_L0(PostTraceBarrierTest, CopyStructArray_TEST1) { - ASSERT_TRUE(postTraceBarrier_ != nullptr); + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; @@ -313,7 +344,7 @@ HWTEST_F_L0(PostTraceBarrierTest, CopyStructArray_TEST1) HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - postTraceBarrier_->CopyStructArray(&oldObj, dst, size, &newObj, src, size); + postTraceBarrier->CopyStructArray(oldObj, dst, size, newObj, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } diff --git a/common_components/heap/w_collector/tests/preforward_barrier_test.cpp b/common_components/heap/w_collector/tests/preforward_barrier_test.cpp index fef53006cc022feda0664a530a122f7361accc7e..5fc7972ce2a8ae8887b4590102fed241f098cc28 100755 --- a/common_components/heap/w_collector/tests/preforward_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/preforward_barrier_test.cpp @@ -14,61 +14,348 @@ */ #include "common_components/heap/w_collector/preforward_barrier.h" -#include "common_components/heap/heap.h" +#include "common_components/heap/w_collector/tests/mock_barrier_collector.h" +#include "common_components/mutator/mutator_manager.h" #include "common_components/tests/test_helper.h" +#include "common_components/heap/heap_manager.h" +#include "common_interfaces/base_runtime.h" using namespace common; namespace common::test { -class PreforwardBarrierTest : public BaseTestWithScope {}; +class PreforwardBarrierTest : public BaseTestWithScope { +protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() {} + + void SetUp() override + { + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); + } + + void TearDown() override + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } +}; + +HWTEST_F_L0(PreforwardBarrierTest, ReadRefField_TEST1) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = preforwardBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadRefField_TEST2) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = preforwardBarrier->ReadRefField(nullptr, field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadRefField_TEST3) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj, true); + + BaseObject* resultObj = preforwardBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + constexpr uint64_t TAG_WEAK = 0x01ULL; + BaseObject* newObj = reinterpret_cast(reinterpret_cast(obj) | TAG_WEAK); + EXPECT_EQ(resultObj, newObj); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadRefField_TEST4) +{ + MockCollectorUnmovableTest collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = preforwardBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadRefField_TEST5) +{ + MockCollectorUnmovableTest collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj, true); + + BaseObject* resultObj = preforwardBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); + constexpr uint64_t TAG_WEAK = 0x01ULL; + BaseObject* newObj = reinterpret_cast(reinterpret_cast(obj) | TAG_WEAK); + EXPECT_EQ(resultObj, newObj); +} + + +HWTEST_F_L0(PreforwardBarrierTest, ReadRefField_TEST6) +{ + MockCollectorForwardTest collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = preforwardBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj == nullptr); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadRefField_TEST7) +{ + MockCollectorForwardTest collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj, true); + + BaseObject* resultObj = preforwardBarrier->ReadRefField(obj, field); + ASSERT_TRUE(resultObj != nullptr); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadStaticRef_TEST1) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = preforwardBarrier->ReadStaticRef(field); + ASSERT_TRUE(resultObj != nullptr); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadStringTableStaticRef_TEST1) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + RefField field(nullptr); + + BaseObject* resultObj = preforwardBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadStruct_TEST1) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + constexpr size_t size = 16; + uint8_t srcBuffer[size] = {}; + uint8_t dstBuffer[size] = {}; + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer); + HeapAddress dst = reinterpret_cast(dstBuffer); + preforwardBarrier->ReadStruct(dst, obj, src, size); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadStruct_TEST2) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + constexpr size_t size = 16; + uint8_t srcBuffer[size] = {}; + uint8_t dstBuffer[size] = {}; + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer); + HeapAddress dst = reinterpret_cast(dstBuffer); + preforwardBarrier->ReadStruct(dst, nullptr, src, size); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); +} + +HWTEST_F_L0(PreforwardBarrierTest, AtomicReadRefField_TEST1) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + constexpr size_t size = 100; + obj->SetSizeForwarded(size); + EXPECT_EQ(obj->GetSizeForwarded(), size); + RefField field(obj); + + BaseObject* resultObj = nullptr; + resultObj = preforwardBarrier->AtomicReadRefField(obj, field, std::memory_order_seq_cst); + ASSERT_TRUE(resultObj != nullptr); +} HWTEST_F_L0(PreforwardBarrierTest, AtomicWriteRefField_TEST1) { - Collector &collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto preforwardBarrier = std::make_unique(collector); ASSERT_TRUE(preforwardBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - preforwardBarrier->AtomicWriteRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); + preforwardBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } HWTEST_F_L0(PreforwardBarrierTest, AtomicWriteRefField_TEST2) { - Collector &collector = Heap::GetHeap().GetCollector(); + MockCollector collector; auto preforwardBarrier = std::make_unique(collector); ASSERT_TRUE(preforwardBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - preforwardBarrier->AtomicWriteRefField(nullptr, oldField, &newObj, std::memory_order_relaxed); + preforwardBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } + +HWTEST_F_L0(PreforwardBarrierTest, CompareAndSwapRefField_TEST1) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + bool result = preforwardBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, newObj, + std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_TRUE(result); +} + +HWTEST_F_L0(PreforwardBarrierTest, CompareAndSwapRefField_TEST2) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + + bool result = preforwardBarrier->CompareAndSwapRefField(oldObj, oldField, oldObj, oldObj, + std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_TRUE(result); +} + +HWTEST_F_L0(PreforwardBarrierTest, CompareAndSwapRefField_TEST3) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + + bool result = preforwardBarrier->CompareAndSwapRefField(oldObj, newField, oldObj, newObj, + std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_FALSE(result); +} } // namespace common::test + \ No newline at end of file diff --git a/common_components/heap/w_collector/tests/remark_barrier_test.cpp b/common_components/heap/w_collector/tests/remark_barrier_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..22c13b4f95753e4442982392472ed59c3778f443 --- /dev/null +++ b/common_components/heap/w_collector/tests/remark_barrier_test.cpp @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_components/heap/w_collector/remark_barrier.h" +#include "common_components/heap/w_collector/tests/mock_barrier_collector.h" +#include "common_components/mutator/mutator_manager.h" +#include "common_components/tests/test_helper.h" +#include "common_components/heap/heap_manager.h" +#include "common_interfaces/base_runtime.h" + +using namespace common; + +namespace common::test { +class RemarkBarrierTest : public BaseTestWithScope { +protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() {} + + void SetUp() override + { + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); + } + + void TearDown() override + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } +}; + +HWTEST_F_L0(RemarkBarrierTest, ReadRefField_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject *resultObj = remarkBarrier->ReadRefField(obj, field); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(RemarkBarrierTest, ReadRefField_TEST2) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject *resultObj = remarkBarrier->ReadRefField(nullptr, field); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(RemarkBarrierTest, ReadStaticRef_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject *resultObj = remarkBarrier->ReadStaticRef(field); + EXPECT_EQ(resultObj, obj); +} + +HWTEST_F_L0(RemarkBarrierTest, ReadStringTableStaticRef_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + RefField field(nullptr); + + BaseObject* resultObj = remarkBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + +HWTEST_F_L0(RemarkBarrierTest, ReadStruct_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + constexpr size_t size = 16; + uint8_t srcBuffer[size] = {}; + uint8_t dstBuffer[size] = {}; + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer); + HeapAddress dst = reinterpret_cast(dstBuffer); + remarkBarrier->ReadStruct(dst, obj, src, size); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); +} + +HWTEST_F_L0(RemarkBarrierTest, WriteRefField_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + + RefField field(oldObj); + BaseObject *target = field.GetTargetObject(); + EXPECT_TRUE(target != nullptr); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + + remarkBarrier->WriteRefField(oldObj, field, newObj); + + MAddress newAddress = field.GetFieldValue(); + MAddress expectedAddress = RefField<>(newObj).GetFieldValue(); + EXPECT_EQ(newAddress, expectedAddress); +} + +HWTEST_F_L0(RemarkBarrierTest, WriteRefField_TEST2) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + + RefField field(MAddress(0)); + BaseObject *target = field.GetTargetObject(); + EXPECT_TRUE(target == nullptr); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + + remarkBarrier->WriteRefField(oldObj, field, newObj); + + MAddress newAddress = field.GetFieldValue(); + MAddress expectedAddress = RefField<>(newObj).GetFieldValue(); + EXPECT_EQ(newAddress, expectedAddress); +} + +HWTEST_F_L0(RemarkBarrierTest, WriteBarrier_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + +#ifndef ARK_USE_SATB_BARRIER + constexpr uint64_t TAG_BITS_SHIFT = 48; + constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT; + constexpr uint64_t TAG_SPECIAL = 0x02ULL; + constexpr uint64_t TAG_BOOLEAN = 0x04ULL; + constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN; + + RefField<> field(MAddress(0)); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + addr |= TAG_HEAP_OBJECT_MASK; + BaseObject* obj = reinterpret_cast(addr); + remarkBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +#endif +} + +HWTEST_F_L0(RemarkBarrierTest, WriteBarrier_TEST2) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + +#ifdef ARK_USE_SATB_BARRIER + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField normalField(obj); + remarkBarrier->WriteBarrier(obj, normalField, obj); + EXPECT_TRUE(obj != nullptr); + + BaseObject weakObj; + RefField weakField(MAddress(0)); + remarkBarrier->WriteBarrier(&weakObj, weakField, &weakObj); + EXPECT_TRUE(weakObj != nullptr); + + BaseObject nonTaggedObj; + RefField nonTaggedField(&nonTaggedObj); + remarkBarrier->WriteBarrier(nullptr, nonTaggedField, &nonTaggedObj); + EXPECT_TRUE(nonTaggedObj != nullptr); +#endif +} + +HWTEST_F_L0(RemarkBarrierTest, WriteStruct_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + auto objPtr = std::make_unique(); + constexpr size_t size = 16; + auto srcBuffer = std::make_unique(size); + auto dstBuffer = std::make_unique(size); + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer.get()); + HeapAddress dst = reinterpret_cast(dstBuffer.get()); + remarkBarrier->WriteStruct(objPtr.get(), dst, size, src, size); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); +} + +HWTEST_F_L0(RemarkBarrierTest, AtomicReadRefField_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + constexpr size_t size = 100; + obj->SetSizeForwarded(size); + EXPECT_EQ(obj->GetSizeForwarded(), size); + RefField field(obj); + + BaseObject *resultObj = nullptr; + resultObj = remarkBarrier->AtomicReadRefField(obj, field, std::memory_order_seq_cst); + ASSERT_TRUE(resultObj != nullptr); +} + +HWTEST_F_L0(RemarkBarrierTest, AtomicWriteRefField_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + + remarkBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed); + EXPECT_EQ(oldField.GetFieldValue(), neWAddress); +} + +HWTEST_F_L0(RemarkBarrierTest, AtomicWriteRefField_TEST2) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + + remarkBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed); + EXPECT_EQ(oldField.GetFieldValue(), neWAddress); +} + +HWTEST_F_L0(RemarkBarrierTest, AtomicSwapRefField_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + + BaseObject *resultObj = nullptr; + resultObj = remarkBarrier->AtomicSwapRefField(oldObj, oldField, newObj, std::memory_order_relaxed); + EXPECT_EQ(oldField.GetFieldValue(), newField.GetFieldValue()); +} + +HWTEST_F_L0(RemarkBarrierTest, CompareAndSwapRefField_TEST1) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + + bool result = remarkBarrier->CompareAndSwapRefField( + oldObj, oldField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_TRUE(result); +} + +HWTEST_F_L0(RemarkBarrierTest, CompareAndSwapRefField_TEST2) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + + bool result = remarkBarrier->CompareAndSwapRefField( + oldObj, oldField, oldObj, oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_TRUE(result); +} + +HWTEST_F_L0(RemarkBarrierTest, CompareAndSwapRefField_TEST3) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); + constexpr size_t oldSize = 100; + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); + constexpr size_t newSize = 200; + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); + MAddress neWAddress = newField.GetFieldValue(); + EXPECT_NE(oldAddress, neWAddress); + + bool result = remarkBarrier->CompareAndSwapRefField( + oldObj, newField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + ASSERT_FALSE(result); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/heap/w_collector/tests/trace_barrier_test.cpp b/common_components/heap/w_collector/tests/trace_barrier_test.cpp index 1e046cbcdc41e86c5fdca2fbde7eed12de3f1aaf..4ae48b653905e126afdc6c600d298a53786b4998 100755 --- a/common_components/heap/w_collector/tests/trace_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/trace_barrier_test.cpp @@ -13,126 +13,160 @@ * limitations under the License. */ -#include "common_components/heap/heap.h" #include "common_components/heap/w_collector/trace_barrier.h" +#include "common_components/heap/w_collector/tests/mock_barrier_collector.h" +#include "common_components/mutator/mutator_manager.h" #include "common_components/tests/test_helper.h" +#include "common_components/heap/heap_manager.h" +#include "common_interfaces/base_runtime.h" using namespace common; namespace common::test { class TraceBarrierTest : public BaseTestWithScope { protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() {} + void SetUp() override { - Collector &collector = Heap::GetHeap().GetCollector(); - traceBarrier_ = std::make_unique(collector); + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); } void TearDown() override - {} - - std::unique_ptr traceBarrier_{nullptr}; + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } }; HWTEST_F_L0(TraceBarrierTest, ReadRefField_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject *resultObj = traceBarrier_->ReadRefField(&obj, field); - ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + BaseObject *resultObj = traceBarrier->ReadRefField(obj, field); + EXPECT_EQ(resultObj, obj); } HWTEST_F_L0(TraceBarrierTest, ReadRefField_TEST2) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject *resultObj = traceBarrier_->ReadRefField(nullptr, field); - ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + BaseObject *resultObj = traceBarrier->ReadRefField(nullptr, field); + EXPECT_EQ(resultObj, obj); } HWTEST_F_L0(TraceBarrierTest, ReadStaticRef_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject obj; - RefField field(&obj); + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); - BaseObject *resultObj = traceBarrier_->ReadStaticRef(field); - ASSERT_TRUE(resultObj != nullptr); - EXPECT_EQ(resultObj, &obj); + BaseObject *resultObj = traceBarrier->ReadStaticRef(field); + EXPECT_EQ(resultObj, obj); } HWTEST_F_L0(TraceBarrierTest, ReadStruct_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 16; uint8_t srcBuffer[size] = {}; uint8_t dstBuffer[size] = {}; srcBuffer[0] = 1; HeapAddress src = reinterpret_cast(srcBuffer); HeapAddress dst = reinterpret_cast(dstBuffer); - traceBarrier_->ReadStruct(dst, &obj, src, size); + traceBarrier->ReadStruct(dst, obj, src, size); EXPECT_EQ(dstBuffer[0], 1); EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } HWTEST_F_L0(TraceBarrierTest, WriteRefField_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField field(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + + RefField field(oldObj); BaseObject *target = field.GetTargetObject(); EXPECT_TRUE(target != nullptr); - MAddress oldAddress = field.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - traceBarrier_->WriteRefField(&oldObj, field, &newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + + traceBarrier->WriteRefField(oldObj, field, newObj); + MAddress newAddress = field.GetFieldValue(); - EXPECT_NE(newAddress, oldAddress); + MAddress expectedAddress = RefField<>(newObj).GetFieldValue(); + EXPECT_EQ(newAddress, expectedAddress); } HWTEST_F_L0(TraceBarrierTest, WriteRefField_TEST2) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField<> field(MAddress(0)); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + + RefField field(MAddress(0)); BaseObject *target = field.GetTargetObject(); EXPECT_TRUE(target == nullptr); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); - traceBarrier_->WriteRefField(&oldObj, field, &newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + + traceBarrier->WriteRefField(oldObj, field, newObj); + MAddress newAddress = field.GetFieldValue(); - EXPECT_EQ(newField.GetFieldValue(), newAddress); + MAddress expectedAddress = RefField<>(newObj).GetFieldValue(); + EXPECT_EQ(newAddress, expectedAddress); } HWTEST_F_L0(TraceBarrierTest, WriteBarrier_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); #ifndef ARK_USE_SATB_BARRIER constexpr uint64_t TAG_BITS_SHIFT = 48; @@ -142,179 +176,209 @@ HWTEST_F_L0(TraceBarrierTest, WriteBarrier_TEST1) constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN; RefField<> field(MAddress(0)); - traceBarrier_->WriteBarrier(nullptr, field, nullptr); + traceBarrier->WriteBarrier(nullptr, field, nullptr); BaseObject *obj = reinterpret_cast(TAG_HEAP_OBJECT_MASK); - traceBarrier_->WriteBarrier(obj, field, obj); + traceBarrier->WriteBarrier(obj, field, obj); EXPECT_TRUE(obj != nullptr); #endif } -HWTEST_F_L0(TraceBarrierTest, WriteStaticRef_TEST1) +HWTEST_F_L0(TraceBarrierTest, WriteBarrier_TEST2) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); + +#ifdef ARK_USE_SATB_BARRIER + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField normalField(obj); + traceBarrier->WriteBarrier(obj, normalField, obj); + EXPECT_TRUE(obj != nullptr); - BaseObject oldObj; - constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField field(&oldObj); - MAddress oldAddress = field.GetFieldValue(); + BaseObject weakObj; + RefField weakField(MAddress(0)); + traceBarrier->WriteBarrier(&weakObj, weakField, &weakObj); + EXPECT_TRUE(weakObj != nullptr); - BaseObject newObj; - constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - traceBarrier_->WriteStaticRef(field, &newObj); - MAddress newAddress = field.GetFieldValue(); - EXPECT_NE(newAddress, oldAddress); + BaseObject nonTaggedObj; + RefField nonTaggedField(&nonTaggedObj); + traceBarrier->WriteBarrier(nullptr, nonTaggedField, &nonTaggedObj); + EXPECT_TRUE(nonTaggedObj != nullptr); +#endif } HWTEST_F_L0(TraceBarrierTest, AtomicReadRefField_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject obj; + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); constexpr size_t size = 100; - obj.SetSizeForwarded(size); - EXPECT_EQ(obj.GetSizeForwarded(), size); - RefField field(&obj); + obj->SetSizeForwarded(size); + EXPECT_EQ(obj->GetSizeForwarded(), size); + RefField field(obj); BaseObject *resultObj = nullptr; - resultObj = traceBarrier_->AtomicReadRefField(&obj, field, std::memory_order_seq_cst); + resultObj = traceBarrier->AtomicReadRefField(obj, field, std::memory_order_seq_cst); ASSERT_TRUE(resultObj != nullptr); } HWTEST_F_L0(TraceBarrierTest, AtomicWriteRefField_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - traceBarrier_->AtomicWriteRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); + traceBarrier->AtomicWriteRefField(oldObj, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } HWTEST_F_L0(TraceBarrierTest, AtomicWriteRefField_TEST2) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - traceBarrier_->AtomicWriteRefField(nullptr, oldField, &newObj, std::memory_order_relaxed); + traceBarrier->AtomicWriteRefField(nullptr, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } HWTEST_F_L0(TraceBarrierTest, AtomicSwapRefField_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); BaseObject *resultObj = nullptr; - resultObj = traceBarrier_->AtomicSwapRefField(&oldObj, oldField, &newObj, std::memory_order_relaxed); - ASSERT_TRUE(resultObj != nullptr); + resultObj = traceBarrier->AtomicSwapRefField(oldObj, oldField, newObj, std::memory_order_relaxed); EXPECT_EQ(oldField.GetFieldValue(), newField.GetFieldValue()); } HWTEST_F_L0(TraceBarrierTest, CompareAndSwapRefField_TEST1) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - bool result = traceBarrier_->CompareAndSwapRefField( - &oldObj, oldField, &oldObj, &newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + bool result = traceBarrier->CompareAndSwapRefField( + oldObj, oldField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_TRUE(result); } HWTEST_F_L0(TraceBarrierTest, CompareAndSwapRefField_TEST2) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); - bool result = traceBarrier_->CompareAndSwapRefField( - &oldObj, oldField, &oldObj, &oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + bool result = traceBarrier->CompareAndSwapRefField( + oldObj, oldField, oldObj, oldObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_TRUE(result); } HWTEST_F_L0(TraceBarrierTest, CompareAndSwapRefField_TEST3) { - ASSERT_TRUE(traceBarrier_ != nullptr); + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); - BaseObject oldObj; + HeapAddress oldAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* oldObj = reinterpret_cast(oldAddr); constexpr size_t oldSize = 100; - oldObj.SetSizeForwarded(oldSize); - EXPECT_EQ(oldObj.GetSizeForwarded(), oldSize); - RefField oldField(&oldObj); + oldObj->SetSizeForwarded(oldSize); + EXPECT_EQ(oldObj->GetSizeForwarded(), oldSize); + RefField oldField(oldObj); MAddress oldAddress = oldField.GetFieldValue(); - BaseObject newObj; + HeapAddress newAddr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* newObj = reinterpret_cast(newAddr); constexpr size_t newSize = 200; - newObj.SetSizeForwarded(newSize); - EXPECT_EQ(newObj.GetSizeForwarded(), newSize); - RefField newField(&newObj); + newObj->SetSizeForwarded(newSize); + EXPECT_EQ(newObj->GetSizeForwarded(), newSize); + RefField newField(newObj); MAddress neWAddress = newField.GetFieldValue(); EXPECT_NE(oldAddress, neWAddress); - bool result = traceBarrier_->CompareAndSwapRefField( - &oldObj, newField, &oldObj, &newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); + bool result = traceBarrier->CompareAndSwapRefField( + oldObj, newField, oldObj, newObj, std::memory_order_seq_cst, std::memory_order_seq_cst); ASSERT_FALSE(result); } } // namespace common::test \ No newline at end of file diff --git a/common_components/heap/w_collector/w_collector.cpp b/common_components/heap/w_collector/w_collector.cpp index 4f91fbf21a6c7dd95e90db0027edbd9f642ff32a..c0642429624319eb0d527a59bcac6f7a101aa5a1 100755 --- a/common_components/heap/w_collector/w_collector.cpp +++ b/common_components/heap/w_collector/w_collector.cpp @@ -66,18 +66,18 @@ bool WCollector::TryUpdateRefFieldImpl(BaseObject* obj, RefField<>& field, BaseO { RefField<> oldRef(field); fromObj = oldRef.GetTargetObject(); - if (IsFromObject(fromObj)) { - if (copy) { + if (IsFromObject(fromObj)) { //LCOV_EXCL_BR_LINE + if (copy) { //LCOV_EXCL_BR_LINE toObj = const_cast(this)->TryForwardObject(fromObj); - if (toObj != nullptr) { + if (toObj != nullptr) { //LCOV_EXCL_BR_LINE HeapProfilerListener::GetInstance().OnMoveEvent(reinterpret_cast(fromObj), reinterpret_cast(toObj), toObj->GetSize()); } - } else { + } else { //LCOV_EXCL_BR_LINE toObj = FindToVersion(fromObj); } - if (toObj == nullptr) { + if (toObj == nullptr) { //LCOV_EXCL_BR_LINE return false; } RefField<> tmpField(toObj, oldRef.IsWeak()); @@ -86,17 +86,17 @@ bool WCollector::TryUpdateRefFieldImpl(BaseObject* obj, RefField<>& field, BaseO DLOG(TRACE, "update obj %p<%p>(%zu)+%zu ref-field@%p: %#zx -> %#zx", obj, obj->GetTypeInfo(), obj->GetSize(), BaseObject::FieldOffset(obj, &field), &field, oldRef.GetFieldValue(), tmpField.GetFieldValue()); - } else { + } else { //LCOV_EXCL_BR_LINE DLOG(TRACE, "update ref@%p: 0x%zx -> %p", &field, oldRef.GetFieldValue(), toObj); } return true; - } else { - if (obj != nullptr) { + } else { //LCOV_EXCL_BR_LINE + if (obj != nullptr) { //LCOV_EXCL_BR_LINE DLOG(TRACE, "update obj %p<%p>(%zu)+%zu but cas failed ref-field@%p: %#zx(%#zx) -> %#zx but cas failed ", obj, obj->GetTypeInfo(), obj->GetSize(), BaseObject::FieldOffset(obj, &field), &field, oldRef.GetFieldValue(), field.GetFieldValue(), tmpField.GetFieldValue()); - } else { + } else { //LCOV_EXCL_BR_LINE DLOG(TRACE, "update but cas failed ref@%p: 0x%zx(%zx) -> %p", &field, oldRef.GetFieldValue(), field.GetFieldValue(), toObj); } @@ -122,22 +122,22 @@ bool WCollector::TryForwardRefField(BaseObject* obj, RefField<>& field, BaseObje // this api untags current pointer as well as old pointer, caller should take care of this. bool WCollector::TryUntagRefField(BaseObject* obj, RefField<>& field, BaseObject*& target) const { - for (;;) { + for (;;) { //LCOV_EXCL_BR_LINE RefField<> oldRef(field); - if (oldRef.IsTagged()) { + if (oldRef.IsTagged()) { //LCOV_EXCL_BR_LINE target = oldRef.GetTargetObject(); RefField<> newRef(target); - if (field.CompareExchange(oldRef.GetFieldValue(), newRef.GetFieldValue())) { + if (field.CompareExchange(oldRef.GetFieldValue(), newRef.GetFieldValue())) { //LCOV_EXCL_BR_LINE if (obj != nullptr) { DLOG(FIX, "untag obj %p<%p>(%zu) ref-field@%p: %#zx -> %#zx", obj, obj->GetTypeInfo(), obj->GetSize(), &field, oldRef.GetFieldValue(), newRef.GetFieldValue()); - } else { + } else { //LCOV_EXCL_BR_LINE DLOG(FIX, "untag ref@%p: %#zx -> %#zx", &field, oldRef.GetFieldValue(), newRef.GetFieldValue()); } return true; } - } else { + } else { //LCOV_EXCL_BR_LINE return false; } } diff --git a/common_components/log/tests/BUILD.gn b/common_components/log/tests/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..2ecfd0aa452a942d8f401afe2c0d618c12fc88f6 --- /dev/null +++ b/common_components/log/tests/BUILD.gn @@ -0,0 +1,57 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//arkcompiler/ets_runtime/common_components/tests/test_helper.gni") + +module_output_path = "ets_runtime" + +host_unittest_action("Log_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "log_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + +group("unittest") { + testonly = true + + # deps file + deps = [ + ":Log_Test", + ] +} + +group("host_unittest") { + testonly = true + + # deps file + deps = [ + ":Log_TestAction", + ] +} \ No newline at end of file diff --git a/common_components/log/tests/log_test.cpp b/common_components/log/tests/log_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e41af1f5b83c3bd9835e8f400704bbf209fcdc0d --- /dev/null +++ b/common_components/log/tests/log_test.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_components/log/log.h" +#include "common_components/log/log_base.h" +#include "common_components/tests/test_helper.h" + +using namespace common; + +// ==================== Test Fixture ==================== +namespace common::test { +class LogTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override + { + } + + void TearDown() override + { + } +}; + +// ==================== Test Case ==================== +HWTEST_F_L0(LogTest, ConvertFromRuntime_Info_ReturnsInfo) { + Level result = Log::ConvertFromRuntime(LOG_LEVEL::INFO); + EXPECT_EQ(result, Level::INFO); +} + + +HWTEST_F_L0(LogTest, ConvertFromRuntime_Debug_ReturnsDebug) { + Level result = Log::ConvertFromRuntime(LOG_LEVEL::DEBUG); + EXPECT_EQ(result, Level::DEBUG); +} + + +HWTEST_F_L0(LogTest, ConvertFromRuntime_Fatal_ReturnsFatal) { + Level result = Log::ConvertFromRuntime(LOG_LEVEL::FATAL); + EXPECT_EQ(result, Level::FATAL); +} + + +HWTEST_F_L0(LogTest, ConvertFromRuntime_Default_ReturnsDebug) { + Level result = Log::ConvertFromRuntime(static_cast(999)); + EXPECT_EQ(result, Level::DEBUG); +} +} + +namespace common { +class TestLogRedirect { +public: + TestLogRedirect() + { + originalCoutBuffer = std::cout.rdbuf(); + originalCerrBuffer = std::cerr.rdbuf(); + + std::cout.rdbuf(buffer.rdbuf()); + std::cerr.rdbuf(buffer.rdbuf()); + } + + ~TestLogRedirect() + { + std::cout.rdbuf(originalCoutBuffer); + std::cerr.rdbuf(originalCerrBuffer); + } + + std::string GetOutput() const + { + return buffer.str(); + } + + void ClearOutput() + { + buffer.str(std::string()); + } + +private: + std::stringstream buffer; + std::streambuf* originalCoutBuffer; + std::streambuf* originalCerrBuffer; +}; +} // namespace common + +namespace common::test { +class TimerTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override + { + redirect.ClearOutput(); + + LogOptions options; + options.level = Level::DEBUG; + options.component = static_cast(Component::ALL); + + Log::Initialize(options); + } + void TearDown() override {} + + TestLogRedirect redirect; +}; + +static constexpr uint32_t SECOND_TIME = 1000000; +HWTEST_F_L0(TimerTest, Timer_BasicUsage_LogsTime) +{ + { + Timer t("TestScope"); + for (volatile int i = 0; i < SECOND_TIME; ++i); + } + + std::string output = redirect.GetOutput(); + EXPECT_NE(output.find("TestScope time:"), std::string::npos); + EXPECT_NE(output.find("us"), std::string::npos); +} + +HWTEST_F_L0(TimerTest, Timer_LevelNotDebug_NoLogging) +{ + LogOptions options; + options.level = Level::INFO; + options.component = static_cast(Component::ALL); + Log::Initialize(options); + + { + Timer t("SilentScope"); + for (volatile int i = 0; i < SECOND_TIME; ++i); + } + + std::string output = redirect.GetOutput(); + EXPECT_EQ(output.find("SilentScope"), std::string::npos); +} + +HWTEST_F_L0(TimerTest, Timer_LongName_CorrectFormat) +{ + { + Timer t("VeryLongTimerNameForTesting"); + for (volatile int i = 0; i < SECOND_TIME; ++i); + } + + std::string output = redirect.GetOutput(); + EXPECT_NE(output.find("VeryLongTimerNameForTesting time:"), std::string::npos); +} + +HWTEST_F_L0(TimerTest, Timer_MultipleInstances_DistinctOutput) +{ + { + Timer t1("First"); + for (volatile int i = 0; i < SECOND_TIME; ++i); + } + + { + Timer t2("Second"); + for (volatile int i = 0; i < SECOND_TIME; ++i); + } + + std::string output = redirect.GetOutput(); + EXPECT_NE(output.find("First time:"), std::string::npos); + EXPECT_NE(output.find("Second time:"), std::string::npos); +} +} \ No newline at end of file diff --git a/common_components/mutator/tests/BUILD.gn b/common_components/mutator/tests/BUILD.gn index 1671269613a6f619950f6ebe0bedfeb7fffb458b..442f3c15abc184ea51473ab9318871c1cf0c895c 100755 --- a/common_components/mutator/tests/BUILD.gn +++ b/common_components/mutator/tests/BUILD.gn @@ -15,29 +15,6 @@ import("//arkcompiler/ets_runtime/common_components/tests/test_helper.gni") module_output_path = "ets_runtime" -host_unittest_action("Mutator_Test") { - module_out_path = module_output_path - - sources = [ - # test file - "mutator_test.cpp", - ] - - configs = [ - "//arkcompiler/ets_runtime/common_components:common_components_test_config", - "//arkcompiler/ets_runtime:icu_path_test_config", - ] - - deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] - - # hiviewdfx libraries - external_deps = [ - "icu:shared_icui18n", - "icu:shared_icuuc", - "runtime_core:libarkassembler_static", - ] -} - host_unittest_action("Mutator_Manager_Test") { module_out_path = module_output_path @@ -89,9 +66,7 @@ group("unittest") { # deps file deps = [ - ":Mutator_Test", ":Mutator_Manager_Test", - ":Satb_Buffer_Test", ] } @@ -100,8 +75,6 @@ group("host_unittest") { # deps file deps = [ - ":Mutator_TestAction", ":Mutator_Manager_TestAction", - ":Satb_Buffer_TestAction", ] } diff --git a/common_components/mutator/tests/mutator_manager_test.cpp b/common_components/mutator/tests/mutator_manager_test.cpp index a8a3989cd8df9daa626d6d5cf6c17995c80069e4..d6a6f79fc2f0f753a093559f256b085ff2ab88c4 100755 --- a/common_components/mutator/tests/mutator_manager_test.cpp +++ b/common_components/mutator/tests/mutator_manager_test.cpp @@ -107,4 +107,122 @@ HWTEST_F_L0(MutatorManagerTest, DumpMutators_Test1) managerPtr->DumpMutators(timeoutTimes); delete managerPtr; } + +HWTEST_F_L0(MutatorManagerTest, DestroyRuntimeMutator_Test1) +{ + ThreadType threadType = ThreadType::GC_THREAD; + Mutator* ptr = MutatorManager::Instance().CreateRuntimeMutator(threadType); + EXPECT_NE(ptr, nullptr); + + MutatorManager::Instance().DestroyRuntimeMutator(threadType); + ptr = ThreadLocal::GetMutator(); + EXPECT_EQ(ptr, nullptr); +} + +HWTEST_F_L0(MutatorManagerTest, DestroyMutator_Test1) +{ + ThreadType threadType = ThreadType::GC_THREAD; + Mutator* ptr = MutatorManager::Instance().CreateRuntimeMutator(threadType); + + MutatorManager::Instance().DestroyMutator(ptr); + EXPECT_TRUE(MutatorManager::Instance().TryAcquireMutatorManagementRLock()); + MutatorManager::Instance().MutatorManagementRUnlock(); + + MutatorManager::Instance().MutatorManagementWLock(); + MutatorManager::Instance().DestroyMutator(ptr); + EXPECT_FALSE(MutatorManager::Instance().TryAcquireMutatorManagementRLock()); + MutatorManager::Instance().MutatorManagementWUnlock(); +} + +HWTEST_F_L0(MutatorManagerTest, AcquireMutatorManagementWLockForCpuProfile_Test1) +{ + std::atomic threadStarted{false}; + std::thread testthread([&]() { + threadStarted = true; + MutatorManager::Instance().MutatorManagementWLock(); + MutatorManager::Instance().AcquireMutatorManagementWLockForCpuProfile(); + }); + while (!threadStarted) {} + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + MutatorManager::Instance().MutatorManagementWUnlock(); + testthread.join(); + EXPECT_FALSE(MutatorManager::Instance().TryAcquireMutatorManagementRLock()); + MutatorManager::Instance().MutatorManagementWUnlock(); +} + +HWTEST_F_L0(MutatorManagerTest, EnsureCpuProfileFinish_Test1) +{ + std::list undoneMutators; + ThreadType threadType = ThreadType::GC_THREAD; + Mutator* ptr = MutatorManager::Instance().CreateRuntimeMutator(threadType); + ptr->SetCpuProfileState(MutatorBase::CpuProfileState::FINISH_CPUPROFILE); + undoneMutators.push_back(ptr); + MutatorManager::Instance().EnsureCpuProfileFinish(undoneMutators); + EXPECT_EQ(undoneMutators.size(), 0); +} + +HWTEST_F_L0(MutatorManagerTest, EnsureCpuProfileFinish_Test2) +{ + std::list Mutators; + ThreadType threadType = ThreadType::GC_THREAD; + Mutator* ptr = MutatorManager::Instance().CreateRuntimeMutator(threadType); + ptr->SetCpuProfileState(MutatorBase::CpuProfileState::NO_CPUPROFILE); + ptr->SetInSaferegion(MutatorBase::SaferegionState::SAFE_REGION_TRUE); + Mutators.push_back(ptr); + MutatorManager::Instance().EnsureCpuProfileFinish(Mutators); + EXPECT_EQ(Mutators.size(), 0); +} + +HWTEST_F_L0(MutatorManagerTest, EnsureCpuProfileFinish_Test3) +{ + std::list Mutators; + ThreadType threadType = ThreadType::GC_THREAD; + Mutator* ptr = MutatorManager::Instance().CreateRuntimeMutator(threadType); + std::thread testthread([&]() { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + ptr->SetCpuProfileState(MutatorBase::CpuProfileState::NO_CPUPROFILE); + }); + ptr->SetCpuProfileState(MutatorBase::CpuProfileState::IN_CPUPROFILING); + ptr->SetInSaferegion(MutatorBase::SaferegionState::SAFE_REGION_TRUE); + Mutators.push_back(ptr); + MutatorManager::Instance().EnsureCpuProfileFinish(Mutators); + testthread.join(); + EXPECT_EQ(Mutators.size(), 0); +} + +HWTEST_F_L0(MutatorManagerTest, EnsureCpuProfileFinish_Test4) +{ + std::list Mutators; + ThreadType threadType = ThreadType::GC_THREAD; + Mutator* ptr = MutatorManager::Instance().CreateRuntimeMutator(threadType); + std::thread testthread([&]() { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + ptr->SetInSaferegion(MutatorBase::SaferegionState::SAFE_REGION_TRUE); + ptr->SetCpuProfileState(MutatorBase::CpuProfileState::NO_CPUPROFILE); + }); + ptr->SetCpuProfileState(MutatorBase::CpuProfileState::IN_CPUPROFILING); + ptr->SetInSaferegion(MutatorBase::SaferegionState::SAFE_REGION_FALSE); + Mutators.push_back(ptr); + MutatorManager::Instance().EnsureCpuProfileFinish(Mutators); + testthread.join(); + EXPECT_EQ(Mutators.size(), 0); +} + +HWTEST_F_L0(MutatorManagerTest, EnsureCpuProfileFinish_Test5) +{ + std::list Mutators; + ThreadType threadType = ThreadType::GC_THREAD; + Mutator* ptr = MutatorManager::Instance().CreateRuntimeMutator(threadType); + std::thread testthread([&]() { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + ptr->SetInSaferegion(MutatorBase::SaferegionState::SAFE_REGION_TRUE); + + }); + ptr->SetCpuProfileState(MutatorBase::CpuProfileState::NO_CPUPROFILE); + ptr->SetInSaferegion(MutatorBase::SaferegionState::SAFE_REGION_FALSE); + Mutators.push_back(ptr); + MutatorManager::Instance().EnsureCpuProfileFinish(Mutators); + testthread.join(); + EXPECT_EQ(Mutators.size(), 0); +} } // namespace common::test diff --git a/common_components/mutator/tests/mutator_test.cpp b/common_components/mutator/tests/mutator_test.cpp deleted file mode 100755 index 82495e2540f102f36305fc8c6bf6eca9b09d5a34..0000000000000000000000000000000000000000 --- a/common_components/mutator/tests/mutator_test.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common_components/tests/test_helper.h" -#include "common_components/mutator/mutator.h" -#include "common_components/base_runtime/base_runtime.cpp" - -using namespace common; - -namespace common::test { -class MutatorTest : public BaseTestWithScope { -protected: - void SetUp() override {} - void TearDown() override {} - static void SetUpTestCase() - { - BaseRuntime::GetInstance()->Init(); - } - static void TearDownTestCase() - { - BaseRuntime::GetInstance()->Fini(); - } -}; - -HWTEST_F_L0(MutatorTest, GetThreadLocalData_Test1) -{ - ThreadLocalData *ret = GetThreadLocalData(); - ASSERT_TRUE(ret != nullptr); -} - -HWTEST_F_L0(MutatorTest, TransitionGCPhase_Test1) -{ - MutatorBase *mutatorBase = new MutatorBase(); - mutatorBase->Init(); - bool ret = mutatorBase->TransitionGCPhase(false); - EXPECT_TRUE(ret == true); - - MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_GC_PHASE; - mutatorBase->SetSuspensionFlag(flag); - - ret = mutatorBase->TransitionGCPhase(false); - EXPECT_TRUE(ret == true); - - ret = mutatorBase->TransitionGCPhase(true); - EXPECT_TRUE(ret == true); - ret = mutatorBase->TransitionGCPhase(false); - EXPECT_TRUE(ret == true); - delete mutatorBase; -} - -HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test0) -{ - MutatorBase *mutatorBase = new MutatorBase(); - mutatorBase->Init(); - - MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_STW; - mutatorBase->SetSuspensionFlag(flag); - - mutatorBase->HandleSuspensionRequest(); - EXPECT_TRUE(mutatorBase->InSaferegion() == false); - - flag = MutatorBase::SuspensionType::SUSPENSION_FOR_GC_PHASE; - mutatorBase->SetSuspensionFlag(flag); - mutatorBase->HandleSuspensionRequest(); - EXPECT_TRUE(mutatorBase->InSaferegion() == false); - delete mutatorBase; -} - -HWTEST_F_L0(MutatorTest, SuspendForStw_Test0) -{ - MutatorBase *mutatorBase = new MutatorBase(); - mutatorBase->Init(); - - mutatorBase->SuspendForStw(); - EXPECT_TRUE(mutatorBase->InSaferegion() == false); - delete mutatorBase; -} -} // namespace common::test diff --git a/common_components/mutator/tests/satb_buffer_test.cpp b/common_components/mutator/tests/satb_buffer_test.cpp index 91398370875b5d7c6f31ff85547ee71821bbded2..b20f8704b3d9c5dd7e7cf49f36bc938004fdc1a3 100755 --- a/common_components/mutator/tests/satb_buffer_test.cpp +++ b/common_components/mutator/tests/satb_buffer_test.cpp @@ -13,22 +13,126 @@ * limitations under the License. */ -#include "common_components/tests/test_helper.h" +#include "common_components/base_runtime/base_runtime_param.h" +#include "common_components/heap/allocator/region_desc.h" +#include "common_components/heap/allocator/region_space.h" #include "common_components/mutator/satb_buffer.h" +#include "common_components/tests/test_helper.h" +#include using namespace common; - namespace common::test { + class SatbBufferTest : public BaseTestWithScope { protected: - void SetUp() override {} - void TearDown() override {} + void* regionMemory_; + size_t totalUnits_ = 1024; + size_t heapSize_; + Mutator* mutator_ = nullptr; + + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() + { + BaseRuntime::GetInstance()->Fini(); + } + + void SetUp() override + { + heapSize_ = totalUnits_ * RegionDesc::UNIT_SIZE; + size_t allocSize = heapSize_ + totalUnits_ * sizeof(RegionDesc); + regionMemory_ = malloc(allocSize); + ASSERT_NE(regionMemory_, nullptr); + uintptr_t unitInfoStart = reinterpret_cast(regionMemory_); + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + RegionManager& manager = theAllocator.GetRegionManager(); + manager.Initialize(totalUnits_, reinterpret_cast(regionMemory_)); + size_t metadataSize = totalUnits_ * sizeof(RegionDesc); + uintptr_t heapStartAddress = unitInfoStart + metadataSize; + RegionDesc::Initialize(totalUnits_, unitInfoStart, heapStartAddress); + mutator_ = Mutator::NewMutator(); + ASSERT_NE(mutator_, nullptr); + mutator_->InitTid(); + ThreadLocal::GetThreadLocalData()->mutator = mutator_; + } + + void TearDown() override + { + if (mutator_) { + delete mutator_; + mutator_ = nullptr; + } + if (regionMemory_) { + free(regionMemory_); + regionMemory_ = nullptr; + } + } }; -TEST_F(SatbBufferTest, ShouldEnqueue_Test1) +HWTEST_F_L0(SatbBufferTest, NullptrReturnsFalse)\ +{ + EXPECT_FALSE(SatbBuffer::Instance().ShouldEnqueue(nullptr)); +} + +HWTEST_F_L0(SatbBufferTest, IsYoungSpaceObject1) +{ + ASSERT_NE(mutator_, nullptr); + mutator_->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocRegion(); + ASSERT_NE(addr, 0); + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); + region->SetRegionType(RegionDesc::RegionType::FREE_REGION); + Heap::GetHeap().SetGCReason(GC_REASON_YOUNG); + + BaseObject* obj = reinterpret_cast(addr); + EXPECT_FALSE(SatbBuffer::Instance().ShouldEnqueue(obj)); +} + +HWTEST_F_L0(SatbBufferTest, IsYoungSpaceObject2) +{ + ASSERT_NE(mutator_, nullptr); + mutator_->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocRegion(); + ASSERT_NE(addr, 0); + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); + region->SetRegionType(RegionDesc::RegionType::FROM_REGION); + Heap::GetHeap().SetGCReason(GC_REASON_HEU); + + BaseObject* obj = reinterpret_cast(addr); + EXPECT_FALSE(SatbBuffer::Instance().ShouldEnqueue(obj)); +} + +HWTEST_F_L0(SatbBufferTest, IsYoungSpaceObject3) +{ + ASSERT_NE(mutator_, nullptr); + mutator_->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocRegion(); + ASSERT_NE(addr, 0); + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); + region->SetRegionType(RegionDesc::RegionType::FROM_REGION); + Heap::GetHeap().SetGCReason(GC_REASON_YOUNG); + + BaseObject* obj = reinterpret_cast(addr); + EXPECT_FALSE(SatbBuffer::Instance().ShouldEnqueue(obj)); +} + +HWTEST_F_L0(SatbBufferTest, IsYoungSpaceObject4) { - BaseObject* obj = nullptr; - bool ret = SatbBuffer::Instance().ShouldEnqueue(obj); - EXPECT_TRUE(ret == false); + ASSERT_NE(mutator_, nullptr); + mutator_->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocRegion(); + ASSERT_NE(addr, 0); + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); + region->SetRegionType(RegionDesc::RegionType::FREE_REGION); + Heap::GetHeap().SetGCReason(GC_REASON_HEU); + BaseObject* obj = reinterpret_cast(addr); + EXPECT_FALSE(SatbBuffer::Instance().ShouldEnqueue(obj)); } } // namespace common::test diff --git a/common_components/tests/ohos_test.xml b/common_components/tests/ohos_test.xml index e43733dde5c320156a88028aeb38b035ccaa0933..a9332b249edfadefb88244a85a60ce144a938823 100644 --- a/common_components/tests/ohos_test.xml +++ b/common_components/tests/ohos_test.xml @@ -18,11 +18,26 @@