1 //===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/Support/Memory.h"
11 #include "llvm/Support/Process.h"
12 
13 #include "gtest/gtest.h"
14 #include <cstdlib>
15 
16 using namespace llvm;
17 using namespace sys;
18 
19 namespace {
20 
21 class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
22 public:
23   MappedMemoryTest() {
24     Flags = GetParam();
25     PageSize = sys::Process::GetPageSize();
26   }
27 
28 protected:
29   // Adds RW flags to permit testing of the resulting memory
30   unsigned getTestableEquivalent(unsigned RequestedFlags) {
31     switch (RequestedFlags) {
32     case Memory::MF_READ:
33     case Memory::MF_WRITE:
34     case Memory::MF_READ|Memory::MF_WRITE:
35       return Memory::MF_READ|Memory::MF_WRITE;
36     case Memory::MF_READ|Memory::MF_EXEC:
37     case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
38     case Memory::MF_EXEC:
39       return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
40     }
41     // Default in case values are added to the enum, as required by some compilers
42     return Memory::MF_READ|Memory::MF_WRITE;
43   }
44 
45   // Returns true if the memory blocks overlap
46   bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
47     if (M1.base() == M2.base())
48       return true;
49 
50     if (M1.base() > M2.base())
51       return (unsigned char *)M2.base() + M2.size() > M1.base();
52 
53     return (unsigned char *)M1.base() + M1.size() > M2.base();
54   }
55 
56   unsigned Flags;
57   size_t   PageSize;
58 };
59 
60 TEST_P(MappedMemoryTest, AllocAndRelease) {
61   error_code EC;
62   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
63   EXPECT_EQ(error_code::success(), EC);
64 
65   EXPECT_NE((void*)0, M1.base());
66   EXPECT_LE(sizeof(int), M1.size());
67 
68   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
69 }
70 
71 TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
72   error_code EC;
73   MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
74   EXPECT_EQ(error_code::success(), EC);
75   MemoryBlock M2 = Memory::allocateMappedMemory(64, 0, Flags, EC);
76   EXPECT_EQ(error_code::success(), EC);
77   MemoryBlock M3 = Memory::allocateMappedMemory(32, 0, Flags, EC);
78   EXPECT_EQ(error_code::success(), EC);
79 
80   EXPECT_NE((void*)0, M1.base());
81   EXPECT_LE(16U, M1.size());
82   EXPECT_NE((void*)0, M2.base());
83   EXPECT_LE(64U, M2.size());
84   EXPECT_NE((void*)0, M3.base());
85   EXPECT_LE(32U, M3.size());
86 
87   EXPECT_FALSE(doesOverlap(M1, M2));
88   EXPECT_FALSE(doesOverlap(M2, M3));
89   EXPECT_FALSE(doesOverlap(M1, M3));
90 
91   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
92   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
93   MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
94   EXPECT_EQ(error_code::success(), EC);
95   EXPECT_NE((void*)0, M4.base());
96   EXPECT_LE(16U, M4.size());
97   EXPECT_FALSE(Memory::releaseMappedMemory(M4));
98   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
99 }
100 
101 TEST_P(MappedMemoryTest, BasicWrite) {
102   // This test applies only to writeable combinations
103   if (Flags && !(Flags & Memory::MF_WRITE))
104     return;
105 
106   error_code EC;
107   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
108   EXPECT_EQ(error_code::success(), EC);
109 
110   EXPECT_NE((void*)0, M1.base());
111   EXPECT_LE(sizeof(int), M1.size());
112 
113   int *a = (int*)M1.base();
114   *a = 1;
115   EXPECT_EQ(1, *a);
116 
117   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
118 }
119 
120 TEST_P(MappedMemoryTest, MultipleWrite) {
121   // This test applies only to writeable combinations
122   if (Flags && !(Flags & Memory::MF_WRITE))
123     return;
124   error_code EC;
125   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
126   EXPECT_EQ(error_code::success(), EC);
127   MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
128   EXPECT_EQ(error_code::success(), EC);
129   MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
130   EXPECT_EQ(error_code::success(), EC);
131 
132   EXPECT_FALSE(doesOverlap(M1, M2));
133   EXPECT_FALSE(doesOverlap(M2, M3));
134   EXPECT_FALSE(doesOverlap(M1, M3));
135 
136   EXPECT_NE((void*)0, M1.base());
137   EXPECT_LE(1U * sizeof(int), M1.size());
138   EXPECT_NE((void*)0, M2.base());
139   EXPECT_LE(8U * sizeof(int), M2.size());
140   EXPECT_NE((void*)0, M3.base());
141   EXPECT_LE(4U * sizeof(int), M3.size());
142 
143   int *x = (int*)M1.base();
144   *x = 1;
145 
146   int *y = (int*)M2.base();
147   for (int i = 0; i < 8; i++) {
148     y[i] = i;
149   }
150 
151   int *z = (int*)M3.base();
152   *z = 42;
153 
154   EXPECT_EQ(1, *x);
155   EXPECT_EQ(7, y[7]);
156   EXPECT_EQ(42, *z);
157 
158   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
159   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
160 
161   MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), 0, Flags, EC);
162   EXPECT_EQ(error_code::success(), EC);
163   EXPECT_NE((void*)0, M4.base());
164   EXPECT_LE(64U * sizeof(int), M4.size());
165   x = (int*)M4.base();
166   *x = 4;
167   EXPECT_EQ(4, *x);
168   EXPECT_FALSE(Memory::releaseMappedMemory(M4));
169 
170   // Verify that M2 remains unaffected by other activity
171   for (int i = 0; i < 8; i++) {
172     EXPECT_EQ(i, y[i]);
173   }
174   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
175 }
176 
177 TEST_P(MappedMemoryTest, EnabledWrite) {
178   error_code EC;
179   MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), 0, Flags, EC);
180   EXPECT_EQ(error_code::success(), EC);
181   MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
182   EXPECT_EQ(error_code::success(), EC);
183   MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
184   EXPECT_EQ(error_code::success(), EC);
185 
186   EXPECT_NE((void*)0, M1.base());
187   EXPECT_LE(2U * sizeof(int), M1.size());
188   EXPECT_NE((void*)0, M2.base());
189   EXPECT_LE(8U * sizeof(int), M2.size());
190   EXPECT_NE((void*)0, M3.base());
191   EXPECT_LE(4U * sizeof(int), M3.size());
192 
193   EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
194   EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
195   EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
196 
197   EXPECT_FALSE(doesOverlap(M1, M2));
198   EXPECT_FALSE(doesOverlap(M2, M3));
199   EXPECT_FALSE(doesOverlap(M1, M3));
200 
201   int *x = (int*)M1.base();
202   *x = 1;
203   int *y = (int*)M2.base();
204   for (unsigned int i = 0; i < 8; i++) {
205     y[i] = i;
206   }
207   int *z = (int*)M3.base();
208   *z = 42;
209 
210   EXPECT_EQ(1, *x);
211   EXPECT_EQ(7, y[7]);
212   EXPECT_EQ(42, *z);
213 
214   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
215   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
216   EXPECT_EQ(6, y[6]);
217 
218   MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
219   EXPECT_EQ(error_code::success(), EC);
220   EXPECT_NE((void*)0, M4.base());
221   EXPECT_LE(16U, M4.size());
222   EXPECT_EQ(error_code::success(), Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
223   x = (int*)M4.base();
224   *x = 4;
225   EXPECT_EQ(4, *x);
226   EXPECT_FALSE(Memory::releaseMappedMemory(M4));
227   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
228 }
229 
230 TEST_P(MappedMemoryTest, SuccessiveNear) {
231   error_code EC;
232   MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
233   EXPECT_EQ(error_code::success(), EC);
234   MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
235   EXPECT_EQ(error_code::success(), EC);
236   MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
237   EXPECT_EQ(error_code::success(), EC);
238 
239   EXPECT_NE((void*)0, M1.base());
240   EXPECT_LE(16U, M1.size());
241   EXPECT_NE((void*)0, M2.base());
242   EXPECT_LE(64U, M2.size());
243   EXPECT_NE((void*)0, M3.base());
244   EXPECT_LE(32U, M3.size());
245 
246   EXPECT_FALSE(doesOverlap(M1, M2));
247   EXPECT_FALSE(doesOverlap(M2, M3));
248   EXPECT_FALSE(doesOverlap(M1, M3));
249 
250   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
251   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
252   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
253 }
254 
255 TEST_P(MappedMemoryTest, DuplicateNear) {
256   error_code EC;
257   MemoryBlock Near((void*)(3*PageSize), 16);
258   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
259   EXPECT_EQ(error_code::success(), EC);
260   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
261   EXPECT_EQ(error_code::success(), EC);
262   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
263   EXPECT_EQ(error_code::success(), EC);
264 
265   EXPECT_NE((void*)0, M1.base());
266   EXPECT_LE(16U, M1.size());
267   EXPECT_NE((void*)0, M2.base());
268   EXPECT_LE(64U, M2.size());
269   EXPECT_NE((void*)0, M3.base());
270   EXPECT_LE(32U, M3.size());
271 
272   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
273   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
274   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
275 }
276 
277 TEST_P(MappedMemoryTest, ZeroNear) {
278   error_code EC;
279   MemoryBlock Near(0, 0);
280   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
281   EXPECT_EQ(error_code::success(), EC);
282   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
283   EXPECT_EQ(error_code::success(), EC);
284   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
285   EXPECT_EQ(error_code::success(), EC);
286 
287   EXPECT_NE((void*)0, M1.base());
288   EXPECT_LE(16U, M1.size());
289   EXPECT_NE((void*)0, M2.base());
290   EXPECT_LE(64U, M2.size());
291   EXPECT_NE((void*)0, M3.base());
292   EXPECT_LE(32U, M3.size());
293 
294   EXPECT_FALSE(doesOverlap(M1, M2));
295   EXPECT_FALSE(doesOverlap(M2, M3));
296   EXPECT_FALSE(doesOverlap(M1, M3));
297 
298   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
299   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
300   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
301 }
302 
303 TEST_P(MappedMemoryTest, ZeroSizeNear) {
304   error_code EC;
305   MemoryBlock Near((void*)(4*PageSize), 0);
306   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
307   EXPECT_EQ(error_code::success(), EC);
308   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
309   EXPECT_EQ(error_code::success(), EC);
310   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
311   EXPECT_EQ(error_code::success(), EC);
312 
313   EXPECT_NE((void*)0, M1.base());
314   EXPECT_LE(16U, M1.size());
315   EXPECT_NE((void*)0, M2.base());
316   EXPECT_LE(64U, M2.size());
317   EXPECT_NE((void*)0, M3.base());
318   EXPECT_LE(32U, M3.size());
319 
320   EXPECT_FALSE(doesOverlap(M1, M2));
321   EXPECT_FALSE(doesOverlap(M2, M3));
322   EXPECT_FALSE(doesOverlap(M1, M3));
323 
324   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
325   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
326   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
327 }
328 
329 TEST_P(MappedMemoryTest, UnalignedNear) {
330   error_code EC;
331   MemoryBlock Near((void*)(2*PageSize+5), 0);
332   MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
333   EXPECT_EQ(error_code::success(), EC);
334 
335   EXPECT_NE((void*)0, M1.base());
336   EXPECT_LE(sizeof(int), M1.size());
337 
338   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
339 }
340 
341 // Note that Memory::MF_WRITE is not supported exclusively across
342 // operating systems and architectures and can imply MF_READ|MF_WRITE
343 unsigned MemoryFlags[] = {
344                            Memory::MF_READ,
345                            Memory::MF_WRITE,
346                            Memory::MF_READ|Memory::MF_WRITE,
347                            Memory::MF_EXEC,
348                            Memory::MF_READ|Memory::MF_EXEC,
349                            Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
350                          };
351 
352 INSTANTIATE_TEST_CASE_P(AllocationTests,
353                         MappedMemoryTest,
354                         ::testing::ValuesIn(MemoryFlags));
355 
356 }  // anonymous namespace
357