• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "base/arena_allocator.h"
18 #include "base/arena_bit_vector.h"
19 #include "gtest/gtest.h"
20 
21 namespace art {
22 
23 class ArenaAllocatorTest : public testing::Test {
24  protected:
NumberOfArenas(ArenaAllocator * arena)25   size_t NumberOfArenas(ArenaAllocator* arena) {
26     size_t result = 0u;
27     for (Arena* a = arena->arena_head_; a != nullptr; a = a->next_) {
28       ++result;
29     }
30     return result;
31   }
32 };
33 
TEST_F(ArenaAllocatorTest,Test)34 TEST_F(ArenaAllocatorTest, Test) {
35   ArenaPool pool;
36   ArenaAllocator arena(&pool);
37   ArenaBitVector bv(&arena, 10, true);
38   bv.SetBit(5);
39   EXPECT_EQ(1U, bv.GetStorageSize());
40   bv.SetBit(35);
41   EXPECT_EQ(2U, bv.GetStorageSize());
42 }
43 
TEST_F(ArenaAllocatorTest,MakeDefined)44 TEST_F(ArenaAllocatorTest, MakeDefined) {
45   // Regression test to make sure we mark the allocated area defined.
46   ArenaPool pool;
47   static constexpr size_t kSmallArraySize = 10;
48   static constexpr size_t kLargeArraySize = 50;
49   uint32_t* small_array;
50   {
51     // Allocate a small array from an arena and release it.
52     ArenaAllocator arena(&pool);
53     small_array = arena.AllocArray<uint32_t>(kSmallArraySize);
54     ASSERT_EQ(0u, small_array[kSmallArraySize - 1u]);
55   }
56   {
57     // Reuse the previous arena and allocate more than previous allocation including red zone.
58     ArenaAllocator arena(&pool);
59     uint32_t* large_array = arena.AllocArray<uint32_t>(kLargeArraySize);
60     ASSERT_EQ(0u, large_array[kLargeArraySize - 1u]);
61     // Verify that the allocation was made on the same arena.
62     ASSERT_EQ(small_array, large_array);
63   }
64 }
65 
TEST_F(ArenaAllocatorTest,LargeAllocations)66 TEST_F(ArenaAllocatorTest, LargeAllocations) {
67   {
68     ArenaPool pool;
69     ArenaAllocator arena(&pool);
70     // Note: Leaving some space for memory tool red zones.
71     void* alloc1 = arena.Alloc(Arena::kDefaultSize * 5 / 8);
72     void* alloc2 = arena.Alloc(Arena::kDefaultSize * 2 / 8);
73     ASSERT_NE(alloc1, alloc2);
74     ASSERT_EQ(1u, NumberOfArenas(&arena));
75   }
76   {
77     ArenaPool pool;
78     ArenaAllocator arena(&pool);
79     void* alloc1 = arena.Alloc(Arena::kDefaultSize * 13 / 16);
80     void* alloc2 = arena.Alloc(Arena::kDefaultSize * 11 / 16);
81     ASSERT_NE(alloc1, alloc2);
82     ASSERT_EQ(2u, NumberOfArenas(&arena));
83     void* alloc3 = arena.Alloc(Arena::kDefaultSize * 7 / 16);
84     ASSERT_NE(alloc1, alloc3);
85     ASSERT_NE(alloc2, alloc3);
86     ASSERT_EQ(3u, NumberOfArenas(&arena));
87   }
88   {
89     ArenaPool pool;
90     ArenaAllocator arena(&pool);
91     void* alloc1 = arena.Alloc(Arena::kDefaultSize * 13 / 16);
92     void* alloc2 = arena.Alloc(Arena::kDefaultSize * 9 / 16);
93     ASSERT_NE(alloc1, alloc2);
94     ASSERT_EQ(2u, NumberOfArenas(&arena));
95     // Note: Leaving some space for memory tool red zones.
96     void* alloc3 = arena.Alloc(Arena::kDefaultSize * 5 / 16);
97     ASSERT_NE(alloc1, alloc3);
98     ASSERT_NE(alloc2, alloc3);
99     ASSERT_EQ(2u, NumberOfArenas(&arena));
100   }
101   {
102     ArenaPool pool;
103     ArenaAllocator arena(&pool);
104     void* alloc1 = arena.Alloc(Arena::kDefaultSize * 9 / 16);
105     void* alloc2 = arena.Alloc(Arena::kDefaultSize * 13 / 16);
106     ASSERT_NE(alloc1, alloc2);
107     ASSERT_EQ(2u, NumberOfArenas(&arena));
108     // Note: Leaving some space for memory tool red zones.
109     void* alloc3 = arena.Alloc(Arena::kDefaultSize * 5 / 16);
110     ASSERT_NE(alloc1, alloc3);
111     ASSERT_NE(alloc2, alloc3);
112     ASSERT_EQ(2u, NumberOfArenas(&arena));
113   }
114   {
115     ArenaPool pool;
116     ArenaAllocator arena(&pool);
117     // Note: Leaving some space for memory tool red zones.
118     for (size_t i = 0; i != 15; ++i) {
119       arena.Alloc(Arena::kDefaultSize * 1 / 16);    // Allocate 15 times from the same arena.
120       ASSERT_EQ(i + 1u, NumberOfArenas(&arena));
121       arena.Alloc(Arena::kDefaultSize * 17 / 16);   // Allocate a separate arena.
122       ASSERT_EQ(i + 2u, NumberOfArenas(&arena));
123     }
124   }
125 }
126 
127 }  // namespace art
128