Fix mapping of files from bundle to only map the necessary part (#42402)
authorVitek Karas <vitek.karas@microsoft.com>
Mon, 21 Sep 2020 13:20:13 +0000 (06:20 -0700)
committerGitHub <noreply@github.com>
Mon, 21 Sep 2020 13:20:13 +0000 (06:20 -0700)
Mapping the whole bundle every time leads to VM space starvation. Which mostly matters on 32bit.

src/coreclr/src/vm/peimagelayout.cpp

index 00098c2..ad0114a 100644 (file)
@@ -712,14 +712,22 @@ FlatImageLayout::FlatImageLayout(PEImage* pOwner)
         if (m_FileMap == NULL)
             ThrowLastError();
 
-        //DWORD lowPart = (DWORD)offset;
-        //DWORD highPart = (DWORD)(offset >> 32);
-        char *addr = (char*)CLRMapViewOfFile(m_FileMap, FILE_MAP_READ, 0, 0, 0);
-        addr += offset;
-        m_FileView.Assign((LPVOID)addr);
-
-        if (m_FileView == NULL)
+        // - Windows - MapViewOfFileEx requires offset to be allocation granularity aligned (typically 64KB)
+        // - Linux/OSX - mmap requires offset to be page aligned (PAL sets allocation granularity to page size)
+        UINT32 alignment = g_SystemInfo.dwAllocationGranularity;
+        UINT64 mapBegin = AlignDown((UINT64)offset, alignment);
+        UINT64 mapSize = ((UINT64)(offset + size)) - mapBegin;
+
+        _ASSERTE((offset - mapBegin) < alignment);
+        _ASSERTE((offset - mapBegin) < mapSize);
+        _ASSERTE(mapSize >= (UINT64)size);
+
+        char *addr = (char*)CLRMapViewOfFile(m_FileMap, FILE_MAP_READ, mapBegin >> 32, (DWORD)mapBegin, (DWORD)mapSize);
+        if (addr == NULL)
             ThrowLastError();
+
+        addr += (offset - mapBegin);
+        m_FileView.Assign((LPVOID)addr);
     }
     Init(m_FileView, (COUNT_T)size);
 }