MemoryPool.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "il2cpp-config.h"
  2. #include "utils/MemoryPool.h"
  3. #include "utils/Memory.h"
  4. #include <algorithm>
  5. #include <limits>
  6. namespace il2cpp
  7. {
  8. namespace utils
  9. {
  10. const size_t kPageSize = IL2CPP_PAGE_SIZE;
  11. const size_t kDefaultRegionSize = 64 * 1024;
  12. // by making all allocations a multiple of this value, we ensure the next
  13. // allocation will always be aligned to this value
  14. const size_t kMemoryAlignment = 8;
  15. static inline size_t MakeMultipleOf(size_t size, size_t alignment)
  16. {
  17. return (size + alignment - 1) & ~(alignment - 1);
  18. }
  19. struct MemoryPool::Region
  20. {
  21. char* start;
  22. char* current;
  23. size_t size;
  24. size_t free;
  25. };
  26. MemoryPool::MemoryPool()
  27. {
  28. AddRegion(kDefaultRegionSize);
  29. }
  30. MemoryPool::MemoryPool(size_t initialSize)
  31. {
  32. AddRegion(initialSize);
  33. }
  34. MemoryPool::~MemoryPool()
  35. {
  36. for (RegionList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter)
  37. {
  38. IL2CPP_FREE((*iter)->start);
  39. IL2CPP_FREE(*iter);
  40. }
  41. m_Regions.clear();
  42. }
  43. void* MemoryPool::Malloc(size_t size)
  44. {
  45. size = MakeMultipleOf(size, kMemoryAlignment);
  46. Region* region = m_Regions.back();
  47. if (region->free < size)
  48. region = AddRegion(size);
  49. IL2CPP_ASSERT(region->free >= size);
  50. void* value = region->current;
  51. region->current += size;
  52. region->free -= size;
  53. return value;
  54. }
  55. void* MemoryPool::Calloc(size_t count, size_t size)
  56. {
  57. void* ret = Malloc(count * size);
  58. return memset(ret, 0, count * size);
  59. }
  60. MemoryPool::Region* MemoryPool::AddRegion(size_t size)
  61. {
  62. Region* newRegion = (Region*)IL2CPP_MALLOC(sizeof(Region));
  63. Region* lastFreeRegion = m_Regions.size() > 0 ? m_Regions.back() : NULL;
  64. size_t allocationSize;
  65. if (lastFreeRegion != NULL && lastFreeRegion->free >= kPageSize)
  66. {
  67. allocationSize = MakeMultipleOf(size, kPageSize);
  68. m_Regions.pop_back();
  69. m_Regions.push_back(newRegion);
  70. m_Regions.push_back(lastFreeRegion);
  71. }
  72. else
  73. {
  74. allocationSize = std::max(kDefaultRegionSize, MakeMultipleOf(size, kPageSize));
  75. m_Regions.push_back(newRegion);
  76. }
  77. newRegion->start = newRegion->current = (char*)IL2CPP_MALLOC(allocationSize);
  78. newRegion->size = newRegion->free = allocationSize;
  79. return newRegion;
  80. }
  81. }
  82. }