protected override void Dispose()

in src/Microsoft.Diagnostics.Runtime/Windows/AWEBasedCacheEntry.cs [208:276]


        protected override void Dispose(bool disposing)
        {
            for (int i = 0; i < _pages.Length; i++)
            {
                ReaderWriterLockSlim pageLock = _pageLocks[i];
                pageLock.EnterWriteLock();

                try
                {
                    CachePage<UIntPtr> page = _pages[i];
                    if (page != null)
                    {
                        // NOTE: While VirtualAllocPageSize SHOULD be a multiple of SystemPageSize there is no guarantee I can find that says that is true always and everywhere
                        // so to be safe I make sure we don't leave any straggling pages behind if that is true.
                        uint numberOfPages = (uint)(page.DataExtent / (ulong)SystemPageSize) + ((page.DataExtent % (ulong)SystemPageSize) == 0 ? 0U : 1U);

                        // We need to unmap the physical memory from this VM range and then free the VM range
                        bool unmapPhysicalPagesResult = CacheNativeMethods.AWE.MapUserPhysicalPages(page.Data, numberOfPages, pageArray: UIntPtr.Zero);
                        if (!unmapPhysicalPagesResult)
                        {
                            Debug.Fail("MapUserPhysicalPage failed to unmap a physical page");

                            // this is an error but we don't want to remove the ptr entry since we apparently didn't unmap the physical memory
                            continue;
                        }

                        // NOTE: When calling with VirtualFreeTypeRelease sizeToFree must be 0 (which indicates the entire allocation)
                        bool virtualFreeRes = CacheNativeMethods.Memory.VirtualFree(page.Data, sizeToFree: UIntPtr.Zero, CacheNativeMethods.Memory.VirtualFreeType.Release);
                        if (!virtualFreeRes)
                        {
                            Debug.Fail("MapUserPhysicalPage failed to unmap a physical page");

                            // this is an error but we already unmapped the physical memory so also throw away our VM pointer
                            _pages[i] = null;

                            continue;
                        }

                        // Done, throw away our VM pointer
                        _pages[i] = null;
                    }
                }
                finally
                {
                    pageLock.ExitWriteLock();

                    if (_pages[i] == null)
                    {
                        pageLock.Dispose();
                    }
                }
            }

            uint numberOfPagesToFree = (uint)_pageFrameArrayItemCount;
            bool freeUserPhyiscalPagesRes = CacheNativeMethods.AWE.FreeUserPhysicalPages(ref numberOfPagesToFree, _pageFrameArray);
            if (!freeUserPhyiscalPagesRes)
            {
                Debug.Fail("Failed to free our physical pages");
            }

            if (numberOfPagesToFree != _pageFrameArrayItemCount)
            {
                Debug.Fail("Failed to free ALL of our physical pages");
            }

            // Free our page frame array
            CacheNativeMethods.Memory.HeapFree(_pageFrameArray);
            _pageFrameArray = UIntPtr.Zero;
        }