From 75956767b2c172497c553f151e35c5b8d50b524f Mon Sep 17 00:00:00 2001
From: Cheng Shao <terrorjack@type.dance>
Date: Mon, 10 Jun 2024 12:50:23 +0000
Subject: [PATCH] rts: use page sized mblocks on wasm

This patch changes mblock size to page size on wasm. It allows us to
simplify our wasi-libc fork, makes it much easier to test third party
libc allocators like emmalloc/mimalloc, as well as experimenting with
threaded RTS in wasm.

(cherry picked from commit 558353f4e22643b94b9710a45c3364c518d57b46)
(cherry picked from commit f3ea9fb8ed92952941408c39885722e9ed1c2f70)
(cherry picked from commit f747805fcab09336f095c22e632171d1ffc996be)
---
 .../tests/T18757.stdout-wasm32-unknown-wasi   |  1 +
 rts/include/rts/Constants.h                   |  4 +++
 rts/sm/NonMoving.h                            |  5 ++++
 rts/wasm/OSMem.c                              | 27 ++++++-------------
 4 files changed, 18 insertions(+), 19 deletions(-)
 create mode 100644 libraries/ghc-compact/tests/T18757.stdout-wasm32-unknown-wasi

diff --git a/libraries/ghc-compact/tests/T18757.stdout-wasm32-unknown-wasi b/libraries/ghc-compact/tests/T18757.stdout-wasm32-unknown-wasi
new file mode 100644
index 00000000000..ca45db43d2a
--- /dev/null
+++ b/libraries/ghc-compact/tests/T18757.stdout-wasm32-unknown-wasi
@@ -0,0 +1 @@
+[61420,61420,61420,60388,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132,60132]
diff --git a/rts/include/rts/Constants.h b/rts/include/rts/Constants.h
index 3bf5a7a2d5a..31e783af3b3 100644
--- a/rts/include/rts/Constants.h
+++ b/rts/include/rts/Constants.h
@@ -170,7 +170,11 @@
 #define BLOCK_SHIFT  12
 
 /* The size of a megablock (2^MBLOCK_SHIFT bytes) */
+#if defined(wasm32_HOST_ARCH)
+#define MBLOCK_SHIFT   16
+#else
 #define MBLOCK_SHIFT   20
+#endif
 
 /* -----------------------------------------------------------------------------
    Bitmap/size fields (used in info tables)
diff --git a/rts/sm/NonMoving.h b/rts/sm/NonMoving.h
index 90763089f68..979b03102c3 100644
--- a/rts/sm/NonMoving.h
+++ b/rts/sm/NonMoving.h
@@ -17,7 +17,12 @@
 #include "BeginPrivate.h"
 
 // Segments
+#if defined(wasm32_HOST_ARCH)
+#define NONMOVING_SEGMENT_BITS 14ULL   // 2^14 = 16kByte
+#else
 #define NONMOVING_SEGMENT_BITS 15ULL   // 2^15 = 32kByte
+#endif
+
 // Mask to find base of segment
 #define NONMOVING_SEGMENT_MASK (((uintptr_t)1 << NONMOVING_SEGMENT_BITS) - 1)
 // In bytes
diff --git a/rts/wasm/OSMem.c b/rts/wasm/OSMem.c
index ff4217f413e..d01b3361a0e 100644
--- a/rts/wasm/OSMem.c
+++ b/rts/wasm/OSMem.c
@@ -32,14 +32,8 @@
 // libc allocator's certain invariants. But dlmalloc permits this
 // behavior!
 //
-// Therefore, we bypass dlmalloc, and directly call memory.grow to
-// allocate megablocks. We even patch dlmalloc in the libc sysroot
-// shipped in our wasi-sdk release, so that whenever dlmalloc calls
-// sbrk(), it extends the linear memory to align to the megablock
-// size, so to avoid space waste as much as possible. Our wasi-libc
-// patch doesn't impact ABI interoperability, and when stock clang
-// compiles code that calls malloc() to wasm objects, those objects
-// would just link fine with our build products.
+// Therefore, we bypass dlmalloc, and directly call sbrk() to
+// allocate megablocks.
 //
 // One remaining question is how to free a megablock. Wasm spec
 // doesn't allow shrinking the linear memory, so the logic of
@@ -49,12 +43,13 @@
 // megablock on Wasm.
 
 #include "Rts.h"
-
-#include "RtsUtils.h"
 #include "sm/OSMem.h"
-#include "rts/storage/HeapAlloc.h"
 
-#include <__macro_PAGESIZE.h>
+#include <unistd.h>
+
+#define PAGESIZE (0x10000)
+
+GHC_STATIC_ASSERT(MBLOCK_SIZE == PAGESIZE, "MBLOCK_SIZE must be equal to wasm page size");
 
 void osMemInit(void)
 {
@@ -63,13 +58,7 @@ void osMemInit(void)
 void *
 osGetMBlocks(uint32_t n)
 {
-  size_t base = __builtin_wasm_memory_size(0) * PAGESIZE;
-  size_t start = MBLOCK_ROUND_UP(base);
-  size_t end = start + (n << MBLOCK_SHIFT);
-  ptrdiff_t delta = (end - base) / PAGESIZE;
-  if (__builtin_wasm_memory_grow(0, delta) == SIZE_MAX)
-    barf("osGetMBlocks failed");
-  return start;
+  return sbrk(PAGESIZE * n);
 }
 
 void osBindMBlocksToNode(
-- 
GitLab