From 429076c7b48970e1c32b9639c622a061d6c38691 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Mon, 30 Jun 2025 11:31:20 +0800 Subject: [PATCH] add common_components tdd Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICHW1B Change-Id: I2e8806ca88628ddc216ded931d6a7fe75233ca41 Signed-off-by: yp9522 Signed-off-by: lhc --- BUILD.gn | 9 +- common_components/BUILD.gn | 2 + .../allocator/tests/region_manager_test.cpp | 136 +++++- .../allocator/tests/region_space_test.cpp | 4 + .../heap/barrier/tests/barrier_test.cpp | 102 ++++- .../tests/collector_resources_test.cpp | 39 ++ .../heap/collector/tests/task_queue_test.cpp | 241 +++------- .../heap/w_collector/copy_barrier.cpp | 10 +- .../heap/w_collector/tests/BUILD.gn | 174 +++++++- .../w_collector/tests/copy_barrier_test.cpp | 310 ++++++++++--- .../w_collector/tests/enum_barrier_test.cpp | 396 +++++++++++------ .../w_collector/tests/idle_barrier_test.cpp | 228 +++++----- .../tests/mock_barrier_collector.h | 102 +++++ .../tests/post_trace_barrier_test.cpp | 343 ++++++++------- .../tests/preforward_barrier_test.cpp | 331 +++++++++++++- .../w_collector/tests/remark_barrier_test.cpp | 415 ++++++++++++++++++ .../w_collector/tests/trace_barrier_test.cpp | 330 ++++++++------ .../heap/w_collector/w_collector.cpp | 32 +- common_components/log/tests/BUILD.gn | 57 +++ common_components/log/tests/log_test.cpp | 169 +++++++ .../mutator/tests/mutator_manager_test.cpp | 118 +++++ .../mutator/tests/mutator_test.cpp | 138 ++++++ .../mutator/tests/satb_buffer_test.cpp | 120 ++++- common_components/tests/ohos_test.xml | 20 + .../thread/tests/thread_holder_test.cpp | 17 +- 25 files changed, 2997 insertions(+), 846 deletions(-) create mode 100755 common_components/heap/w_collector/tests/mock_barrier_collector.h create mode 100755 common_components/heap/w_collector/tests/remark_barrier_test.cpp create mode 100644 common_components/log/tests/BUILD.gn create mode 100644 common_components/log/tests/log_test.cpp diff --git a/BUILD.gn b/BUILD.gn index c54269b7cb..3759548109 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -164,8 +164,9 @@ group("common_components_js_unittest") { "common_components/mutator/tests:unittest", "common_components/heap/collector/tests:unittest", "common_components/objects/tests:unittest", - "common_components/heap/barrier/tests:unittest", "common_components/thread/tests:unittest", + "common_components/heap/barrier/tests:unittest", + "common_components/log/tests:unittest", ] } } @@ -183,9 +184,9 @@ group("common_components_unittest") { "common_components/mutator/tests:host_unittest", "common_components/heap/collector/tests:host_unittest", "common_components/objects/tests:host_unittest", - "common_components/heap/barrier/tests:host_unittest", "common_components/thread/tests:host_unittest", - "common_components/heap/collector/tests:host_unittest", + "common_components/heap/barrier/tests:host_unittest", + "common_components/log/tests:host_unittest", ] } } @@ -244,7 +245,7 @@ group("ark_unittest") { "common_components/heap/barrier/tests:unittest", "common_components/thread/tests:host_unittest", "common_components/heap/collector/tests:host_unittest", - "common_components/heap/collector/tests:host_unittest", + "common_components/log/tests:host_unittest", ] } } diff --git a/common_components/BUILD.gn b/common_components/BUILD.gn index 23ca5bac12..2c85c26f9b 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", ] } diff --git a/common_components/heap/allocator/tests/region_manager_test.cpp b/common_components/heap/allocator/tests/region_manager_test.cpp index 65314efbd7..9ca82adc09 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; @@ -325,4 +324,139 @@ 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, VisitRememberSet) +{ + bool callbackCalled = false; + std::function func = [&callbackCalled](BaseObject* obj) { + callbackCalled = true; + }; + size_t unitIdx = 0; + size_t nUnit = 1; + RegionDesc* region = RegionDesc::InitRegion(unitIdx, nUnit, RegionDesc::UnitRole::SMALL_SIZED_UNITS); + region->AddLiveByteCount(0); + region->VisitRememberSet(func); + region->SetUnitRole(RegionDesc::UnitRole::LARGE_SIZED_UNITS); + region->VisitRememberSet(func); + EXPECT_FALSE(callbackCalled); + + RegionRSet* rSet = region->GetRSet(); + bool result = rSet->MarkCardTable(0); + region->VisitRememberSet(func); + EXPECT_FALSE(result); + EXPECT_TRUE(callbackCalled); +} + +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 9da2659698..1d62c2afc5 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 d78a62b39b..46d7a33bb9 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/collector_resources_test.cpp b/common_components/heap/collector/tests/collector_resources_test.cpp index c05a505ae9..e5c41750fc 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/task_queue_test.cpp b/common_components/heap/collector/tests/task_queue_test.cpp index 9d2bd3a063..e90a061577 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 b09ac3ad8d..1a5d3eef90 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 300f6daa0b..c4bd6cd11e 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 440c86c100..df5e3a24de 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 e771b6bcac..045895b218 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 989a8583aa..a799ead119 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 0000000000..3688b6dbd5 --- /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 d51db25d40..7b7eb4221a 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 fef53006cc..5fc7972ce2 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 0000000000..22c13b4f95 --- /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 1e046cbcdc..4ae48b6539 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 cdd38c4ef8..d9b5e9ffb9 100755 --- a/common_components/heap/w_collector/w_collector.cpp +++ b/common_components/heap/w_collector/w_collector.cpp @@ -62,37 +62,37 @@ 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); - if (field.CompareExchange(oldRef.GetFieldValue(), tmpField.GetFieldValue())) { - if (obj != nullptr) { + if (field.CompareExchange(oldRef.GetFieldValue(), tmpField.GetFieldValue())) { //LCOV_EXCL_BR_LINE + if (obj != nullptr) { //LCOV_EXCL_BR_LINE 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); } @@ -118,22 +118,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 0000000000..2ecfd0aa45 --- /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 0000000000..e41af1f5b8 --- /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/mutator_manager_test.cpp b/common_components/mutator/tests/mutator_manager_test.cpp index a8a3989cd8..d6a6f79fc2 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 index 82495e2540..ea7274d929 100755 --- a/common_components/mutator/tests/mutator_test.cpp +++ b/common_components/mutator/tests/mutator_test.cpp @@ -15,11 +15,17 @@ #include "common_components/tests/test_helper.h" #include "common_components/mutator/mutator.h" +#include "common_components/mutator/mutator.cpp" #include "common_components/base_runtime/base_runtime.cpp" +#include "common_interfaces/objects/base_object.h" using namespace common; namespace common::test { +class TestMutator : public Mutator { +public: + using Mutator::VisitRawObjects; +}; class MutatorTest : public BaseTestWithScope { protected: void SetUp() override {} @@ -87,4 +93,136 @@ HWTEST_F_L0(MutatorTest, SuspendForStw_Test0) EXPECT_TRUE(mutatorBase->InSaferegion() == false); delete mutatorBase; } + +HWTEST_F_L0(MutatorTest, VisitRawObjects_Nullptr_NoCall) +{ + TestMutator* mutator = new TestMutator(); + mutator->Init(); + mutator->PushRawObject(nullptr); + + bool called = false; + RootVisitor func = [&called](const ObjectRef& obj) { + called = true; + }; + mutator->VisitRawObjects(func); + EXPECT_FALSE(called); + delete mutator; +} + +HWTEST_F_L0(MutatorTest, VisitRawObjects_NonNull_Call) +{ + TestMutator* mutator = new TestMutator(); + mutator->Init(); + BaseObject* mockObj = reinterpret_cast(malloc(sizeof(BaseObject))); + mutator->PushRawObject(mockObj); + + bool called = false; + RootVisitor func = [&called, mockObj](const ObjectRef& obj) { + called = true; + EXPECT_EQ(obj.object, mockObj); + }; + + mutator->VisitRawObjects(func); + EXPECT_TRUE(called); + delete mutator; + delete mockObj; +} + +HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test1) +{ + MutatorBase *mutatorBase = new MutatorBase(); + mutatorBase->Init(); + MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_STW; + mutatorBase->SetSuspensionFlag(flag); + flag = MutatorBase::SuspensionType::SUSPENSION_FOR_GC_PHASE; + mutatorBase->SetSuspensionFlag(flag); + mutatorBase->HandleSuspensionRequest(); + EXPECT_FALSE(mutatorBase->InSaferegion()); + EXPECT_TRUE(mutatorBase->FinishedTransition()); + delete mutatorBase; +} + +HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test2) +{ + MutatorBase *mutatorBase = new MutatorBase(); + mutatorBase->Init(); + MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_CPU_PROFILE; + mutatorBase->SetSuspensionFlag(flag); + mutatorBase->SetCpuProfileState(MutatorBase::CpuProfileState::FINISH_CPUPROFILE); + std::thread t([&]() { + std::this_thread::sleep_for(std::chrono::nanoseconds(1)); + mutatorBase->ClearSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE); + }); + mutatorBase->HandleSuspensionRequest(); + t.join(); + EXPECT_FALSE(mutatorBase->InSaferegion()); + EXPECT_TRUE(mutatorBase->FinishedCpuProfile()); + delete mutatorBase; +} + +HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test3) +{ + MutatorBase *mutatorBase = new MutatorBase(); + mutatorBase->Init(); + mutatorBase->SetSuspensionFlag(MutatorBase::SUSPENSION_FOR_STW); + mutatorBase->SetSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE); + mutatorBase->SetCpuProfileState(MutatorBase::CpuProfileState::FINISH_CPUPROFILE); + std::thread t([&]() { + std::this_thread::sleep_for(std::chrono::nanoseconds(1)); + mutatorBase->ClearSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE); + }); + mutatorBase->HandleSuspensionRequest(); + t.join(); + EXPECT_FALSE(mutatorBase->InSaferegion()); + EXPECT_TRUE(mutatorBase->FinishedCpuProfile()); + delete mutatorBase; +} + +HWTEST_F_L0(MutatorTest, HandleGCPhase_SatbNodeNotNull) +{ + Mutator* mutator = MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); + HeapAddress addr = common::HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject *mockObj = reinterpret_cast(addr); + new (mockObj) BaseObject(); + mutator->RememberObjectInSatbBuffer(mockObj); + EXPECT_NE(mutator->GetSatbBufferNode(), nullptr); + MutatorBase* base = static_cast(mutator->GetMutatorBasePtr()); + base->HandleGCPhase(GCPhase::GC_PHASE_REMARK_SATB); + EXPECT_EQ(mutator->GetSatbBufferNode(), nullptr); + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); +} + +HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_LeaveSaferegion1) +{ + MutatorBase* mutatorBase = new MutatorBase(); + mutatorBase->Init(); + mutatorBase->IncObserver(); + std::thread t([&]() { + std::this_thread::sleep_for(std::chrono::nanoseconds(1)); + mutatorBase->DecObserver(); + }); + mutatorBase->HandleSuspensionRequest(); + t.join(); + EXPECT_FALSE(mutatorBase->InSaferegion()); + delete mutatorBase; +} + +HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_LeaveSaferegion2) +{ + MutatorBase* mutatorBase = new MutatorBase(); + mutatorBase->Init(); + MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_CPU_PROFILE; + mutatorBase->SetSuspensionFlag(flag); + mutatorBase->SetCpuProfileState(MutatorBase::CpuProfileState::FINISH_CPUPROFILE); + mutatorBase->IncObserver(); + std::thread t([&]() { + std::this_thread::sleep_for(std::chrono::nanoseconds(1)); + mutatorBase->ClearSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE); + mutatorBase->DecObserver(); + }); + mutatorBase->HandleSuspensionRequest(); + t.join(); + EXPECT_FALSE(mutatorBase->InSaferegion()); + 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 9139837087..b20f8704b3 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 e43733dde5..a9332b249e 100644 --- a/common_components/tests/ohos_test.xml +++ b/common_components/tests/ohos_test.xml @@ -18,11 +18,26 @@