MarkContext.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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::DefaultListLockPolicy, 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. bool AddTrackedObject(FinalizableObject * obj);
  26. template <bool parallel, bool interior>
  27. void Mark(void * candidate, void * parentReference);
  28. template <bool parallel>
  29. void MarkInterior(void * candidate);
  30. template <bool parallel, bool interior>
  31. void ScanObject(void ** obj, size_t byteCount);
  32. template <bool parallel, bool interior>
  33. void ScanMemory(void ** obj, size_t byteCount);
  34. template <bool parallel, bool interior>
  35. void ProcessMark();
  36. void MarkTrackedObject(FinalizableObject * obj);
  37. void ProcessTracked();
  38. uint Split(uint targetCount, __in_ecount(targetCount) MarkContext ** targetContexts);
  39. void Abort();
  40. void Release();
  41. bool HasPendingMarkObjects() const { return !markStack.IsEmpty(); }
  42. bool HasPendingTrackObjects() const { return !trackStack.IsEmpty(); }
  43. bool HasPendingObjects() const { return HasPendingMarkObjects() || HasPendingTrackObjects(); }
  44. PageAllocator * GetPageAllocator() { return this->pagePool->GetPageAllocator(); }
  45. bool IsEmpty()
  46. {
  47. if (HasPendingObjects())
  48. {
  49. return false;
  50. }
  51. Assert(pagePool->IsEmpty());
  52. Assert(!GetPageAllocator()->DisableAllocationOutOfMemory());
  53. return true;
  54. }
  55. #if DBG
  56. void VerifyPostMarkState()
  57. {
  58. Assert(this->markStack.HasChunk());
  59. }
  60. #endif
  61. void Cleanup()
  62. {
  63. Assert(!HasPendingObjects());
  64. Assert(!GetPageAllocator()->DisableAllocationOutOfMemory());
  65. this->pagePool->ReleaseFreePages();
  66. }
  67. void DecommitPages() { this->pagePool->Decommit(); }
  68. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  69. void SetMaxPageCount(size_t maxPageCount) { markStack.SetMaxPageCount(maxPageCount); trackStack.SetMaxPageCount(maxPageCount); }
  70. #endif
  71. #ifdef RECYCLER_MARK_TRACK
  72. void SetMarkMap(MarkMap* markMap)
  73. {
  74. this->markMap = markMap;
  75. }
  76. #endif
  77. private:
  78. Recycler * recycler;
  79. PagePool * pagePool;
  80. PageStack<MarkCandidate> markStack;
  81. PageStack<FinalizableObject *> trackStack;
  82. #ifdef RECYCLER_MARK_TRACK
  83. MarkMap* markMap;
  84. void OnObjectMarked(void* object, void* parent);
  85. #endif
  86. };
  87. }