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::get_self()->page_size();
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(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(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);
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(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(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(error_code(), EC);
129 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
131 EXPECT_EQ(error_code(), EC);
132 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
134 EXPECT_EQ(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(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(error_code(), EC);
187 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
189 EXPECT_EQ(error_code(), EC);
190 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
192 EXPECT_EQ(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(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)));
234 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
235 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
238 TEST_P(MappedMemoryTest, SuccessiveNear) {
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);
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());
254 EXPECT_FALSE(doesOverlap(M1, M2));
255 EXPECT_FALSE(doesOverlap(M2, M3));
256 EXPECT_FALSE(doesOverlap(M1, M3));
258 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
259 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
260 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
263 TEST_P(MappedMemoryTest, DuplicateNear) {
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);
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());
280 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
281 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
282 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
285 TEST_P(MappedMemoryTest, ZeroNear) {
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);
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());
302 EXPECT_FALSE(doesOverlap(M1, M2));
303 EXPECT_FALSE(doesOverlap(M2, M3));
304 EXPECT_FALSE(doesOverlap(M1, M3));
306 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
307 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
308 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
311 TEST_P(MappedMemoryTest, ZeroSizeNear) {
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);
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());
328 EXPECT_FALSE(doesOverlap(M1, M2));
329 EXPECT_FALSE(doesOverlap(M2, M3));
330 EXPECT_FALSE(doesOverlap(M1, M3));
332 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
333 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
334 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
337 TEST_P(MappedMemoryTest, UnalignedNear) {
339 MemoryBlock Near((void*)(2*PageSize+5), 0);
340 MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
341 EXPECT_EQ(error_code(), EC);
343 EXPECT_NE((void*)nullptr, M1.base());
344 EXPECT_LE(sizeof(int), M1.size());
346 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
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[] = {
354 Memory::MF_READ|Memory::MF_WRITE,
356 Memory::MF_READ|Memory::MF_EXEC,
357 Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
360 INSTANTIATE_TEST_CASE_P(AllocationTests,
362 ::testing::ValuesIn(MemoryFlags));
364 } // anonymous namespace