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;
}