Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vorlicek <jan.vorlicek@volny.cz>2021-05-20 12:02:22 +0300
committerGitHub <noreply@github.com>2021-05-20 12:02:22 +0300
commit636f89d78efeda58e938534f9b1da1981e6c8575 (patch)
tree2db3eaa9328a8a3f60fcff818b3fd6f7fe02f668 /src/coreclr/utilcode
parent542ef8ba780303a63e628bbcd67d97586428be77 (diff)
Move metadata off the executable heaps (#52912)
* Move metadata off the executable heaps This change moves metadata structures that manage blocks of heap memory out of the heaps in preparation for the W^X changes that will make the heap memory read-execute only and modifying the metadata would require unnecessary mappings and unmappings of the memory as read-write. The structures moved in this change are the following: * LoaderHeapBlock * FreeBlock * HeapList * Remove unnecessary m_pCurBlock from the UnlockedLoaderHeap
Diffstat (limited to 'src/coreclr/utilcode')
-rw-r--r--src/coreclr/utilcode/loaderheap.cpp74
1 files changed, 30 insertions, 44 deletions
diff --git a/src/coreclr/utilcode/loaderheap.cpp b/src/coreclr/utilcode/loaderheap.cpp
index 8cfbba75659..33974b9e290 100644
--- a/src/coreclr/utilcode/loaderheap.cpp
+++ b/src/coreclr/utilcode/loaderheap.cpp
@@ -910,7 +910,6 @@ UnlockedLoaderHeap::UnlockedLoaderHeap(DWORD dwReserveBlockSize,
}
CONTRACTL_END;
- m_pCurBlock = NULL;
m_pFirstBlock = NULL;
m_dwReserveBlockSize = dwReserveBlockSize;
@@ -982,6 +981,8 @@ UnlockedLoaderHeap::~UnlockedLoaderHeap()
fSuccess = ClrVirtualFree(pVirtualAddress, 0, MEM_RELEASE);
_ASSERTE(fSuccess);
}
+
+ delete pSearch;
}
if (m_reservedBlock.m_fReleaseMemory)
@@ -1047,12 +1048,22 @@ size_t UnlockedLoaderHeap::GetBytesAvailReservedRegion()
#define SETUP_NEW_BLOCK(pData, dwSizeToCommit, dwSizeToReserve) \
m_pPtrToEndOfCommittedRegion = (BYTE *) (pData) + (dwSizeToCommit); \
- m_pAllocPtr = (BYTE *) (pData) + sizeof(LoaderHeapBlock); \
+ m_pAllocPtr = (BYTE *) (pData); \
m_pEndReservedRegion = (BYTE *) (pData) + (dwSizeToReserve);
#ifndef DACCESS_COMPILE
+void ReleaseReservedMemory(BYTE* value)
+{
+ if (value)
+ {
+ ClrVirtualFree(value, 0, MEM_RELEASE);
+ }
+}
+
+using ReservedMemoryHolder = SpecializedWrapper<BYTE, ReleaseReservedMemory>;
+
BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit)
{
CONTRACTL
@@ -1065,13 +1076,10 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit)
size_t dwSizeToReserve;
- // Add sizeof(LoaderHeapBlock)
- dwSizeToCommit += sizeof(LoaderHeapBlock);
-
// Round to page size again
dwSizeToCommit = ALIGN_UP(dwSizeToCommit, GetOsPageSize());
- void *pData = NULL;
+ ReservedMemoryHolder pData = NULL;
BOOL fReleaseMemory = TRUE;
// We were provided with a reserved memory block at instance creation time, so use it if it's big enough.
@@ -1079,7 +1087,7 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit)
m_reservedBlock.dwVirtualSize >= dwSizeToCommit)
{
// Get the info out of the block.
- pData = m_reservedBlock.pVirtualAddress;
+ pData = (PTR_BYTE)m_reservedBlock.pVirtualAddress;
dwSizeToReserve = m_reservedBlock.dwVirtualSize;
fReleaseMemory = m_reservedBlock.m_fReleaseMemory;
@@ -1126,16 +1134,17 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit)
return FALSE;
}
+ if (!fReleaseMemory)
+ {
+ pData.SuppressRelease();
+ }
+
// Commit first set of pages, since it will contain the LoaderHeapBlock
void *pTemp = ClrVirtualAlloc(pData, dwSizeToCommit, MEM_COMMIT, (m_Options & LHF_EXECUTABLE) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
if (pTemp == NULL)
{
//_ASSERTE(!"Unable to ClrVirtualAlloc commit in a loaderheap");
- // Unable to commit - release pages
- if (fReleaseMemory)
- ClrVirtualFree(pData, 0, MEM_RELEASE);
-
return FALSE;
}
@@ -1147,44 +1156,27 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit)
((const BYTE *) pData) + dwSizeToReserve,
(void *) this))
{
-
- if (fReleaseMemory)
- ClrVirtualFree(pData, 0, MEM_RELEASE);
-
return FALSE;
}
}
- m_dwTotalAlloc += dwSizeToCommit;
-
- LoaderHeapBlock *pNewBlock;
+ LoaderHeapBlock *pNewBlock = new (nothrow) LoaderHeapBlock;
+ if (pNewBlock == NULL)
+ {
+ return FALSE;
+ }
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- // Always assume we are touching executable heap
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+ m_dwTotalAlloc += dwSizeToCommit;
- pNewBlock = (LoaderHeapBlock *) pData;
+ pData.SuppressRelease();
pNewBlock->dwVirtualSize = dwSizeToReserve;
pNewBlock->pVirtualAddress = pData;
- pNewBlock->pNext = NULL;
+ pNewBlock->pNext = m_pFirstBlock;
pNewBlock->m_fReleaseMemory = fReleaseMemory;
- LoaderHeapBlock *pCurBlock = m_pCurBlock;
-
- // Add to linked list
- while (pCurBlock != NULL &&
- pCurBlock->pNext != NULL)
- pCurBlock = pCurBlock->pNext;
-
- if (pCurBlock != NULL)
- m_pCurBlock->pNext = pNewBlock;
- else
- m_pFirstBlock = pNewBlock;
-
- // If we want to use the memory immediately...
- m_pCurBlock = pNewBlock;
+ // Add to the linked list
+ m_pFirstBlock = pNewBlock;
SETUP_NEW_BLOCK(pData, dwSizeToCommit, dwSizeToReserve);
@@ -1827,16 +1819,11 @@ void UnlockedLoaderHeap::DumpFreeList()
size_t dwsize = pBlock->m_dwSize;
BOOL ccbad = FALSE;
BOOL sizeunaligned = FALSE;
- BOOL sizesmall = FALSE;
if ( 0 != (dwsize & ALLOC_ALIGN_CONSTANT) )
{
sizeunaligned = TRUE;
}
- if ( dwsize < sizeof(LoaderHeapBlock))
- {
- sizesmall = TRUE;
- }
for (size_t i = sizeof(LoaderHeapFreeBlock); i < dwsize; i++)
{
@@ -1850,7 +1837,6 @@ void UnlockedLoaderHeap::DumpFreeList()
printf("Addr = %pxh, Size = %lxh", pBlock, ((ULONG)dwsize));
if (ccbad) printf(" *** ERROR: NOT CC'd ***");
if (sizeunaligned) printf(" *** ERROR: size not a multiple of ALLOC_ALIGN_CONSTANT ***");
- if (sizesmall) printf(" *** ERROR: size smaller than sizeof(LoaderHeapFreeBlock) ***");
printf("\n");
pBlock = pBlock->m_pNext;