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 #include "mem/mem.h" 16 #include "mem/mmap_mem_pool-inl.h" 17 18 #include "gtest/gtest.h" 19 20 namespace panda { 21 22 class MMapMemPoolTest : public testing::Test { 23 public: MMapMemPoolTest()24 MMapMemPoolTest() 25 { 26 instance_ = nullptr; 27 } 28 ~MMapMemPoolTest()29 ~MMapMemPoolTest() 30 { 31 if (instance_ != nullptr) { 32 delete instance_; 33 } 34 FinalizeMemConfig(); 35 } 36 37 protected: CreateMMapMemPool(size_t object_pool_size=0,size_t internal_size=0,size_t compiler_size=0,size_t code_size=0)38 MmapMemPool *CreateMMapMemPool(size_t object_pool_size = 0, size_t internal_size = 0, size_t compiler_size = 0, 39 size_t code_size = 0) 40 { 41 ASSERT(instance_ == nullptr); 42 SetupMemConfig(object_pool_size, internal_size, compiler_size, code_size); 43 instance_ = new MmapMemPool(); 44 return instance_; 45 } 46 47 private: SetupMemConfig(size_t object_pool_size,size_t internal_size,size_t compiler_size,size_t code_size)48 void SetupMemConfig(size_t object_pool_size, size_t internal_size, size_t compiler_size, size_t code_size) 49 { 50 mem::MemConfig::Initialize(object_pool_size, internal_size, compiler_size, code_size); 51 } 52 FinalizeMemConfig()53 void FinalizeMemConfig() 54 { 55 mem::MemConfig::Finalize(); 56 } 57 58 MmapMemPool *instance_; 59 }; 60 61 HWTEST_F(MMapMemPoolTest, HeapOOMTest, testing::ext::TestSize.Level0) 62 { 63 MmapMemPool *memPool = CreateMMapMemPool(4_MB); 64 65 auto pool1 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_HUMONGOUS_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 66 ASSERT_TRUE(pool1.GetMem() != nullptr); 67 auto pool2 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_HUMONGOUS_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 68 ASSERT_TRUE(pool2.GetMem() == nullptr); 69 auto pool3 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 70 ASSERT_TRUE(pool3.GetMem() == nullptr); 71 auto pool4 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 72 ASSERT_TRUE(pool4.GetMem() == nullptr); 73 74 memPool->FreePool(pool1.GetMem(), pool1.GetSize()); 75 } 76 77 HWTEST_F(MMapMemPoolTest, HeapOOMAndAllocInOtherSpacesTest, testing::ext::TestSize.Level0) 78 { 79 MmapMemPool *memPool = CreateMMapMemPool(4_MB, 1_MB, 1_MB, 1_MB); 80 81 auto pool1 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::BUMP_ALLOCATOR); 82 ASSERT_TRUE(pool1.GetMem() != nullptr); 83 auto pool2 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::BUMP_ALLOCATOR); 84 ASSERT_TRUE(pool2.GetMem() == nullptr); 85 auto pool3 = memPool->AllocPool(1_MB, SpaceType::SPACE_TYPE_COMPILER, AllocatorType::BUMP_ALLOCATOR); 86 ASSERT_TRUE(pool3.GetMem() != nullptr); 87 auto pool4 = memPool->AllocPool(1_MB, SpaceType::SPACE_TYPE_CODE, AllocatorType::BUMP_ALLOCATOR); 88 ASSERT_TRUE(pool4.GetMem() != nullptr); 89 auto pool5 = memPool->AllocPool(1_MB, SpaceType::SPACE_TYPE_INTERNAL, AllocatorType::BUMP_ALLOCATOR); 90 ASSERT_TRUE(pool5.GetMem() != nullptr); 91 92 // cleaning 93 memPool->FreePool(pool1.GetMem(), pool1.GetSize()); 94 memPool->FreePool(pool3.GetMem(), pool3.GetSize()); 95 memPool->FreePool(pool4.GetMem(), pool4.GetSize()); 96 memPool->FreePool(pool5.GetMem(), pool5.GetSize()); 97 } 98 99 HWTEST_F(MMapMemPoolTest, GetAllocatorInfoTest, testing::ext::TestSize.Level0) 100 { 101 static constexpr AllocatorType ALLOC_TYPE = AllocatorType::BUMP_ALLOCATOR; 102 static constexpr size_t POOL_SIZE = 4_MB; 103 static constexpr size_t POINTER_POOL_OFFSET = 1_MB; 104 ASSERT_TRUE(POINTER_POOL_OFFSET < POOL_SIZE); 105 MmapMemPool *memPool = CreateMMapMemPool(POOL_SIZE * 2, 0, 0, 0); 106 int *allocator_addr = new int(); 107 Pool pool_with_alloc_addr = memPool->AllocPool(POOL_SIZE, SpaceType::SPACE_TYPE_OBJECT, ALLOC_TYPE, allocator_addr); 108 Pool pool_without_alloc_addr = memPool->AllocPool(POOL_SIZE, SpaceType::SPACE_TYPE_OBJECT, ALLOC_TYPE); 109 ASSERT_TRUE(pool_with_alloc_addr.GetMem() != nullptr); 110 ASSERT_TRUE(pool_without_alloc_addr.GetMem() != nullptr); 111 112 void *first_pool_pointer = ToVoidPtr(ToUintPtr(pool_with_alloc_addr.GetMem()) + POINTER_POOL_OFFSET); 113 ASSERT_TRUE(ToUintPtr(memPool->GetAllocatorInfoForAddr(first_pool_pointer).GetAllocatorHeaderAddr()) == 114 ToUintPtr(allocator_addr)); 115 ASSERT_TRUE(memPool->GetAllocatorInfoForAddr(first_pool_pointer).GetType() == ALLOC_TYPE); 116 ASSERT_TRUE(ToUintPtr(memPool->GetStartAddrPoolForAddr(first_pool_pointer)) == 117 ToUintPtr(pool_with_alloc_addr.GetMem())); 118 119 void *second_pool_pointer = ToVoidPtr(ToUintPtr(pool_without_alloc_addr.GetMem()) + POINTER_POOL_OFFSET); 120 ASSERT_TRUE(ToUintPtr(memPool->GetAllocatorInfoForAddr(second_pool_pointer).GetAllocatorHeaderAddr()) == 121 ToUintPtr(pool_without_alloc_addr.GetMem())); 122 ASSERT_TRUE(memPool->GetAllocatorInfoForAddr(second_pool_pointer).GetType() == ALLOC_TYPE); 123 ASSERT_TRUE(ToUintPtr(memPool->GetStartAddrPoolForAddr(second_pool_pointer)) == 124 ToUintPtr(pool_without_alloc_addr.GetMem())); 125 126 // cleaning 127 memPool->FreePool(pool_with_alloc_addr.GetMem(), pool_with_alloc_addr.GetSize()); 128 memPool->FreePool(pool_without_alloc_addr.GetMem(), pool_without_alloc_addr.GetSize()); 129 130 delete allocator_addr; 131 } 132 133 HWTEST_F(MMapMemPoolTest, CheckLimitsForInternalSpacesTest, testing::ext::TestSize.Level0) 134 { 135 #ifndef PANDA_TARGET_32 136 MmapMemPool *mem_pool = CreateMMapMemPool(1_MB, 2_MB, 2_MB, 2_MB); 137 Pool object_pool = mem_pool->AllocPool(1_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::BUMP_ALLOCATOR); 138 Pool internal_pool = mem_pool->AllocPool(2_MB, SpaceType::SPACE_TYPE_COMPILER, AllocatorType::BUMP_ALLOCATOR); 139 Pool code_pool = mem_pool->AllocPool(2_MB, SpaceType::SPACE_TYPE_CODE, AllocatorType::BUMP_ALLOCATOR); 140 Pool compiler_pool = mem_pool->AllocPool(2_MB, SpaceType::SPACE_TYPE_INTERNAL, AllocatorType::BUMP_ALLOCATOR); 141 // Check that these pools has been created successfully 142 ASSERT_TRUE(object_pool.GetMem() != nullptr); 143 ASSERT_TRUE(internal_pool.GetMem() != nullptr); 144 ASSERT_TRUE(code_pool.GetMem() != nullptr); 145 ASSERT_TRUE(compiler_pool.GetMem() != nullptr); 146 147 // cleaning 148 mem_pool->FreePool(object_pool.GetMem(), object_pool.GetSize()); 149 mem_pool->FreePool(internal_pool.GetMem(), internal_pool.GetSize()); 150 mem_pool->FreePool(code_pool.GetMem(), code_pool.GetSize()); 151 mem_pool->FreePool(compiler_pool.GetMem(), compiler_pool.GetSize()); 152 #endif 153 } 154 155 HWTEST_F(MMapMemPoolTest, PoolReturnTest, testing::ext::TestSize.Level0) 156 { 157 MmapMemPool *memPool = CreateMMapMemPool(8_MB); 158 159 auto pool1 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 160 ASSERT_TRUE(pool1.GetMem() != nullptr); 161 auto pool2 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 162 ASSERT_TRUE(pool2.GetMem() != nullptr); 163 auto pool3 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 164 ASSERT_TRUE(pool3.GetMem() == nullptr); 165 memPool->FreePool(pool1.GetMem(), pool1.GetSize()); 166 memPool->FreePool(pool2.GetMem(), pool2.GetSize()); 167 168 auto pool4 = memPool->AllocPool(6_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 169 ASSERT_TRUE(pool4.GetMem() != nullptr); 170 auto pool5 = memPool->AllocPool(1_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 171 ASSERT_TRUE(pool5.GetMem() != nullptr); 172 auto pool6 = memPool->AllocPool(1_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 173 ASSERT_TRUE(pool6.GetMem() != nullptr); 174 memPool->FreePool(pool6.GetMem(), pool6.GetSize()); 175 memPool->FreePool(pool4.GetMem(), pool4.GetSize()); 176 memPool->FreePool(pool5.GetMem(), pool5.GetSize()); 177 178 auto pool7 = memPool->AllocPool(8_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 179 ASSERT_TRUE(pool7.GetMem() != nullptr); 180 memPool->FreePool(pool7.GetMem(), pool7.GetSize()); 181 } 182 183 HWTEST_F(MMapMemPoolTest, CheckEnoughPoolsTest, testing::ext::TestSize.Level0) 184 { 185 static constexpr size_t POOL_SIZE = 4_MB; 186 MmapMemPool *memPool = CreateMMapMemPool(10_MB); 187 188 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 189 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(3, POOL_SIZE)); 190 auto pool1 = memPool->AllocPool(3_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 191 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(1, POOL_SIZE)); 192 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 193 auto pool2 = memPool->AllocPool(1_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 194 memPool->FreePool(pool1.GetMem(), pool1.GetSize()); 195 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(1, POOL_SIZE)); 196 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 197 memPool->FreePool(pool2.GetMem(), pool2.GetSize()); 198 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 199 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(3, POOL_SIZE)); 200 201 auto pool3 = memPool->AllocPool(4_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 202 auto pool4 = memPool->AllocPool(1_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 203 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(1, POOL_SIZE)); 204 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 205 memPool->FreePool(pool3.GetMem(), pool3.GetSize()); 206 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 207 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(3, POOL_SIZE)); 208 auto pool5 = memPool->AllocPool(5_MB, SpaceType::SPACE_TYPE_OBJECT, AllocatorType::HUMONGOUS_ALLOCATOR); 209 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(1, POOL_SIZE)); 210 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 211 memPool->FreePool(pool5.GetMem(), pool5.GetSize()); 212 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 213 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(3, POOL_SIZE)); 214 memPool->FreePool(pool4.GetMem(), pool4.GetSize()); 215 ASSERT_TRUE(memPool->HaveEnoughPoolsInObjectSpace(2, POOL_SIZE)); 216 ASSERT_FALSE(memPool->HaveEnoughPoolsInObjectSpace(3, POOL_SIZE)); 217 } 218 219 } // namespace panda 220