MemoryTest.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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. error_code EC;
  51. MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
  52. EXPECT_EQ(error_code::success(), EC);
  53. EXPECT_NE((void*)0, M1.base());
  54. EXPECT_LE(sizeof(int), M1.size());
  55. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  56. }
  57. TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
  58. error_code EC;
  59. MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
  60. EXPECT_EQ(error_code::success(), EC);
  61. MemoryBlock M2 = Memory::allocateMappedMemory(64, 0, Flags, EC);
  62. EXPECT_EQ(error_code::success(), EC);
  63. MemoryBlock M3 = Memory::allocateMappedMemory(32, 0, Flags, EC);
  64. EXPECT_EQ(error_code::success(), EC);
  65. EXPECT_NE((void*)0, M1.base());
  66. EXPECT_LE(16U, M1.size());
  67. EXPECT_NE((void*)0, M2.base());
  68. EXPECT_LE(64U, M2.size());
  69. EXPECT_NE((void*)0, 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, 0, Flags, EC);
  77. EXPECT_EQ(error_code::success(), EC);
  78. EXPECT_NE((void*)0, 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 writeable combinations
  85. if (Flags && !(Flags & Memory::MF_WRITE))
  86. return;
  87. error_code EC;
  88. MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
  89. EXPECT_EQ(error_code::success(), EC);
  90. EXPECT_NE((void*)0, M1.base());
  91. EXPECT_LE(sizeof(int), M1.size());
  92. int *a = (int*)M1.base();
  93. *a = 1;
  94. EXPECT_EQ(1, *a);
  95. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  96. }
  97. TEST_P(MappedMemoryTest, MultipleWrite) {
  98. // This test applies only to writeable combinations
  99. if (Flags && !(Flags & Memory::MF_WRITE))
  100. return;
  101. error_code EC;
  102. MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
  103. EXPECT_EQ(error_code::success(), EC);
  104. MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
  105. EXPECT_EQ(error_code::success(), EC);
  106. MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
  107. EXPECT_EQ(error_code::success(), EC);
  108. EXPECT_FALSE(doesOverlap(M1, M2));
  109. EXPECT_FALSE(doesOverlap(M2, M3));
  110. EXPECT_FALSE(doesOverlap(M1, M3));
  111. EXPECT_NE((void*)0, M1.base());
  112. EXPECT_LE(1U * sizeof(int), M1.size());
  113. EXPECT_NE((void*)0, M2.base());
  114. EXPECT_LE(8U * sizeof(int), M2.size());
  115. EXPECT_NE((void*)0, M3.base());
  116. EXPECT_LE(4U * sizeof(int), M3.size());
  117. int *x = (int*)M1.base();
  118. *x = 1;
  119. int *y = (int*)M2.base();
  120. for (int i = 0; i < 8; i++) {
  121. y[i] = i;
  122. }
  123. int *z = (int*)M3.base();
  124. *z = 42;
  125. EXPECT_EQ(1, *x);
  126. EXPECT_EQ(7, y[7]);
  127. EXPECT_EQ(42, *z);
  128. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  129. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  130. MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), 0, Flags, EC);
  131. EXPECT_EQ(error_code::success(), EC);
  132. EXPECT_NE((void*)0, M4.base());
  133. EXPECT_LE(64U * sizeof(int), M4.size());
  134. x = (int*)M4.base();
  135. *x = 4;
  136. EXPECT_EQ(4, *x);
  137. EXPECT_FALSE(Memory::releaseMappedMemory(M4));
  138. // Verify that M2 remains unaffected by other activity
  139. for (int i = 0; i < 8; i++) {
  140. EXPECT_EQ(i, y[i]);
  141. }
  142. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  143. }
  144. TEST_P(MappedMemoryTest, EnabledWrite) {
  145. error_code EC;
  146. MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), 0, Flags, EC);
  147. EXPECT_EQ(error_code::success(), EC);
  148. MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
  149. EXPECT_EQ(error_code::success(), EC);
  150. MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
  151. EXPECT_EQ(error_code::success(), EC);
  152. EXPECT_NE((void*)0, M1.base());
  153. EXPECT_LE(2U * sizeof(int), M1.size());
  154. EXPECT_NE((void*)0, M2.base());
  155. EXPECT_LE(8U * sizeof(int), M2.size());
  156. EXPECT_NE((void*)0, M3.base());
  157. EXPECT_LE(4U * sizeof(int), M3.size());
  158. EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
  159. EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
  160. EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
  161. EXPECT_FALSE(doesOverlap(M1, M2));
  162. EXPECT_FALSE(doesOverlap(M2, M3));
  163. EXPECT_FALSE(doesOverlap(M1, M3));
  164. int *x = (int*)M1.base();
  165. *x = 1;
  166. int *y = (int*)M2.base();
  167. for (unsigned int i = 0; i < 8; i++) {
  168. y[i] = i;
  169. }
  170. int *z = (int*)M3.base();
  171. *z = 42;
  172. EXPECT_EQ(1, *x);
  173. EXPECT_EQ(7, y[7]);
  174. EXPECT_EQ(42, *z);
  175. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  176. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  177. EXPECT_EQ(6, y[6]);
  178. MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
  179. EXPECT_EQ(error_code::success(), EC);
  180. EXPECT_NE((void*)0, M4.base());
  181. EXPECT_LE(16U, M4.size());
  182. EXPECT_EQ(error_code::success(), Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
  183. x = (int*)M4.base();
  184. *x = 4;
  185. EXPECT_EQ(4, *x);
  186. EXPECT_FALSE(Memory::releaseMappedMemory(M4));
  187. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  188. }
  189. TEST_P(MappedMemoryTest, SuccessiveNear) {
  190. error_code EC;
  191. MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
  192. EXPECT_EQ(error_code::success(), EC);
  193. MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
  194. EXPECT_EQ(error_code::success(), EC);
  195. MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
  196. EXPECT_EQ(error_code::success(), EC);
  197. EXPECT_NE((void*)0, M1.base());
  198. EXPECT_LE(16U, M1.size());
  199. EXPECT_NE((void*)0, M2.base());
  200. EXPECT_LE(64U, M2.size());
  201. EXPECT_NE((void*)0, M3.base());
  202. EXPECT_LE(32U, M3.size());
  203. EXPECT_FALSE(doesOverlap(M1, M2));
  204. EXPECT_FALSE(doesOverlap(M2, M3));
  205. EXPECT_FALSE(doesOverlap(M1, M3));
  206. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  207. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  208. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  209. }
  210. TEST_P(MappedMemoryTest, DuplicateNear) {
  211. error_code EC;
  212. MemoryBlock Near((void*)(3*PageSize), 16);
  213. MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  214. EXPECT_EQ(error_code::success(), EC);
  215. MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  216. EXPECT_EQ(error_code::success(), EC);
  217. MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  218. EXPECT_EQ(error_code::success(), EC);
  219. EXPECT_NE((void*)0, M1.base());
  220. EXPECT_LE(16U, M1.size());
  221. EXPECT_NE((void*)0, M2.base());
  222. EXPECT_LE(64U, M2.size());
  223. EXPECT_NE((void*)0, M3.base());
  224. EXPECT_LE(32U, M3.size());
  225. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  226. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  227. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  228. }
  229. TEST_P(MappedMemoryTest, ZeroNear) {
  230. error_code EC;
  231. MemoryBlock Near(0, 0);
  232. MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  233. EXPECT_EQ(error_code::success(), EC);
  234. MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  235. EXPECT_EQ(error_code::success(), EC);
  236. MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  237. EXPECT_EQ(error_code::success(), EC);
  238. EXPECT_NE((void*)0, M1.base());
  239. EXPECT_LE(16U, M1.size());
  240. EXPECT_NE((void*)0, M2.base());
  241. EXPECT_LE(64U, M2.size());
  242. EXPECT_NE((void*)0, M3.base());
  243. EXPECT_LE(32U, M3.size());
  244. EXPECT_FALSE(doesOverlap(M1, M2));
  245. EXPECT_FALSE(doesOverlap(M2, M3));
  246. EXPECT_FALSE(doesOverlap(M1, M3));
  247. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  248. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  249. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  250. }
  251. TEST_P(MappedMemoryTest, ZeroSizeNear) {
  252. error_code EC;
  253. MemoryBlock Near((void*)(4*PageSize), 0);
  254. MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
  255. EXPECT_EQ(error_code::success(), EC);
  256. MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
  257. EXPECT_EQ(error_code::success(), EC);
  258. MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
  259. EXPECT_EQ(error_code::success(), EC);
  260. EXPECT_NE((void*)0, M1.base());
  261. EXPECT_LE(16U, M1.size());
  262. EXPECT_NE((void*)0, M2.base());
  263. EXPECT_LE(64U, M2.size());
  264. EXPECT_NE((void*)0, M3.base());
  265. EXPECT_LE(32U, M3.size());
  266. EXPECT_FALSE(doesOverlap(M1, M2));
  267. EXPECT_FALSE(doesOverlap(M2, M3));
  268. EXPECT_FALSE(doesOverlap(M1, M3));
  269. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  270. EXPECT_FALSE(Memory::releaseMappedMemory(M3));
  271. EXPECT_FALSE(Memory::releaseMappedMemory(M2));
  272. }
  273. TEST_P(MappedMemoryTest, UnalignedNear) {
  274. error_code EC;
  275. MemoryBlock Near((void*)(2*PageSize+5), 0);
  276. MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
  277. EXPECT_EQ(error_code::success(), EC);
  278. EXPECT_NE((void*)0, M1.base());
  279. EXPECT_LE(sizeof(int), M1.size());
  280. EXPECT_FALSE(Memory::releaseMappedMemory(M1));
  281. }
  282. // Note that Memory::MF_WRITE is not supported exclusively across
  283. // operating systems and architectures and can imply MF_READ|MF_WRITE
  284. unsigned MemoryFlags[] = {
  285. Memory::MF_READ,
  286. Memory::MF_WRITE,
  287. Memory::MF_READ|Memory::MF_WRITE,
  288. Memory::MF_EXEC,
  289. Memory::MF_READ|Memory::MF_EXEC,
  290. Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
  291. };
  292. INSTANTIATE_TEST_CASE_P(AllocationTests,
  293. MappedMemoryTest,
  294. ::testing::ValuesIn(MemoryFlags));
  295. } // anonymous namespace