1 //===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Support/Memory.h"
11 #include "llvm/Support/Process.h"
12 #include "gtest/gtest.h"
20 class MappedMemoryTest
: public ::testing::TestWithParam
<unsigned> {
24 PageSize
= sys::Process::getPageSize();
28 // Adds RW flags to permit testing of the resulting memory
29 unsigned getTestableEquivalent(unsigned RequestedFlags
) {
30 switch (RequestedFlags
) {
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
:
38 return Memory::MF_READ
|Memory::MF_WRITE
|Memory::MF_EXEC
;
40 // Default in case values are added to the enum, as required by some compilers
41 return Memory::MF_READ
|Memory::MF_WRITE
;
44 // Returns true if the memory blocks overlap
45 bool doesOverlap(MemoryBlock M1
, MemoryBlock M2
) {
46 if (M1
.base() == M2
.base())
49 if (M1
.base() > M2
.base())
50 return (unsigned char *)M2
.base() + M2
.size() > M1
.base();
52 return (unsigned char *)M1
.base() + M1
.size() > M2
.base();
59 TEST_P(MappedMemoryTest
, AllocAndRelease
) {
61 MemoryBlock M1
= Memory::allocateMappedMemory(sizeof(int), nullptr, Flags
,EC
);
62 EXPECT_EQ(std::error_code(), EC
);
64 EXPECT_NE((void*)nullptr, M1
.base());
65 EXPECT_LE(sizeof(int), M1
.size());
67 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
70 TEST_P(MappedMemoryTest
, MultipleAllocAndRelease
) {
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
);
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());
86 EXPECT_FALSE(doesOverlap(M1
, M2
));
87 EXPECT_FALSE(doesOverlap(M2
, M3
));
88 EXPECT_FALSE(doesOverlap(M1
, M3
));
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
));
100 TEST_P(MappedMemoryTest
, BasicWrite
) {
101 // This test applies only to readable and writeable combinations
103 !((Flags
& Memory::MF_READ
) && (Flags
& Memory::MF_WRITE
)))
107 MemoryBlock M1
= Memory::allocateMappedMemory(sizeof(int), nullptr, Flags
,EC
);
108 EXPECT_EQ(std::error_code(), EC
);
110 EXPECT_NE((void*)nullptr, M1
.base());
111 EXPECT_LE(sizeof(int), M1
.size());
113 int *a
= (int*)M1
.base();
117 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
120 TEST_P(MappedMemoryTest
, MultipleWrite
) {
121 // This test applies only to readable and writeable combinations
123 !((Flags
& Memory::MF_READ
) && (Flags
& Memory::MF_WRITE
)))
126 MemoryBlock M1
= Memory::allocateMappedMemory(sizeof(int), nullptr, Flags
,
128 EXPECT_EQ(std::error_code(), EC
);
129 MemoryBlock M2
= Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags
,
131 EXPECT_EQ(std::error_code(), EC
);
132 MemoryBlock M3
= Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags
,
134 EXPECT_EQ(std::error_code(), EC
);
136 EXPECT_FALSE(doesOverlap(M1
, M2
));
137 EXPECT_FALSE(doesOverlap(M2
, M3
));
138 EXPECT_FALSE(doesOverlap(M1
, M3
));
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());
147 int *x
= (int*)M1
.base();
150 int *y
= (int*)M2
.base();
151 for (int i
= 0; i
< 8; i
++) {
155 int *z
= (int*)M3
.base();
162 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
163 EXPECT_FALSE(Memory::releaseMappedMemory(M3
));
165 MemoryBlock M4
= Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
167 EXPECT_EQ(std::error_code(), EC
);
168 EXPECT_NE((void*)nullptr, M4
.base());
169 EXPECT_LE(64U * sizeof(int), M4
.size());
173 EXPECT_FALSE(Memory::releaseMappedMemory(M4
));
175 // Verify that M2 remains unaffected by other activity
176 for (int i
= 0; i
< 8; i
++) {
179 EXPECT_FALSE(Memory::releaseMappedMemory(M2
));
182 TEST_P(MappedMemoryTest
, EnabledWrite
) {
184 MemoryBlock M1
= Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags
,
186 EXPECT_EQ(std::error_code(), EC
);
187 MemoryBlock M2
= Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags
,
189 EXPECT_EQ(std::error_code(), EC
);
190 MemoryBlock M3
= Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags
,
192 EXPECT_EQ(std::error_code(), EC
);
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());
201 EXPECT_FALSE(Memory::protectMappedMemory(M1
, getTestableEquivalent(Flags
)));
202 EXPECT_FALSE(Memory::protectMappedMemory(M2
, getTestableEquivalent(Flags
)));
203 EXPECT_FALSE(Memory::protectMappedMemory(M3
, getTestableEquivalent(Flags
)));
205 EXPECT_FALSE(doesOverlap(M1
, M2
));
206 EXPECT_FALSE(doesOverlap(M2
, M3
));
207 EXPECT_FALSE(doesOverlap(M1
, M3
));
209 int *x
= (int*)M1
.base();
211 int *y
= (int*)M2
.base();
212 for (unsigned int i
= 0; i
< 8; i
++) {
215 int *z
= (int*)M3
.base();
222 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
223 EXPECT_FALSE(Memory::releaseMappedMemory(M3
));
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
)));
235 EXPECT_FALSE(Memory::releaseMappedMemory(M4
));
236 EXPECT_FALSE(Memory::releaseMappedMemory(M2
));
239 TEST_P(MappedMemoryTest
, SuccessiveNear
) {
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
);
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());
255 EXPECT_FALSE(doesOverlap(M1
, M2
));
256 EXPECT_FALSE(doesOverlap(M2
, M3
));
257 EXPECT_FALSE(doesOverlap(M1
, M3
));
259 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
260 EXPECT_FALSE(Memory::releaseMappedMemory(M3
));
261 EXPECT_FALSE(Memory::releaseMappedMemory(M2
));
264 TEST_P(MappedMemoryTest
, DuplicateNear
) {
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
);
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());
281 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
282 EXPECT_FALSE(Memory::releaseMappedMemory(M3
));
283 EXPECT_FALSE(Memory::releaseMappedMemory(M2
));
286 TEST_P(MappedMemoryTest
, ZeroNear
) {
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
);
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());
303 EXPECT_FALSE(doesOverlap(M1
, M2
));
304 EXPECT_FALSE(doesOverlap(M2
, M3
));
305 EXPECT_FALSE(doesOverlap(M1
, M3
));
307 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
308 EXPECT_FALSE(Memory::releaseMappedMemory(M3
));
309 EXPECT_FALSE(Memory::releaseMappedMemory(M2
));
312 TEST_P(MappedMemoryTest
, ZeroSizeNear
) {
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
);
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());
329 EXPECT_FALSE(doesOverlap(M1
, M2
));
330 EXPECT_FALSE(doesOverlap(M2
, M3
));
331 EXPECT_FALSE(doesOverlap(M1
, M3
));
333 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
334 EXPECT_FALSE(Memory::releaseMappedMemory(M3
));
335 EXPECT_FALSE(Memory::releaseMappedMemory(M2
));
338 TEST_P(MappedMemoryTest
, UnalignedNear
) {
340 MemoryBlock
Near((void*)(2*PageSize
+5), 0);
341 MemoryBlock M1
= Memory::allocateMappedMemory(15, &Near
, Flags
, EC
);
342 EXPECT_EQ(std::error_code(), EC
);
344 EXPECT_NE((void*)nullptr, M1
.base());
345 EXPECT_LE(sizeof(int), M1
.size());
347 EXPECT_FALSE(Memory::releaseMappedMemory(M1
));
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
[] = {
355 Memory::MF_READ
|Memory::MF_WRITE
,
357 Memory::MF_READ
|Memory::MF_EXEC
,
358 Memory::MF_READ
|Memory::MF_WRITE
|Memory::MF_EXEC
361 INSTANTIATE_TEST_CASE_P(AllocationTests
,
363 ::testing::ValuesIn(MemoryFlags
),);
365 } // anonymous namespace