• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "common_components/heap/collector/finalizer_processor.h"
17 #include "common_components/heap/collector/collector_proxy.h"
18 #include "common_components/heap/heap_manager.h"
19 #include "common_components/tests/test_helper.h"
20 
21 using namespace common;
22 
23 namespace common::test {
24 const uint32_t TWO_SECONDS = 2;
25 const uint32_t HUNDRED_MILLISECONDS = 100;
26 constexpr uint64_t TAG_BOOLEAN = 0x04ULL;
27 
28 class FinalizerProcessorTest : public common::test::BaseTestWithScope {
29 protected:
SetUpTestCase()30     static void SetUpTestCase()
31     {
32         BaseRuntime::GetInstance()->Init();
33     }
34 
TearDownTestCase()35     static void TearDownTestCase() {}
36 
SetUp()37     void SetUp() override
38     {
39         MutatorManager::Instance().CreateRuntimeMutator(ThreadType::ARK_PROCESSOR);
40     }
41 
TearDown()42     void TearDown() override
43     {
44         MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::ARK_PROCESSOR);
45     }
46 };
47 
HWTEST_F_L0(FinalizerProcessorTest,RegisterFinalizer_TEST1)48 HWTEST_F_L0(FinalizerProcessorTest, RegisterFinalizer_TEST1)
49 {
50     FinalizerProcessor finalizerProcessor;
51     HeapAddress addr = common::HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
52     BaseObject *obj = reinterpret_cast<BaseObject*>(addr | TAG_BOOLEAN);
53     new (obj) BaseObject(); // Construct BaseObject
54     finalizerProcessor.RegisterFinalizer(obj);
55     bool flag = common::RegionSpace::IsMarkedObject(obj);
56     EXPECT_FALSE(flag);
57 }
58 
HWTEST_F_L0(FinalizerProcessorTest,EnqueueFinalizables_TEST1)59 HWTEST_F_L0(FinalizerProcessorTest, EnqueueFinalizables_TEST1)
60 {
61     FinalizerProcessor finalizerProcessor;
62     HeapAddress addr = common::HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
63     BaseObject *obj = reinterpret_cast<BaseObject*>(addr | TAG_BOOLEAN);
64     new (obj) BaseObject(); // Construct BaseObject
65     finalizerProcessor.RegisterFinalizer(obj);
66     std::function<bool(BaseObject*)> finalizable = [](BaseObject* obj) {
67         return !common::RegionSpace::IsMarkedObject(obj);
68     };
69     finalizerProcessor.EnqueueFinalizables(finalizable, 1);
70     bool flag = finalizable(obj);
71     EXPECT_TRUE(flag);
72 }
73 
HWTEST_F_L0(FinalizerProcessorTest,EnqueueFinalizables_TEST2)74 HWTEST_F_L0(FinalizerProcessorTest, EnqueueFinalizables_TEST2)
75 {
76     FinalizerProcessor finalizerProcessor;
77     HeapAddress addr = common::HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
78     BaseObject *obj = reinterpret_cast<BaseObject*>(addr | TAG_BOOLEAN);
79     new (obj) BaseObject();
80     finalizerProcessor.RegisterFinalizer(obj);
81     RootVisitor visitor = [](ObjectRef&) {
82         return;
83     };
84     std::function<bool(BaseObject*)> finalizable = [this](BaseObject* obj) {
85         return common::RegionSpace::IsMarkedObject(obj);
86     };
87     auto before = finalizerProcessor.VisitFinalizers(visitor);
88     finalizerProcessor.EnqueueFinalizables(finalizable, 1);
89     auto after = finalizerProcessor.VisitFinalizers(visitor);
90     bool flag = finalizable(obj);
91     EXPECT_FALSE(flag);
92     EXPECT_EQ(before, after);
93 }
94 
HWTEST_F_L0(FinalizerProcessorTest,EnqueueFinalizables_TEST3)95 HWTEST_F_L0(FinalizerProcessorTest, EnqueueFinalizables_TEST3)
96 {
97     FinalizerProcessor finalizerProcessor;
98     RootVisitor visitor = [](ObjectRef&) {
99         return;
100     };
101     std::function<bool(BaseObject*)> finalizable = [this](BaseObject* obj) {
102         return common::RegionSpace::IsMarkedObject(obj);
103     };
104     auto num1 = finalizerProcessor.VisitFinalizers(visitor);
105     finalizerProcessor.EnqueueFinalizables(finalizable, 0);
106     EXPECT_EQ(num1, 0);
107     auto num2 = finalizerProcessor.VisitFinalizers(visitor);
108     finalizerProcessor.EnqueueFinalizables(finalizable, 1);
109     EXPECT_EQ(num2, 0);
110     HeapAddress addr = common::HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
111     BaseObject *obj = reinterpret_cast<BaseObject*>(addr | TAG_BOOLEAN);
112     new (obj) BaseObject();
113     finalizerProcessor.RegisterFinalizer(obj);
114     auto num3 = finalizerProcessor.VisitFinalizers(visitor);
115     finalizerProcessor.EnqueueFinalizables(finalizable, 0);
116     bool flag = finalizable(obj);
117     EXPECT_NE(num3, 0);
118     EXPECT_FALSE(flag);
119 }
120 
HWTEST_F_L0(FinalizerProcessorTest,Run_TEST1)121 HWTEST_F_L0(FinalizerProcessorTest, Run_TEST1)
122 {
123     FinalizerProcessor finalizerProcessor;
124     HeapAddress addr = common::HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
125     BaseObject *obj = reinterpret_cast<BaseObject*>(addr | TAG_BOOLEAN);
126     new (obj) BaseObject();
127     AllocationBuffer* buffer = new (std::nothrow) AllocationBuffer();
128     RegionDesc* region = RegionDesc::GetRegionDescAt(addr);
129     buffer->SetPreparedRegion(region);
130     Heap::GetHeap().GetAllocator().AddHungryBuffer(*buffer);
131     finalizerProcessor.RegisterFinalizer(obj);
132     finalizerProcessor.Start();
133     std::thread notifier([&]() {
134         std::this_thread::sleep_for(std::chrono::milliseconds(HUNDRED_MILLISECONDS));
135         finalizerProcessor.NotifyToFeedAllocBuffers();
136         std::this_thread::sleep_for(std::chrono::milliseconds(HUNDRED_MILLISECONDS));
137         finalizerProcessor.NotifyToReclaimGarbage();
138     });
139     notifier.join();
140     std::this_thread::sleep_for(std::chrono::seconds(TWO_SECONDS));
141     finalizerProcessor.Stop();
142     EXPECT_NE(buffer->GetPreparedRegion(), nullptr);
143     delete buffer;
144 }
145 } // namespace common::test
146