MarkContext.h 3.3 KB

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