MemoryTest.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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. #include "llvm/Support/Memory.h"
  10. #include "llvm/Support/Process.h"
  11. #include "gtest/gtest.h"
  12. #include <cstdlib>
  13. using namespace llvm;
  14. using namespace sys;
  15. namespace {
  16. class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
  17. public:
  18. MappedMemoryTest() {
  19. Flags = GetParam();
  20. PageSize = sys::Process::getPageSize();
  21. }
  22. protected:
  23. // Adds RW flags to permit testing of the resulting memory
  24. unsigned getTestableEquivalent(unsigned RequestedFlags) {
  25. switch (RequestedFlags) {
  26. case Memory::MF_READ:
  27. case Memory::MF_WRITE:
  28. case Memory::MF_READ|Memory::MF_WRITE:
  29. return Memory::MF_READ|Memory::MF_WRITE;
  30. case Memory::MF_READ|Memory::MF_EXEC:
  31. case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
  32. case Memory::MF_EXEC:
  33. return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
  34. }
  35. // Default in case values are added to the enum, as required by some compilers
  36. return Memory::MF_READ|Memory::MF_WRITE;
  37. }
  38. // Returns true if the memory blocks overlap
  39. bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
  40. if (M1.base() == M2.base())
  41. return true;
  42. if (M1.base() > M2.base())
  43. return (unsigned char *)M2.base() + M2.size() > M1.base();
  44. return (unsigned char *)M1.base() + M1.size() > M2.base();
  45. }
  46. unsigned Flags;
  47. size_t PageSize;
  48. };
  49. TEST_P(MappedMemoryTest, AllocAndRelease) {
  50. std::error_code EC;
  51. MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
  52. EXPECT_EQ(std::error_code(), EC);
  53. EXPECT_NE((void*)nullptr, M1.base());
  54. EXPECT_LE(sizeof(int), M1.size());
  55. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  56. }
  57. TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
  58. std::error_code EC;
  59. MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  60. EXPECT_EQ(std::error_code(), EC);
  61. MemoryBlock M2 = Memory::allocateMappedMemory(64, nullptr, Flags, EC);
  62. EXPECT_EQ(std::error_code(), EC);
  63. MemoryBlock M3 = Memory::allocateMappedMemory(32, nullptr, Flags, EC);
  64. EXPECT_EQ(std::error_code(), EC);
  65. EXPECT_NE((void*)nullptr, M1.base());
  66. EXPECT_LE(16U, M1.size());
  67. EXPECT_NE((void*)nullptr, M2.base());
  68. EXPECT_LE(64U, M2.size());
  69. EXPECT_NE((void*)nullptr, M3.base());
  70. EXPECT_LE(32U, M3.size());
  71. EXPECT_FALSE(doesOverlap(M1, M2));
  72. EXPECT_FALSE(doesOverlap(M2, M3));
  73. EXPECT_FALSE(doesOverlap(M1, M3));
  74. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  75. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  76. MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  77. EXPECT_EQ(std::error_code(), EC);
  78. EXPECT_NE((void*)nullptr, M4.base());
  79. EXPECT_LE(16U, M4.size());
  80. EXPECT_FALSE(Memory::releaseMappedMemory(M4));
  81. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  82. }
  83. TEST_P(MappedMemoryTest, BasicWrite) {
  84. // This test applies only to readable and writeable combinations
  85. if (Flags &&
  86. !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
  87. return;
  88. std::error_code EC;
  89. MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
  90. EXPECT_EQ(std::error_code(), EC);
  91. EXPECT_NE((void*)nullptr, M1.base());
  92. EXPECT_LE(sizeof(int), M1.size());
  93. int *a = (int*)M1.base();
  94. *a = 1;
  95. EXPECT_EQ(1, *a);
  96. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  97. }
  98. TEST_P(MappedMemoryTest, MultipleWrite) {
  99. // This test applies only to readable and writeable combinations
  100. if (Flags &&
  101. !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
  102. return;
  103. std::error_code EC;
  104. MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
  105. EC);
  106. EXPECT_EQ(std::error_code(), EC);
  107. MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
  108. EC);
  109. EXPECT_EQ(std::error_code(), EC);
  110. MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
  111. EC);
  112. EXPECT_EQ(std::error_code(), EC);
  113. EXPECT_FALSE(doesOverlap(M1, M2));
  114. EXPECT_FALSE(doesOverlap(M2, M3));
  115. EXPECT_FALSE(doesOverlap(M1, M3));
  116. EXPECT_NE((void*)nullptr, M1.base());
  117. EXPECT_LE(1U * sizeof(int), M1.size());
  118. EXPECT_NE((void*)nullptr, M2.base());
  119. EXPECT_LE(8U * sizeof(int), M2.size());
  120. EXPECT_NE((void*)nullptr, M3.base());
  121. EXPECT_LE(4U * sizeof(int), M3.size());
  122. int *x = (int*)M1.base();
  123. *x = 1;
  124. int *y = (int*)M2.base();
  125. for (int i = 0; i < 8; i++) {
  126. y[i] = i;
  127. }
  128. int *z = (int*)M3.base();
  129. *z = 42;
  130. EXPECT_EQ(1, *x);
  131. EXPECT_EQ(7, y[7]);
  132. EXPECT_EQ(42, *z);
  133. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  134. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  135. MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
  136. Flags, EC);
  137. EXPECT_EQ(std::error_code(), EC);
  138. EXPECT_NE((void*)nullptr, M4.base());
  139. EXPECT_LE(64U * sizeof(int), M4.size());
  140. x = (int*)M4.base();
  141. *x = 4;
  142. EXPECT_EQ(4, *x);
  143. EXPECT_FALSE(Memory::releaseMappedMemory(M4));
  144. // Verify that M2 remains unaffected by other activity
  145. for (int i = 0; i < 8; i++) {
  146. EXPECT_EQ(i, y[i]);
  147. }
  148. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  149. }
  150. TEST_P(MappedMemoryTest, EnabledWrite) {
  151. std::error_code EC;
  152. MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
  153. EC);
  154. EXPECT_EQ(std::error_code(), EC);
  155. MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
  156. EC);
  157. EXPECT_EQ(std::error_code(), EC);
  158. MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
  159. EC);
  160. EXPECT_EQ(std::error_code(), EC);
  161. EXPECT_NE((void*)nullptr, M1.base());
  162. EXPECT_LE(2U * sizeof(int), M1.size());
  163. EXPECT_NE((void*)nullptr, M2.base());
  164. EXPECT_LE(8U * sizeof(int), M2.size());
  165. EXPECT_NE((void*)nullptr, M3.base());
  166. EXPECT_LE(4U * sizeof(int), M3.size());
  167. EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
  168. EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
  169. EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
  170. EXPECT_FALSE(doesOverlap(M1, M2));
  171. EXPECT_FALSE(doesOverlap(M2, M3));
  172. EXPECT_FALSE(doesOverlap(M1, M3));
  173. int *x = (int*)M1.base();
  174. *x = 1;
  175. int *y = (int*)M2.base();
  176. for (unsigned int i = 0; i < 8; i++) {
  177. y[i] = i;
  178. }
  179. int *z = (int*)M3.base();
  180. *z = 42;
  181. EXPECT_EQ(1, *x);
  182. EXPECT_EQ(7, y[7]);
  183. EXPECT_EQ(42, *z);
  184. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  185. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  186. EXPECT_EQ(6, y[6]);
  187. MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  188. EXPECT_EQ(std::error_code(), EC);
  189. EXPECT_NE((void*)nullptr, M4.base());
  190. EXPECT_LE(16U, M4.size());
  191. EXPECT_EQ(std::error_code(),
  192. Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
  193. x = (int*)M4.base();
  194. *x = 4;
  195. EXPECT_EQ(4, *x);
  196. EXPECT_FALSE(Memory::releaseMappedMemory(M4));
  197. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  198. }
  199. TEST_P(MappedMemoryTest, SuccessiveNear) {
  200. std::error_code EC;
  201. MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
  202. EXPECT_EQ(std::error_code(), EC);
  203. MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
  204. EXPECT_EQ(std::error_code(), EC);
  205. MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
  206. EXPECT_EQ(std::error_code(), EC);
  207. EXPECT_NE((void*)nullptr, M1.base());
  208. EXPECT_LE(16U, M1.size());
  209. EXPECT_NE((void*)nullptr, M2.base());
  210. EXPECT_LE(64U, M2.size());
  211. EXPECT_NE((void*)nullptr, M3.base());
  212. EXPECT_LE(32U, M3.size());
  213. EXPECT_FALSE(doesOverlap(M1, M2));
  214. EXPECT_FALSE(doesOverlap(M2, M3));
  215. EXPECT_FALSE(doesOverlap(M1, M3));
  216. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  217. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  218. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  219. }
  220. TEST_P(MappedMemoryTest, DuplicateNear) {
  221. std::error_code EC;
  222. MemoryBlock Near((void*)(3*PageSize), 16);
  223. MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  224. EXPECT_EQ(std::error_code(), EC);
  225. MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  226. EXPECT_EQ(std::error_code(), EC);
  227. MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  228. EXPECT_EQ(std::error_code(), EC);
  229. EXPECT_NE((void*)nullptr, M1.base());
  230. EXPECT_LE(16U, M1.size());
  231. EXPECT_NE((void*)nullptr, M2.base());
  232. EXPECT_LE(64U, M2.size());
  233. EXPECT_NE((void*)nullptr, M3.base());
  234. EXPECT_LE(32U, M3.size());
  235. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  236. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  237. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  238. }
  239. TEST_P(MappedMemoryTest, ZeroNear) {
  240. std::error_code EC;
  241. MemoryBlock Near(nullptr, 0);
  242. MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  243. EXPECT_EQ(std::error_code(), EC);
  244. MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  245. EXPECT_EQ(std::error_code(), EC);
  246. MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  247. 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());
  254. EXPECT_FALSE(doesOverlap(M1, M2));
  255. EXPECT_FALSE(doesOverlap(M2, M3));
  256. EXPECT_FALSE(doesOverlap(M1, M3));
  257. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  258. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  259. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  260. }
  261. TEST_P(MappedMemoryTest, ZeroSizeNear) {
  262. std::error_code EC;
  263. MemoryBlock Near((void*)(4*PageSize), 0);
  264. MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  265. EXPECT_EQ(std::error_code(), EC);
  266. MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  267. EXPECT_EQ(std::error_code(), EC);
  268. MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  269. EXPECT_EQ(std::error_code(), EC);
  270. EXPECT_NE((void*)nullptr, M1.base());
  271. EXPECT_LE(16U, M1.size());
  272. EXPECT_NE((void*)nullptr, M2.base());
  273. EXPECT_LE(64U, M2.size());
  274. EXPECT_NE((void*)nullptr, M3.base());
  275. EXPECT_LE(32U, M3.size());
  276. EXPECT_FALSE(doesOverlap(M1, M2));
  277. EXPECT_FALSE(doesOverlap(M2, M3));
  278. EXPECT_FALSE(doesOverlap(M1, M3));
  279. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  280. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  281. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  282. }
  283. TEST_P(MappedMemoryTest, UnalignedNear) {
  284. std::error_code EC;
  285. MemoryBlock Near((void*)(2*PageSize+5), 0);
  286. MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
  287. EXPECT_EQ(std::error_code(), EC);
  288. EXPECT_NE((void*)nullptr, M1.base());
  289. EXPECT_LE(sizeof(int), M1.size());
  290. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  291. }
  292. // Note that Memory::MF_WRITE is not supported exclusively across
  293. // operating systems and architectures and can imply MF_READ|MF_WRITE
  294. unsigned MemoryFlags[] = {
  295. Memory::MF_READ,
  296. Memory::MF_WRITE,
  297. Memory::MF_READ|Memory::MF_WRITE,
  298. Memory::MF_EXEC,
  299. Memory::MF_READ|Memory::MF_EXEC,
  300. Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
  301. };
  302. INSTANTIATE_TEST_CASE_P(AllocationTests,
  303. MappedMemoryTest,
  304. ::testing::ValuesIn(MemoryFlags));
  305. } // anonymous namespace