d4cad0e03ebe22e0b18cfce26eab2cf0b29d610d
[ghc.git] / compiler / deSugar / StaticPtrTable.hs
1 -- | Code generation for the Static Pointer Table
2 --
3 -- (c) 2014 I/O Tweag
4 --
5 -- Each module that uses 'static' keyword declares an initialization function of
6 -- the form hs_spt_init_<module>() which is emitted into the _stub.c file and
7 -- annotated with __attribute__((constructor)) so that it gets executed at
8 -- startup time.
9 --
10 -- The function's purpose is to call hs_spt_insert to insert the static
11 -- pointers of this module in the hashtable of the RTS, and it looks something
12 -- like this:
13 --
14 -- > static void hs_hpc_init_Main(void) __attribute__((constructor));
15 -- > static void hs_hpc_init_Main(void) {
16 -- >
17 -- > static StgWord64 k0[2] = {16252233372134256ULL,7370534374096082ULL};
18 -- > extern StgPtr Main_sptEntryZC0_closure;
19 -- > hs_spt_insert(k0, &Main_sptEntryZC0_closure);
20 -- >
21 -- > static StgWord64 k1[2] = {12545634534567898ULL,5409674567544151ULL};
22 -- > extern StgPtr Main_sptEntryZC1_closure;
23 -- > hs_spt_insert(k1, &Main_sptEntryZC1_closure);
24 -- >
25 -- > }
26 --
27 -- where constants are values of a fingerprint of the string
28 -- "<package_id>:<module_name>.sptEntry:<N>"
29 --
30 module StaticPtrTable (sptInitCode) where
31
32 import CoreSyn
33 import Module
34 import Outputable
35 import Id
36 import CLabel
37 import GHC.Fingerprint
38
39
40 -- | @sptInitCode module statics@ is a C stub to insert the static entries
41 -- @statics@ of @module@ into the static pointer table
42 --
43 -- Each entry contains the fingerprint used to locate the entry and the
44 -- top-level binding for the entry.
45 --
46 sptInitCode :: Module -> [(Fingerprint, (Id,CoreExpr))] -> SDoc
47 sptInitCode _ [] = Outputable.empty
48 sptInitCode this_mod entries = vcat
49 [ text "static void hs_spt_init_" <> ppr this_mod
50 <> text "(void) __attribute__((constructor));"
51 , text "static void hs_spt_init_" <> ppr this_mod <> text "(void)"
52 , braces $ vcat $
53 [ text "static StgWord64 k" <> int i <> text "[2] = "
54 <> pprFingerprint fp <> semi
55 $$ text "extern StgPtr "
56 <> (ppr $ mkClosureLabel (idName n) (idCafInfo n)) <> semi
57 $$ text "hs_spt_insert" <> parens
58 (hcat $ punctuate comma
59 [ char 'k' <> int i
60 , char '&' <> ppr (mkClosureLabel (idName n) (idCafInfo n))
61 ]
62 )
63 <> semi
64 | (i, (fp, (n, _))) <- zip [0..] entries
65 ]
66 ]
67
68 where
69
70 pprFingerprint :: Fingerprint -> SDoc
71 pprFingerprint (Fingerprint w1 w2) =
72 braces $ hcat $ punctuate comma
73 [ integer (fromIntegral w1) <> text "ULL"
74 , integer (fromIntegral w2) <> text "ULL"
75 ]