SmallFinalizableHeapBlock.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. namespace Memory
  6. {
  7. template <class TBlockAttributes> class SmallFinalizableHeapBucketT;
  8. #ifdef RECYCLER_VISITED_HOST
  9. template <class TBlockAttributes> class SmallRecyclerVisitedHostHeapBlockT;
  10. #endif
  11. #ifdef RECYCLER_WRITE_BARRIER
  12. template <class TBlockAttributes> class SmallFinalizableWithBarrierHeapBlockT;
  13. #endif
  14. template <class TBlockAttributes>
  15. class SmallFinalizableHeapBlockT : public SmallNormalHeapBlockT<TBlockAttributes>
  16. {
  17. typedef SmallNormalHeapBlockT<TBlockAttributes> Base;
  18. typedef typename Base::SmallHeapBlockBitVector SmallHeapBlockBitVector;
  19. typedef typename Base::HeapBlockType HeapBlockType;
  20. friend class HeapBucketT<SmallFinalizableHeapBlockT>;
  21. using Base::MediumFinalizableBlockType;
  22. public:
  23. typedef TBlockAttributes HeapBlockAttributes;
  24. static const ObjectInfoBits RequiredAttributes = FinalizeBit;
  25. static SmallFinalizableHeapBlockT * New(HeapBucketT<SmallFinalizableHeapBlockT> * bucket);
  26. static void Delete(SmallFinalizableHeapBlockT * block);
  27. SmallFinalizableHeapBlockT * GetNextBlock() const
  28. {
  29. HeapBlock* block = SmallHeapBlockT<TBlockAttributes>::GetNextBlock();
  30. return block ? block->template AsFinalizableBlock<TBlockAttributes>() : nullptr;
  31. }
  32. void SetNextBlock(SmallFinalizableHeapBlockT * next) { Base::SetNextBlock(next); }
  33. bool TryGetAddressOfAttributes(void* objectAddress, unsigned char **ppAttr);
  34. bool TryGetAttributes(void* objectAddress, unsigned char *pAttr);
  35. template <bool doSpecialMark>
  36. void ProcessMarkedObject(void* candidate, MarkContext * markContext);
  37. void SetAttributes(void * address, unsigned char attributes);
  38. #if ENABLE_PARTIAL_GC || ENABLE_CONCURRENT_GC
  39. static bool CanRescanFullBlock();
  40. static bool RescanObject(SmallFinalizableHeapBlockT<TBlockAttributes> * block, __in_ecount(localObjectSize) char * objectAddress, uint localObjectSize, uint objectIndex, Recycler * recycler);
  41. bool RescanTrackedObject(FinalizableObject * object, uint objectIndex, Recycler * recycler);
  42. #endif
  43. SweepState Sweep(RecyclerSweep& sweepeData, bool queuePendingSweep, bool allocable);
  44. void DisposeObjects();
  45. void TransferDisposedObjects();
  46. bool HasPendingDisposeObjects() const
  47. {
  48. return (this->pendingDisposeCount != 0);
  49. }
  50. void AddPendingDisposeObject()
  51. {
  52. #if ENABLE_ALLOCATIONS_DURING_CONCURRENT_SWEEP
  53. if (CONFIG_FLAG_RELEASE(EnableConcurrentSweepAlloc))
  54. {
  55. AssertMsg(!this->isPendingConcurrentSweepPrep, "Finalizable blocks don't support allocations during concurrent sweep.");
  56. }
  57. #endif
  58. this->pendingDisposeCount++;
  59. Assert(this->pendingDisposeCount <= this->objectCount);
  60. }
  61. bool HasDisposedObjects() const { return this->disposedObjectList != nullptr; }
  62. bool HasAnyDisposeObjects() const { return this->HasPendingDisposeObjects() || this->HasDisposedObjects(); }
  63. template <typename Fn>
  64. void ForEachPendingDisposeObject(Fn fn)
  65. {
  66. if (this->HasPendingDisposeObjects())
  67. {
  68. for (uint i = 0; i < this->objectCount; i++)
  69. {
  70. if ((this->ObjectInfo(i) & PendingDisposeBit) != 0)
  71. {
  72. // When pending dispose, exactly the PendingDisposeBits should be set
  73. Assert(this->ObjectInfo(i) == PendingDisposeObjectBits);
  74. fn(i);
  75. }
  76. }
  77. }
  78. else
  79. {
  80. #if DBG
  81. for (uint i = 0; i < this->objectCount; i++)
  82. {
  83. Assert((this->ObjectInfo(i) & PendingDisposeBit) == 0);
  84. }
  85. #endif
  86. }
  87. }
  88. ushort AddDisposedObjectFreeBitVector(SmallHeapBlockBitVector * free);
  89. #ifdef RECYCLER_SLOW_CHECK_ENABLED
  90. uint CheckDisposedObjectFreeBitVector();
  91. virtual bool GetFreeObjectListOnAllocator(FreeObject ** freeObjectList) override;
  92. #endif
  93. #if DBG
  94. #if ENABLE_PARTIAL_GC
  95. void FinishPartialCollect();
  96. #endif
  97. bool IsPendingDispose() const { return isPendingDispose; }
  98. void SetIsPendingDispose() { isPendingDispose = true; }
  99. #endif
  100. void FinalizeAllObjects();
  101. #ifdef DUMP_FRAGMENTATION_STATS
  102. ushort GetFinalizeCount() {
  103. return finalizeCount;
  104. }
  105. #endif
  106. virtual bool FindHeapObject(void* objectAddress, Recycler * recycler, FindHeapObjectFlags flags, RecyclerHeapObjectInfo& heapObject) override
  107. {
  108. return this->template FindHeapObjectImpl<SmallFinalizableHeapBlockT<TBlockAttributes>>(objectAddress, recycler, flags, heapObject);
  109. }
  110. protected:
  111. SmallFinalizableHeapBlockT(HeapBucketT<SmallFinalizableHeapBlockT> * bucket, ushort objectSize, ushort objectCount);
  112. #ifdef RECYCLER_VISITED_HOST
  113. SmallFinalizableHeapBlockT(HeapBucketT<SmallRecyclerVisitedHostHeapBlockT<TBlockAttributes>> * bucket, ushort objectSize, ushort objectCount, HeapBlockType blockType);
  114. #endif
  115. #ifdef RECYCLER_WRITE_BARRIER
  116. SmallFinalizableHeapBlockT(HeapBucketT<SmallFinalizableWithBarrierHeapBlockT<TBlockAttributes>> * bucket, ushort objectSize, ushort objectCount, HeapBlockType blockType);
  117. #endif
  118. #if DBG
  119. void Init(ushort objectSize, ushort objectCount);
  120. bool isPendingDispose;
  121. #endif
  122. ushort finalizeCount;
  123. ushort pendingDisposeCount;
  124. FreeObject* disposedObjectList;
  125. FreeObject* disposedObjectListTail;
  126. friend class ::ScriptMemoryDumper;
  127. #ifdef RECYCLER_MEMORY_VERIFY
  128. friend void SmallHeapBlockT<TBlockAttributes>::Verify(bool pendingDispose);
  129. #endif
  130. };
  131. #ifdef RECYCLER_VISITED_HOST
  132. template <class TBlockAttributes>
  133. class SmallRecyclerVisitedHostHeapBlockT : public SmallFinalizableHeapBlockT<TBlockAttributes>
  134. {
  135. typedef SmallFinalizableHeapBlockT<TBlockAttributes> Base;
  136. friend class HeapBucketT<SmallRecyclerVisitedHostHeapBlockT>;
  137. public:
  138. typedef TBlockAttributes HeapBlockAttributes;
  139. static const ObjectInfoBits RequiredAttributes = RecyclerVisitedHostBit;
  140. static SmallRecyclerVisitedHostHeapBlockT * New(HeapBucketT<SmallRecyclerVisitedHostHeapBlockT> * bucket);
  141. static void Delete(SmallRecyclerVisitedHostHeapBlockT * block);
  142. void SetAttributes(void * address, unsigned char attributes);
  143. template <bool doSpecialMark>
  144. void ProcessMarkedObject(void* candidate, MarkContext * markContext);
  145. template <bool doSpecialMark, typename Fn>
  146. bool UpdateAttributesOfMarkedObjects(MarkContext * markContext, void * objectAddress, size_t objectSize, unsigned char attributes, Fn fn);
  147. static bool RescanObject(SmallRecyclerVisitedHostHeapBlockT<TBlockAttributes> * block, __in_ecount(localObjectSize) char * objectAddress, uint localObjectSize, uint objectIndex, Recycler * recycler);
  148. SmallRecyclerVisitedHostHeapBlockT * GetNextBlock() const
  149. {
  150. HeapBlock* block = SmallHeapBlockT<TBlockAttributes>::GetNextBlock();
  151. return block ? block->template AsRecyclerVisitedHostBlock<TBlockAttributes>() : nullptr;
  152. }
  153. virtual bool FindHeapObject(void* objectAddress, Recycler * recycler, FindHeapObjectFlags flags, RecyclerHeapObjectInfo& heapObject) override sealed
  154. {
  155. return this->template FindHeapObjectImpl<SmallRecyclerVisitedHostHeapBlockT<TBlockAttributes>>(objectAddress, recycler, flags, heapObject);
  156. }
  157. protected:
  158. SmallRecyclerVisitedHostHeapBlockT(HeapBucketT<SmallRecyclerVisitedHostHeapBlockT> * bucket, ushort objectSize, ushort objectCount)
  159. : SmallFinalizableHeapBlockT<TBlockAttributes>(bucket, objectSize, objectCount, TBlockAttributes::IsSmallBlock ? Base::SmallRecyclerVisitedHostBlockType : Base::MediumRecyclerVisitedHostBlockType)
  160. {
  161. }
  162. };
  163. #endif
  164. #ifdef RECYCLER_WRITE_BARRIER
  165. template <class TBlockAttributes>
  166. class SmallFinalizableWithBarrierHeapBlockT : public SmallFinalizableHeapBlockT<TBlockAttributes>
  167. {
  168. typedef SmallFinalizableHeapBlockT<TBlockAttributes> Base;
  169. friend class HeapBucketT<SmallFinalizableWithBarrierHeapBlockT>;
  170. public:
  171. typedef TBlockAttributes HeapBlockAttributes;
  172. static const ObjectInfoBits RequiredAttributes = FinalizableWithBarrierBit;
  173. static SmallFinalizableWithBarrierHeapBlockT * New(HeapBucketT<SmallFinalizableWithBarrierHeapBlockT> * bucket);
  174. static void Delete(SmallFinalizableWithBarrierHeapBlockT * block);
  175. SmallFinalizableWithBarrierHeapBlockT * GetNextBlock() const
  176. {
  177. HeapBlock* block = SmallHeapBlockT<TBlockAttributes>::GetNextBlock();
  178. return block ? block->template AsFinalizableWriteBarrierBlock<TBlockAttributes>() : nullptr;
  179. }
  180. virtual bool FindHeapObject(void* objectAddress, Recycler * recycler, FindHeapObjectFlags flags, RecyclerHeapObjectInfo& heapObject) override sealed
  181. {
  182. return this->template FindHeapObjectImpl<SmallFinalizableWithBarrierHeapBlockT<TBlockAttributes>>(objectAddress, recycler, flags, heapObject);
  183. }
  184. protected:
  185. SmallFinalizableWithBarrierHeapBlockT(HeapBucketT<SmallFinalizableWithBarrierHeapBlockT> * bucket, ushort objectSize, ushort objectCount)
  186. : SmallFinalizableHeapBlockT<TBlockAttributes>(bucket, objectSize, objectCount, TBlockAttributes::IsSmallBlock ? Base::SmallFinalizableBlockWithBarrierType : Base::MediumFinalizableBlockWithBarrierType)
  187. {
  188. }
  189. };
  190. #endif
  191. typedef SmallFinalizableHeapBlockT<SmallAllocationBlockAttributes> SmallFinalizableHeapBlock;
  192. typedef SmallFinalizableHeapBlockT<MediumAllocationBlockAttributes> MediumFinalizableHeapBlock;
  193. #ifdef RECYCLER_VISITED_HOST
  194. typedef SmallRecyclerVisitedHostHeapBlockT<SmallAllocationBlockAttributes> SmallRecyclerVisitedHostHeapBlock;
  195. typedef SmallRecyclerVisitedHostHeapBlockT<MediumAllocationBlockAttributes> MediumRecyclerVisitedHostHeapBlock;
  196. #endif
  197. #ifdef RECYCLER_WRITE_BARRIER
  198. typedef SmallFinalizableWithBarrierHeapBlockT<SmallAllocationBlockAttributes> SmallFinalizableWithBarrierHeapBlock;
  199. typedef SmallFinalizableWithBarrierHeapBlockT<MediumAllocationBlockAttributes> MediumFinalizableWithBarrierHeapBlock;
  200. #endif
  201. }