1 /**
2 * Copyright (c) 2021-2024 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 <iterator>
17 #include <gtest/gtest.h>
18
19 #include "libpandabase/mem/mem.h"
20 #include "runtime/mem/gc/g1/collection_set.h"
21 #include "runtime/mem/mem_stats_default.h"
22 #include "runtime/mem/mem_stats_additional_info.h"
23
24 namespace ark::mem {
25
26 class CollectionSetTest : public testing::Test {
27 public:
CollectionSetTest()28 CollectionSetTest()
29 {
30 static constexpr size_t MEMORY_POOL_SIZE = 16_MB;
31 MemConfig::Initialize(0, MEMORY_POOL_SIZE, 0, 0, 0, 0);
32 PoolManager::Initialize();
33 memStats_ = new mem::MemStatsType();
34 allocator_ = new InternalAllocatorT<mem::InternalAllocatorConfig::PANDA_ALLOCATORS>(memStats_);
35 // mem::InternalAllocatorPtr allocator_ptr(allocator_);
36 mem::InternalAllocator<>::InitInternalAllocatorFromRuntime(static_cast<Allocator *>(allocator_));
37 }
38
~CollectionSetTest()39 ~CollectionSetTest() override
40 {
41 delete allocator_;
42 PoolManager::Finalize();
43 ark::mem::MemConfig::Finalize();
44 delete memStats_;
45 InternalAllocator<>::ClearInternalAllocatorFromRuntime();
46 }
47
48 NO_COPY_SEMANTIC(CollectionSetTest);
49 NO_MOVE_SEMANTIC(CollectionSetTest);
50
51 private:
52 MemStatsType *memStats_;
53 InternalAllocatorT<mem::InternalAllocatorConfig::PANDA_ALLOCATORS> *allocator_;
54 };
55
56 // NOLINTBEGIN(readability-magic-numbers)
57
TEST_F(CollectionSetTest,TestCtor)58 TEST_F(CollectionSetTest, TestCtor)
59 {
60 Region youngRegion(nullptr, 0x0, 0x1000);
61 youngRegion.AddFlag(RegionFlag::IS_EDEN);
62 PandaVector<Region *> youngRegions = {&youngRegion};
63
64 CollectionSet cs(std::move(youngRegions));
65
66 ASSERT_EQ(1U, cs.size());
67 auto young = cs.Young();
68 auto tenured = cs.Tenured();
69 auto humongous = cs.Humongous();
70 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
71 ASSERT_EQ(&youngRegion, *young.begin());
72 ASSERT_EQ(0U, std::distance(tenured.begin(), tenured.end()));
73 ASSERT_EQ(0U, std::distance(humongous.begin(), humongous.end()));
74 }
75
TEST_F(CollectionSetTest,TestAddTenuredRegion)76 TEST_F(CollectionSetTest, TestAddTenuredRegion)
77 {
78 Region youngRegion(nullptr, 0x0, 0x1000);
79 youngRegion.AddFlag(RegionFlag::IS_EDEN);
80 PandaVector<Region *> youngRegions = {&youngRegion};
81 Region tenuredRegion(nullptr, 0x1000, 0x2000);
82 tenuredRegion.AddFlag(RegionFlag::IS_OLD);
83
84 CollectionSet cs(std::move(youngRegions));
85 cs.AddRegion(&tenuredRegion);
86
87 ASSERT_EQ(2U, cs.size());
88 auto young = cs.Young();
89 auto tenured = cs.Tenured();
90 auto humongous = cs.Humongous();
91 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
92 ASSERT_EQ(&youngRegion, *young.begin());
93 ASSERT_EQ(1U, std::distance(tenured.begin(), tenured.end()));
94 ASSERT_EQ(&tenuredRegion, *tenured.begin());
95 ASSERT_EQ(0U, std::distance(humongous.begin(), humongous.end()));
96 }
97
TEST_F(CollectionSetTest,TestAddHumongousRegion)98 TEST_F(CollectionSetTest, TestAddHumongousRegion)
99 {
100 Region youngRegion(nullptr, 0x0, 0x1000);
101 youngRegion.AddFlag(RegionFlag::IS_EDEN);
102 PandaVector<Region *> youngRegions = {&youngRegion};
103 Region humongousRegion(nullptr, 0x1000, 0x2000);
104 humongousRegion.AddFlag(RegionFlag::IS_OLD);
105 humongousRegion.AddFlag(RegionFlag::IS_LARGE_OBJECT);
106
107 CollectionSet cs(std::move(youngRegions));
108 cs.AddRegion(&humongousRegion);
109
110 ASSERT_EQ(2U, cs.size());
111 auto young = cs.Young();
112 auto tenured = cs.Tenured();
113 auto humongous = cs.Humongous();
114 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
115 ASSERT_EQ(&youngRegion, *young.begin());
116 ASSERT_EQ(0U, std::distance(tenured.begin(), tenured.end()));
117 ASSERT_EQ(1U, std::distance(humongous.begin(), humongous.end()));
118 ASSERT_EQ(&humongousRegion, *humongous.begin());
119 }
120
TEST_F(CollectionSetTest,TestAddDifferentRegions)121 TEST_F(CollectionSetTest, TestAddDifferentRegions)
122 {
123 Region youngRegion(nullptr, 0x0, 0x1000);
124 youngRegion.AddFlag(RegionFlag::IS_EDEN);
125 PandaVector<Region *> youngRegions = {&youngRegion};
126 Region tenured1Region(nullptr, 0x1000, 0x2000);
127 tenured1Region.AddFlag(RegionFlag::IS_OLD);
128 Region tenured2Region(nullptr, 0x1000, 0x2000);
129 tenured2Region.AddFlag(RegionFlag::IS_OLD);
130 Region humongous1Region(nullptr, 0x2000, 0x3000);
131 humongous1Region.AddFlag(RegionFlag::IS_OLD);
132 humongous1Region.AddFlag(RegionFlag::IS_LARGE_OBJECT);
133 Region humongous2Region(nullptr, 0x2000, 0x3000);
134 humongous2Region.AddFlag(RegionFlag::IS_OLD);
135 humongous2Region.AddFlag(RegionFlag::IS_LARGE_OBJECT);
136
137 CollectionSet cs(std::move(youngRegions));
138 cs.AddRegion(&humongous1Region);
139 cs.AddRegion(&tenured1Region);
140 cs.AddRegion(&humongous2Region);
141 cs.AddRegion(&tenured2Region);
142
143 ASSERT_EQ(5U, cs.size());
144 auto young = cs.Young();
145 auto tenured = cs.Tenured();
146 auto humongous = cs.Humongous();
147 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
148 ASSERT_EQ(&youngRegion, *young.begin());
149 ASSERT_EQ(2U, std::distance(tenured.begin(), tenured.end()));
150 ASSERT_EQ(2U, std::distance(humongous.begin(), humongous.end()));
151 ASSERT_EQ(5U, std::distance(cs.begin(), cs.end()));
152 auto it = cs.begin();
153 // one young region
154 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_EDEN));
155 // two tenured regions
156 ++it;
157 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
158 ASSERT_FALSE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
159 ++it;
160 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
161 ASSERT_FALSE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
162 // two humongous regions
163 ++it;
164 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
165 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
166 ++it;
167 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
168 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
169 }
170
171 // NOLINTEND(readability-magic-numbers)
172
173 } // namespace ark::mem
174