SmallFinalizableHeapBucket.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "CommonMemoryPch.h"
  6. template <class TBlockType>
  7. SmallFinalizableHeapBucketBaseT<TBlockType>::SmallFinalizableHeapBucketBaseT() :
  8. pendingDisposeList(nullptr)
  9. {
  10. #if DBG || defined(RECYCLER_SLOW_CHECK_ENABLED)
  11. tempPendingDisposeList = nullptr;
  12. #endif
  13. }
  14. template <class TBlockType>
  15. SmallFinalizableHeapBucketBaseT<TBlockType>::~SmallFinalizableHeapBucketBaseT()
  16. {
  17. Assert(this->AllocatorsAreEmpty());
  18. this->DeleteHeapBlockList(this->pendingDisposeList);
  19. Assert(this->tempPendingDisposeList == nullptr);
  20. }
  21. template <class TBlockType>
  22. void
  23. SmallFinalizableHeapBucketBaseT<TBlockType>::FinalizeAllObjects()
  24. {
  25. // Finalize all objects on shutdown.
  26. // Clear allocators to update the information on the heapblock
  27. // Walk through the allocated object and call finalize and dispose on them
  28. this->ClearAllocators();
  29. FinalizeHeapBlockList(this->pendingDisposeList);
  30. #if ENABLE_PARTIAL_GC
  31. FinalizeHeapBlockList(this->partialHeapBlockList);
  32. #endif
  33. FinalizeHeapBlockList(this->heapBlockList);
  34. FinalizeHeapBlockList(this->fullBlockList);
  35. #if ENABLE_PARTIAL_GC && ENABLE_CONCURRENT_GC
  36. FinalizeHeapBlockList(this->partialSweptHeapBlockList);
  37. #endif
  38. }
  39. template <class TBlockType>
  40. void
  41. SmallFinalizableHeapBucketBaseT<TBlockType>::FinalizeHeapBlockList(TBlockType * list)
  42. {
  43. HeapBlockList::ForEach(list, [](TBlockType * heapBlock)
  44. {
  45. heapBlock->FinalizeAllObjects();
  46. });
  47. }
  48. #if DBG || defined(RECYCLER_SLOW_CHECK_ENABLED)
  49. template <class TBlockType>
  50. size_t
  51. SmallFinalizableHeapBucketBaseT<TBlockType>::GetNonEmptyHeapBlockCount(bool checkCount) const
  52. {
  53. size_t currentHeapBlockCount = __super::GetNonEmptyHeapBlockCount(false)
  54. + HeapBlockList::Count(pendingDisposeList)
  55. + HeapBlockList::Count(tempPendingDisposeList);
  56. RECYCLER_SLOW_CHECK(Assert(!checkCount || this->heapBlockCount == currentHeapBlockCount));
  57. return currentHeapBlockCount;
  58. }
  59. #endif
  60. template <class TBlockType>
  61. void
  62. SmallFinalizableHeapBucketBaseT<TBlockType>::ResetMarks(ResetMarkFlags flags)
  63. {
  64. __super::ResetMarks(flags);
  65. if ((flags & ResetMarkFlags_ScanImplicitRoot) != 0)
  66. {
  67. HeapBlockList::ForEach(this->pendingDisposeList, [flags](TBlockType * heapBlock)
  68. {
  69. heapBlock->MarkImplicitRoots();
  70. });
  71. }
  72. }
  73. #if ENABLE_MEM_STATS
  74. template <class TBlockType>
  75. void
  76. SmallFinalizableHeapBucketBaseT<TBlockType>::AggregateBucketStats()
  77. {
  78. __super::AggregateBucketStats();
  79. HeapBlockList::ForEach(pendingDisposeList, [this](TBlockType* heapBlock) {
  80. heapBlock->AggregateBlockStats(this->memStats);
  81. });
  82. }
  83. #endif
  84. template<class TBlockType>
  85. void
  86. SmallFinalizableHeapBucketBaseT<TBlockType>::Sweep(RecyclerSweep& recyclerSweep)
  87. {
  88. Assert(!recyclerSweep.IsBackground());
  89. #if DBG || defined(RECYCLER_SLOW_CHECK_ENABLED)
  90. Assert(this->tempPendingDisposeList == nullptr);
  91. this->tempPendingDisposeList = pendingDisposeList;
  92. #endif
  93. TBlockType * currentDisposeList = pendingDisposeList;
  94. this->pendingDisposeList = nullptr;
  95. BaseT::SweepBucket(recyclerSweep, [=](RecyclerSweep& recyclerSweep)
  96. {
  97. #if DBG
  98. if (TBlockType::HeapBlockAttributes::IsSmallBlock)
  99. {
  100. recyclerSweep.SetupVerifyListConsistencyDataForSmallBlock(nullptr, false, true);
  101. }
  102. else if (TBlockType::HeapBlockAttributes::IsMediumBlock)
  103. {
  104. recyclerSweep.SetupVerifyListConsistencyDataForMediumBlock(nullptr, false, true);
  105. }
  106. else
  107. {
  108. Assert(false);
  109. }
  110. #endif
  111. HeapBucketT<TBlockType>::SweepHeapBlockList(recyclerSweep, currentDisposeList, false);
  112. #if DBG || defined(RECYCLER_SLOW_CHECK_ENABLED)
  113. Assert(this->tempPendingDisposeList == currentDisposeList);
  114. this->tempPendingDisposeList = nullptr;
  115. #endif
  116. RECYCLER_SLOW_CHECK(this->VerifyHeapBlockCount(recyclerSweep.IsBackground()));
  117. });
  118. }
  119. template <class TBlockType>
  120. void
  121. SmallFinalizableHeapBucketBaseT<TBlockType>::DisposeObjects()
  122. {
  123. HeapBlockList::ForEach(this->pendingDisposeList, [](TBlockType * heapBlock)
  124. {
  125. Assert(heapBlock->HasAnyDisposeObjects());
  126. heapBlock->DisposeObjects();
  127. });
  128. }
  129. template <class TBlockType>
  130. void
  131. SmallFinalizableHeapBucketBaseT<TBlockType>::TransferDisposedObjects()
  132. {
  133. Assert(!this->IsAllocationStopped());
  134. TBlockType * currentPendingDisposeList = this->pendingDisposeList;
  135. if (currentPendingDisposeList != nullptr)
  136. {
  137. this->pendingDisposeList = nullptr;
  138. HeapBlockList::ForEach(currentPendingDisposeList, [=](TBlockType * heapBlock)
  139. {
  140. heapBlock->TransferDisposedObjects();
  141. Assert(heapBlock->HasFreeObject());
  142. });
  143. // For partial collect, dispose will modify the object, and we
  144. // also touch the page by chaining the object through the free list
  145. // might as well reuse the block for partial collect
  146. this->AppendAllocableHeapBlockList(currentPendingDisposeList);
  147. }
  148. RECYCLER_SLOW_CHECK(this->VerifyHeapBlockCount(false));
  149. }
  150. template <class TBlockType>
  151. void
  152. SmallFinalizableHeapBucketBaseT<TBlockType>::EnumerateObjects(ObjectInfoBits infoBits, void(*CallBackFunction)(void * address, size_t size))
  153. {
  154. __super::EnumerateObjects(infoBits, CallBackFunction);
  155. HeapBucket::EnumerateObjects(this->pendingDisposeList, infoBits, CallBackFunction);
  156. }
  157. #ifdef RECYCLER_SLOW_CHECK_ENABLED
  158. template <class TBlockType>
  159. size_t
  160. SmallFinalizableHeapBucketBaseT<TBlockType>::Check()
  161. {
  162. size_t smallHeapBlockCount = __super::Check(false) + HeapInfo::Check(false, true, this->pendingDisposeList);
  163. Assert(this->heapBlockCount == smallHeapBlockCount);
  164. return smallHeapBlockCount;
  165. }
  166. #endif
  167. #ifdef RECYCLER_MEMORY_VERIFY
  168. template <class TBlockType>
  169. void
  170. SmallFinalizableHeapBucketBaseT<TBlockType>::Verify()
  171. {
  172. BaseT::Verify();
  173. #if DBG
  174. RecyclerVerifyListConsistencyData recyclerVerifyListConsistencyData;
  175. if (TBlockType::HeapBlockAttributes::IsSmallBlock)
  176. {
  177. recyclerVerifyListConsistencyData.SetupVerifyListConsistencyDataForSmallBlock(nullptr, false, true);
  178. }
  179. else if (TBlockType::HeapBlockAttributes::IsMediumBlock)
  180. {
  181. recyclerVerifyListConsistencyData.SetupVerifyListConsistencyDataForMediumBlock(nullptr, false, true);
  182. }
  183. else
  184. {
  185. Assert(false);
  186. }
  187. HeapBlockList::ForEach(this->pendingDisposeList, [this, &recyclerVerifyListConsistencyData](TBlockType * heapBlock)
  188. {
  189. DebugOnly(this->VerifyBlockConsistencyInList(heapBlock, recyclerVerifyListConsistencyData));
  190. heapBlock->Verify(true);
  191. });
  192. #endif
  193. }
  194. #endif
  195. #ifdef RECYCLER_VERIFY_MARK
  196. template <class TBlockType>
  197. void
  198. SmallFinalizableHeapBucketBaseT<TBlockType>::VerifyMark()
  199. {
  200. __super::VerifyMark();
  201. HeapBlockList::ForEach(this->pendingDisposeList, [](TBlockType * heapBlock)
  202. {
  203. Assert(heapBlock->HasAnyDisposeObjects());
  204. heapBlock->VerifyMark();
  205. });
  206. }
  207. #endif
  208. namespace Memory
  209. {
  210. template class SmallFinalizableHeapBucketBaseT<SmallFinalizableHeapBlock>;
  211. #ifdef RECYCLER_VISITED_HOST
  212. template class SmallFinalizableHeapBucketBaseT<SmallRecyclerVisitedHostHeapBlock>;
  213. template class SmallFinalizableHeapBucketBaseT<MediumRecyclerVisitedHostHeapBlock>;
  214. #endif
  215. #ifdef RECYCLER_WRITE_BARRIER
  216. template class SmallFinalizableHeapBucketBaseT<SmallFinalizableWithBarrierHeapBlock>;
  217. #endif
  218. template class SmallFinalizableHeapBucketBaseT<MediumFinalizableHeapBlock>;
  219. #ifdef RECYCLER_WRITE_BARRIER
  220. template class SmallFinalizableHeapBucketBaseT<MediumFinalizableWithBarrierHeapBlock>;
  221. #endif
  222. }