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