From abab915714274070c7afff76bc014d04a8c1f78b Mon Sep 17 00:00:00 2001
From: Ben Gamari <ben@smart-cactus.org>
Date: Wed, 25 Nov 2020 10:54:31 -0500
Subject: [PATCH] rts: Allocate MBlocks with MAP_TOP_DOWN on Windows

As noted in #18991, we would previously allocate heap in low memory.
Due to this the linker, which typically *needs* low memory, would end up
competing with the heap. In longer builds we end up running out of
low memory entirely, leading to linking failures.

(cherry picked from commit a1a75aa9be2c133dd1372a08eeb6a92c31688df7)
---
 rts/win32/OSMem.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/rts/win32/OSMem.c b/rts/win32/OSMem.c
index 35fe72fd58ba..07247e54b9f8 100644
--- a/rts/win32/OSMem.c
+++ b/rts/win32/OSMem.c
@@ -67,8 +67,11 @@ allocNew(uint32_t n) {
     alloc_rec* rec;
     rec = (alloc_rec*)stgMallocBytes(sizeof(alloc_rec),"getMBlocks: allocNew");
     rec->size = ((W_)n+1)*MBLOCK_SIZE;
+    // N.B. We use MEM_TOP_DOWN here to ensure that we leave the bottom of the
+    // address space available for the linker and libraries, which in general
+    // want to live in low memory. See #18991.
     rec->base =
-        VirtualAlloc(NULL, rec->size, MEM_RESERVE, PAGE_READWRITE);
+        VirtualAlloc(NULL, rec->size, MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE);
     if(rec->base==0) {
         stgFree((void*)rec);
         rec=0;
-- 
GitLab