MarshalAlloc.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "il2cpp-config.h"
  2. #include "MarshalAlloc.h"
  3. #include "os/MarshalAlloc.h"
  4. #include "os/ThreadLocalValue.h"
  5. #include "vm/Exception.h"
  6. #include <deque>
  7. #include "Baselib.h"
  8. #include "Cpp/ReentrantLock.h"
  9. namespace il2cpp
  10. {
  11. namespace vm
  12. {
  13. #if _DEBUG
  14. static os::ThreadLocalValue s_Allocations;
  15. static baselib::ReentrantLock s_AllocationStorageMutex;
  16. static std::deque<std::vector<std::map<void*, size_t> > > s_AllocationStorage;
  17. static std::vector<std::map<void*, size_t> >& GetAllocationsForCurrentThread()
  18. {
  19. std::vector<std::map<void*, size_t> >* ptr = NULL;
  20. s_Allocations.GetValue(reinterpret_cast<void**>(&ptr));
  21. if (ptr == NULL)
  22. {
  23. os::FastAutoLock lock(&s_AllocationStorageMutex);
  24. s_AllocationStorage.push_back(std::vector<std::map<void*, size_t> >());
  25. ptr = &s_AllocationStorage.back();
  26. s_Allocations.SetValue(ptr);
  27. }
  28. return *ptr;
  29. }
  30. static std::map<void*, size_t>* GetAllocationsForCurrentFrame()
  31. {
  32. std::vector<std::map<void*, size_t> >& currentThreadAllocations = GetAllocationsForCurrentThread();
  33. if (currentThreadAllocations.size() > 0)
  34. return &currentThreadAllocations.back();
  35. return NULL;
  36. }
  37. #endif
  38. void* MarshalAlloc::Allocate(size_t size)
  39. {
  40. void* ptr = os::MarshalAlloc::Allocate(size);
  41. #if _DEBUG
  42. std::map<void*, size_t>* allocations = GetAllocationsForCurrentFrame();
  43. if (allocations != NULL)
  44. (*allocations)[ptr] = size;
  45. #endif
  46. return ptr;
  47. }
  48. void* MarshalAlloc::ReAlloc(void* ptr, size_t size)
  49. {
  50. void* realloced = os::MarshalAlloc::ReAlloc(ptr, size);
  51. #if _DEBUG
  52. std::map<void*, size_t>* allocations = GetAllocationsForCurrentFrame();
  53. if (allocations != NULL)
  54. {
  55. if (ptr != NULL && ptr != realloced)
  56. {
  57. std::map<void*, size_t>::iterator found = allocations->find(ptr);
  58. IL2CPP_ASSERT(found != allocations->end() && "Invalid call to MarshalAlloc::ReAlloc. The pointer is not in the allocation list.");
  59. allocations->erase(found);
  60. }
  61. (*allocations)[realloced] = size;
  62. }
  63. #endif
  64. return realloced;
  65. }
  66. void MarshalAlloc::Free(void* ptr)
  67. {
  68. #if _DEBUG
  69. std::map<void*, size_t>* allocations = GetAllocationsForCurrentFrame();
  70. if (allocations != NULL)
  71. {
  72. std::map<void*, size_t>::iterator found = allocations->find(ptr);
  73. if (found != allocations->end()) // It might not be necessarily allocated by us, e.g. we might be freeing memory that's returned from native P/Invoke call
  74. allocations->erase(found);
  75. }
  76. #endif
  77. os::MarshalAlloc::Free(ptr);
  78. }
  79. void* MarshalAlloc::AllocateHGlobal(size_t size)
  80. {
  81. return os::MarshalAlloc::AllocateHGlobal(size);
  82. }
  83. void* MarshalAlloc::ReAllocHGlobal(void* ptr, size_t size)
  84. {
  85. return os::MarshalAlloc::ReAllocHGlobal(ptr, size);
  86. }
  87. void MarshalAlloc::FreeHGlobal(void* ptr)
  88. {
  89. os::MarshalAlloc::FreeHGlobal(ptr);
  90. }
  91. #if _DEBUG
  92. void MarshalAlloc::PushAllocationFrame()
  93. {
  94. GetAllocationsForCurrentThread().push_back(std::map<void*, size_t>());
  95. }
  96. void MarshalAlloc::PopAllocationFrame()
  97. {
  98. GetAllocationsForCurrentThread().pop_back();
  99. }
  100. bool MarshalAlloc::HasUnfreedAllocations()
  101. {
  102. std::map<void*, size_t>* allocations = GetAllocationsForCurrentFrame();
  103. return allocations != NULL && allocations->size() > 0;
  104. }
  105. void MarshalAlloc::ClearAllTrackedAllocations()
  106. {
  107. std::map<void*, size_t>* allocations = GetAllocationsForCurrentFrame();
  108. if (allocations != NULL)
  109. allocations->clear();
  110. }
  111. #endif
  112. } /* namespace vm */
  113. } /* namespace il2cpp */