From 85dc235f9602eb0d68a7a0bb8eae21c2d576968b Mon Sep 17 00:00:00 2001 From: yp9522 Date: Tue, 15 Jul 2025 18:34:53 +0800 Subject: [PATCH] add common_components tdd Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICMIV2 Change-Id: I6d9f4bafa747b953c38fb4129a1242e60557295d Signed-off-by: yp9522 --- BUILD.gn | 12 +- common_components/base/tests/BUILD.gn | 27 +- .../base/tests/utf_helper_test.cpp | 329 ++++++++++++++++++ .../heap/allocator/tests/allocator_test.cpp | 1 + .../allocator/tests/heap_allocator_test.cpp | 16 +- .../allocator/tests/region_manager_test.cpp | 129 +++++-- .../allocator/tests/region_space_test.cpp | 265 ++++++++------ .../heap/barrier/tests/barrier_test.cpp | 16 + common_components/taskpool/tests/BUILD.gn | 82 +++++ .../taskpool/tests/task_queue_test.cpp | 115 ++++++ .../taskpool/tests/taskpool_test.cpp | 127 +++++++ common_components/tests/ohos_test.xml | 95 +++++ 12 files changed, 1057 insertions(+), 157 deletions(-) create mode 100644 common_components/base/tests/utf_helper_test.cpp create mode 100644 common_components/taskpool/tests/BUILD.gn create mode 100644 common_components/taskpool/tests/task_queue_test.cpp create mode 100644 common_components/taskpool/tests/taskpool_test.cpp diff --git a/BUILD.gn b/BUILD.gn index 7a00f3610d..e2cece635f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -159,16 +159,16 @@ group("common_components_js_unittest") { deps += [ "common_components/base/tests:unittest", "common_components/base_runtime/tests:unittest", - - #"common_components/heap/allocator/tests:unittest", + "common_components/common/tests:unittest", + "common_components/heap/allocator/tests:unittest", "common_components/heap/barrier/tests:unittest", - #"common_components/heap/collector/tests:unittest", "common_components/heap/w_collector/tests:unittest", "common_components/mutator/tests:unittest", "common_components/objects/tests:unittest", "common_components/thread/tests:unittest", "common_components/log/tests:unittest", + "common_components/taskpool/tests:unittest", ] } } @@ -181,16 +181,16 @@ group("common_components_unittest") { deps += [ "common_components/base/tests:host_unittest", "common_components/base_runtime/tests:host_unittest", - - #"common_components/heap/allocator/tests:host_unittest", + "common_components/common/tests:host_unittest", + "common_components/heap/allocator/tests:host_unittest", "common_components/heap/barrier/tests:host_unittest", - #"common_components/heap/collector/tests:host_unittest", "common_components/heap/w_collector/tests:host_unittest", "common_components/mutator/tests:host_unittest", "common_components/objects/tests:host_unittest", "common_components/thread/tests:host_unittest", "common_components/log/tests:host_unittest", + "common_components/taskpool/tests:host_unittest", ] } } diff --git a/common_components/base/tests/BUILD.gn b/common_components/base/tests/BUILD.gn index 39e86f58d2..f3fbbe230d 100755 --- a/common_components/base/tests/BUILD.gn +++ b/common_components/base/tests/BUILD.gn @@ -34,7 +34,30 @@ host_unittest_action("C_String_Test") { external_deps = [ "icu:shared_icui18n", "icu:shared_icuuc", - "runtime_core:libarkassembler_static", + "zlib:libz", + ] +} + +host_unittest_action("Utf_Helper_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "utf_helper_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", ] } @@ -44,6 +67,7 @@ group("unittest") { # deps file deps = [ ":C_String_Test", + ":Utf_Helper_Test", ] } @@ -53,5 +77,6 @@ group("host_unittest") { # deps file deps = [ ":C_String_TestAction", + ":Utf_Helper_TestAction", ] } \ No newline at end of file diff --git a/common_components/base/tests/utf_helper_test.cpp b/common_components/base/tests/utf_helper_test.cpp new file mode 100644 index 0000000000..a6bd777ea9 --- /dev/null +++ b/common_components/base/tests/utf_helper_test.cpp @@ -0,0 +1,329 @@ +/* + * 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/base/utf_helper.h" +#include "common_components/tests/test_helper.h" + +using namespace common; +namespace common::test { +class UtfHelperTest : public common::test::BaseTestWithScope { +}; + +HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test1) +{ + uint16_t utf16[] = {0xD7FF}; + size_t index = 0; + size_t len = 1; + uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false); + EXPECT_EQ(result, 0xD7FF); + + uint16_t utf16In[] = {0xDC00}; + result = utf_helper::DecodeUTF16(utf16In, len, &index, false); + EXPECT_EQ(result, 0xDC00); + + uint16_t utf16In1[] = {0xD800}; + result = utf_helper::DecodeUTF16(utf16In1, len, &index, false); + EXPECT_EQ(result, 0xD800); + + uint16_t utf16In2[] = {0xD7FF}; + len = 2; + result = utf_helper::DecodeUTF16(utf16In2, len, &index, false); + EXPECT_EQ(result, 0xD7FF); + + len = 1; + result = utf_helper::DecodeUTF16(utf16In2, len, &index, false); + EXPECT_EQ(result, 0xD7FF); + + result = utf_helper::DecodeUTF16(utf16In, len, &index, false); + EXPECT_EQ(result, 0xDC00); +} + +HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test2) +{ + size_t index = 0; + uint16_t utf16[] = {0xD800, 0xDC00}; + size_t len = 2; + utf16[1] = 0xFFFF; + uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false); + EXPECT_EQ(result, 0xD800); +} + +HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test3) +{ + size_t index = 0; + uint16_t utf16[] = {0xD800, 0xDC00}; + size_t len = 2; + uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, true); + EXPECT_EQ(result, 0xD800); + + uint16_t utf16In[] = {0xD800, 0x0041}; + result = utf_helper::DecodeUTF16(utf16In, len, &index, false); + EXPECT_EQ(result, 0xD800); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test1) +{ + uint16_t input[] = {0xDC00}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test2) +{ + uint16_t input[] = {0xD800}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); + + uint16_t input1[] = {0xD800, 0xD800}; + size_t len1 = sizeof(input1) / sizeof(input1[0]); + result = utf_helper::HandleAndDecodeInvalidUTF16(input1, len1, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); + + uint16_t input2[] = {'A'}; + size_t len2 = sizeof(input2) / sizeof(input2[0]); + result = utf_helper::HandleAndDecodeInvalidUTF16(input2, len2, &index); + EXPECT_EQ(result, 'A'); + + uint16_t input3[] = {0xD800 ^ 0x01}; + size_t len3 = sizeof(input3) / sizeof(input3[0]); + result = utf_helper::HandleAndDecodeInvalidUTF16(input3, len3, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test3) +{ + uint16_t input[] = {0xDBFF, 0xDFFF}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t expected = ((0xDBFF - utf_helper::DECODE_LEAD_LOW) << utf_helper::UTF16_OFFSET) + + (0xDFFF - utf_helper::DECODE_TRAIL_LOW) + utf_helper::DECODE_SECOND_FACTOR; + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, expected); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test4) +{ + uint16_t input[] = {0xD800, 0xDC00}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t expected = ((0xD800 - utf_helper::DECODE_LEAD_LOW) << utf_helper::UTF16_OFFSET) + + (0xDC00 - utf_helper::DECODE_TRAIL_LOW) + utf_helper::DECODE_SECOND_FACTOR; + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, expected); + EXPECT_EQ(index, 1); +} + +HWTEST_F_L0(UtfHelperTest, IsValidUTF8Test1) +{ + std::vector data = {0xED, 0xA0, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data)); + + std::vector data1 = {0xED, 0x90, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data1)); + + std::vector data2 = {0xED, 0xC0, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data2)); + + std::vector data3 = {0xED, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data3)); + + std::vector data4 = {0xE0, 0xA0, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data4)); +} + +HWTEST_F_L0(UtfHelperTest, IsValidUTF8Test2) +{ + std::vector data = {0xF4, 0x90, 0x80, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data)); + + std::vector data1 = {0xF5, 0x80, 0x80, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data1)); + + std::vector data2 = {0xF0, 0x90, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data2)); + + std::vector data3 = {0xF1, 0x80, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data3)); + + std::vector data4 = {0xF4, 0x80, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data4)); +} + +HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf16ToUtf8Test3) +{ + uint8_t utf8Out[10]; + size_t result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, utf8Out, 5, 10, 0, false, false, false); + EXPECT_EQ(result, 0); + + uint16_t utf16In[] = {0x0041}; + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, sizeof(utf16In), 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, sizeof(utf8Out), 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, sizeof(utf8Out), 0, false, false, false); + EXPECT_EQ(result, 1); +} + +HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf16ToLatin1Test) +{ + uint8_t utf8Out[10]; + size_t result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, utf8Out, 5, 10); + EXPECT_EQ(result, 0); + + uint16_t utf16In[] = {0x0041}; + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, nullptr, 1, sizeof(utf16In)); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, utf8Out, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, utf8Out, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, nullptr, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, nullptr, 1, sizeof(utf8Out)); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, nullptr, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, utf8Out, 1, sizeof(utf8Out)); + EXPECT_EQ(result, 1); + + const uint16_t input[] = {0x0041, 0x0042, 0x0043}; + uint8_t output[2] = {0}; + result = utf_helper::ConvertRegionUtf16ToLatin1(input, output, 3, 2); + EXPECT_EQ(result, 2); +} + +HWTEST_F_L0(UtfHelperTest, DebuggerConvertRegionUtf16ToUtf8Test) +{ + uint8_t utf8Out[10]; + size_t result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 5, sizeof(utf8Out), 0, false, false); + EXPECT_EQ(result, 0); + + uint16_t utf16In[] = {0x0041}; + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, sizeof(utf16In), 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, sizeof(utf8Out), 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, sizeof(utf8Out), 0, false, false); + EXPECT_EQ(result, 1); + + uint16_t utf16In1[] = {0x0041, 0x0042, 0x0043}; + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In1, nullptr, 3, 0, 0, false, false); + EXPECT_EQ(result, 0); +} + +HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test4) +{ + uint16_t utf16[] = {0xD800, 0xDC00}; + size_t index = 0; + size_t len = sizeof(utf16) / sizeof(utf16[0]); + + uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false); + EXPECT_EQ(result, 0x10000); + EXPECT_EQ(index, 1); +} + +HWTEST_F_L0(UtfHelperTest, Utf8ToUtf16Size_LastByteIsTwoByteStart_TrimLastByte) +{ + const uint8_t utf8[] = {0xC0}; + size_t utf8Len = sizeof(utf8); + + size_t result = utf_helper::Utf8ToUtf16Size(utf8, utf8Len); + EXPECT_EQ(result, 1); +} + +HWTEST_F_L0(UtfHelperTest, Utf8ToUtf16Size_LastTwoBytesStartWithThreeByteHeader_TrimTwoBytes) +{ + const uint8_t utf8[] = {0xE2, 0x82}; + size_t utf8Len = sizeof(utf8); + + size_t result = utf_helper::Utf8ToUtf16Size(utf8, utf8Len); + EXPECT_EQ(result, 2); +} + +HWTEST_F_L0(UtfHelperTest, Utf8ToUtf16Size_IncompleteSequenceAtEnd_ReturnsSizeWithoutInvalid) +{ + const uint8_t utf8[] = {0xF0, 0x90, 0x8D}; + size_t result = utf_helper::Utf8ToUtf16Size(utf8, 3); + EXPECT_EQ(result, 3); +} + +HWTEST_F_L0(UtfHelperTest, DebuggerConvertRegionUtf16ToUtf8_ZeroCodepoint_WriteNulChar) +{ + uint16_t utf16In[] = {0x0000}; + uint8_t utf8Out[10] = {0}; + size_t utf16Len = 1; + size_t utf8Len = sizeof(utf8Out); + size_t start = 0; + bool modify = false; + bool isWriteBuffer = true; + + size_t result = utf_helper::DebuggerConvertRegionUtf16ToUtf8( + utf16In, utf8Out, utf16Len, utf8Len, start, modify, isWriteBuffer); + + EXPECT_EQ(result, 1); + EXPECT_EQ(utf8Out[0], 0x00U); +} + +HWTEST_F_L0(UtfHelperTest, ConvertUtf16ToUtf8_NulChar_WriteBufferMode_ReturnsZeroByte) +{ + uint16_t d0 = 0x0000; + uint16_t d1 = 0; + bool modify = false; + bool isWriteBuffer = true; + + utf_helper::Utf8Char result = utf_helper::ConvertUtf16ToUtf8(d0, d1, modify, isWriteBuffer); + + EXPECT_EQ(result.n, 1); + EXPECT_EQ(result.ch[0], 0x00U); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/heap/allocator/tests/allocator_test.cpp b/common_components/heap/allocator/tests/allocator_test.cpp index 58820668fc..c7d02c39d7 100755 --- a/common_components/heap/allocator/tests/allocator_test.cpp +++ b/common_components/heap/allocator/tests/allocator_test.cpp @@ -44,6 +44,7 @@ public: bool IsHeapObject(HeapAddress) const override { return false; } #endif void FeedHungryBuffers() override {} + size_t GetSurvivedSize() const override { return 0; } }; class AllocatorTest : public common::test::BaseTestWithScope { }; diff --git a/common_components/heap/allocator/tests/heap_allocator_test.cpp b/common_components/heap/allocator/tests/heap_allocator_test.cpp index 7f8c1372b2..be2b6faa6f 100644 --- a/common_components/heap/allocator/tests/heap_allocator_test.cpp +++ b/common_components/heap/allocator/tests/heap_allocator_test.cpp @@ -13,15 +13,11 @@ * limitations under the License. */ -#include - #include "common_interfaces/heap/heap_allocator.h" +#include "common_components/heap/allocator/region_desc.h" #include "common_components/heap/allocator/region_space.h" -#include "common_components/heap/collector/trace_collector.h" -#include "common_components/heap/heap.cpp" -#include "common_components/base_runtime/base_runtime_param.h" -#include "common_components/heap/heap_manager.h" #include "common_components/tests/test_helper.h" +#include "common_interfaces/base_runtime.h" using namespace common; @@ -36,7 +32,11 @@ class HeapAllocatorTest : public BaseTestWithScope { void TearDown() override { - delete scope_; + if (scope_ != nullptr) { + delete scope_; + scope_ = nullptr; + } + BaseRuntime::GetInstance()->Fini(); } @@ -46,7 +46,7 @@ class HeapAllocatorTest : public BaseTestWithScope { HWTEST_F_L0(HeapAllocatorTest, AllocLargeObject) { - uintptr_t addr = common::HeapAllocator::Allocate(Heap::NORMAL_UNIT_SIZE, common::LanguageType::DYNAMIC); + uintptr_t addr = common::HeapAllocator::AllocateInHuge(Heap::NORMAL_UNIT_SIZE, common::LanguageType::DYNAMIC); ASSERT(addr > 0); RegionDesc* region = RegionDesc::GetAliveRegionDescAt(addr); ASSERT(region->IsLargeRegion()); diff --git a/common_components/heap/allocator/tests/region_manager_test.cpp b/common_components/heap/allocator/tests/region_manager_test.cpp index 07b15d7c6d..4658325ffc 100755 --- a/common_components/heap/allocator/tests/region_manager_test.cpp +++ b/common_components/heap/allocator/tests/region_manager_test.cpp @@ -156,9 +156,8 @@ HWTEST_F_L0(RegionManagerTest, VisitAllObjectsBeforeFix1) uintptr_t start = region->GetRegionStart(); region->SetRegionAllocPtr(start + SIZE_SIXTEEN); - region->SetFixLine(); bool callbackCalled = false; - region->VisitAllObjectsBeforeFix([&](BaseObject* obj) { + region->VisitAllObjectsBeforeCopy([&](BaseObject* obj) { callbackCalled = true; EXPECT_EQ(obj, reinterpret_cast(region->GetRegionStart())); }); @@ -175,9 +174,8 @@ HWTEST_F_L0(RegionManagerTest, VisitAllObjectsBeforeFix2) uintptr_t start = region->GetRegionStart(); region->SetRegionAllocPtr(start + SIZE_SIXTEEN); - region->SetFixLine(); bool callbackCalled = false; - region->VisitAllObjectsBeforeFix([&](BaseObject* obj) { + region->VisitAllObjectsBeforeCopy([&](BaseObject* obj) { callbackCalled = true; EXPECT_EQ(obj, reinterpret_cast(region->GetRegionStart())); }); @@ -191,9 +189,9 @@ HWTEST_F_L0(RegionManagerTest, VisitAllObjectsBeforeFix3) RegionDesc* region = RegionDesc::InitRegion(unitIdx, nUnit, RegionDesc::UnitRole::LARGE_SIZED_UNITS); ASSERT_NE(region, nullptr); - region->SetFixLine(); + bool callbackCalled = false; - region->VisitAllObjectsBeforeFix([&](BaseObject* obj) { + region->VisitAllObjectsBeforeCopy([&](BaseObject* obj) { callbackCalled = true; EXPECT_EQ(obj, reinterpret_cast(region->GetRegionStart())); }); @@ -207,9 +205,9 @@ HWTEST_F_L0(RegionManagerTest, VisitAllObjectsBeforeFix4) RegionDesc* region = RegionDesc::InitRegion(unitIdx, nUnit, RegionDesc::UnitRole::SMALL_SIZED_UNITS); ASSERT_NE(region, nullptr); - region->SetFixLine(); + bool callbackCalled = false; - region->VisitAllObjectsBeforeFix([&](BaseObject* obj) { + region->VisitAllObjectsBeforeCopy([&](BaseObject* obj) { callbackCalled = true; EXPECT_EQ(obj, reinterpret_cast(region->GetRegionStart())); }); @@ -301,9 +299,9 @@ HWTEST_F_L0(RegionManagerTest, TakeRegion2) size_t nUnit = 1; manager.Initialize(SIZE_MAX_TEST, reinterpret_cast(regionMemory_)); RegionDesc* garbageRegion = RegionDesc::InitRegion(SIZE_HALF_MAX_TEST, nUnit, - RegionDesc::UnitRole::SMALL_SIZED_UNITS); + RegionDesc::UnitRole::LARGE_SIZED_UNITS); auto size = manager.CollectRegion(garbageRegion); - RegionDesc* region = manager.TakeRegion(16, RegionDesc::UnitRole::SMALL_SIZED_UNITS, true, false); + RegionDesc* region = manager.TakeRegion(16, RegionDesc::UnitRole::LARGE_SIZED_UNITS, true, false); EXPECT_NE(region, nullptr); } @@ -345,11 +343,7 @@ HWTEST_F_L0(RegionManagerTest, AllocReadOnly2) 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) @@ -361,11 +355,7 @@ HWTEST_F_L0(RegionManagerTest, AllocReadOnly3) 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) @@ -377,10 +367,7 @@ HWTEST_F_L0(RegionManagerTest, AllocReadOnly4) 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) @@ -392,10 +379,7 @@ HWTEST_F_L0(RegionManagerTest, AllocReadOnly5) 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) @@ -407,10 +391,7 @@ HWTEST_F_L0(RegionManagerTest, AllocReadOnly6) 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) @@ -422,10 +403,96 @@ HWTEST_F_L0(RegionManagerTest, AllocReadOnly7) 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()); +} + +HWTEST_F_L0(RegionManagerTest, VisitRememberSetTest) +{ + size_t totalUnits = 1024; + size_t heapSize = totalUnits * RegionDesc::UNIT_SIZE; + + void* regionMemory = malloc(heapSize + 4096); + ASSERT_NE(regionMemory, nullptr); + + uintptr_t heapStartAddress = reinterpret_cast(regionMemory); + uintptr_t regionInfoAddr = heapStartAddress + 4096; + + RegionManager manager; + manager.Initialize(totalUnits, regionInfoAddr); + + size_t unitIdx = 0; + size_t nUnit = 4; + RegionDesc* region = RegionDesc::InitRegion(unitIdx, nUnit, RegionDesc::UnitRole::LARGE_SIZED_UNITS); + ASSERT_NE(region, nullptr); + + manager.MarkRememberSet([&](BaseObject* obj) {}); + + int callbackCount = 0; + region->VisitRememberSet([&](BaseObject* obj) { + callbackCount++; + }); + + EXPECT_GE(callbackCount, 0); + free(regionMemory); +} + +HWTEST_F_L0(RegionManagerTest, VisitRememberSetBeforeCopyTest) +{ + size_t totalUnits = 1024; + size_t heapSize = totalUnits * RegionDesc::UNIT_SIZE; + + void* regionMemory = malloc(heapSize + 4096); + ASSERT_NE(regionMemory, nullptr); + + uintptr_t heapStartAddress = reinterpret_cast(regionMemory); + uintptr_t regionInfoAddr = heapStartAddress + 4096; + + RegionManager manager; + manager.Initialize(totalUnits, regionInfoAddr); + + size_t unitIdx = 0; + size_t nUnit = 4; + RegionDesc* region = RegionDesc::InitRegion(unitIdx, nUnit, RegionDesc::UnitRole::LARGE_SIZED_UNITS); + ASSERT_NE(region, nullptr); + + manager.MarkRememberSet([&](BaseObject* obj) {}); + + int callbackCount = 0; + region->VisitRememberSetBeforeCopy([&](BaseObject* obj) { + callbackCount++; + }); + + EXPECT_GE(callbackCount, 0); + free(regionMemory); +} + +HWTEST_F_L0(RegionManagerTest, VisitRememberSetBeforeTraceTest) +{ + size_t totalUnits = 1024; + size_t heapSize = totalUnits * RegionDesc::UNIT_SIZE; + + void* regionMemory = malloc(heapSize + 4096); + ASSERT_NE(regionMemory, nullptr); + + uintptr_t heapStartAddress = reinterpret_cast(regionMemory); + uintptr_t regionInfoAddr = heapStartAddress + 4096; + + RegionManager manager; + manager.Initialize(totalUnits, regionInfoAddr); + + size_t unitIdx = 0; + size_t nUnit = 4; + RegionDesc* region = RegionDesc::InitRegion(unitIdx, nUnit, RegionDesc::UnitRole::LARGE_SIZED_UNITS); + ASSERT_NE(region, nullptr); + + manager.MarkRememberSet([&](BaseObject* obj) {}); + + int callbackCount = 0; + region->VisitRememberSetBeforeTrace([&](BaseObject* obj) { + callbackCount++; + }); + + EXPECT_GE(callbackCount, 0); + free(regionMemory); } } diff --git a/common_components/heap/allocator/tests/region_space_test.cpp b/common_components/heap/allocator/tests/region_space_test.cpp index f2db5516d6..62c6ff0e7e 100755 --- a/common_components/heap/allocator/tests/region_space_test.cpp +++ b/common_components/heap/allocator/tests/region_space_test.cpp @@ -13,96 +13,56 @@ * limitations under the License. */ -#include "common_interfaces/heap/heap_allocator.h" +#include "common_components/heap/allocator/region_desc.h" #include "common_components/heap/allocator/region_space.h" -#include "common_components/heap/collector/trace_collector.h" -#include "common_components/heap/heap.cpp" -#include "common_components/base_runtime/base_runtime_param.h" -#include "common_components/heap/heap_manager.h" +#include "common_components/heap/allocator/region_space.cpp" +#include "common_components/heap/collector/collector_resources.h" #include "common_components/tests/test_helper.h" -#include +#include "common_interfaces/base_runtime.h" using namespace common; namespace common::test { class RegionSpaceTest : public common::test::BaseTestWithScope { -protected: - 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_); - 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_; - BaseRuntime::GetInstance()->GetHeapParam().regionSize = 64; // 64:region size - RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); - RegionManager& regionManager = theAllocator.GetRegionManager(); - regionManager.SetMaxUnitCountForRegion(); + BaseRuntime::GetInstance()->Init(); + holder_ = ThreadHolder::CreateAndRegisterNewThreadHolder(nullptr); + scope_ = new ThreadHolder::TryBindMutatorScope(holder_); } void TearDown() override { - if (mutator_) { - delete mutator_; - mutator_ = nullptr; - } - if (regionMemory_) { - free(regionMemory_); - regionMemory_ = nullptr; + if (scope_ != nullptr) { + delete scope_; + scope_ = nullptr; } + + BaseRuntime::GetInstance()->Fini(); } -}; -HWTEST_F_L0(RegionSpaceTest, ShouldRetryAllocation) -{ - auto* mutator = common::Mutator::GetMutator(); - mutator->SetMutatorPhase(GCPhase::GC_PHASE_UNDEF); - ThreadLocal::SetThreadType(ThreadType::GC_THREAD); - Heap::GetHeap().EnableGC(false); - Heap::GetHeap().GetCollectorResources().SetGcStarted(true); - Allocator *regionSpace = RegionSpace::CreateAllocator(); - EXPECT_EQ(regionSpace->Allocate(16, AllocType::MOVEABLE_OBJECT), 0); -} + ThreadHolder *holder_ {nullptr}; + ThreadHolder::TryBindMutatorScope *scope_ {nullptr}; +}; HWTEST_F_L0(RegionSpaceTest, FeedHungryBuffers2) { auto* mutator = common::Mutator::GetMutator(); mutator->SetMutatorPhase(GCPhase::GC_PHASE_FIX); - RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); - RegionManager& manager = theAllocator.GetRegionManager(); ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); - manager.Initialize(1024, reinterpret_cast(regionMemory_)); AllocationBuffer* buffer1 = new (std::nothrow) AllocationBuffer(); AllocationBuffer* buffer2 = new (std::nothrow) AllocationBuffer(); - RegionDesc* Region = RegionDesc::InitRegion(0, 1, RegionDesc::UnitRole::SMALL_SIZED_UNITS); - buffer1->SetPreparedRegion(Region); + RegionDesc* region = RegionDesc::InitRegion(0, 1, RegionDesc::UnitRole::LARGE_SIZED_UNITS); + region->InitFreeUnits(); + buffer1->SetPreparedRegion(region); + buffer2->SetPreparedRegion(region); Heap::GetHeap().GetAllocator().AddHungryBuffer(*buffer1); Heap::GetHeap().GetAllocator().AddHungryBuffer(*buffer2); Heap::GetHeap().GetAllocator().FeedHungryBuffers(); EXPECT_NE(buffer2->GetPreparedRegion(), nullptr); + delete buffer1; + delete buffer2; } HWTEST_F_L0(RegionSpaceTest, FeedHungryBuffers3) @@ -115,57 +75,52 @@ HWTEST_F_L0(RegionSpaceTest, FeedHungryBuffers3) EXPECT_EQ(hungryBuffers.size(), 0); } - HWTEST_F_L0(RegionSpaceTest, AllocRegion_PhaseEnum) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocOldRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocRegion_PhaseMark) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_MARK); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_MARK); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocOldRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocRegion_PhaseRemarkStab) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_REMARK_SATB); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_REMARK_SATB); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocOldRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocRegion_PhasePostMark) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_POST_MARK); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_POST_MARK); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocOldRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocRegion_PhasePrecopy) @@ -199,7 +154,6 @@ HWTEST_F_L0(RegionSpaceTest, AllocRegion_PhaseFix) ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); EXPECT_EQ(region->GetCopyLine(), region->GetRegionStart()); - EXPECT_EQ(region->GetFixLine(), region->GetRegionStart()); } HWTEST_F_L0(RegionSpaceTest, AllocRegion_PhaseUndef) @@ -211,59 +165,54 @@ HWTEST_F_L0(RegionSpaceTest, AllocRegion_PhaseUndef) ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); EXPECT_EQ(region->GetCopyLine(), std::numeric_limits::max()); - EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); } HWTEST_F_L0(RegionSpaceTest, AllocPinnedRegion_PhaseEnum) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocPinnedRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocPinnedRegion_PhaseMark) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_MARK); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_MARK); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocPinnedRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocPinnedRegion_PhaseRemarkStab) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_REMARK_SATB); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_REMARK_SATB); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocPinnedRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocPinnedRegion_PhasePostMark) { - ASSERT_NE(mutator_, nullptr); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_POST_MARK); + auto* mutator = common::Mutator::GetMutator(); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_POST_MARK); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); uintptr_t addr = theAllocator.AllocPinnedRegion(); ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); 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(RegionSpaceTest, AllocPinnedRegion_PhasePrecopy) @@ -297,7 +246,6 @@ HWTEST_F_L0(RegionSpaceTest, AllocPinnedRegion_PhaseFix) ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); EXPECT_EQ(region->GetCopyLine(), region->GetRegionStart()); - EXPECT_EQ(region->GetFixLine(), region->GetRegionStart()); } HWTEST_F_L0(RegionSpaceTest, AllocPinnedRegion_PhaseUndef) @@ -309,7 +257,6 @@ HWTEST_F_L0(RegionSpaceTest, AllocPinnedRegion_PhaseUndef) ASSERT_NE(addr, 0); RegionDesc* region = RegionDesc::GetRegionDescAt(addr); EXPECT_EQ(region->GetCopyLine(), std::numeric_limits::max()); - EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); } HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion2) @@ -318,9 +265,8 @@ HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion2) mutator->SetMutatorPhase(GCPhase::GC_PHASE_FIX); ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); - RegionDesc* region = theAllocator.AllocateThreadLocalRegion(false); + RegionDesc* region = theAllocator.AllocateThreadLocalRegion(false); EXPECT_EQ(region->GetCopyLine(), region->GetRegionStart()); - EXPECT_EQ(region->GetFixLine(), region->GetRegionStart()); } HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion3) @@ -329,13 +275,11 @@ HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion3) mutator->SetMutatorPhase(GCPhase::GC_PHASE_COPY); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); - RegionDesc* region = theAllocator.AllocateThreadLocalRegion(false); + RegionDesc* region = theAllocator.AllocateThreadLocalRegion(false); EXPECT_EQ(region->GetCopyLine(), region->GetRegionStart()); - EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); mutator->SetMutatorPhase(GCPhase::GC_PHASE_PRECOPY); - RegionDesc* region1 = theAllocator.AllocateThreadLocalRegion(false); + RegionDesc* region1 = theAllocator.AllocateThreadLocalRegion(false); EXPECT_EQ(region1->GetCopyLine(), region1->GetRegionStart()); - EXPECT_EQ(region1->GetFixLine(), std::numeric_limits::max()); } HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion4) @@ -344,42 +288,141 @@ HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion4) mutator->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); ThreadLocal::SetThreadType(ThreadType::ARK_PROCESSOR); - RegionDesc* region = theAllocator.AllocateThreadLocalRegion(false); + RegionDesc* region = theAllocator.AllocateThreadLocalRegion(false); EXPECT_EQ(region->GetTraceLine(), region->GetRegionStart()); EXPECT_EQ(region->GetCopyLine(), std::numeric_limits::max()); - EXPECT_EQ(region->GetFixLine(), std::numeric_limits::max()); mutator->SetMutatorPhase(GCPhase::GC_PHASE_MARK); - RegionDesc* region2 = theAllocator.AllocateThreadLocalRegion(false); + RegionDesc* region2 = theAllocator.AllocateThreadLocalRegion(false); EXPECT_EQ(region2->GetTraceLine(), region2->GetRegionStart()); EXPECT_EQ(region2->GetCopyLine(), std::numeric_limits::max()); - EXPECT_EQ(region2->GetFixLine(), std::numeric_limits::max()); mutator->SetMutatorPhase(GCPhase::GC_PHASE_REMARK_SATB); - RegionDesc* region3 = theAllocator.AllocateThreadLocalRegion(false); + RegionDesc* region3 = theAllocator.AllocateThreadLocalRegion(false); EXPECT_EQ(region3->GetTraceLine(), region3->GetRegionStart()); EXPECT_EQ(region3->GetCopyLine(), std::numeric_limits::max()); - EXPECT_EQ(region3->GetFixLine(), std::numeric_limits::max()); mutator->SetMutatorPhase(GCPhase::GC_PHASE_POST_MARK); - RegionDesc* region4 = theAllocator.AllocateThreadLocalRegion(false); + RegionDesc* region4 = theAllocator.AllocateThreadLocalRegion(false); EXPECT_EQ(region4->GetTraceLine(), region4->GetRegionStart()); EXPECT_EQ(region4->GetCopyLine(), std::numeric_limits::max()); - EXPECT_EQ(region4->GetFixLine(), std::numeric_limits::max()); } -HWTEST_F_L0(RegionSpaceTest, CopyRegion1) +HWTEST_F_L0(RegionSpaceTest, CopyRegion) { auto* mutator = common::Mutator::GetMutator(); - mutator_->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + mutator->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); - theAllocator.AssembleSmallGarbageCandidates(); - RegionDesc* region = theAllocator.GetRegionManager().TakeRegion( - 16, RegionDesc::UnitRole::SMALL_SIZED_UNITS, true, false); + uintptr_t addr = theAllocator.AllocOldRegion(); + ASSERT_NE(addr, 0); + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); region->SetRegionType(RegionDesc::RegionType::FROM_REGION); ASSERT(region->IsFromRegion()); - region->AddLiveByteCount(1); theAllocator.CopyRegion(region); - EXPECT_NE(theAllocator.FromSpaceSize(), 0); + EXPECT_EQ(theAllocator.FromSpaceSize(), 0); +} + +HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion1_NotGcThread_EntersElseBranch) +{ + auto& heapAllocator = Heap::GetHeap().GetAllocator(); + RegionSpace& regionSpace = reinterpret_cast(heapAllocator); + + Mutator::GetMutator()->SetMutatorPhase(GCPhase::GC_PHASE_ENUM); + + auto* region = regionSpace.AllocateThreadLocalRegion(false); + EXPECT_NE(region, nullptr); +} + +HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion2_NotGcThread_EntersElseBranch) +{ + auto& heapAllocator = Heap::GetHeap().GetAllocator(); + RegionSpace& regionSpace = reinterpret_cast(heapAllocator); + + Mutator::GetMutator()->SetMutatorPhase(GCPhase::GC_PHASE_PRECOPY); + + auto* region = regionSpace.AllocateThreadLocalRegion(false); + EXPECT_NE(region, nullptr); +} + +HWTEST_F_L0(RegionSpaceTest, AllocateThreadLocalRegion3_NotGcThread_EntersElseBranch) +{ + auto& heapAllocator = Heap::GetHeap().GetAllocator(); + RegionSpace& regionSpace = reinterpret_cast(heapAllocator); + + Mutator::GetMutator()->SetMutatorPhase(GCPhase::GC_PHASE_FIX); + + auto* region = regionSpace.AllocateThreadLocalRegion(false); + EXPECT_NE(region, nullptr); +} + +HWTEST_F_L0(RegionSpaceTest, Allocate_ValidSize_ReturnsNonNull) +{ + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocOldRegion(); + ASSERT_NE(addr, 0); + + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); + region->InitFreeUnits(); + region->SetRegionType(RegionDesc::RegionType::THREAD_LOCAL_REGION); + Mutator::GetMutator()->SetMutatorPhase(GCPhase::GC_PHASE_UNDEF); + Heap::GetHeap().EnableGC(true); + Heap::GetHeap().GetCollectorResources().SetGcStarted(false); + + uintptr_t result = theAllocator.Allocate(16, AllocType::PINNED_OBJECT); + EXPECT_NE(result, 0u); +} + +HWTEST_F_L0(RegionSpaceTest, FeedHungryBuffers_ShouldProvideValidRegions) +{ + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocOldRegion(); + ASSERT_NE(addr, 0); + + AllocationBuffer* buffer1 = new (std::nothrow) AllocationBuffer(); + AllocationBuffer* buffer2 = new (std::nothrow) AllocationBuffer(); + ASSERT_NE(buffer1, nullptr); + ASSERT_NE(buffer2, nullptr); + + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); + ASSERT_NE(region, nullptr); + region->InitFreeUnits(); + region->SetRegionType(RegionDesc::RegionType::THREAD_LOCAL_REGION); + + buffer1->SetPreparedRegion(region); + buffer2->SetPreparedRegion(region); + Heap::GetHeap().GetAllocator().AddHungryBuffer(*buffer1); + Heap::GetHeap().GetAllocator().AddHungryBuffer(*buffer2); + + Mutator::GetMutator()->SetMutatorPhase(GCPhase::GC_PHASE_FIX); + + Heap::GetHeap().GetAllocator().FeedHungryBuffers(); + + EXPECT_NE(buffer2->GetPreparedRegion(), nullptr); + delete buffer1; + delete buffer2; +} + +HWTEST_F_L0(RegionSpaceTest, AllocationBuffer_AllocateRawPointerObject_ValidSize_ReturnsNonNull) +{ + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocOldRegion(); + ASSERT_NE(addr, 0); + + RegionDesc* region = RegionDesc::GetRegionDescAt(addr); + ASSERT_NE(region, nullptr); + region->InitFreeUnits(); + region->SetRegionType(RegionDesc::RegionType::THREAD_LOCAL_REGION); + + AllocationBuffer* buffer = new (std::nothrow) AllocationBuffer(); + ASSERT_NE(buffer, nullptr); + buffer->SetPreparedRegion(region); + + Mutator::GetMutator()->SetMutatorPhase(GCPhase::GC_PHASE_UNDEF); + Heap::GetHeap().EnableGC(true); + Heap::GetHeap().GetCollectorResources().SetGcStarted(false); + + uintptr_t result = theAllocator.Allocate(16, AllocType::PINNED_OBJECT); + EXPECT_NE(result, 0u); + delete buffer; } } diff --git a/common_components/heap/barrier/tests/barrier_test.cpp b/common_components/heap/barrier/tests/barrier_test.cpp index 391784f103..f5f3611445 100644 --- a/common_components/heap/barrier/tests/barrier_test.cpp +++ b/common_components/heap/barrier/tests/barrier_test.cpp @@ -248,4 +248,20 @@ HWTEST_F_L0(BarrierTest, ReadStruct_ReadsCorrectly) { EXPECT_EQ(result->b, initValue->b); delete initValue; +} + +HWTEST_F_L0(BarrierTest, AtomicWriteStaticRef_NonConcurrent) +{ + DummyObject* targetObj = new DummyObject(); + DummyObject* initialObj = new DummyObject(); + + RefField field(reinterpret_cast(0x1)); + field.SetTargetObject(initialObj); + + MockCollector collector; + Barrier barrier(collector); + + barrier.AtomicWriteRefField(nullptr, field, targetObj, std::memory_order_relaxed); + + EXPECT_EQ(field.GetTargetObject(std::memory_order_relaxed), targetObj); } \ No newline at end of file diff --git a/common_components/taskpool/tests/BUILD.gn b/common_components/taskpool/tests/BUILD.gn new file mode 100644 index 0000000000..b04cd28d01 --- /dev/null +++ b/common_components/taskpool/tests/BUILD.gn @@ -0,0 +1,82 @@ +# 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("Taskpool_Task_Queue_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "task_queue_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("Taskpool_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "taskpool_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 = [ + ":Taskpool_Task_Queue_Test", + ":Taskpool_Test", + ] +} + +group("host_unittest") { + testonly = true + + # deps file + deps = [ + ":Taskpool_Task_Queue_TestAction", + ":Taskpool_TestAction", + ] +} \ No newline at end of file diff --git a/common_components/taskpool/tests/task_queue_test.cpp b/common_components/taskpool/tests/task_queue_test.cpp new file mode 100644 index 0000000000..e9d3972891 --- /dev/null +++ b/common_components/taskpool/tests/task_queue_test.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_components/tests/test_helper.h" +#include "common_components/taskpool/task_queue.h" +#include "common_components/taskpool/task.h" + +#include +#include + +namespace common { + +class TaskQueueTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override + { + queue_ = new TaskQueue(); + } + + void TearDown() override + { + delete queue_; + queue_ = nullptr; + } + + TaskQueue* queue_; +}; + +class MockTask : public Task { +public: + explicit MockTask(int id) : Task(id), executed_(false) {} + + bool Run(uint32_t threadId) override + { + executed_ = true; + return true; + } + + bool IsExecuted() const { return executed_; } + +private: + mutable bool executed_; +}; + + +HWTEST_F_L0(TaskQueueTest, PopTask_DelayedTaskExpired_CanBeExecuted) +{ + auto task = std::make_unique(2); + queue_->PostDelayedTask(std::move(task), 500); + + usleep(600 * 1000); + + auto poppedTask = queue_->PopTask(); + ASSERT_NE(poppedTask, nullptr); + + MockTask* mockTask = static_cast(poppedTask.get()); + EXPECT_FALSE(mockTask->IsExecuted()); + + (void)poppedTask->Run(0); + EXPECT_TRUE(mockTask->IsExecuted()); +} + +HWTEST_F_L0(TaskQueueTest, PopTask_MultipleDelayedTasks_ExecuteInOrder) +{ + auto task1 = std::make_unique(1); + auto task2 = std::make_unique(2); + auto task3 = std::make_unique(3); + + queue_->PostDelayedTask(std::move(task1), 800); + queue_->PostDelayedTask(std::move(task2), 500); + queue_->PostDelayedTask(std::move(task3), 1000); + + usleep(600 * 1000); + + auto poppedTask = queue_->PopTask(); + ASSERT_NE(poppedTask, nullptr); + EXPECT_EQ(poppedTask->GetId(), 2); + + poppedTask->Run(0); + MockTask* mockTask2 = static_cast(poppedTask.get()); + EXPECT_TRUE(mockTask2->IsExecuted()); + + usleep(300 * 1000); + + poppedTask = queue_->PopTask(); + ASSERT_NE(poppedTask, nullptr); + EXPECT_EQ(poppedTask->GetId(), 1); + + poppedTask->Run(0); + MockTask* mockTask1 = static_cast(poppedTask.get()); + EXPECT_TRUE(mockTask1->IsExecuted()); + + usleep(200 * 1000); + + poppedTask = queue_->PopTask(); + ASSERT_NE(poppedTask, nullptr); + EXPECT_EQ(poppedTask->GetId(), 3); + + poppedTask->Run(0); + MockTask* mockTask3 = static_cast(poppedTask.get()); + EXPECT_TRUE(mockTask3->IsExecuted()); +} +} \ No newline at end of file diff --git a/common_components/taskpool/tests/taskpool_test.cpp b/common_components/taskpool/tests/taskpool_test.cpp new file mode 100644 index 0000000000..bd3873f44d --- /dev/null +++ b/common_components/taskpool/tests/taskpool_test.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_components/tests/test_helper.h" +#include "common_components/taskpool/taskpool.h" +#include "common_components/taskpool/task.h" + +#include +#include +#include + +namespace common { + +class MockTask : public Task { +public: + explicit MockTask(int32_t id) + : Task(id), executed_(false), terminated_(false) {} + + bool Run(uint32_t threadId) override + { + executed_ = true; + return true; + } + + bool IsExecuted() const { return executed_; } + + bool IsTerminate() const + { + return terminated_; + } + + void Terminate() + { + terminated_ = true; + } + +private: + std::atomic executed_; + std::atomic terminated_; +}; + +class TaskpoolTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override {} + void TearDown() override {} + + class ScopedTaskpool { + public: + explicit ScopedTaskpool(int threadNum = DEFAULT_TASKPOOL_THREAD_NUM) + : isInitialized_(false) + { + isInitialized_ = true; + pool_.Initialize(threadNum); + } + + Taskpool* Get() + { + return &pool_; + } + + private: + Taskpool pool_; + bool isInitialized_; + }; +}; + +HWTEST_F_L0(TaskpoolTest, InitializeAndDestroy) { + TaskpoolTest::ScopedTaskpool pool(2); + EXPECT_NE(pool.Get(), nullptr); + EXPECT_GT(pool.Get()->GetTotalThreadNum(), 0U); +} + +HWTEST_F_L0(TaskpoolTest, SetQosPriority) { + TaskpoolTest::ScopedTaskpool pool(1); + pool.Get()->SetThreadPriority(PriorityMode::BACKGROUND); +} + +HWTEST_F_L0(TaskpoolTest, ForEachTask) { + TaskpoolTest::ScopedTaskpool pool(1); + + auto task = std::make_unique(1); + pool.Get()->PostTask(std::move(task)); + + std::atomic count(0); + pool.Get()->ForEachTask([&count](Task* t) { + count++; + }); + + EXPECT_EQ(count.load(), 1); +} + +HWTEST_F_L0(TaskpoolTest, TerminateTask) { + TaskpoolTest::ScopedTaskpool pool(2); + Taskpool* taskpool = pool.Get(); + ASSERT_NE(taskpool, nullptr); + + auto task1 = std::make_unique(1); + auto task2 = std::make_unique(2); + taskpool->PostTask(std::move(task1)); + taskpool->PostTask(std::move(task2)); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + taskpool->TerminateTask(1, TaskType::ALL); + + bool isTerminated = false; + taskpool->ForEachTask([&isTerminated](Task* task) { + if (task->GetId() == 1 && task->IsTerminate()) { + isTerminated = true; + } + }); + + EXPECT_FALSE(isTerminated); +} +} \ No newline at end of file diff --git a/common_components/tests/ohos_test.xml b/common_components/tests/ohos_test.xml index a9332b249e..972245bcf7 100644 --- a/common_components/tests/ohos_test.xml +++ b/common_components/tests/ohos_test.xml @@ -43,6 +43,11 @@