1 /*
2 * Copyright (c) 2021-2022 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 panda::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);
32 PoolManager::Initialize();
33 mem_stats_ = new mem::MemStatsType();
34 allocator_ = new InternalAllocatorT<mem::InternalAllocatorConfig::PANDA_ALLOCATORS>(mem_stats_);
35 // mem::InternalAllocatorPtr allocator_ptr(allocator_);
36 mem::InternalAllocator<>::InitInternalAllocatorFromRuntime(static_cast<Allocator *>(allocator_));
37 }
38
~CollectionSetTest()39 ~CollectionSetTest()
40 {
41 delete allocator_;
42 PoolManager::Finalize();
43 panda::mem::MemConfig::Finalize();
44 delete mem_stats_;
45 InternalAllocator<>::ClearInternalAllocatorFromRuntime();
46 }
47
48 private:
49 MemStatsType *mem_stats_;
50 InternalAllocatorT<mem::InternalAllocatorConfig::PANDA_ALLOCATORS> *allocator_;
51 };
52
TEST_F(CollectionSetTest,TestCtor)53 TEST_F(CollectionSetTest, TestCtor)
54 {
55 Region young_region(nullptr, 0x0, 0x1000);
56 young_region.AddFlag(RegionFlag::IS_EDEN);
57 PandaVector<Region *> young_regions = {&young_region};
58
59 CollectionSet cs(std::move(young_regions));
60
61 ASSERT_EQ(1U, cs.size());
62 auto young = cs.Young();
63 auto tenured = cs.Tenured();
64 auto humongous = cs.Humongous();
65 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
66 ASSERT_EQ(&young_region, *young.begin());
67 ASSERT_EQ(0U, std::distance(tenured.begin(), tenured.end()));
68 ASSERT_EQ(0U, std::distance(humongous.begin(), humongous.end()));
69 }
70
TEST_F(CollectionSetTest,TestAddTenuredRegion)71 TEST_F(CollectionSetTest, TestAddTenuredRegion)
72 {
73 Region young_region(nullptr, 0x0, 0x1000);
74 young_region.AddFlag(RegionFlag::IS_EDEN);
75 PandaVector<Region *> young_regions = {&young_region};
76 Region tenured_region(nullptr, 0x1000, 0x2000);
77 tenured_region.AddFlag(RegionFlag::IS_OLD);
78
79 CollectionSet cs(std::move(young_regions));
80 cs.AddRegion(&tenured_region);
81
82 ASSERT_EQ(2U, cs.size());
83 auto young = cs.Young();
84 auto tenured = cs.Tenured();
85 auto humongous = cs.Humongous();
86 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
87 ASSERT_EQ(&young_region, *young.begin());
88 ASSERT_EQ(1U, std::distance(tenured.begin(), tenured.end()));
89 ASSERT_EQ(&tenured_region, *tenured.begin());
90 ASSERT_EQ(0U, std::distance(humongous.begin(), humongous.end()));
91 }
92
TEST_F(CollectionSetTest,TestAddHumongousRegion)93 TEST_F(CollectionSetTest, TestAddHumongousRegion)
94 {
95 Region young_region(nullptr, 0x0, 0x1000);
96 young_region.AddFlag(RegionFlag::IS_EDEN);
97 PandaVector<Region *> young_regions = {&young_region};
98 Region humongous_region(nullptr, 0x1000, 0x2000);
99 humongous_region.AddFlag(RegionFlag::IS_OLD);
100 humongous_region.AddFlag(RegionFlag::IS_LARGE_OBJECT);
101
102 CollectionSet cs(std::move(young_regions));
103 cs.AddRegion(&humongous_region);
104
105 ASSERT_EQ(2U, cs.size());
106 auto young = cs.Young();
107 auto tenured = cs.Tenured();
108 auto humongous = cs.Humongous();
109 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
110 ASSERT_EQ(&young_region, *young.begin());
111 ASSERT_EQ(0U, std::distance(tenured.begin(), tenured.end()));
112 ASSERT_EQ(1U, std::distance(humongous.begin(), humongous.end()));
113 ASSERT_EQ(&humongous_region, *humongous.begin());
114 }
115
TEST_F(CollectionSetTest,TestAddDifferentRegions)116 TEST_F(CollectionSetTest, TestAddDifferentRegions)
117 {
118 Region young_region(nullptr, 0x0, 0x1000);
119 young_region.AddFlag(RegionFlag::IS_EDEN);
120 PandaVector<Region *> young_regions = {&young_region};
121 Region tenured1_region(nullptr, 0x1000, 0x2000);
122 tenured1_region.AddFlag(RegionFlag::IS_OLD);
123 Region tenured2_region(nullptr, 0x1000, 0x2000);
124 tenured2_region.AddFlag(RegionFlag::IS_OLD);
125 Region humongous1_region(nullptr, 0x2000, 0x3000);
126 humongous1_region.AddFlag(RegionFlag::IS_OLD);
127 humongous1_region.AddFlag(RegionFlag::IS_LARGE_OBJECT);
128 Region humongous2_region(nullptr, 0x2000, 0x3000);
129 humongous2_region.AddFlag(RegionFlag::IS_OLD);
130 humongous2_region.AddFlag(RegionFlag::IS_LARGE_OBJECT);
131
132 CollectionSet cs(std::move(young_regions));
133 cs.AddRegion(&humongous1_region);
134 cs.AddRegion(&tenured1_region);
135 cs.AddRegion(&humongous2_region);
136 cs.AddRegion(&tenured2_region);
137
138 ASSERT_EQ(5U, cs.size());
139 auto young = cs.Young();
140 auto tenured = cs.Tenured();
141 auto humongous = cs.Humongous();
142 ASSERT_EQ(1U, std::distance(young.begin(), young.end()));
143 ASSERT_EQ(&young_region, *young.begin());
144 ASSERT_EQ(2U, std::distance(tenured.begin(), tenured.end()));
145 ASSERT_EQ(2U, std::distance(humongous.begin(), humongous.end()));
146 ASSERT_EQ(5U, std::distance(cs.begin(), cs.end()));
147 auto it = cs.begin();
148 // one young region
149 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_EDEN));
150 // two tenured regions
151 ++it;
152 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
153 ASSERT_FALSE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
154 ++it;
155 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
156 ASSERT_FALSE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
157 // two humongous regions
158 ++it;
159 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
160 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
161 ++it;
162 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_OLD));
163 ASSERT_TRUE((*it)->HasFlag(RegionFlag::IS_LARGE_OBJECT));
164 }
165
166 } // namespace panda::mem
167