Revert "Save a word in the info table on x86_64"
[ghc.git] / libraries / ghc-heap / GHC / Exts / Heap / InfoTable.hsc
1 module GHC.Exts.Heap.InfoTable
2     ( module GHC.Exts.Heap.InfoTable.Types
3     , itblSize
4     , peekItbl
5     , pokeItbl
6     ) where
7
8 #include "Rts.h"
9
10 import GHC.Exts.Heap.InfoTable.Types
11 #if !defined(TABLES_NEXT_TO_CODE)
12 import GHC.Exts.Heap.Constants
13 import Data.Maybe
14 #endif
15 import Foreign
16
17 -------------------------------------------------------------------------
18 -- Profiling specific code
19 --
20 -- The functions that follow all rely on PROFILING. They are duplicated in
21 -- ghc-heap/GHC/Exts/Heap/InfoTableProf.hsc where PROFILING is defined. This
22 -- allows hsc2hs to generate values for both profiling and non-profiling builds.
23
24 -- | Read an InfoTable from the heap into a haskell type.
25 -- WARNING: This code assumes it is passed a pointer to a "standard" info
26 -- table. If tables_next_to_code is enabled, it will look 1 byte before the
27 -- start for the entry field.
28 peekItbl :: Ptr StgInfoTable -> IO StgInfoTable
29 peekItbl a0 = do
30 #if !defined(TABLES_NEXT_TO_CODE)
31   let ptr = a0 `plusPtr` (negate wORD_SIZE)
32   entry' <- Just <$> (#peek struct StgInfoTable_, entry) ptr
33 #else
34   let ptr = a0
35       entry' = Nothing
36 #endif
37   ptrs'   <- (#peek struct StgInfoTable_, layout.payload.ptrs) ptr
38   nptrs'  <- (#peek struct StgInfoTable_, layout.payload.nptrs) ptr
39   tipe'   <- (#peek struct StgInfoTable_, type) ptr
40 #if __GLASGOW_HASKELL__ > 804
41   srtlen' <- (#peek struct StgInfoTable_, has_srt) a0
42 #else
43   srtlen' <- (#peek struct StgInfoTable_, srt_bitmap) ptr
44 #endif
45   return StgInfoTable
46     { entry  = entry'
47     , ptrs   = ptrs'
48     , nptrs  = nptrs'
49     , tipe   = toEnum (fromIntegral (tipe' :: HalfWord))
50     , srtlen = srtlen'
51     , code   = Nothing
52     }
53
54 pokeItbl :: Ptr StgInfoTable -> StgInfoTable -> IO ()
55 pokeItbl a0 itbl = do
56 #if !defined(TABLES_NEXT_TO_CODE)
57   (#poke StgInfoTable, entry) a0 (fromJust (entry itbl))
58 #endif
59   (#poke StgInfoTable, layout.payload.ptrs) a0 (ptrs itbl)
60   (#poke StgInfoTable, layout.payload.nptrs) a0 (nptrs itbl)
61   (#poke StgInfoTable, type) a0 (fromEnum (tipe itbl))
62 #if __GLASGOW_HASKELL__ > 804
63   (#poke StgInfoTable, has_srt) a0 (srtlen itbl)
64 #else
65   (#poke StgInfoTable, srt_bitmap) a0 (srtlen itbl)
66 #endif
67 #if defined(TABLES_NEXT_TO_CODE)
68   let code_offset = a0 `plusPtr` (#offset StgInfoTable, code)
69   case code itbl of
70     Nothing -> return ()
71     Just (Left xs) -> pokeArray code_offset xs
72     Just (Right xs) -> pokeArray code_offset xs
73 #endif
74
75 -- | Size in bytes of a standard InfoTable
76 itblSize :: Int
77 itblSize = (#size struct StgInfoTable_)