Home | History | Annotate | Download | only in Support
      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
    366