HeapInfoManager.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  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. namespace Memory
  7. {
  8. template <class Fn>
  9. bool HeapInfoManager::AreAllHeapInfo(Fn fn)
  10. {
  11. return fn(defaultHeap);
  12. }
  13. template <class Fn>
  14. bool HeapInfoManager::IsAnyHeapInfo(Fn fn)
  15. {
  16. return fn(defaultHeap);
  17. }
  18. template <class Fn>
  19. void HeapInfoManager::ForEachHeapInfo(Fn fn)
  20. {
  21. fn(defaultHeap);
  22. }
  23. template <class Fn>
  24. void HeapInfoManager::ForEachHeapInfo(RecyclerSweepManager& recyclerSweepManager, Fn fn)
  25. {
  26. fn(defaultHeap, recyclerSweepManager.defaultHeapRecyclerSweep);
  27. }
  28. template <class Fn>
  29. void HeapInfoManager::ForEachHeapInfo(RecyclerSweepManager * recyclerSweepManager, Fn fn)
  30. {
  31. fn(defaultHeap, recyclerSweepManager? &recyclerSweepManager->defaultHeapRecyclerSweep : nullptr);
  32. }
  33. HeapInfoManager::HeapInfoManager(AllocationPolicyManager * policyManager, Js::ConfigFlagsTable& configFlagsTable, IdleDecommitPageAllocator * leafPageAllocator) :
  34. defaultHeap(policyManager, configFlagsTable, leafPageAllocator),
  35. #if ENABLE_PARTIAL_GC
  36. uncollectedNewPageCount(0),
  37. unusedPartialCollectFreeBytes(0),
  38. #endif
  39. uncollectedAllocBytes(0),
  40. lastUncollectedAllocBytes(0),
  41. pendingZeroPageCount(0)
  42. {
  43. }
  44. void HeapInfoManager::Initialize(Recycler * recycler
  45. #ifdef RECYCLER_PAGE_HEAP
  46. , PageHeapMode pageheapmode
  47. , bool captureAllocCallStack
  48. , bool captureFreeCallStack
  49. #endif
  50. )
  51. {
  52. ForEachHeapInfo([=](HeapInfo& heapInfo)
  53. {
  54. heapInfo.Initialize(recycler
  55. #ifdef RECYCLER_PAGE_HEAP
  56. , pageheapmode
  57. , captureAllocCallStack
  58. , captureFreeCallStack
  59. #endif
  60. );
  61. });
  62. }
  63. #if defined(PROFILE_RECYCLER_ALLOC) || defined(RECYCLER_MEMORY_VERIFY) || defined(MEMSPECT_TRACKING) || defined(ETW_MEMORY_TRACKING)
  64. void HeapInfoManager::Initialize(Recycler * recycler, void(*trackNativeAllocCallBack)(Recycler *, void *, size_t)
  65. #ifdef RECYCLER_PAGE_HEAP
  66. , PageHeapMode pageheapmode
  67. , bool captureAllocCallStack
  68. , bool captureFreeCallStack
  69. #endif
  70. )
  71. {
  72. ForEachHeapInfo([=](HeapInfo& heapInfo)
  73. {
  74. heapInfo.Initialize(recycler, trackNativeAllocCallBack
  75. #ifdef RECYCLER_PAGE_HEAP
  76. , pageheapmode
  77. , captureAllocCallStack
  78. , captureFreeCallStack
  79. #endif
  80. );
  81. });
  82. }
  83. #endif
  84. void
  85. HeapInfoManager::ScanInitialImplicitRoots()
  86. {
  87. ForEachHeapInfo([](HeapInfo& heapInfo)
  88. {
  89. heapInfo.ScanInitialImplicitRoots();
  90. });
  91. }
  92. void
  93. HeapInfoManager::ScanNewImplicitRoots()
  94. {
  95. ForEachHeapInfo([](HeapInfo& heapInfo)
  96. {
  97. heapInfo.ScanNewImplicitRoots();
  98. });
  99. }
  100. void
  101. HeapInfoManager::ResetMarks(ResetMarkFlags flags)
  102. {
  103. ForEachHeapInfo([=](HeapInfo& heapInfo)
  104. {
  105. heapInfo.ResetMarks(flags);
  106. });
  107. }
  108. size_t
  109. HeapInfoManager::Rescan(RescanFlags flags)
  110. {
  111. size_t rescannedPageCount = 0;
  112. ForEachHeapInfo([&](HeapInfo& heapInfo)
  113. {
  114. rescannedPageCount += heapInfo.Rescan(flags);
  115. });
  116. return rescannedPageCount;
  117. }
  118. void
  119. HeapInfoManager::FinalizeAndSweep(RecyclerSweepManager& recyclerSweepManager, bool concurrent)
  120. {
  121. SuspendIdleDecommitNonLeaf();
  122. // Call finalize before sweeping so that the finalizer can still access object it referenced
  123. ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  124. {
  125. heapInfo.Finalize(recyclerSweep);
  126. });
  127. ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  128. {
  129. heapInfo.Sweep(recyclerSweep, concurrent);
  130. });
  131. ResumeIdleDecommitNonLeaf();
  132. }
  133. void
  134. HeapInfoManager::SweepSmallNonFinalizable(RecyclerSweepManager& recyclerSweepManager)
  135. {
  136. ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  137. {
  138. heapInfo.SweepSmallNonFinalizable(recyclerSweep);
  139. });
  140. }
  141. #if ENABLE_PARTIAL_GC || ENABLE_CONCURRENT_GC
  142. #ifdef RECYCLER_WRITE_WATCH
  143. void HeapInfoManager::EnableWriteWatch()
  144. {
  145. ForEachHeapInfo([](HeapInfo& heapInfo)
  146. {
  147. heapInfo.EnableWriteWatch();
  148. });
  149. }
  150. bool HeapInfoManager::ResetWriteWatch()
  151. {
  152. return AreAllHeapInfo([](HeapInfo& heapInfo)
  153. {
  154. return heapInfo.ResetWriteWatch();
  155. });
  156. }
  157. #if DBG
  158. size_t HeapInfoManager::GetWriteWatchPageCount()
  159. {
  160. size_t writeWatchPageCount = 0;
  161. ForEachHeapInfo([&](HeapInfo& heapInfo)
  162. {
  163. writeWatchPageCount += heapInfo.GetWriteWatchPageCount();
  164. });
  165. return writeWatchPageCount;
  166. }
  167. #endif
  168. #endif
  169. void
  170. HeapInfoManager::SweepPendingObjects(RecyclerSweepManager& recyclerSweepManager)
  171. {
  172. ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  173. {
  174. heapInfo.SweepPendingObjects(recyclerSweep);
  175. });
  176. }
  177. #endif
  178. #if ENABLE_PARTIAL_GC
  179. void
  180. HeapInfoManager::SweepPartialReusePages(RecyclerSweepManager& recyclerSweepManager)
  181. {
  182. ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  183. {
  184. heapInfo.SweepPartialReusePages(recyclerSweep);
  185. });
  186. }
  187. void
  188. HeapInfoManager::FinishPartialCollect(RecyclerSweepManager * recyclerSweepManager)
  189. {
  190. ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep * recyclerSweep)
  191. {
  192. heapInfo.FinishPartialCollect(recyclerSweep);
  193. });
  194. }
  195. #endif
  196. #if ENABLE_CONCURRENT_GC
  197. void
  198. HeapInfoManager::PrepareSweep()
  199. {
  200. ForEachHeapInfo([](HeapInfo& heapInfo)
  201. {
  202. heapInfo.PrepareSweep();
  203. });
  204. }
  205. #if ENABLE_ALLOCATIONS_DURING_CONCURRENT_SWEEP
  206. void
  207. HeapInfoManager::StartAllocationsDuringConcurrentSweep()
  208. {
  209. ForEachHeapInfo([](HeapInfo& heapInfo)
  210. {
  211. heapInfo.StartAllocationsDuringConcurrentSweep();
  212. });
  213. }
  214. bool
  215. HeapInfoManager::DoTwoPassConcurrentSweepPreCheck()
  216. {
  217. return IsAnyHeapInfo([](HeapInfo& heapInfo)
  218. {
  219. return heapInfo.DoTwoPassConcurrentSweepPreCheck();
  220. });
  221. }
  222. void
  223. HeapInfoManager::FinishSweepPrep(RecyclerSweepManager& recyclerSweepManager)
  224. {
  225. ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  226. {
  227. heapInfo.FinishSweepPrep(recyclerSweep);
  228. });
  229. }
  230. void
  231. HeapInfoManager::FinishConcurrentSweepPass1(RecyclerSweepManager& recyclerSweepManager)
  232. {
  233. ForEachHeapInfo(recyclerSweepManager, [=](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  234. {
  235. heapInfo.FinishConcurrentSweepPass1(recyclerSweep);
  236. });
  237. }
  238. void
  239. HeapInfoManager::FinishConcurrentSweep()
  240. {
  241. ForEachHeapInfo([](HeapInfo& heapInfo)
  242. {
  243. heapInfo.FinishConcurrentSweep();
  244. });
  245. }
  246. #endif
  247. void
  248. HeapInfoManager::ConcurrentTransferSweptObjects(RecyclerSweepManager& recyclerSweepManager)
  249. {
  250. ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  251. {
  252. heapInfo.ConcurrentTransferSweptObjects(recyclerSweep);
  253. });
  254. }
  255. #if ENABLE_PARTIAL_GC
  256. void
  257. HeapInfoManager::ConcurrentPartialTransferSweptObjects(RecyclerSweepManager& recyclerSweepManager)
  258. {
  259. ForEachHeapInfo(recyclerSweepManager, [&](HeapInfo& heapInfo, RecyclerSweep& recyclerSweep)
  260. {
  261. heapInfo.ConcurrentPartialTransferSweptObjects(recyclerSweep);
  262. });
  263. }
  264. #endif
  265. #endif
  266. void
  267. HeapInfoManager::DisposeObjects()
  268. {
  269. ForEachHeapInfo([](HeapInfo& heapInfo)
  270. {
  271. heapInfo.DisposeObjects();
  272. });
  273. }
  274. void
  275. HeapInfoManager::TransferDisposedObjects()
  276. {
  277. ForEachHeapInfo([](HeapInfo& heapInfo)
  278. {
  279. heapInfo.TransferDisposedObjects();
  280. });
  281. }
  282. void
  283. HeapInfoManager::EnumerateObjects(ObjectInfoBits infoBits, void(*CallBackFunction)(void * address, size_t size))
  284. {
  285. ForEachHeapInfo([=](HeapInfo& heapInfo)
  286. {
  287. heapInfo.EnumerateObjects(infoBits, CallBackFunction);
  288. });
  289. }
  290. #if DBG
  291. bool
  292. HeapInfoManager::AllocatorsAreEmpty()
  293. {
  294. return AreAllHeapInfo([](HeapInfo& heapInfo)
  295. {
  296. return heapInfo.AllocatorsAreEmpty();
  297. });
  298. }
  299. void
  300. HeapInfoManager::ResetThreadId()
  301. {
  302. ForEachHeapInfo([](HeapInfo& heapInfo)
  303. {
  304. return heapInfo.ResetThreadId();
  305. });
  306. }
  307. void
  308. HeapInfoManager::SetDisableThreadAccessCheck()
  309. {
  310. ForEachHeapInfo([](HeapInfo& heapInfo)
  311. {
  312. return heapInfo.SetDisableThreadAccessCheck();
  313. });
  314. }
  315. #endif
  316. #ifdef RECYCLER_FINALIZE_CHECK
  317. size_t
  318. HeapInfoManager::GetFinalizeCount()
  319. {
  320. size_t finalizeCount = 0;
  321. ForEachHeapInfo([&](HeapInfo& heapInfo)
  322. {
  323. finalizeCount += heapInfo.GetFinalizeCount();
  324. });
  325. return finalizeCount;
  326. }
  327. #endif
  328. #ifdef RECYCLER_SLOW_CHECK_ENABLED
  329. void
  330. HeapInfoManager::Check()
  331. {
  332. ForEachHeapInfo([](HeapInfo& heapInfo)
  333. {
  334. heapInfo.Check();
  335. });
  336. }
  337. #endif
  338. #ifdef RECYCLER_MEMORY_VERIFY
  339. void
  340. HeapInfoManager::EnableVerify()
  341. {
  342. ForEachHeapInfo([](HeapInfo& heapInfo)
  343. {
  344. heapInfo.EnableVerify();
  345. });
  346. }
  347. void
  348. HeapInfoManager::Verify()
  349. {
  350. ForEachHeapInfo([](HeapInfo& heapInfo)
  351. {
  352. heapInfo.Verify();
  353. });
  354. }
  355. #endif
  356. #ifdef RECYCLER_VERIFY_MARK
  357. void
  358. HeapInfoManager::VerifyMark()
  359. {
  360. ForEachHeapInfo([](HeapInfo& heapInfo)
  361. {
  362. heapInfo.VerifyMark();
  363. });
  364. }
  365. #endif
  366. #ifdef RECYCLER_NO_PAGE_REUSE
  367. void
  368. HeapInfoManager::DisablePageReuse()
  369. {
  370. ForEachHeapInfo([](HeapInfo& heapInfo)
  371. {
  372. heapInfo.DisablePageReuse();
  373. });
  374. }
  375. #endif
  376. }
  377. #ifdef ENABLE_MEM_STATS
  378. #include "BucketStatsReporter.h"
  379. namespace Memory
  380. {
  381. // REVIEW: this is in the wrong place
  382. void
  383. HeapInfoManager::ReportMemStats(Recycler * recycler)
  384. {
  385. ::Memory::BucketStatsReporter report(recycler);
  386. if (!report.IsEnabled())
  387. {
  388. return;
  389. }
  390. ForEachHeapInfo([&](HeapInfo& heapInfo)
  391. {
  392. heapInfo.GetBucketStats(report);
  393. });
  394. report.Report();
  395. }
  396. }
  397. #endif
  398. #ifdef RECYCLER_PAGE_HEAP
  399. bool
  400. HeapInfoManager::IsPageHeapEnabled()
  401. {
  402. return IsAnyHeapInfo([](HeapInfo& heapInfo)
  403. {
  404. return heapInfo.IsPageHeapEnabled();
  405. });
  406. }
  407. #endif
  408. // ==============================================================
  409. // Page allocator APIs
  410. // ==============================================================
  411. void
  412. HeapInfoManager::Prime()
  413. {
  414. ForEachHeapInfo([](HeapInfo& heapInfo)
  415. {
  416. heapInfo.Prime();
  417. });
  418. }
  419. void
  420. HeapInfoManager::Close()
  421. {
  422. ForEachHeapInfo([](HeapInfo& heapInfo)
  423. {
  424. heapInfo.CloseNonLeaf();
  425. });
  426. }
  427. void
  428. HeapInfoManager::SuspendIdleDecommitNonLeaf()
  429. {
  430. ForEachHeapInfo([](HeapInfo& heapInfo)
  431. {
  432. heapInfo.SuspendIdleDecommitNonLeaf();
  433. });
  434. }
  435. void
  436. HeapInfoManager::ResumeIdleDecommitNonLeaf()
  437. {
  438. ForEachHeapInfo([](HeapInfo& heapInfo)
  439. {
  440. heapInfo.ResumeIdleDecommitNonLeaf();
  441. });
  442. }
  443. void
  444. HeapInfoManager::EnterIdleDecommit()
  445. {
  446. ForEachHeapInfo([](HeapInfo& heapInfo)
  447. {
  448. heapInfo.EnterIdleDecommit();
  449. });
  450. }
  451. IdleDecommitSignal
  452. HeapInfoManager::LeaveIdleDecommit(bool allowTimer)
  453. {
  454. IdleDecommitSignal idleDecommitSignal = IdleDecommitSignal_None;
  455. ForEachHeapInfo([&idleDecommitSignal, allowTimer](HeapInfo& heapInfo)
  456. {
  457. IdleDecommitSignal signal = heapInfo.LeaveIdleDecommit(allowTimer);
  458. idleDecommitSignal = max(idleDecommitSignal, signal);
  459. });
  460. return idleDecommitSignal;
  461. }
  462. #ifdef IDLE_DECOMMIT_ENABLED
  463. DWORD
  464. HeapInfoManager::IdleDecommit()
  465. {
  466. DWORD waitTime = INFINITE;
  467. ForEachHeapInfo([&](HeapInfo& heapInfo)
  468. {
  469. DWORD heapInfoWaitTime = heapInfo.IdleDecommit();
  470. waitTime = min(waitTime, heapInfoWaitTime);
  471. });
  472. return waitTime;
  473. }
  474. #endif
  475. #if DBG
  476. void
  477. HeapInfoManager::ShutdownIdleDecommit()
  478. {
  479. ForEachHeapInfo([](HeapInfo& heapInfo)
  480. {
  481. heapInfo.ShutdownIdleDecommit();
  482. });
  483. }
  484. #endif
  485. #if ENABLE_BACKGROUND_PAGE_ZEROING
  486. void HeapInfoManager::StartQueueZeroPage()
  487. {
  488. ForEachHeapInfo([](HeapInfo& heapInfo)
  489. {
  490. heapInfo.StartQueueZeroPage();
  491. });
  492. }
  493. void HeapInfoManager::StopQueueZeroPage()
  494. {
  495. ForEachHeapInfo([](HeapInfo& heapInfo)
  496. {
  497. heapInfo.StopQueueZeroPage();
  498. });
  499. }
  500. void HeapInfoManager::BackgroundZeroQueuedPages()
  501. {
  502. ForEachHeapInfo([](HeapInfo& heapInfo)
  503. {
  504. heapInfo.BackgroundZeroQueuedPages();
  505. });
  506. }
  507. void HeapInfoManager::ZeroQueuedPages()
  508. {
  509. ForEachHeapInfo([](HeapInfo& heapInfo)
  510. {
  511. heapInfo.ZeroQueuedPages();
  512. });
  513. }
  514. \
  515. void HeapInfoManager::FlushBackgroundPages()
  516. {
  517. ForEachHeapInfo([](HeapInfo& heapInfo)
  518. {
  519. heapInfo.FlushBackgroundPages();
  520. });
  521. }
  522. #if DBG
  523. bool HeapInfoManager::HasZeroQueuedPages()
  524. {
  525. return IsAnyHeapInfo([](HeapInfo& heapInfo)
  526. {
  527. return heapInfo.HasZeroQueuedPages();
  528. });
  529. }
  530. #endif
  531. #endif
  532. void
  533. HeapInfoManager::DecommitNow(bool all)
  534. {
  535. ForEachHeapInfo([=](HeapInfo& heapInfo)
  536. {
  537. heapInfo.DecommitNow(all);
  538. });
  539. }
  540. size_t
  541. HeapInfoManager::GetUsedBytes()
  542. {
  543. size_t usedBytes = 0;
  544. ForEachHeapInfo([&](HeapInfo& heapInfo)
  545. {
  546. usedBytes += heapInfo.GetUsedBytes();
  547. });
  548. return usedBytes;
  549. }
  550. size_t
  551. HeapInfoManager::GetReservedBytes()
  552. {
  553. size_t reservedBytes = 0;
  554. ForEachHeapInfo([&](HeapInfo& heapInfo)
  555. {
  556. reservedBytes += heapInfo.GetReservedBytes();
  557. });
  558. return reservedBytes;
  559. }
  560. size_t
  561. HeapInfoManager::GetCommittedBytes()
  562. {
  563. size_t commitedBytes = 0;
  564. ForEachHeapInfo([&](HeapInfo& heapInfo)
  565. {
  566. commitedBytes += heapInfo.GetCommittedBytes();
  567. });
  568. return commitedBytes;
  569. }
  570. size_t
  571. HeapInfoManager::GetNumberOfSegments()
  572. {
  573. size_t numberOfSegments = 0;
  574. ForEachHeapInfo([&](HeapInfo& heapInfo)
  575. {
  576. numberOfSegments += heapInfo.GetNumberOfSegments();
  577. });
  578. return numberOfSegments;
  579. }
  580. AllocationPolicyManager *
  581. HeapInfoManager::GetAllocationPolicyManager()
  582. {
  583. return this->defaultHeap.GetRecyclerLeafPageAllocator()->GetAllocationPolicyManager();
  584. }
  585. bool
  586. HeapInfoManager::IsRecyclerPageAllocator(PageAllocator * pageAllocator)
  587. {
  588. return IsAnyHeapInfo([=](HeapInfo& heapInfo)
  589. {
  590. return (heapInfo.GetRecyclerPageAllocator() == pageAllocator);
  591. });
  592. }
  593. bool
  594. HeapInfoManager::IsRecyclerLeafPageAllocator(PageAllocator * pageAllocator)
  595. {
  596. return IsAnyHeapInfo([=](HeapInfo& heapInfo)
  597. {
  598. return (heapInfo.GetRecyclerLeafPageAllocator() == pageAllocator);
  599. });
  600. }
  601. bool
  602. HeapInfoManager::IsRecyclerLargeBlockPageAllocator(PageAllocator * pageAllocator)
  603. {
  604. return IsAnyHeapInfo([=](HeapInfo& heapInfo)
  605. {
  606. return (heapInfo.GetRecyclerLargeBlockPageAllocator() == pageAllocator);
  607. });
  608. }
  609. #ifdef RECYCLER_WRITE_BARRIER
  610. bool
  611. HeapInfoManager::IsRecyclerWithBarrierPageAllocator(PageAllocator * pageAllocator)
  612. {
  613. return IsAnyHeapInfo([=](HeapInfo& heapInfo)
  614. {
  615. return (heapInfo.GetRecyclerWithBarrierPageAllocator() == pageAllocator);
  616. });
  617. }
  618. #endif
  619. #ifdef RECYCLER_PAGE_HEAP
  620. bool
  621. HeapInfoManager::DoCaptureAllocCallStack()
  622. {
  623. return IsAnyHeapInfo([=](HeapInfo& heapInfo)
  624. {
  625. return heapInfo.captureAllocCallStack;
  626. });
  627. }
  628. bool
  629. HeapInfoManager::DoCaptureFreeCallStack()
  630. {
  631. return IsAnyHeapInfo([=](HeapInfo& heapInfo)
  632. {
  633. return heapInfo.captureFreeCallStack;
  634. });
  635. }
  636. #endif