MarkContext.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. #if defined(_M_IX86) || defined(_M_X64)
  7. // For prefetch
  8. #include <mmintrin.h>
  9. #endif
  10. MarkContext::MarkContext(Recycler * recycler, PagePool * pagePool) :
  11. recycler(recycler),
  12. pagePool(pagePool),
  13. markStack(pagePool),
  14. #ifdef RECYCLER_VISITED_HOST
  15. preciseStack(pagePool),
  16. #endif
  17. trackStack(pagePool)
  18. {
  19. }
  20. MarkContext::~MarkContext()
  21. {
  22. #ifdef RECYCLER_MARK_TRACK
  23. this->markMap = nullptr;
  24. #endif
  25. }
  26. #ifdef RECYCLER_MARK_TRACK
  27. void MarkContext::OnObjectMarked(void* object, void* parent)
  28. {
  29. if (!this->markMap->ContainsKey(object))
  30. {
  31. this->markMap->AddNew(object, parent);
  32. }
  33. }
  34. #endif
  35. void MarkContext::Init(uint reservedPageCount)
  36. {
  37. markStack.Init(reservedPageCount);
  38. #ifdef RECYCLER_VISITED_HOST
  39. preciseStack.Init();
  40. #endif
  41. trackStack.Init();
  42. }
  43. void MarkContext::Clear()
  44. {
  45. markStack.Clear();
  46. #ifdef RECYCLER_VISITED_HOST
  47. preciseStack.Clear();
  48. #endif
  49. trackStack.Clear();
  50. }
  51. void MarkContext::Abort()
  52. {
  53. markStack.Abort();
  54. #ifdef RECYCLER_VISITED_HOST
  55. preciseStack.Abort();
  56. #endif
  57. trackStack.Abort();
  58. pagePool->ReleaseFreePages();
  59. }
  60. void MarkContext::Release()
  61. {
  62. markStack.Release();
  63. #ifdef RECYCLER_VISITED_HOST
  64. preciseStack.Release();
  65. #endif
  66. trackStack.Release();
  67. pagePool->ReleaseFreePages();
  68. }
  69. uint MarkContext::Split(uint targetCount, __in_ecount(targetCount) MarkContext ** targetContexts)
  70. {
  71. #pragma prefast(suppress:__WARNING_REDUNDANTTEST, "Due to implementation of the PageStack template this test may end up being redundant")
  72. Assert(targetCount > 0 && targetCount <= PageStack<MarkCandidate>::MaxSplitTargets && targetCount <= PageStack<IRecyclerVisitedObject*>::MaxSplitTargets);
  73. __analysis_assume(targetCount <= PageStack<MarkCandidate>::MaxSplitTargets);
  74. __analysis_assume(targetCount <= PageStack<IRecyclerVisitedObject*>::MaxSplitTargets);
  75. PageStack<MarkCandidate> * targetMarkStacks[PageStack<MarkCandidate>::MaxSplitTargets];
  76. #ifdef RECYCLER_VISITED_HOST
  77. PageStack<IRecyclerVisitedObject*> * targetPreciseStacks[PageStack<IRecyclerVisitedObject*>::MaxSplitTargets];
  78. #endif
  79. for (uint i = 0; i < targetCount; i++)
  80. {
  81. targetMarkStacks[i] = &targetContexts[i]->markStack;
  82. #ifdef RECYCLER_VISITED_HOST
  83. targetPreciseStacks[i] = &targetContexts[i]->preciseStack;
  84. #endif
  85. }
  86. // Return the max count of the two splits - since the stacks have more or less unrelated sizes, they
  87. // could yield different number of splits, but the caller wants to know the max parallelism it
  88. // should use on the results of the split.
  89. const uint markStackSplitCount = this->markStack.Split(targetCount, targetMarkStacks);
  90. #ifdef RECYCLER_VISITED_HOST
  91. const uint preciseStackSplitCount = this->preciseStack.Split(targetCount, targetPreciseStacks);
  92. return max(markStackSplitCount, preciseStackSplitCount);
  93. #else
  94. return markStackSplitCount;
  95. #endif
  96. }
  97. void MarkContext::ProcessTracked()
  98. {
  99. if (trackStack.IsEmpty())
  100. {
  101. return;
  102. }
  103. FinalizableObject * trackedObject;
  104. while (trackStack.Pop(&trackedObject))
  105. {
  106. MarkTrackedObject(trackedObject);
  107. }
  108. Assert(trackStack.IsEmpty());
  109. trackStack.Release();
  110. }