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