summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheng Shao <terrorjack@type.dance>2023-01-29 16:02:49 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2023-02-01 13:18:47 +0000
commitc4cc32d9e8b29e913324a44a74ed021b7bb7e165 (patch)
tree15613e9c3f697e6f269a59e246b8287df934ef36
parent5695611e5636a7f496f05c925b76009c4c7a1123 (diff)
downloadhaskell-c4cc32d9e8b29e913324a44a74ed021b7bb7e165.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. (cherry picked from commit da468391872f6be286db37a0f016a37f9f362509)
-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]