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