MarkContext.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. interface IRecyclerVisitedObject;
  6. namespace Memory
  7. {
  8. class Recycler;
  9. typedef JsUtil::SynchronizedDictionary<void *, void *, NoCheckHeapAllocator, PrimeSizePolicy, RecyclerPointerComparer, JsUtil::SimpleDictionaryEntry, Js::DefaultContainerLockPolicy, CriticalSection> MarkMap;
  10. #if __has_feature(address_sanitizer)
  11. enum class RecyclerScanMemoryType { General, Stack };
  12. #endif
  13. class MarkContext
  14. {
  15. private:
  16. struct MarkCandidate
  17. {
  18. void ** obj;
  19. size_t byteCount;
  20. };
  21. public:
  22. static const int MarkCandidateSize = sizeof(MarkCandidate);
  23. MarkContext(Recycler * recycler, PagePool * pagePool);
  24. ~MarkContext();
  25. void Init(uint reservedPageCount);
  26. void Clear();
  27. Recycler * GetRecycler() { return this->recycler; }
  28. bool AddMarkedObject(void * obj, size_t byteCount);
  29. #ifdef RECYCLER_VISITED_HOST
  30. bool AddPreciselyTracedObject(IRecyclerVisitedObject *obj);
  31. #endif
  32. #if ENABLE_CONCURRENT_GC
  33. bool AddTrackedObject(FinalizableObject * obj);
  34. #endif
  35. template <bool parallel, bool interior, bool doSpecialMark>
  36. void Mark(void * candidate, void * parentReference);
  37. template <bool parallel>
  38. void MarkInterior(void * candidate);
  39. template <bool parallel, bool interior>
  40. void ScanObject(void ** obj, size_t byteCount);
  41. template <bool parallel, bool interior, bool doSpecialMark>
  42. void ScanMemory(void ** obj, size_t byteCount
  43. ADDRESS_SANITIZER_APPEND(void *asanFakeStack = nullptr));
  44. template <bool parallel, bool interior>
  45. void ProcessMark();
  46. void MarkTrackedObject(FinalizableObject * obj);
  47. void ProcessTracked();
  48. uint Split(uint targetCount, __in_ecount(targetCount) MarkContext ** targetContexts);
  49. void Abort();
  50. void Release();
  51. bool HasPendingMarkObjects() const { return !markStack.IsEmpty(); }
  52. #ifdef RECYCLER_VISITED_HOST
  53. bool HasPendingPreciselyTracedObjects() const { return !preciseStack.IsEmpty(); }
  54. #endif
  55. bool HasPendingTrackObjects() const { return !trackStack.IsEmpty(); }
  56. bool HasPendingObjects() const {
  57. return HasPendingMarkObjects()
  58. #ifdef RECYCLER_VISITED_HOST
  59. || HasPendingPreciselyTracedObjects()
  60. #endif
  61. || HasPendingTrackObjects();
  62. }
  63. PageAllocator * GetPageAllocator() { return this->pagePool->GetPageAllocator(); }
  64. bool IsEmpty()
  65. {
  66. if (HasPendingObjects())
  67. {
  68. return false;
  69. }
  70. Assert(pagePool->IsEmpty());
  71. Assert(!GetPageAllocator()->DisableAllocationOutOfMemory());
  72. return true;
  73. }
  74. #if DBG
  75. void VerifyPostMarkState()
  76. {
  77. Assert(this->markStack.HasChunk());
  78. }
  79. #endif
  80. void Cleanup()
  81. {
  82. Assert(!HasPendingObjects());
  83. Assert(!GetPageAllocator()->DisableAllocationOutOfMemory());
  84. this->pagePool->ReleaseFreePages();
  85. }
  86. void DecommitPages() { this->pagePool->Decommit(); }
  87. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  88. void SetMaxPageCount(size_t maxPageCount) {
  89. markStack.SetMaxPageCount(maxPageCount);
  90. #ifdef RECYCLER_VISITED_HOST
  91. preciseStack.SetMaxPageCount(maxPageCount);
  92. #endif
  93. trackStack.SetMaxPageCount(maxPageCount);
  94. }
  95. #endif
  96. #ifdef RECYCLER_MARK_TRACK
  97. void SetMarkMap(MarkMap* markMap)
  98. {
  99. this->markMap = markMap;
  100. }
  101. #endif
  102. private:
  103. Recycler * recycler;
  104. PagePool * pagePool;
  105. PageStack<MarkCandidate> markStack;
  106. #ifdef RECYCLER_VISITED_HOST
  107. PageStack<IRecyclerVisitedObject*> preciseStack;
  108. #endif
  109. PageStack<FinalizableObject *> trackStack;
  110. #ifdef RECYCLER_MARK_TRACK
  111. MarkMap* markMap;
  112. void OnObjectMarked(void* object, void* parent);
  113. #endif
  114. #if DBG
  115. public:
  116. void* parentRef;
  117. #endif
  118. };
  119. }