Skip to content

Commit 0cabeda

Browse files
committed
PreReservedSectionAllocWrapper should ZeroMemory for MEM_RELEASE
1 parent 3114b63 commit 0cabeda

1 file changed

Lines changed: 50 additions & 49 deletions

File tree

lib/Common/Memory/SectionAllocWrapper.cpp

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ AllocLocalView(HANDLE sectionHandle, LPVOID remoteBaseAddr, LPVOID remoteRequest
421421
#endif
422422
LPVOID address = nullptr;
423423
SIZE_T viewSize = requestSize + offsetAlignment;
424-
int status = NtdllLibrary::Instance->MapViewOfSection(sectionHandle, GetCurrentProcess(), &address, NULL, NULL, &mapOffset, &viewSize, NtdllLibrary::ViewUnmap, NULL, PAGE_READWRITE);
424+
int status = NtdllLibrary::Instance->MapViewOfSection(sectionHandle, GetCurrentProcess(), &address, NULL, viewSize, &mapOffset, &viewSize, NtdllLibrary::ViewUnmap, NULL, PAGE_READWRITE);
425425
if (status != 0 || address == nullptr)
426426
{
427427
return nullptr;
@@ -553,13 +553,16 @@ BOOL SectionAllocWrapper::Free(LPVOID lpAddress, size_t dwSize, DWORD dwFreeType
553553
else
554554
{
555555
Assert((dwFreeType & MEM_DECOMMIT) == MEM_DECOMMIT);
556-
LPVOID localAddr = AllocLocal(lpAddress, dwSize);
557-
if (localAddr == nullptr)
556+
for (size_t i = 0; i < dwSize / AutoSystemInfo::PageSize; ++i)
558557
{
559-
return FALSE;
558+
LPVOID localAddr = AllocLocal((char*)lpAddress + i * AutoSystemInfo::PageSize, AutoSystemInfo::PageSize);
559+
if (localAddr == nullptr)
560+
{
561+
return FALSE;
562+
}
563+
ZeroMemory(localAddr, AutoSystemInfo::PageSize);
564+
FreeLocal(localAddr);
560565
}
561-
ZeroMemory(localAddr, dwSize);
562-
FreeLocal(localAddr);
563566
DWORD oldFlags = NULL;
564567
if (!VirtualProtectEx(this->process, lpAddress, dwSize, PAGE_NOACCESS, &oldFlags))
565568
{
@@ -877,61 +880,59 @@ LPVOID PreReservedSectionAllocWrapper::Alloc(LPVOID lpAddress, size_t dwSize, DW
877880
BOOL
878881
PreReservedSectionAllocWrapper::Free(LPVOID lpAddress, size_t dwSize, DWORD dwFreeType)
879882
{
883+
AutoCriticalSection autocs(&this->cs);
884+
885+
if (dwSize == 0)
880886
{
881-
AutoCriticalSection autocs(&this->cs);
887+
Assert(false);
888+
return FALSE;
889+
}
882890

883-
if (dwSize == 0)
884-
{
885-
Assert(false);
886-
return FALSE;
887-
}
891+
if (this->preReservedStartAddress == nullptr)
892+
{
893+
Assert(false);
894+
return FALSE;
895+
}
896+
897+
Assert(dwSize % AutoSystemInfo::PageSize == 0);
888898

889-
if (this->preReservedStartAddress == nullptr)
899+
// zero one page at a time to minimize working set impact while zeroing
900+
for (size_t i = 0; i < dwSize / AutoSystemInfo::PageSize; ++i)
901+
{
902+
LPVOID localAddr = AllocLocal((char*)lpAddress + i * AutoSystemInfo::PageSize, AutoSystemInfo::PageSize);
903+
if (localAddr == nullptr)
890904
{
891-
Assert(false);
892905
return FALSE;
893906
}
907+
ZeroMemory(localAddr, AutoSystemInfo::PageSize);
908+
FreeLocal(localAddr);
909+
}
894910

895-
Assert(dwSize % AutoSystemInfo::PageSize == 0);
896-
BOOL success = TRUE;
897-
if((dwFreeType & MEM_DECOMMIT) == MEM_DECOMMIT)
898-
{
899-
LPVOID localAddr = AllocLocal(lpAddress, dwSize);
900-
if (localAddr == nullptr)
901-
{
902-
success = FALSE;
903-
}
904-
else
905-
{
906-
ZeroMemory(localAddr, dwSize);
907-
FreeLocal(localAddr);
908-
DWORD oldFlags = NULL;
909-
success = VirtualProtectEx(this->process, lpAddress, dwSize, PAGE_NOACCESS, &oldFlags);
910-
}
911-
}
912-
size_t requestedNumOfSegments = dwSize / AutoSystemInfo::Data.GetAllocationGranularityPageSize();
913-
Assert(requestedNumOfSegments <= MAXUINT32);
911+
DWORD oldFlags = NULL;
912+
if(!VirtualProtectEx(this->process, lpAddress, dwSize, PAGE_NOACCESS, &oldFlags))
913+
{
914+
return FALSE;
915+
}
914916

915-
if (success)
916-
{
917-
PreReservedHeapTrace(_u("MEM_DECOMMIT: Address: 0x%p of size: 0x%x bytes\n"), lpAddress, dwSize);
918-
}
917+
size_t requestedNumOfSegments = dwSize / AutoSystemInfo::Data.GetAllocationGranularityPageSize();
918+
Assert(requestedNumOfSegments <= MAXUINT32);
919919

920-
if ((dwFreeType & MEM_RELEASE) == MEM_RELEASE)
921-
{
922-
Assert((uintptr_t)lpAddress >= (uintptr_t)this->preReservedStartAddress);
923-
AssertMsg(((uintptr_t)lpAddress & (AutoSystemInfo::Data.GetAllocationGranularityPageCount() - 1)) == 0, "Not aligned with Allocation Granularity?");
924-
AssertMsg(dwSize % AutoSystemInfo::Data.GetAllocationGranularityPageSize() == 0, "Release size should match the allocation granularity size");
925-
Assert(requestedNumOfSegments != 0);
920+
PreReservedHeapTrace(_u("MEM_DECOMMIT: Address: 0x%p of size: 0x%x bytes\n"), lpAddress, dwSize);
926921

927-
BVIndex freeSegmentsBVIndex = (BVIndex)(((uintptr_t)lpAddress - (uintptr_t)this->preReservedStartAddress) / AutoSystemInfo::Data.GetAllocationGranularityPageSize());
928-
AssertMsg(freeSegmentsBVIndex < PreReservedAllocationSegmentCount, "Invalid Index ?");
929-
freeSegments.SetRange(freeSegmentsBVIndex, static_cast<uint>(requestedNumOfSegments));
930-
PreReservedHeapTrace(_u("MEM_RELEASE: Address: 0x%p of size: 0x%x * 0x%x bytes\n"), lpAddress, requestedNumOfSegments, AutoSystemInfo::Data.GetAllocationGranularityPageSize());
931-
}
922+
if ((dwFreeType & MEM_RELEASE) == MEM_RELEASE)
923+
{
924+
Assert((uintptr_t)lpAddress >= (uintptr_t)this->preReservedStartAddress);
925+
AssertMsg(((uintptr_t)lpAddress & (AutoSystemInfo::Data.GetAllocationGranularityPageCount() - 1)) == 0, "Not aligned with Allocation Granularity?");
926+
AssertMsg(dwSize % AutoSystemInfo::Data.GetAllocationGranularityPageSize() == 0, "Release size should match the allocation granularity size");
927+
Assert(requestedNumOfSegments != 0);
932928

933-
return success;
929+
BVIndex freeSegmentsBVIndex = (BVIndex)(((uintptr_t)lpAddress - (uintptr_t)this->preReservedStartAddress) / AutoSystemInfo::Data.GetAllocationGranularityPageSize());
930+
AssertMsg(freeSegmentsBVIndex < PreReservedAllocationSegmentCount, "Invalid Index ?");
931+
freeSegments.SetRange(freeSegmentsBVIndex, static_cast<uint>(requestedNumOfSegments));
932+
PreReservedHeapTrace(_u("MEM_RELEASE: Address: 0x%p of size: 0x%x * 0x%x bytes\n"), lpAddress, requestedNumOfSegments, AutoSystemInfo::Data.GetAllocationGranularityPageSize());
934933
}
934+
935+
return TRUE;
935936
}
936937

937938

0 commit comments

Comments
 (0)