Taints the non-acquire RMW's store address with the load part
[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::getPageSize();
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   std::error_code EC;
61   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
62   EXPECT_EQ(std::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   std::error_code EC;
72   MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
73   EXPECT_EQ(std::error_code(), EC);
74   MemoryBlock M2 = Memory::allocateMappedMemory(64, nullptr, Flags, EC);
75   EXPECT_EQ(std::error_code(), EC);
76   MemoryBlock M3 = Memory::allocateMappedMemory(32, nullptr, Flags, EC);
77   EXPECT_EQ(std::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(std::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   std::error_code EC;
107   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
108   EXPECT_EQ(std::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   std::error_code EC;
126   MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
127                                                 EC);
128   EXPECT_EQ(std::error_code(), EC);
129   MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
130                                                 EC);
131   EXPECT_EQ(std::error_code(), EC);
132   MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
133                                                 EC);
134   EXPECT_EQ(std::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(std::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   std::error_code EC;
184   MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
185                                                 EC);
186   EXPECT_EQ(std::error_code(), EC);
187   MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
188                                                 EC);
189   EXPECT_EQ(std::error_code(), EC);
190   MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
191                                                 EC);
192   EXPECT_EQ(std::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(std::error_code(), EC);
228   EXPECT_NE((void*)nullptr, M4.base());
229   EXPECT_LE(16U, M4.size());
230   EXPECT_EQ(std::error_code(),
231             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   std::error_code EC;
241   MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
242   EXPECT_EQ(std::error_code(), EC);
243   MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
244   EXPECT_EQ(std::error_code(), EC);
245   MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
246   EXPECT_EQ(std::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   std::error_code EC;
266   MemoryBlock Near((void*)(3*PageSize), 16);
267   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
268   EXPECT_EQ(std::error_code(), EC);
269   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
270   EXPECT_EQ(std::error_code(), EC);
271   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
272   EXPECT_EQ(std::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   std::error_code EC;
288   MemoryBlock Near(nullptr, 0);
289   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
290   EXPECT_EQ(std::error_code(), EC);
291   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
292   EXPECT_EQ(std::error_code(), EC);
293   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
294   EXPECT_EQ(std::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   std::error_code EC;
314   MemoryBlock Near((void*)(4*PageSize), 0);
315   MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
316   EXPECT_EQ(std::error_code(), EC);
317   MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
318   EXPECT_EQ(std::error_code(), EC);
319   MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
320   EXPECT_EQ(std::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   std::error_code EC;
340   MemoryBlock Near((void*)(2*PageSize+5), 0);
341   MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
342   EXPECT_EQ(std::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