xref: /aosp_15_r20/art/libartbase/base/arena_allocator_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "arena_allocator-inl.h"
18*795d594fSAndroid Build Coastguard Worker #include "arena_bit_vector.h"
19*795d594fSAndroid Build Coastguard Worker #include "base/common_art_test.h"
20*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
21*795d594fSAndroid Build Coastguard Worker #include "malloc_arena_pool.h"
22*795d594fSAndroid Build Coastguard Worker #include "memory_tool.h"
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker namespace art {
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker class ArenaAllocatorTest : public testing::Test {
27*795d594fSAndroid Build Coastguard Worker  protected:
NumberOfArenas(ArenaAllocator * allocator)28*795d594fSAndroid Build Coastguard Worker   size_t NumberOfArenas(ArenaAllocator* allocator) {
29*795d594fSAndroid Build Coastguard Worker     size_t result = 0u;
30*795d594fSAndroid Build Coastguard Worker     for (Arena* a = allocator->arena_head_; a != nullptr; a = a->next_) {
31*795d594fSAndroid Build Coastguard Worker       ++result;
32*795d594fSAndroid Build Coastguard Worker     }
33*795d594fSAndroid Build Coastguard Worker     return result;
34*795d594fSAndroid Build Coastguard Worker   }
35*795d594fSAndroid Build Coastguard Worker };
36*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArenaAllocatorTest,Test)37*795d594fSAndroid Build Coastguard Worker TEST_F(ArenaAllocatorTest, Test) {
38*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
39*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
40*795d594fSAndroid Build Coastguard Worker   ArenaBitVector bv(&allocator, 10, true);
41*795d594fSAndroid Build Coastguard Worker   bv.SetBit(5);
42*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, bv.GetStorageSize());
43*795d594fSAndroid Build Coastguard Worker   bv.SetBit(35);
44*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, bv.GetStorageSize());
45*795d594fSAndroid Build Coastguard Worker }
46*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArenaAllocatorTest,MakeDefined)47*795d594fSAndroid Build Coastguard Worker TEST_F(ArenaAllocatorTest, MakeDefined) {
48*795d594fSAndroid Build Coastguard Worker   // Regression test to make sure we mark the allocated area defined.
49*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
50*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kSmallArraySize = 10;
51*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kLargeArraySize = 50;
52*795d594fSAndroid Build Coastguard Worker   uint32_t* small_array;
53*795d594fSAndroid Build Coastguard Worker   {
54*795d594fSAndroid Build Coastguard Worker     // Allocate a small array from an arena and release it.
55*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
56*795d594fSAndroid Build Coastguard Worker     small_array = allocator.AllocArray<uint32_t>(kSmallArraySize);
57*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0u, small_array[kSmallArraySize - 1u]);
58*795d594fSAndroid Build Coastguard Worker   }
59*795d594fSAndroid Build Coastguard Worker   {
60*795d594fSAndroid Build Coastguard Worker     // Reuse the previous arena and allocate more than previous allocation including red zone.
61*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
62*795d594fSAndroid Build Coastguard Worker     uint32_t* large_array = allocator.AllocArray<uint32_t>(kLargeArraySize);
63*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0u, large_array[kLargeArraySize - 1u]);
64*795d594fSAndroid Build Coastguard Worker     // Verify that the allocation was made on the same arena.
65*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(small_array, large_array);
66*795d594fSAndroid Build Coastguard Worker   }
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArenaAllocatorTest,LargeAllocations)69*795d594fSAndroid Build Coastguard Worker TEST_F(ArenaAllocatorTest, LargeAllocations) {
70*795d594fSAndroid Build Coastguard Worker   if (arena_allocator::kArenaAllocatorPreciseTracking) {
71*795d594fSAndroid Build Coastguard Worker     printf("WARNING: TEST DISABLED FOR precise arena tracking\n");
72*795d594fSAndroid Build Coastguard Worker     return;
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker 
75*795d594fSAndroid Build Coastguard Worker   {
76*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
77*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
78*795d594fSAndroid Build Coastguard Worker     // Note: Leaving some space for memory tool red zones.
79*795d594fSAndroid Build Coastguard Worker     void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 5 / 8);
80*795d594fSAndroid Build Coastguard Worker     void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 2 / 8);
81*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc1, alloc2);
82*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(1u, NumberOfArenas(&allocator));
83*795d594fSAndroid Build Coastguard Worker   }
84*795d594fSAndroid Build Coastguard Worker   {
85*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
86*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
87*795d594fSAndroid Build Coastguard Worker     void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 13 / 16);
88*795d594fSAndroid Build Coastguard Worker     void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 11 / 16);
89*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc1, alloc2);
90*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, NumberOfArenas(&allocator));
91*795d594fSAndroid Build Coastguard Worker     void* alloc3 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 7 / 16);
92*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc1, alloc3);
93*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc2, alloc3);
94*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, NumberOfArenas(&allocator));
95*795d594fSAndroid Build Coastguard Worker   }
96*795d594fSAndroid Build Coastguard Worker   {
97*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
98*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
99*795d594fSAndroid Build Coastguard Worker     void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 13 / 16);
100*795d594fSAndroid Build Coastguard Worker     void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 9 / 16);
101*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc1, alloc2);
102*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, NumberOfArenas(&allocator));
103*795d594fSAndroid Build Coastguard Worker     // Note: Leaving some space for memory tool red zones.
104*795d594fSAndroid Build Coastguard Worker     void* alloc3 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 5 / 16);
105*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc1, alloc3);
106*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc2, alloc3);
107*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, NumberOfArenas(&allocator));
108*795d594fSAndroid Build Coastguard Worker   }
109*795d594fSAndroid Build Coastguard Worker   {
110*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
111*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
112*795d594fSAndroid Build Coastguard Worker     void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 9 / 16);
113*795d594fSAndroid Build Coastguard Worker     void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 13 / 16);
114*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc1, alloc2);
115*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, NumberOfArenas(&allocator));
116*795d594fSAndroid Build Coastguard Worker     // Note: Leaving some space for memory tool red zones.
117*795d594fSAndroid Build Coastguard Worker     void* alloc3 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 5 / 16);
118*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc1, alloc3);
119*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(alloc2, alloc3);
120*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, NumberOfArenas(&allocator));
121*795d594fSAndroid Build Coastguard Worker   }
122*795d594fSAndroid Build Coastguard Worker   {
123*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
124*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
125*795d594fSAndroid Build Coastguard Worker     // Note: Leaving some space for memory tool red zones.
126*795d594fSAndroid Build Coastguard Worker     for (size_t i = 0; i != 15; ++i) {
127*795d594fSAndroid Build Coastguard Worker       // Allocate 15 times from the same arena.
128*795d594fSAndroid Build Coastguard Worker       allocator.Alloc(arena_allocator::kArenaDefaultSize * 1 / 16);
129*795d594fSAndroid Build Coastguard Worker       ASSERT_EQ(i + 1u, NumberOfArenas(&allocator));
130*795d594fSAndroid Build Coastguard Worker       // Allocate a separate arena.
131*795d594fSAndroid Build Coastguard Worker       allocator.Alloc(arena_allocator::kArenaDefaultSize * 17 / 16);
132*795d594fSAndroid Build Coastguard Worker       ASSERT_EQ(i + 2u, NumberOfArenas(&allocator));
133*795d594fSAndroid Build Coastguard Worker     }
134*795d594fSAndroid Build Coastguard Worker   }
135*795d594fSAndroid Build Coastguard Worker }
136*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArenaAllocatorTest,AllocAlignment)137*795d594fSAndroid Build Coastguard Worker TEST_F(ArenaAllocatorTest, AllocAlignment) {
138*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
139*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator(&pool);
140*795d594fSAndroid Build Coastguard Worker   for (size_t iterations = 0; iterations <= 10; ++iterations) {
141*795d594fSAndroid Build Coastguard Worker     for (size_t size = 1; size <= ArenaAllocator::kAlignment + 1; ++size) {
142*795d594fSAndroid Build Coastguard Worker       void* allocation = allocator.Alloc(size);
143*795d594fSAndroid Build Coastguard Worker       EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(allocation))
144*795d594fSAndroid Build Coastguard Worker           << reinterpret_cast<uintptr_t>(allocation);
145*795d594fSAndroid Build Coastguard Worker     }
146*795d594fSAndroid Build Coastguard Worker   }
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArenaAllocatorTest,ReallocReuse)149*795d594fSAndroid Build Coastguard Worker TEST_F(ArenaAllocatorTest, ReallocReuse) {
150*795d594fSAndroid Build Coastguard Worker   // Realloc does not reuse arenas when running under sanitization.
151*795d594fSAndroid Build Coastguard Worker   TEST_DISABLED_FOR_MEMORY_TOOL();
152*795d594fSAndroid Build Coastguard Worker 
153*795d594fSAndroid Build Coastguard Worker   {
154*795d594fSAndroid Build Coastguard Worker     // Case 1: small aligned allocation, aligned extend inside arena.
155*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
156*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2;
159*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
160*795d594fSAndroid Build Coastguard Worker 
161*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 3;
162*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
163*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(original_allocation, realloc_allocation);
164*795d594fSAndroid Build Coastguard Worker   }
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker   {
167*795d594fSAndroid Build Coastguard Worker     // Case 2: small aligned allocation, non-aligned extend inside arena.
168*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
169*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2;
172*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2);
175*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
176*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(original_allocation, realloc_allocation);
177*795d594fSAndroid Build Coastguard Worker   }
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker   {
180*795d594fSAndroid Build Coastguard Worker     // Case 3: small non-aligned allocation, aligned extend inside arena.
181*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
182*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2);
185*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 4;
188*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
189*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(original_allocation, realloc_allocation);
190*795d594fSAndroid Build Coastguard Worker   }
191*795d594fSAndroid Build Coastguard Worker 
192*795d594fSAndroid Build Coastguard Worker   {
193*795d594fSAndroid Build Coastguard Worker     // Case 4: small non-aligned allocation, aligned non-extend inside arena.
194*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
195*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
196*795d594fSAndroid Build Coastguard Worker 
197*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2);
198*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 3;
201*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
202*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(original_allocation, realloc_allocation);
203*795d594fSAndroid Build Coastguard Worker   }
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker   // The next part is brittle, as the default size for an arena is variable, and we don't know about
206*795d594fSAndroid Build Coastguard Worker   // sanitization.
207*795d594fSAndroid Build Coastguard Worker 
208*795d594fSAndroid Build Coastguard Worker   {
209*795d594fSAndroid Build Coastguard Worker     // Case 5: large allocation, aligned extend into next arena.
210*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
211*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker     const size_t original_size = arena_allocator::kArenaDefaultSize -
214*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment * 5;
215*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker     const size_t new_size = arena_allocator::kArenaDefaultSize + ArenaAllocator::kAlignment * 2;
218*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
219*795d594fSAndroid Build Coastguard Worker     EXPECT_NE(original_allocation, realloc_allocation);
220*795d594fSAndroid Build Coastguard Worker   }
221*795d594fSAndroid Build Coastguard Worker 
222*795d594fSAndroid Build Coastguard Worker   {
223*795d594fSAndroid Build Coastguard Worker     // Case 6: large allocation, non-aligned extend into next arena.
224*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
225*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker     const size_t original_size = arena_allocator::kArenaDefaultSize -
228*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment * 4 -
229*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment / 2;
230*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker     const size_t new_size = arena_allocator::kArenaDefaultSize +
233*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment * 2 +
234*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment / 2;
235*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
236*795d594fSAndroid Build Coastguard Worker     EXPECT_NE(original_allocation, realloc_allocation);
237*795d594fSAndroid Build Coastguard Worker   }
238*795d594fSAndroid Build Coastguard Worker }
239*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArenaAllocatorTest,ReallocAlignment)240*795d594fSAndroid Build Coastguard Worker TEST_F(ArenaAllocatorTest, ReallocAlignment) {
241*795d594fSAndroid Build Coastguard Worker   {
242*795d594fSAndroid Build Coastguard Worker     // Case 1: small aligned allocation, aligned extend inside arena.
243*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
244*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2;
247*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
248*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(IsAligned<ArenaAllocator::kAlignment>(original_allocation));
249*795d594fSAndroid Build Coastguard Worker 
250*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 3;
251*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
252*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(realloc_allocation));
253*795d594fSAndroid Build Coastguard Worker 
254*795d594fSAndroid Build Coastguard Worker     void* after_alloc = allocator.Alloc(1);
255*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(after_alloc));
256*795d594fSAndroid Build Coastguard Worker   }
257*795d594fSAndroid Build Coastguard Worker 
258*795d594fSAndroid Build Coastguard Worker   {
259*795d594fSAndroid Build Coastguard Worker     // Case 2: small aligned allocation, non-aligned extend inside arena.
260*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
261*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2;
264*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
265*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(IsAligned<ArenaAllocator::kAlignment>(original_allocation));
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2);
268*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
269*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(realloc_allocation));
270*795d594fSAndroid Build Coastguard Worker 
271*795d594fSAndroid Build Coastguard Worker     void* after_alloc = allocator.Alloc(1);
272*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(after_alloc));
273*795d594fSAndroid Build Coastguard Worker   }
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker   {
276*795d594fSAndroid Build Coastguard Worker     // Case 3: small non-aligned allocation, aligned extend inside arena.
277*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
278*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2);
281*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
282*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(IsAligned<ArenaAllocator::kAlignment>(original_allocation));
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 4;
285*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
286*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(realloc_allocation));
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker     void* after_alloc = allocator.Alloc(1);
289*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(after_alloc));
290*795d594fSAndroid Build Coastguard Worker   }
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker   {
293*795d594fSAndroid Build Coastguard Worker     // Case 4: small non-aligned allocation, aligned non-extend inside arena.
294*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
295*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker     const size_t original_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2);
298*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
299*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(IsAligned<ArenaAllocator::kAlignment>(original_allocation));
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker     const size_t new_size = ArenaAllocator::kAlignment * 3;
302*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
303*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(realloc_allocation));
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker     void* after_alloc = allocator.Alloc(1);
306*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(after_alloc));
307*795d594fSAndroid Build Coastguard Worker   }
308*795d594fSAndroid Build Coastguard Worker 
309*795d594fSAndroid Build Coastguard Worker   // The next part is brittle, as the default size for an arena is variable, and we don't know about
310*795d594fSAndroid Build Coastguard Worker   // sanitization.
311*795d594fSAndroid Build Coastguard Worker 
312*795d594fSAndroid Build Coastguard Worker   {
313*795d594fSAndroid Build Coastguard Worker     // Case 5: large allocation, aligned extend into next arena.
314*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
315*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker     const size_t original_size = arena_allocator::kArenaDefaultSize -
318*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment * 5;
319*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
320*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(IsAligned<ArenaAllocator::kAlignment>(original_allocation));
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker     const size_t new_size = arena_allocator::kArenaDefaultSize + ArenaAllocator::kAlignment * 2;
323*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
324*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(realloc_allocation));
325*795d594fSAndroid Build Coastguard Worker 
326*795d594fSAndroid Build Coastguard Worker     void* after_alloc = allocator.Alloc(1);
327*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(after_alloc));
328*795d594fSAndroid Build Coastguard Worker   }
329*795d594fSAndroid Build Coastguard Worker 
330*795d594fSAndroid Build Coastguard Worker   {
331*795d594fSAndroid Build Coastguard Worker     // Case 6: large allocation, non-aligned extend into next arena.
332*795d594fSAndroid Build Coastguard Worker     MallocArenaPool pool;
333*795d594fSAndroid Build Coastguard Worker     ArenaAllocator allocator(&pool);
334*795d594fSAndroid Build Coastguard Worker 
335*795d594fSAndroid Build Coastguard Worker     const size_t original_size = arena_allocator::kArenaDefaultSize -
336*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment * 4 -
337*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment / 2;
338*795d594fSAndroid Build Coastguard Worker     void* original_allocation = allocator.Alloc(original_size);
339*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(IsAligned<ArenaAllocator::kAlignment>(original_allocation));
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker     const size_t new_size = arena_allocator::kArenaDefaultSize +
342*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment * 2 +
343*795d594fSAndroid Build Coastguard Worker         ArenaAllocator::kAlignment / 2;
344*795d594fSAndroid Build Coastguard Worker     void* realloc_allocation = allocator.Realloc(original_allocation, original_size, new_size);
345*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(realloc_allocation));
346*795d594fSAndroid Build Coastguard Worker 
347*795d594fSAndroid Build Coastguard Worker     void* after_alloc = allocator.Alloc(1);
348*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsAligned<ArenaAllocator::kAlignment>(after_alloc));
349*795d594fSAndroid Build Coastguard Worker   }
350*795d594fSAndroid Build Coastguard Worker }
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker 
353*795d594fSAndroid Build Coastguard Worker }  // namespace art
354