@@ -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
877880BOOL
878881PreReservedSectionAllocWrapper::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