summaryrefslogtreecommitdiff
path: root/compiler/GHC/CmmToAsm
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 /compiler/GHC/CmmToAsm
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.
Diffstat (limited to 'compiler/GHC/CmmToAsm')
-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]