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"
17 using std::error_code;
21 class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
25 PageSize = sys::process::get_self()->page_size();
29 // Adds RW flags to permit testing of the resulting memory
30 unsigned getTestableEquivalent(unsigned RequestedFlags) {
31 switch (RequestedFlags) {
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:
39 return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
41 // Default in case values are added to the enum, as required by some compilers
42 return Memory::MF_READ|Memory::MF_WRITE;
45 // Returns true if the memory blocks overlap
46 bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
47 if (M1.base() == M2.base())
50 if (M1.base() > M2.base())
51 return (unsigned char *)M2.base() + M2.size() > M1.base();
53 return (unsigned char *)M1.base() + M1.size() > M2.base();
60 TEST_P(MappedMemoryTest, AllocAndRelease) {
62 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
63 EXPECT_EQ(error_code(), EC);
65 EXPECT_NE((void*)nullptr, M1.base());
66 EXPECT_LE(sizeof(int), M1.size());
68 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
71 TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
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);
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());
87 EXPECT_FALSE(doesOverlap(M1, M2));
88 EXPECT_FALSE(doesOverlap(M2, M3));
89 EXPECT_FALSE(doesOverlap(M1, M3));
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));
101 TEST_P(MappedMemoryTest, BasicWrite) {
102 // This test applies only to readable and writeable combinations
104 !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
108 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
109 EXPECT_EQ(error_code(), EC);
111 EXPECT_NE((void*)nullptr, M1.base());
112 EXPECT_LE(sizeof(int), M1.size());
114 int *a = (int*)M1.base();
118 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
121 TEST_P(MappedMemoryTest, MultipleWrite) {
122 // This test applies only to readable and writeable combinations
124 !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
127 MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
129 EXPECT_EQ(error_code(), EC);
130 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
132 EXPECT_EQ(error_code(), EC);
133 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
135 EXPECT_EQ(error_code(), EC);
137 EXPECT_FALSE(doesOverlap(M1, M2));
138 EXPECT_FALSE(doesOverlap(M2, M3));
139 EXPECT_FALSE(doesOverlap(M1, M3));
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());
148 int *x = (int*)M1.base();
151 int *y = (int*)M2.base();
152 for (int i = 0; i < 8; i++) {
156 int *z = (int*)M3.base();
163 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
164 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
166 MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
168 EXPECT_EQ(error_code(), EC);
169 EXPECT_NE((void*)nullptr, M4.base());
170 EXPECT_LE(64U * sizeof(int), M4.size());
174 EXPECT_FALSE(Memory::releaseMappedMemory(M4));
176 // Verify that M2 remains unaffected by other activity
177 for (int i = 0; i < 8; i++) {
180 EXPECT_FALSE(Memory::releaseMappedMemory(M2));
183 TEST_P(MappedMemoryTest, EnabledWrite) {
185 MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
187 EXPECT_EQ(error_code(), EC);
188 MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
190 EXPECT_EQ(error_code(), EC);
191 MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
193 EXPECT_EQ(error_code(), EC);
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());
202 EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
203 EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
204 EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
206 EXPECT_FALSE(doesOverlap(M1, M2));
207 EXPECT_FALSE(doesOverlap(M2, M3));
208 EXPECT_FALSE(doesOverlap(M1, M3));
210 int *x = (int*)M1.base();
212 int *y = (int*)M2.base();
213 for (unsigned int i = 0; i < 8; i++) {
216 int *z = (int*)M3.base();
223 EXPECT_FALSE(Memory::releaseMappedMemory(M1));
224 EXPECT_FALSE(Memory::releaseMappedMemory(M3));
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)));
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(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);
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(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);
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(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);
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(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);
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(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