summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheng Shao <terrorjack@type.dance>2023-01-29 16:02:49 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-01-30 05:07:03 -0500
commitda468391872f6be286db37a0f016a37f9f362509 (patch)
treedd3a62fcd828c9825dfc98f1667aafe4b50f520c
parent8bed166bb79445f90015757fd5baac69a7b835df (diff)
downloadhaskell-da468391872f6be286db37a0f016a37f9f362509.tar.gz
compiler: fix data section alignment in the wasm NCG
Previously we tried to lower the alignment requirement as far as possible, based on the section kind inferred from the CLabel. For info tables, .p2align 1 was applied given the GC should only need the lowest bit to tag forwarding pointers. But this would lead to unaligned loads/stores, which has a performance penalty even if the wasm spec permits it. Furthermore, the test suite has shown memory corruption in a few cases when compacting gc is used. This patch takes a more conservative approach: all data sections except C strings align to word size.
-rw-r--r--compiler/GHC/CmmToAsm/Wasm/FromCmm.hs20
1 files changed, 10 insertions, 10 deletions
diff --git a/compiler/GHC/CmmToAsm/Wasm/FromCmm.hs b/compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
index 52cba6f0a8..8e4f285d27 100644
--- a/compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
+++ b/compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
@@ -123,15 +123,15 @@ alignmentFromWordType TagI32 = mkAlignment 4
alignmentFromWordType TagI64 = mkAlignment 8
alignmentFromWordType _ = panic "alignmentFromWordType: unreachable"
--- | Calculate a data section's alignment. Closures needs to be
--- naturally aligned; info tables need to align to 2, so to get 1 tag
--- bit as forwarding pointer marker. The rest have no alignment
--- requirements.
-alignmentFromCmmSection :: WasmTypeTag w -> CLabel -> Alignment
-alignmentFromCmmSection t lbl
- | isStaticClosureLabel lbl = alignmentFromWordType t
- | isInfoTableLabel lbl = mkAlignment 2
- | otherwise = mkAlignment 1
+-- | Calculate a data section's alignment. As a conservative
+-- optimization, a data section with a single CmmString/CmmFileEmbed
+-- has no alignment requirement, otherwise we always align to the word
+-- size to satisfy pointer tagging requirements and avoid unaligned
+-- loads/stores.
+alignmentFromCmmSection :: WasmTypeTag w -> [DataSectionContent] -> Alignment
+alignmentFromCmmSection _ [DataASCII {}] = mkAlignment 1
+alignmentFromCmmSection _ [DataIncBin {}] = mkAlignment 1
+alignmentFromCmmSection t _ = alignmentFromWordType t
-- | Lower a 'CmmStatic'.
lower_CmmStatic :: CmmStatic -> WasmCodeGenM w DataSectionContent
@@ -1650,7 +1650,7 @@ onCmmData lbl s statics = do
{ dataSectionKind =
dataSectionKindFromCmmSection s,
dataSectionAlignment =
- alignmentFromCmmSection ty_word lbl,
+ alignmentFromCmmSection ty_word cs,
dataSectionContents =
case cs of
[DataASCII buf] -> [DataASCII $ buf `BS.snoc` 0]