Don't use 'using std::error_code' in include/llvm.
[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 using std::error_code;
18
19 namespace {
20
21 class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
22 public:
23   MappedMemoryTest() {
24     Flags = GetParam();
25     PageSize = sys::process::get_self()->page_size();
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), nullptr, Flags,EC);
63   EXPECT_EQ(error_code(), EC);
64
65   EXPECT_NE((void*)nullptr, 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, nullptr, Flags, EC);
74   EXPECT_EQ(error_code(), EC);
75   MemoryBlock M2 = Memory::allocateMappedMemory(64, nullptr, Flags, EC);
76   EXPECT_EQ(error_code(), EC);
77   MemoryBlock M3 = Memory::allocateMappedMemory(32, nullptr, Flags, EC);
78   EXPECT_EQ(error_code(), EC);
79
80   EXPECT_NE((void*)nullptr, M1.base());
81   EXPECT_LE(16U, M1.size());
82   EXPECT_NE((void*)nullptr, M2.base());
83   EXPECT_LE(64U, M2.size());
84   EXPECT_NE((void*)nullptr, 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, nullptr, Flags, EC);
94   EXPECT_EQ(error_code(), EC);
95   EXPECT_NE((void*)nullptr, 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 readable and writeable combinations
103   if (Flags &&
104       !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
105     return;
106
107   error_code EC;
108   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
109   EXPECT_EQ(error_code(), EC);
110
111   EXPECT_NE((void*)nullptr, M1.base());
112   EXPECT_LE(sizeof(int), M1.size());
113
114   int *a = (int*)M1.base();
115   *a = 1;
116   EXPECT_EQ(1, *a);
117
118   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
119 }
120
121 TEST_P(MappedMemoryTest, MultipleWrite) {
122   // This test applies only to readable and writeable combinations
123   if (Flags &&
124       !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
125     return;
126   error_code EC;
127   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
128                                                 EC);
129   EXPECT_EQ(error_code(), EC);
130   MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
131                                                 EC);
132   EXPECT_EQ(error_code(), EC);
133   MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
134                                                 EC);
135   EXPECT_EQ(error_code(), EC);
136
137   EXPECT_FALSE(doesOverlap(M1, M2));
138   EXPECT_FALSE(doesOverlap(M2, M3));
139   EXPECT_FALSE(doesOverlap(M1, M3));
140
141   EXPECT_NE((void*)nullptr, M1.base());
142   EXPECT_LE(1U * sizeof(int), M1.size());
143   EXPECT_NE((void*)nullptr, M2.base());
144   EXPECT_LE(8U * sizeof(int), M2.size());
145   EXPECT_NE((void*)nullptr, M3.base());
146   EXPECT_LE(4U * sizeof(int), M3.size());
147
148   int *x = (int*)M1.base();
149   *x = 1;
150
151   int *y = (int*)M2.base();
152   for (int i = 0; i < 8; i++) {
153     y[i] = i;
154   }
155
156   int *z = (int*)M3.base();
157   *z = 42;
158
159   EXPECT_EQ(1, *x);
160   EXPECT_EQ(7, y[7]);
161   EXPECT_EQ(42, *z);
162
163   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
164   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
165
166   MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
167                                                 Flags, EC);
168   EXPECT_EQ(error_code(), EC);
169   EXPECT_NE((void*)nullptr, M4.base());
170   EXPECT_LE(64U * sizeof(int), M4.size());
171   x = (int*)M4.base();
172   *x = 4;
173   EXPECT_EQ(4, *x);
174   EXPECT_FALSE(Memory::releaseMappedMemory(M4));
175
176   // Verify that M2 remains unaffected by other activity
177   for (int i = 0; i < 8; i++) {
178     EXPECT_EQ(i, y[i]);
179   }
180   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
181 }
182
183 TEST_P(MappedMemoryTest, EnabledWrite) {
184   error_code EC;
185   MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
186                                                 EC);
187   EXPECT_EQ(error_code(), EC);
188   MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
189                                                 EC);
190   EXPECT_EQ(error_code(), EC);
191   MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
192                                                 EC);
193   EXPECT_EQ(error_code(), EC);
194
195   EXPECT_NE((void*)nullptr, M1.base());
196   EXPECT_LE(2U * sizeof(int), M1.size());
197   EXPECT_NE((void*)nullptr, M2.base());
198   EXPECT_LE(8U * sizeof(int), M2.size());
199   EXPECT_NE((void*)nullptr, M3.base());
200   EXPECT_LE(4U * sizeof(int), M3.size());
201
202   EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
203   EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
204   EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
205
206   EXPECT_FALSE(doesOverlap(M1, M2));
207   EXPECT_FALSE(doesOverlap(M2, M3));
208   EXPECT_FALSE(doesOverlap(M1, M3));
209
210   int *x = (int*)M1.base();
211   *x = 1;
212   int *y = (int*)M2.base();
213   for (unsigned int i = 0; i < 8; i++) {
214     y[i] = i;
215   }
216   int *z = (int*)M3.base();
217   *z = 42;
218
219   EXPECT_EQ(1, *x);
220   EXPECT_EQ(7, y[7]);
221   EXPECT_EQ(42, *z);
222
223   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
224   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
225   EXPECT_EQ(6, y[6]);
226
227   MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
228   EXPECT_EQ(error_code(), EC);
229   EXPECT_NE((void*)nullptr, M4.base());
230   EXPECT_LE(16U, M4.size());
231   EXPECT_EQ(error_code(), Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
232   x = (int*)M4.base();
233   *x = 4;
234   EXPECT_EQ(4, *x);
235   EXPECT_FALSE(Memory::releaseMappedMemory(M4));
236   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
237 }
238
239 TEST_P(MappedMemoryTest, SuccessiveNear) {
240   error_code EC;
241   MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
242   EXPECT_EQ(error_code(), EC);
243   MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
244   EXPECT_EQ(error_code(), EC);
245   MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
246   EXPECT_EQ(error_code(), EC);
247
248   EXPECT_NE((void*)nullptr, M1.base());
249   EXPECT_LE(16U, M1.size());
250   EXPECT_NE((void*)nullptr, M2.base());
251   EXPECT_LE(64U, M2.size());
252   EXPECT_NE((void*)nullptr, M3.base());
253   EXPECT_LE(32U, M3.size());
254
255   EXPECT_FALSE(doesOverlap(M1, M2));
256   EXPECT_FALSE(doesOverlap(M2, M3));
257   EXPECT_FALSE(doesOverlap(M1, M3));
258
259   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
260   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
261   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
262 }
263
264 TEST_P(MappedMemoryTest, DuplicateNear) {
265   error_code EC;
266   MemoryBlock Near((void*)(3*PageSize), 16);
267   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
268   EXPECT_EQ(error_code(), EC);
269   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
270   EXPECT_EQ(error_code(), EC);
271   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
272   EXPECT_EQ(error_code(), EC);
273
274   EXPECT_NE((void*)nullptr, M1.base());
275   EXPECT_LE(16U, M1.size());
276   EXPECT_NE((void*)nullptr, M2.base());
277   EXPECT_LE(64U, M2.size());
278   EXPECT_NE((void*)nullptr, M3.base());
279   EXPECT_LE(32U, M3.size());
280
281   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
282   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
283   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
284 }
285
286 TEST_P(MappedMemoryTest, ZeroNear) {
287   error_code EC;
288   MemoryBlock Near(nullptr, 0);
289   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
290   EXPECT_EQ(error_code(), EC);
291   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
292   EXPECT_EQ(error_code(), EC);
293   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
294   EXPECT_EQ(error_code(), EC);
295
296   EXPECT_NE((void*)nullptr, M1.base());
297   EXPECT_LE(16U, M1.size());
298   EXPECT_NE((void*)nullptr, M2.base());
299   EXPECT_LE(64U, M2.size());
300   EXPECT_NE((void*)nullptr, M3.base());
301   EXPECT_LE(32U, M3.size());
302
303   EXPECT_FALSE(doesOverlap(M1, M2));
304   EXPECT_FALSE(doesOverlap(M2, M3));
305   EXPECT_FALSE(doesOverlap(M1, M3));
306
307   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
308   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
309   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
310 }
311
312 TEST_P(MappedMemoryTest, ZeroSizeNear) {
313   error_code EC;
314   MemoryBlock Near((void*)(4*PageSize), 0);
315   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
316   EXPECT_EQ(error_code(), EC);
317   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
318   EXPECT_EQ(error_code(), EC);
319   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
320   EXPECT_EQ(error_code(), EC);
321
322   EXPECT_NE((void*)nullptr, M1.base());
323   EXPECT_LE(16U, M1.size());
324   EXPECT_NE((void*)nullptr, M2.base());
325   EXPECT_LE(64U, M2.size());
326   EXPECT_NE((void*)nullptr, M3.base());
327   EXPECT_LE(32U, M3.size());
328
329   EXPECT_FALSE(doesOverlap(M1, M2));
330   EXPECT_FALSE(doesOverlap(M2, M3));
331   EXPECT_FALSE(doesOverlap(M1, M3));
332
333   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
334   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
335   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
336 }
337
338 TEST_P(MappedMemoryTest, UnalignedNear) {
339   error_code EC;
340   MemoryBlock Near((void*)(2*PageSize+5), 0);
341   MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
342   EXPECT_EQ(error_code(), EC);
343
344   EXPECT_NE((void*)nullptr, M1.base());
345   EXPECT_LE(sizeof(int), M1.size());
346
347   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
348 }
349
350 // Note that Memory::MF_WRITE is not supported exclusively across
351 // operating systems and architectures and can imply MF_READ|MF_WRITE
352 unsigned MemoryFlags[] = {
353                            Memory::MF_READ,
354                            Memory::MF_WRITE,
355                            Memory::MF_READ|Memory::MF_WRITE,
356                            Memory::MF_EXEC,
357                            Memory::MF_READ|Memory::MF_EXEC,
358                            Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
359                          };
360
361 INSTANTIATE_TEST_CASE_P(AllocationTests,
362                         MappedMemoryTest,
363                         ::testing::ValuesIn(MemoryFlags));
364
365 }  // anonymous namespace