1 //===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Support/Memory.h"
11 #include "llvm/Support/Process.h"
12 #include "gtest/gtest.h"
20 class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
24 PageSize = sys::Process::GetPageSize();
28 // Adds RW flags to permit testing of the resulting memory
29 unsigned getTestableEquivalent(unsigned RequestedFlags) {
30 switch (RequestedFlags) {
32 case Memory::MF_WRITE:
33 case Memory::MF_READ|Memory::MF_WRITE:
34 return Memory::MF_READ|Memory::MF_WRITE;
35 case Memory::MF_READ|Memory::MF_EXEC:
36 case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
38 return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
40 // Default in case values are added to the enum, as required by some compilers
41 return Memory::MF_READ|Memory::MF_WRITE;
44 // Returns true if the memory blocks overlap
45 bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
46 if (M1.base() == M2.base())
49 if (M1.base() > M2.base())
50 return (unsigned char *)M2.base() + M2.size() > M1.base();
52 return (unsigned char *)M1.base() + M1.size() > M2.base();
59 TEST_P(MappedMemoryTest, AllocAndRelease) {
61 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
62 EXPECT_EQ(error_code::success(), EC);
64 EXPECT_NE((void*)0, M1.base());
65 EXPECT_LE(sizeof(int), M1.size());
67 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
70 TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
72 MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
73 EXPECT_EQ(error_code::success(), EC);
74 MemoryBlock M2 = Memory::allocateMappedMemory(64, 0, Flags, EC);
75 EXPECT_EQ(error_code::success(), EC);
76 MemoryBlock M3 = Memory::allocateMappedMemory(32, 0, Flags, EC);
77 EXPECT_EQ(error_code::success(), EC);
79 EXPECT_NE((void*)0, M1.base());
80 EXPECT_LE(16U, M1.size());
81 EXPECT_NE((void*)0, M2.base());
82 EXPECT_LE(64U, M2.size());
83 EXPECT_NE((void*)0, M3.base());
84 EXPECT_LE(32U, M3.size());
86 EXPECT_FALSE(doesOverlap(M1, M2));
87 EXPECT_FALSE(doesOverlap(M2, M3));
88 EXPECT_FALSE(doesOverlap(M1, M3));
90 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
91 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
92 MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
93 EXPECT_EQ(error_code::success(), EC);
94 EXPECT_NE((void*)0, M4.base());
95 EXPECT_LE(16U, M4.size());
96 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
97 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
100 TEST_P(MappedMemoryTest, BasicWrite) {
101 // This test applies only to writeable combinations
102 if (Flags && !(Flags & Memory::MF_WRITE))
106 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
107 EXPECT_EQ(error_code::success(), EC);
109 EXPECT_NE((void*)0, M1.base());
110 EXPECT_LE(sizeof(int), M1.size());
112 int *a = (int*)M1.base();
116 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
119 TEST_P(MappedMemoryTest, MultipleWrite) {
120 // This test applies only to writeable combinations
121 if (Flags && !(Flags & Memory::MF_WRITE))
124 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
125 EXPECT_EQ(error_code::success(), EC);
126 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
127 EXPECT_EQ(error_code::success(), EC);
128 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
129 EXPECT_EQ(error_code::success(), EC);
131 EXPECT_FALSE(doesOverlap(M1, M2));
132 EXPECT_FALSE(doesOverlap(M2, M3));
133 EXPECT_FALSE(doesOverlap(M1, M3));
135 EXPECT_NE((void*)0, M1.base());
136 EXPECT_LE(1U * sizeof(int), M1.size());
137 EXPECT_NE((void*)0, M2.base());
138 EXPECT_LE(8U * sizeof(int), M2.size());
139 EXPECT_NE((void*)0, M3.base());
140 EXPECT_LE(4U * sizeof(int), M3.size());
142 int *x = (int*)M1.base();
145 int *y = (int*)M2.base();
146 for (int i = 0; i < 8; i++) {
150 int *z = (int*)M3.base();
157 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
158 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
160 MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), 0, Flags, EC);
161 EXPECT_EQ(error_code::success(), EC);
162 EXPECT_NE((void*)0, M4.base());
163 EXPECT_LE(64U * sizeof(int), M4.size());
167 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
169 // Verify that M2 remains unaffected by other activity
170 for (int i = 0; i < 8; i++) {
173 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
176 TEST_P(MappedMemoryTest, EnabledWrite) {
178 MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), 0, Flags, EC);
179 EXPECT_EQ(error_code::success(), EC);
180 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
181 EXPECT_EQ(error_code::success(), EC);
182 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
183 EXPECT_EQ(error_code::success(), EC);
185 EXPECT_NE((void*)0, M1.base());
186 EXPECT_LE(2U * sizeof(int), M1.size());
187 EXPECT_NE((void*)0, M2.base());
188 EXPECT_LE(8U * sizeof(int), M2.size());
189 EXPECT_NE((void*)0, M3.base());
190 EXPECT_LE(4U * sizeof(int), M3.size());
192 EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
193 EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
194 EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
196 EXPECT_FALSE(doesOverlap(M1, M2));
197 EXPECT_FALSE(doesOverlap(M2, M3));
198 EXPECT_FALSE(doesOverlap(M1, M3));
200 int *x = (int*)M1.base();
202 int *y = (int*)M2.base();
203 for (unsigned int i = 0; i < 8; i++) {
206 int *z = (int*)M3.base();
213 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
214 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
217 MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
218 EXPECT_EQ(error_code::success(), EC);
219 EXPECT_NE((void*)0, M4.base());
220 EXPECT_LE(16U, M4.size());
221 EXPECT_EQ(error_code::success(), Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
225 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
226 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
229 TEST_P(MappedMemoryTest, SuccessiveNear) {
231 MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
232 EXPECT_EQ(error_code::success(), EC);
233 MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
234 EXPECT_EQ(error_code::success(), EC);
235 MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
236 EXPECT_EQ(error_code::success(), EC);
238 EXPECT_NE((void*)0, M1.base());
239 EXPECT_LE(16U, M1.size());
240 EXPECT_NE((void*)0, M2.base());
241 EXPECT_LE(64U, M2.size());
242 EXPECT_NE((void*)0, M3.base());
243 EXPECT_LE(32U, M3.size());
245 EXPECT_FALSE(doesOverlap(M1, M2));
246 EXPECT_FALSE(doesOverlap(M2, M3));
247 EXPECT_FALSE(doesOverlap(M1, M3));
249 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
250 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
251 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
254 TEST_P(MappedMemoryTest, DuplicateNear) {
256 MemoryBlock Near((void*)(3*PageSize), 16);
257 MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
258 EXPECT_EQ(error_code::success(), EC);
259 MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
260 EXPECT_EQ(error_code::success(), EC);
261 MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
262 EXPECT_EQ(error_code::success(), EC);
264 EXPECT_NE((void*)0, M1.base());
265 EXPECT_LE(16U, M1.size());
266 EXPECT_NE((void*)0, M2.base());
267 EXPECT_LE(64U, M2.size());
268 EXPECT_NE((void*)0, M3.base());
269 EXPECT_LE(32U, M3.size());
271 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
272 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
273 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
276 TEST_P(MappedMemoryTest, ZeroNear) {
278 MemoryBlock Near(0, 0);
279 MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
280 EXPECT_EQ(error_code::success(), EC);
281 MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
282 EXPECT_EQ(error_code::success(), EC);
283 MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
284 EXPECT_EQ(error_code::success(), EC);
286 EXPECT_NE((void*)0, M1.base());
287 EXPECT_LE(16U, M1.size());
288 EXPECT_NE((void*)0, M2.base());
289 EXPECT_LE(64U, M2.size());
290 EXPECT_NE((void*)0, M3.base());
291 EXPECT_LE(32U, M3.size());
293 EXPECT_FALSE(doesOverlap(M1, M2));
294 EXPECT_FALSE(doesOverlap(M2, M3));
295 EXPECT_FALSE(doesOverlap(M1, M3));
297 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
298 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
299 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
302 TEST_P(MappedMemoryTest, ZeroSizeNear) {
304 MemoryBlock Near((void*)(4*PageSize), 0);
305 MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
306 EXPECT_EQ(error_code::success(), EC);
307 MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
308 EXPECT_EQ(error_code::success(), EC);
309 MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
310 EXPECT_EQ(error_code::success(), EC);
312 EXPECT_NE((void*)0, M1.base());
313 EXPECT_LE(16U, M1.size());
314 EXPECT_NE((void*)0, M2.base());
315 EXPECT_LE(64U, M2.size());
316 EXPECT_NE((void*)0, M3.base());
317 EXPECT_LE(32U, M3.size());
319 EXPECT_FALSE(doesOverlap(M1, M2));
320 EXPECT_FALSE(doesOverlap(M2, M3));
321 EXPECT_FALSE(doesOverlap(M1, M3));
323 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
324 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
325 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
328 TEST_P(MappedMemoryTest, UnalignedNear) {
330 MemoryBlock Near((void*)(2*PageSize+5), 0);
331 MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
332 EXPECT_EQ(error_code::success(), EC);
334 EXPECT_NE((void*)0, M1.base());
335 EXPECT_LE(sizeof(int), M1.size());
337 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
340 // Note that Memory::MF_WRITE is not supported exclusively across
341 // operating systems and architectures and can imply MF_READ|MF_WRITE
342 unsigned MemoryFlags[] = {
345 Memory::MF_READ|Memory::MF_WRITE,
347 Memory::MF_READ|Memory::MF_EXEC,
348 Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
351 INSTANTIATE_TEST_CASE_P(AllocationTests,
353 ::testing::ValuesIn(MemoryFlags));
355 } // anonymous namespace