• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gtest/gtest.h"
17 #include "runtime/include/runtime.h"
18 #include "runtime/include/mem/panda_containers.h"
19 #include "runtime/mem/runslots_allocator-inl.h"
20 
21 namespace panda::mem::test {
22 
23 class PandaContainersTest : public testing::Test {
24 public:
PandaContainersTest()25     PandaContainersTest()
26     {
27         RuntimeOptions options;
28         options.SetShouldLoadBootPandaFiles(false);
29         options.SetShouldInitializeIntrinsics(false);
30         options.SetLimitStandardAlloc(true);
31         options.SetInternalAllocatorType("panda_allocators");
32         Runtime::Create(options);
33         thread_ = panda::MTManagedThread::GetCurrent();
34         thread_->ManagedCodeBegin();
35     }
36 
37     template <class T>
GetLocalObjects(T * allocator)38     size_t GetLocalObjects(T *allocator)
39     {
40         size_t num_objects = 0;
41         allocator->IterateOverObjects([&num_objects]([[maybe_unused]] ObjectHeader *obj) { num_objects++; });
42         return num_objects;
43     }
44 
~PandaContainersTest()45     ~PandaContainersTest() override
46     {
47         thread_->ManagedCodeEnd();
48         Runtime::Destroy();
49     }
50 
51 protected:
52     panda::MTManagedThread *thread_;
53 };
54 
55 constexpr size_t MAX_SIZE = InternalAllocator<>::LocalSmallObjectAllocator::GetMaxSize();
TEST_F(PandaContainersTest,LocalTest)56 TEST_F(PandaContainersTest, LocalTest)
57 {
58     ASSERT(!Runtime::GetCurrent()->GetOptions().UseMallocForInternalAllocations());
59     auto local_allocator = panda::ManagedThread::GetCurrent()->GetLocalInternalAllocator();
60     ASSERT_EQ(GetLocalObjects(local_allocator), 0);
61     {
62         PandaVectorTL<uint8_t> vector_local;
63         vector_local.push_back(0);
64         // std::vector allocated memory block for it's elements via local_allocator
65         ASSERT_EQ(GetLocalObjects(local_allocator), 1);
66         for (size_t i = 1; i < MAX_SIZE; i++) {
67             vector_local.push_back(i % MAX_SIZE);
68             if (vector_local.capacity() <= MAX_SIZE) {
69                 // Threre is 1 memory block for all elements
70                 ASSERT_EQ(GetLocalObjects(local_allocator), 1);
71             } else {
72                 // When vector size exceeds MAX_SIZE=256 bytes, we allocate it without thread-local runslots allocator
73                 ASSERT_EQ(GetLocalObjects(local_allocator), 0);
74             }
75         }
76         // Simple check on data consistency
77         for (size_t i = 0; i < MAX_SIZE; i++) {
78             ASSERT_EQ(vector_local.at(i), i % MAX_SIZE);
79         }
80         vector_local.push_back(0);
81         // When vector size exceeds MAX_SIZE=256 bytes, we allocate it without thread-local runslots allocator
82         ASSERT_EQ(GetLocalObjects(local_allocator), 0);
83     }
84     ASSERT_EQ(GetLocalObjects(local_allocator), 0);
85 }
86 
87 // Check that, when we use GLOBAL scope, there is no memory in thread-local allocator
TEST_F(PandaContainersTest,GlobalTest)88 TEST_F(PandaContainersTest, GlobalTest)
89 {
90     auto local_allocator = panda::ManagedThread::GetCurrent()->GetLocalInternalAllocator();
91     ASSERT_EQ(GetLocalObjects(local_allocator), 0);
92     {
93         PandaVector<uint8_t> vector_global;
94         vector_global.push_back(0);
95         ASSERT_EQ(GetLocalObjects(local_allocator), 0);
96         for (size_t i = 1; i < MAX_SIZE; i++) {
97             vector_global.push_back(i % MAX_SIZE);
98             ASSERT_EQ(GetLocalObjects(local_allocator), 0);
99         }
100 
101         for (size_t i = 0; i < MAX_SIZE; i++) {
102             ASSERT_EQ(vector_global.at(i), i % MAX_SIZE);
103         }
104         vector_global.push_back(0);
105         ASSERT_EQ(GetLocalObjects(local_allocator), 0);
106     }
107     ASSERT_EQ(GetLocalObjects(local_allocator), 0);
108 }
109 
110 }  // namespace panda::mem::test
111