| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "CommonMemoryPch.h"
- namespace Memory
- {
- template <class Fn>
- bool HeapInfoManager::AreAllHeapInfo(Fn fn)
- {
- return fn(defaultHeap);
- }
- template <class Fn>
- bool HeapInfoManager::IsAnyHeapInfo(Fn fn)
- {
- return fn(defaultHeap);
- }
- template <class Fn>
- void HeapInfoManager::ForEachHeapInfo(Fn fn)
- {
- fn(defaultHeap);
- }
- template <class Fn>
- void HeapInfoManager::ForEachHeapInfo(RecyclerSweepManager& recyclerSweepManager, Fn fn)
- {
- fn(defaultHeap, recyclerSweepManager.defaultHeapRecyclerSweep);
- }
- template <class Fn>
- void HeapInfoManager::ForEachHeapInfo(RecyclerSweepManager * recyclerSweepManager, Fn fn)
- {
- fn(defaultHeap, recyclerSweepManager? &recyclerSweepManager->defaultHeapRecyclerSweep : nullptr);
- }
- HeapInfoManager::HeapInfoManager(AllocationPolicyManager * policyManager, Js::ConfigFlagsTable& configFlagsTable, IdleDecommitPageAllocator * leafPageAllocator) :
- defaultHeap(policyManager, configFlagsTable, leafPageAllocator),
- #if ENABLE_PARTIAL_GC
- uncollectedNewPageCount(0),
- unusedPartialCollectFreeBytes(0),
- #endif
- uncollectedAllocBytes(0),
- lastUncollectedAllocBytes(0),
- pendingZeroPageCount(0)
- {
- }
- void HeapInfoManager::Initialize(Recycler * recycler
- #ifdef RECYCLER_PAGE_HEAP
- , PageHeapMode pageheapmode
- , bool captureAllocCallStack
- , bool captureFreeCallStack
- #endif
- )
- {
- ForEachHeapInfo([=](HeapInfo& heapInfo)
- {
- heapInfo.Initialize(recycler
- #ifdef RECYCLER_PAGE_HEAP
- , pageheapmode
- , captureAllocCallStack
- , captureFreeCallStack
- #endif
- );
- });
- }
- #if defined(PROFILE_RECYCLER_ALLOC) || defined(RECYCLER_MEMORY_VERIFY) || defined(MEMSPECT_TRACKING) || defined(ETW_MEMORY_TRACKING)
- void HeapInfoManager::Initialize(Recycler * recycler, void(*trackNativeAllocCallBack)(Recycler *, void *, size_t)
- #ifdef RECYCLER_PAGE_HEAP
- , PageHeapMode pageheapmode
- , bool captureAllocCallStack
- , bool captureFreeCallStack
- #endif
- )
- {
- ForEachHeapInfo([=](HeapInfo& heapInfo)
- {
- heapInfo.Initialize(recycler, trackNativeAllocCallBack
- #ifdef RECYCLER_PAGE_HEAP
- , pageheapmode
- , captureAllocCallStack
- , captureFreeCallStack
- #endif
- );
- });
- }
- #endif
- void
- HeapInfoManager::ScanInitialImplicitRoots()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.ScanInitialImplicitRoots();
- });
- }
- void
- HeapInfoManager::ScanNewImplicitRoots()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.ScanNewImplicitRoots();
- });
- }
- void
- HeapInfoManager::ResetMarks(ResetMarkFlags flags)
- {
- ForEachHeapInfo([=](HeapInfo& heapInfo)
- {
- heapInfo.ResetMarks(flags);
- });
- }
- size_t
- HeapInfoManager::Rescan(RescanFlags flags)
- {
- size_t rescannedPageCount = 0;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- rescannedPageCount += heapInfo.Rescan(flags);
- });
- return rescannedPageCount;
- }
- void
- HeapInfoManager::FinalizeAndSweep(RecyclerSweepManager& recyclerSweepManager, bool concurrent)
- {
- SuspendIdleDecommitNonLeaf();
- // Call finalize before sweeping so that the finalizer can still access object it referenced
- ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.Finalize(recyclerSweep);
- });
- ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.Sweep(recyclerSweep, concurrent);
- });
- ResumeIdleDecommitNonLeaf();
- }
- void
- HeapInfoManager::SweepSmallNonFinalizable(RecyclerSweepManager& recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.SweepSmallNonFinalizable(recyclerSweep);
- });
- }
- #if ENABLE_PARTIAL_GC || ENABLE_CONCURRENT_GC
- #ifdef RECYCLER_WRITE_WATCH
- void HeapInfoManager::EnableWriteWatch()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.EnableWriteWatch();
- });
- }
- bool HeapInfoManager::ResetWriteWatch()
- {
- return AreAllHeapInfo([](HeapInfo& heapInfo)
- {
- return heapInfo.ResetWriteWatch();
- });
- }
- #if DBG
- size_t HeapInfoManager::GetWriteWatchPageCount()
- {
- size_t writeWatchPageCount = 0;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- writeWatchPageCount += heapInfo.GetWriteWatchPageCount();
- });
- return writeWatchPageCount;
- }
- #endif
- #endif
- void
- HeapInfoManager::SweepPendingObjects(RecyclerSweepManager& recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.SweepPendingObjects(recyclerSweep);
- });
- }
- #endif
- #if ENABLE_PARTIAL_GC
- void
- HeapInfoManager::SweepPartialReusePages(RecyclerSweepManager& recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.SweepPartialReusePages(recyclerSweep);
- });
- }
- void
- HeapInfoManager::FinishPartialCollect(RecyclerSweepManager * recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep * recyclerSweep)
- {
- heapInfo.FinishPartialCollect(recyclerSweep);
- });
- }
- #endif
- #if ENABLE_CONCURRENT_GC
- void
- HeapInfoManager::PrepareSweep()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.PrepareSweep();
- });
- }
- #if ENABLE_ALLOCATIONS_DURING_CONCURRENT_SWEEP
- void
- HeapInfoManager::StartAllocationsDuringConcurrentSweep()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.StartAllocationsDuringConcurrentSweep();
- });
- }
- bool
- HeapInfoManager::DoTwoPassConcurrentSweepPreCheck()
- {
- return IsAnyHeapInfo([](HeapInfo& heapInfo)
- {
- return heapInfo.DoTwoPassConcurrentSweepPreCheck();
- });
- }
- void
- HeapInfoManager::FinishSweepPrep(RecyclerSweepManager& recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.FinishSweepPrep(recyclerSweep);
- });
- }
- void
- HeapInfoManager::FinishConcurrentSweepPass1(RecyclerSweepManager& recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.FinishConcurrentSweepPass1(recyclerSweep);
- });
- }
- void
- HeapInfoManager::FinishConcurrentSweep()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.FinishConcurrentSweep();
- });
- }
- #endif
- void
- HeapInfoManager::ConcurrentTransferSweptObjects(RecyclerSweepManager& recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.ConcurrentTransferSweptObjects(recyclerSweep);
- });
- }
- #if ENABLE_PARTIAL_GC
- void
- HeapInfoManager::ConcurrentPartialTransferSweptObjects(RecyclerSweepManager& recyclerSweepManager)
- {
- ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
- {
- heapInfo.ConcurrentPartialTransferSweptObjects(recyclerSweep);
- });
- }
- #endif
- #endif
- void
- HeapInfoManager::DisposeObjects()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.DisposeObjects();
- });
- }
- void
- HeapInfoManager::TransferDisposedObjects()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.TransferDisposedObjects();
- });
- }
- void
- HeapInfoManager::EnumerateObjects(ObjectInfoBits infoBits, void(*CallBackFunction)(void * address, size_t size))
- {
- ForEachHeapInfo([=](HeapInfo& heapInfo)
- {
- heapInfo.EnumerateObjects(infoBits, CallBackFunction);
- });
- }
- #if DBG
- bool
- HeapInfoManager::AllocatorsAreEmpty()
- {
- return AreAllHeapInfo([](HeapInfo& heapInfo)
- {
- return heapInfo.AllocatorsAreEmpty();
- });
- }
- void
- HeapInfoManager::ResetThreadId()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- return heapInfo.ResetThreadId();
- });
- }
- void
- HeapInfoManager::SetDisableThreadAccessCheck()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- return heapInfo.SetDisableThreadAccessCheck();
- });
- }
- #endif
- #ifdef RECYCLER_FINALIZE_CHECK
- size_t
- HeapInfoManager::GetFinalizeCount()
- {
- size_t finalizeCount = 0;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- finalizeCount += heapInfo.GetFinalizeCount();
- });
- return finalizeCount;
- }
- #endif
- #ifdef RECYCLER_SLOW_CHECK_ENABLED
- void
- HeapInfoManager::Check()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.Check();
- });
- }
- #endif
- #ifdef RECYCLER_MEMORY_VERIFY
- void
- HeapInfoManager::EnableVerify()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.EnableVerify();
- });
- }
- void
- HeapInfoManager::Verify()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.Verify();
- });
- }
- #endif
- #ifdef RECYCLER_VERIFY_MARK
- void
- HeapInfoManager::VerifyMark()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.VerifyMark();
- });
- }
- #endif
- #ifdef RECYCLER_NO_PAGE_REUSE
- void
- HeapInfoManager::DisablePageReuse()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.DisablePageReuse();
- });
- }
- #endif
- }
- #ifdef ENABLE_MEM_STATS
- #include "BucketStatsReporter.h"
- namespace Memory
- {
- // REVIEW: this is in the wrong place
- void
- HeapInfoManager::ReportMemStats(Recycler * recycler)
- {
- ::Memory::BucketStatsReporter report(recycler);
- if (!report.IsEnabled())
- {
- return;
- }
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- heapInfo.GetBucketStats(report);
- });
- report.Report();
- }
- }
- #endif
- #ifdef RECYCLER_PAGE_HEAP
- bool
- HeapInfoManager::IsPageHeapEnabled()
- {
- return IsAnyHeapInfo([](HeapInfo& heapInfo)
- {
- return heapInfo.IsPageHeapEnabled();
- });
- }
- #endif
- // ==============================================================
- // Page allocator APIs
- // ==============================================================
- void
- HeapInfoManager::Prime()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.Prime();
- });
- }
- void
- HeapInfoManager::Close()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.CloseNonLeaf();
- });
- }
- void
- HeapInfoManager::SuspendIdleDecommitNonLeaf()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.SuspendIdleDecommitNonLeaf();
- });
- }
- void
- HeapInfoManager::ResumeIdleDecommitNonLeaf()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.ResumeIdleDecommitNonLeaf();
- });
- }
- void
- HeapInfoManager::EnterIdleDecommit()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.EnterIdleDecommit();
- });
- }
- IdleDecommitSignal
- HeapInfoManager::LeaveIdleDecommit(bool allowTimer)
- {
- IdleDecommitSignal idleDecommitSignal = IdleDecommitSignal_None;
- ForEachHeapInfo([&idleDecommitSignal, allowTimer](HeapInfo& heapInfo)
- {
- IdleDecommitSignal signal = heapInfo.LeaveIdleDecommit(allowTimer);
- idleDecommitSignal = max(idleDecommitSignal, signal);
- });
- return idleDecommitSignal;
- }
- #ifdef IDLE_DECOMMIT_ENABLED
- DWORD
- HeapInfoManager::IdleDecommit()
- {
- DWORD waitTime = INFINITE;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- DWORD heapInfoWaitTime = heapInfo.IdleDecommit();
- waitTime = min(waitTime, heapInfoWaitTime);
- });
- return waitTime;
- }
- #endif
- #if DBG
- void
- HeapInfoManager::ShutdownIdleDecommit()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.ShutdownIdleDecommit();
- });
- }
- #endif
- #if ENABLE_BACKGROUND_PAGE_ZEROING
- void HeapInfoManager::StartQueueZeroPage()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.StartQueueZeroPage();
- });
- }
- void HeapInfoManager::StopQueueZeroPage()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.StopQueueZeroPage();
- });
- }
- void HeapInfoManager::BackgroundZeroQueuedPages()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.BackgroundZeroQueuedPages();
- });
- }
- void HeapInfoManager::ZeroQueuedPages()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.ZeroQueuedPages();
- });
- }
- \
- void HeapInfoManager::FlushBackgroundPages()
- {
- ForEachHeapInfo([](HeapInfo& heapInfo)
- {
- heapInfo.FlushBackgroundPages();
- });
- }
- #if DBG
- bool HeapInfoManager::HasZeroQueuedPages()
- {
- return IsAnyHeapInfo([](HeapInfo& heapInfo)
- {
- return heapInfo.HasZeroQueuedPages();
- });
- }
- #endif
- #endif
- void
- HeapInfoManager::DecommitNow(bool all)
- {
- ForEachHeapInfo([=](HeapInfo& heapInfo)
- {
- heapInfo.DecommitNow(all);
- });
- }
- size_t
- HeapInfoManager::GetUsedBytes()
- {
- size_t usedBytes = 0;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- usedBytes += heapInfo.GetUsedBytes();
- });
- return usedBytes;
- }
- size_t
- HeapInfoManager::GetReservedBytes()
- {
- size_t reservedBytes = 0;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- reservedBytes += heapInfo.GetReservedBytes();
- });
- return reservedBytes;
- }
- size_t
- HeapInfoManager::GetCommittedBytes()
- {
- size_t commitedBytes = 0;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- commitedBytes += heapInfo.GetCommittedBytes();
- });
- return commitedBytes;
- }
- size_t
- HeapInfoManager::GetNumberOfSegments()
- {
- size_t numberOfSegments = 0;
- ForEachHeapInfo([&](HeapInfo& heapInfo)
- {
- numberOfSegments += heapInfo.GetNumberOfSegments();
- });
- return numberOfSegments;
- }
- AllocationPolicyManager *
- HeapInfoManager::GetAllocationPolicyManager()
- {
- return this->defaultHeap.GetRecyclerLeafPageAllocator()->GetAllocationPolicyManager();
- }
- bool
- HeapInfoManager::IsRecyclerPageAllocator(PageAllocator * pageAllocator)
- {
- return IsAnyHeapInfo([=](HeapInfo& heapInfo)
- {
- return (heapInfo.GetRecyclerPageAllocator() == pageAllocator);
- });
- }
- bool
- HeapInfoManager::IsRecyclerLeafPageAllocator(PageAllocator * pageAllocator)
- {
- return IsAnyHeapInfo([=](HeapInfo& heapInfo)
- {
- return (heapInfo.GetRecyclerLeafPageAllocator() == pageAllocator);
- });
- }
- bool
- HeapInfoManager::IsRecyclerLargeBlockPageAllocator(PageAllocator * pageAllocator)
- {
- return IsAnyHeapInfo([=](HeapInfo& heapInfo)
- {
- return (heapInfo.GetRecyclerLargeBlockPageAllocator() == pageAllocator);
- });
- }
- #ifdef RECYCLER_WRITE_BARRIER
- bool
- HeapInfoManager::IsRecyclerWithBarrierPageAllocator(PageAllocator * pageAllocator)
- {
- return IsAnyHeapInfo([=](HeapInfo& heapInfo)
- {
- return (heapInfo.GetRecyclerWithBarrierPageAllocator() == pageAllocator);
- });
- }
- #endif
- #ifdef RECYCLER_PAGE_HEAP
- bool
- HeapInfoManager::DoCaptureAllocCallStack()
- {
- return IsAnyHeapInfo([=](HeapInfo& heapInfo)
- {
- return heapInfo.captureAllocCallStack;
- });
- }
- bool
- HeapInfoManager::DoCaptureFreeCallStack()
- {
- return IsAnyHeapInfo([=](HeapInfo& heapInfo)
- {
- return heapInfo.captureFreeCallStack;
- });
- }
- #endif
|