4201fda36a3fd25dd4209c7dafa3fa5445d5cba6
[ghc.git] / compiler / cmm / CmmInfo.hs
1 {-# LANGUAGE CPP #-}
2 module CmmInfo (
3 mkEmptyContInfoTable,
4 cmmToRawCmm,
5 mkInfoTable,
6 srtEscape,
7
8 -- info table accessors
9 closureInfoPtr,
10 entryCode,
11 getConstrTag,
12 cmmGetClosureType,
13 infoTable,
14 infoTableConstrTag,
15 infoTableSrtBitmap,
16 infoTableClosureType,
17 infoTablePtrs,
18 infoTableNonPtrs,
19 funInfoTable,
20 funInfoArity,
21
22 -- info table sizes and offsets
23 stdInfoTableSizeW,
24 fixedInfoTableSizeW,
25 profInfoTableSizeW,
26 maxStdInfoTableSizeW,
27 maxRetInfoTableSizeW,
28 stdInfoTableSizeB,
29 conInfoTableSizeB,
30 stdSrtBitmapOffset,
31 stdClosureTypeOffset,
32 stdPtrsOffset, stdNonPtrsOffset,
33 ) where
34
35 #include "HsVersions.h"
36
37 import GhcPrelude
38
39 import Cmm
40 import CmmUtils
41 import CLabel
42 import SMRep
43 import Bitmap
44 import Stream (Stream)
45 import qualified Stream
46 import Hoopl.Collections
47
48 import Platform
49 import Maybes
50 import DynFlags
51 import Panic
52 import UniqSupply
53 import MonadUtils
54 import Util
55 import Outputable
56
57 import Data.Bits
58 import Data.Word
59
60 -- When we split at proc points, we need an empty info table.
61 mkEmptyContInfoTable :: CLabel -> CmmInfoTable
62 mkEmptyContInfoTable info_lbl
63 = CmmInfoTable { cit_lbl = info_lbl
64 , cit_rep = mkStackRep []
65 , cit_prof = NoProfilingInfo
66 , cit_srt = Nothing }
67
68 cmmToRawCmm :: DynFlags -> Stream IO CmmGroup ()
69 -> IO (Stream IO RawCmmGroup ())
70 cmmToRawCmm dflags cmms
71 = do { uniqs <- mkSplitUniqSupply 'i'
72 ; let do_one uniqs cmm = do
73 case initUs uniqs $ concatMapM (mkInfoTable dflags) cmm of
74 (b,uniqs') -> return (uniqs',b)
75 -- NB. strictness fixes a space leak. DO NOT REMOVE.
76 ; return (Stream.mapAccumL do_one uniqs cmms >> return ())
77 }
78
79 -- Make a concrete info table, represented as a list of CmmStatic
80 -- (it can't be simply a list of Word, because the SRT field is
81 -- represented by a label+offset expression).
82 --
83 -- With tablesNextToCode, the layout is
84 -- <reversed variable part>
85 -- <normal forward StgInfoTable, but without
86 -- an entry point at the front>
87 -- <code>
88 --
89 -- Without tablesNextToCode, the layout of an info table is
90 -- <entry label>
91 -- <normal forward rest of StgInfoTable>
92 -- <forward variable part>
93 --
94 -- See includes/rts/storage/InfoTables.h
95 --
96 -- For return-points these are as follows
97 --
98 -- Tables next to code:
99 --
100 -- <srt slot>
101 -- <standard info table>
102 -- ret-addr --> <entry code (if any)>
103 --
104 -- Not tables-next-to-code:
105 --
106 -- ret-addr --> <ptr to entry code>
107 -- <standard info table>
108 -- <srt slot>
109 --
110 -- * The SRT slot is only there if there is SRT info to record
111
112 mkInfoTable :: DynFlags -> CmmDecl -> UniqSM [RawCmmDecl]
113 mkInfoTable _ (CmmData sec dat)
114 = return [CmmData sec dat]
115
116 mkInfoTable dflags proc@(CmmProc infos entry_lbl live blocks)
117 --
118 -- in the non-tables-next-to-code case, procs can have at most a
119 -- single info table associated with the entry label of the proc.
120 --
121 | not (tablesNextToCode dflags)
122 = case topInfoTable proc of -- must be at most one
123 -- no info table
124 Nothing ->
125 return [CmmProc mapEmpty entry_lbl live blocks]
126
127 Just info@CmmInfoTable { cit_lbl = info_lbl } -> do
128 (top_decls, (std_info, extra_bits)) <-
129 mkInfoTableContents dflags info Nothing
130 let
131 rel_std_info = map (makeRelativeRefTo dflags info_lbl) std_info
132 rel_extra_bits = map (makeRelativeRefTo dflags info_lbl) extra_bits
133 --
134 -- Separately emit info table (with the function entry
135 -- point as first entry) and the entry code
136 --
137 return (top_decls ++
138 [CmmProc mapEmpty entry_lbl live blocks,
139 mkRODataLits info_lbl
140 (CmmLabel entry_lbl : rel_std_info ++ rel_extra_bits)])
141
142 --
143 -- With tables-next-to-code, we can have many info tables,
144 -- associated with some of the BlockIds of the proc. For each info
145 -- table we need to turn it into CmmStatics, and collect any new
146 -- CmmDecls that arise from doing so.
147 --
148 | otherwise
149 = do
150 (top_declss, raw_infos) <-
151 unzip `fmap` mapM do_one_info (mapToList (info_tbls infos))
152 return (concat top_declss ++
153 [CmmProc (mapFromList raw_infos) entry_lbl live blocks])
154
155 where
156 do_one_info (lbl,itbl) = do
157 (top_decls, (std_info, extra_bits)) <-
158 mkInfoTableContents dflags itbl Nothing
159 let
160 info_lbl = cit_lbl itbl
161 rel_std_info = map (makeRelativeRefTo dflags info_lbl) std_info
162 rel_extra_bits = map (makeRelativeRefTo dflags info_lbl) extra_bits
163 --
164 return (top_decls, (lbl, Statics info_lbl $ map CmmStaticLit $
165 reverse rel_extra_bits ++ rel_std_info))
166
167 -----------------------------------------------------
168 type InfoTableContents = ( [CmmLit] -- The standard part
169 , [CmmLit] ) -- The "extra bits"
170 -- These Lits have *not* had mkRelativeTo applied to them
171
172 mkInfoTableContents :: DynFlags
173 -> CmmInfoTable
174 -> Maybe Int -- Override default RTS type tag?
175 -> UniqSM ([RawCmmDecl], -- Auxiliary top decls
176 InfoTableContents) -- Info tbl + extra bits
177
178 mkInfoTableContents dflags
179 info@(CmmInfoTable { cit_lbl = info_lbl
180 , cit_rep = smrep
181 , cit_prof = prof
182 , cit_srt = srt })
183 mb_rts_tag
184 | RTSRep rts_tag rep <- smrep
185 = mkInfoTableContents dflags info{cit_rep = rep} (Just rts_tag)
186 -- Completely override the rts_tag that mkInfoTableContents would
187 -- otherwise compute, with the rts_tag stored in the RTSRep
188 -- (which in turn came from a handwritten .cmm file)
189
190 | StackRep frame <- smrep
191 = do { (prof_lits, prof_data) <- mkProfLits dflags prof
192 ; let (srt_label, srt_bitmap) = mkSRTLit dflags info_lbl srt
193 ; (liveness_lit, liveness_data) <- mkLivenessBits dflags frame
194 ; let
195 std_info = mkStdInfoTable dflags prof_lits rts_tag srt_bitmap liveness_lit
196 rts_tag | Just tag <- mb_rts_tag = tag
197 | null liveness_data = rET_SMALL -- Fits in extra_bits
198 | otherwise = rET_BIG -- Does not; extra_bits is
199 -- a label
200 ; return (prof_data ++ liveness_data, (std_info, srt_label)) }
201
202 | HeapRep _ ptrs nonptrs closure_type <- smrep
203 = do { let layout = packIntsCLit dflags ptrs nonptrs
204 ; (prof_lits, prof_data) <- mkProfLits dflags prof
205 ; let (srt_label, srt_bitmap) = mkSRTLit dflags info_lbl srt
206 ; (mb_srt_field, mb_layout, extra_bits, ct_data)
207 <- mk_pieces closure_type srt_label
208 ; let std_info = mkStdInfoTable dflags prof_lits
209 (mb_rts_tag `orElse` rtsClosureType smrep)
210 (mb_srt_field `orElse` srt_bitmap)
211 (mb_layout `orElse` layout)
212 ; return (prof_data ++ ct_data, (std_info, extra_bits)) }
213 where
214 mk_pieces :: ClosureTypeInfo -> [CmmLit]
215 -> UniqSM ( Maybe CmmLit -- Override the SRT field with this
216 , Maybe CmmLit -- Override the layout field with this
217 , [CmmLit] -- "Extra bits" for info table
218 , [RawCmmDecl]) -- Auxiliary data decls
219 mk_pieces (Constr con_tag con_descr) _no_srt -- A data constructor
220 = do { (descr_lit, decl) <- newStringLit con_descr
221 ; return ( Just (CmmInt (fromIntegral con_tag)
222 (halfWordWidth dflags))
223 , Nothing, [descr_lit], [decl]) }
224
225 mk_pieces Thunk srt_label
226 = return (Nothing, Nothing, srt_label, [])
227
228 mk_pieces (ThunkSelector offset) _no_srt
229 = return (Just (CmmInt 0 (halfWordWidth dflags)),
230 Just (mkWordCLit dflags (fromIntegral offset)), [], [])
231 -- Layout known (one free var); we use the layout field for offset
232
233 mk_pieces (Fun arity (ArgSpec fun_type)) srt_label
234 = do { let extra_bits = packIntsCLit dflags fun_type arity : srt_label
235 ; return (Nothing, Nothing, extra_bits, []) }
236
237 mk_pieces (Fun arity (ArgGen arg_bits)) srt_label
238 = do { (liveness_lit, liveness_data) <- mkLivenessBits dflags arg_bits
239 ; let fun_type | null liveness_data = aRG_GEN
240 | otherwise = aRG_GEN_BIG
241 extra_bits = [ packIntsCLit dflags fun_type arity ]
242 ++ (if inlineSRT dflags then [] else [ srt_lit ])
243 ++ [ liveness_lit, slow_entry ]
244 ; return (Nothing, Nothing, extra_bits, liveness_data) }
245 where
246 slow_entry = CmmLabel (toSlowEntryLbl info_lbl)
247 srt_lit = case srt_label of
248 [] -> mkIntCLit dflags 0
249 (lit:_rest) -> ASSERT( null _rest ) lit
250
251 mk_pieces other _ = pprPanic "mk_pieces" (ppr other)
252
253 mkInfoTableContents _ _ _ = panic "mkInfoTableContents" -- NonInfoTable dealt with earlier
254
255 packIntsCLit :: DynFlags -> Int -> Int -> CmmLit
256 packIntsCLit dflags a b = packHalfWordsCLit dflags
257 (toStgHalfWord dflags (fromIntegral a))
258 (toStgHalfWord dflags (fromIntegral b))
259
260
261 mkSRTLit :: DynFlags
262 -> CLabel
263 -> Maybe CLabel
264 -> ([CmmLit], -- srt_label, if any
265 CmmLit) -- srt_bitmap
266 mkSRTLit dflags info_lbl (Just lbl)
267 | inlineSRT dflags
268 = ([], CmmLabelDiffOff lbl info_lbl 0 (halfWordWidth dflags))
269 mkSRTLit dflags _ Nothing = ([], CmmInt 0 (halfWordWidth dflags))
270 mkSRTLit dflags _ (Just lbl) = ([CmmLabel lbl], CmmInt 1 (halfWordWidth dflags))
271
272
273 -- | is the SRT offset field inline in the info table on this platform?
274 inlineSRT :: DynFlags -> Bool
275 inlineSRT dflags = platformArch (targetPlatform dflags) == ArchX86_64
276 && tablesNextToCode dflags
277
278 -------------------------------------------------------------------------
279 --
280 -- Lay out the info table and handle relative offsets
281 --
282 -------------------------------------------------------------------------
283
284 -- This function takes
285 -- * the standard info table portion (StgInfoTable)
286 -- * the "extra bits" (StgFunInfoExtraRev etc.)
287 -- * the entry label
288 -- * the code
289 -- and lays them out in memory, producing a list of RawCmmDecl
290
291 -------------------------------------------------------------------------
292 --
293 -- Position independent code
294 --
295 -------------------------------------------------------------------------
296 -- In order to support position independent code, we mustn't put absolute
297 -- references into read-only space. Info tables in the tablesNextToCode
298 -- case must be in .text, which is read-only, so we doctor the CmmLits
299 -- to use relative offsets instead.
300
301 -- Note that this is done even when the -fPIC flag is not specified,
302 -- as we want to keep binary compatibility between PIC and non-PIC.
303
304 makeRelativeRefTo :: DynFlags -> CLabel -> CmmLit -> CmmLit
305
306 makeRelativeRefTo dflags info_lbl (CmmLabel lbl)
307 | tablesNextToCode dflags
308 = CmmLabelDiffOff lbl info_lbl 0 (wordWidth dflags)
309 makeRelativeRefTo dflags info_lbl (CmmLabelOff lbl off)
310 | tablesNextToCode dflags
311 = CmmLabelDiffOff lbl info_lbl off (wordWidth dflags)
312 makeRelativeRefTo _ _ lit = lit
313
314
315 -------------------------------------------------------------------------
316 --
317 -- Build a liveness mask for the stack layout
318 --
319 -------------------------------------------------------------------------
320
321 -- There are four kinds of things on the stack:
322 --
323 -- - pointer variables (bound in the environment)
324 -- - non-pointer variables (bound in the environment)
325 -- - free slots (recorded in the stack free list)
326 -- - non-pointer data slots (recorded in the stack free list)
327 --
328 -- The first two are represented with a 'Just' of a 'LocalReg'.
329 -- The last two with one or more 'Nothing' constructors.
330 -- Each 'Nothing' represents one used word.
331 --
332 -- The head of the stack layout is the top of the stack and
333 -- the least-significant bit.
334
335 mkLivenessBits :: DynFlags -> Liveness -> UniqSM (CmmLit, [RawCmmDecl])
336 -- ^ Returns:
337 -- 1. The bitmap (literal value or label)
338 -- 2. Large bitmap CmmData if needed
339
340 mkLivenessBits dflags liveness
341 | n_bits > mAX_SMALL_BITMAP_SIZE dflags -- does not fit in one word
342 = do { uniq <- getUniqueM
343 ; let bitmap_lbl = mkBitmapLabel uniq
344 ; return (CmmLabel bitmap_lbl,
345 [mkRODataLits bitmap_lbl lits]) }
346
347 | otherwise -- Fits in one word
348 = return (mkStgWordCLit dflags bitmap_word, [])
349 where
350 n_bits = length liveness
351
352 bitmap :: Bitmap
353 bitmap = mkBitmap dflags liveness
354
355 small_bitmap = case bitmap of
356 [] -> toStgWord dflags 0
357 [b] -> b
358 _ -> panic "mkLiveness"
359 bitmap_word = toStgWord dflags (fromIntegral n_bits)
360 .|. (small_bitmap `shiftL` bITMAP_BITS_SHIFT dflags)
361
362 lits = mkWordCLit dflags (fromIntegral n_bits)
363 : map (mkStgWordCLit dflags) bitmap
364 -- The first word is the size. The structure must match
365 -- StgLargeBitmap in includes/rts/storage/InfoTable.h
366
367 -------------------------------------------------------------------------
368 --
369 -- Generating a standard info table
370 --
371 -------------------------------------------------------------------------
372
373 -- The standard bits of an info table. This part of the info table
374 -- corresponds to the StgInfoTable type defined in
375 -- includes/rts/storage/InfoTables.h.
376 --
377 -- Its shape varies with ticky/profiling/tables next to code etc
378 -- so we can't use constant offsets from Constants
379
380 mkStdInfoTable
381 :: DynFlags
382 -> (CmmLit,CmmLit) -- Closure type descr and closure descr (profiling)
383 -> Int -- Closure RTS tag
384 -> CmmLit -- SRT length
385 -> CmmLit -- layout field
386 -> [CmmLit]
387
388 mkStdInfoTable dflags (type_descr, closure_descr) cl_type srt layout_lit
389 = -- Parallel revertible-black hole field
390 prof_info
391 -- Ticky info (none at present)
392 -- Debug info (none at present)
393 ++ [layout_lit, tag, srt]
394
395 where
396 prof_info
397 | gopt Opt_SccProfilingOn dflags = [type_descr, closure_descr]
398 | otherwise = []
399
400 tag = CmmInt (fromIntegral cl_type) (halfWordWidth dflags)
401
402 -------------------------------------------------------------------------
403 --
404 -- Making string literals
405 --
406 -------------------------------------------------------------------------
407
408 mkProfLits :: DynFlags -> ProfilingInfo -> UniqSM ((CmmLit,CmmLit), [RawCmmDecl])
409 mkProfLits dflags NoProfilingInfo = return ((zeroCLit dflags, zeroCLit dflags), [])
410 mkProfLits _ (ProfilingInfo td cd)
411 = do { (td_lit, td_decl) <- newStringLit td
412 ; (cd_lit, cd_decl) <- newStringLit cd
413 ; return ((td_lit,cd_lit), [td_decl,cd_decl]) }
414
415 newStringLit :: [Word8] -> UniqSM (CmmLit, GenCmmDecl CmmStatics info stmt)
416 newStringLit bytes
417 = do { uniq <- getUniqueM
418 ; return (mkByteStringCLit (mkStringLitLabel uniq) bytes) }
419
420
421 -- Misc utils
422
423 -- | Value of the srt field of an info table when using an StgLargeSRT
424 srtEscape :: DynFlags -> StgHalfWord
425 srtEscape dflags = toStgHalfWord dflags (-1)
426
427 -------------------------------------------------------------------------
428 --
429 -- Accessing fields of an info table
430 --
431 -------------------------------------------------------------------------
432
433 -- | Wrap a 'CmmExpr' in an alignment check when @-falignment-sanitisation@ is
434 -- enabled.
435 wordAligned :: DynFlags -> CmmExpr -> CmmExpr
436 wordAligned dflags e
437 | gopt Opt_AlignmentSanitisation dflags
438 = CmmMachOp (MO_AlignmentCheck (wORD_SIZE dflags) (wordWidth dflags)) [e]
439 | otherwise
440 = e
441
442 closureInfoPtr :: DynFlags -> CmmExpr -> CmmExpr
443 -- Takes a closure pointer and returns the info table pointer
444 closureInfoPtr dflags e =
445 CmmLoad (wordAligned dflags e) (bWord dflags)
446
447 entryCode :: DynFlags -> CmmExpr -> CmmExpr
448 -- Takes an info pointer (the first word of a closure)
449 -- and returns its entry code
450 entryCode dflags e
451 | tablesNextToCode dflags = e
452 | otherwise = CmmLoad e (bWord dflags)
453
454 getConstrTag :: DynFlags -> CmmExpr -> CmmExpr
455 -- Takes a closure pointer, and return the *zero-indexed*
456 -- constructor tag obtained from the info table
457 -- This lives in the SRT field of the info table
458 -- (constructors don't need SRTs).
459 getConstrTag dflags closure_ptr
460 = CmmMachOp (MO_UU_Conv (halfWordWidth dflags) (wordWidth dflags)) [infoTableConstrTag dflags info_table]
461 where
462 info_table = infoTable dflags (closureInfoPtr dflags closure_ptr)
463
464 cmmGetClosureType :: DynFlags -> CmmExpr -> CmmExpr
465 -- Takes a closure pointer, and return the closure type
466 -- obtained from the info table
467 cmmGetClosureType dflags closure_ptr
468 = CmmMachOp (MO_UU_Conv (halfWordWidth dflags) (wordWidth dflags)) [infoTableClosureType dflags info_table]
469 where
470 info_table = infoTable dflags (closureInfoPtr dflags closure_ptr)
471
472 infoTable :: DynFlags -> CmmExpr -> CmmExpr
473 -- Takes an info pointer (the first word of a closure)
474 -- and returns a pointer to the first word of the standard-form
475 -- info table, excluding the entry-code word (if present)
476 infoTable dflags info_ptr
477 | tablesNextToCode dflags = cmmOffsetB dflags info_ptr (- stdInfoTableSizeB dflags)
478 | otherwise = cmmOffsetW dflags info_ptr 1 -- Past the entry code pointer
479
480 infoTableConstrTag :: DynFlags -> CmmExpr -> CmmExpr
481 -- Takes an info table pointer (from infoTable) and returns the constr tag
482 -- field of the info table (same as the srt_bitmap field)
483 infoTableConstrTag = infoTableSrtBitmap
484
485 infoTableSrtBitmap :: DynFlags -> CmmExpr -> CmmExpr
486 -- Takes an info table pointer (from infoTable) and returns the srt_bitmap
487 -- field of the info table
488 infoTableSrtBitmap dflags info_tbl
489 = CmmLoad (cmmOffsetB dflags info_tbl (stdSrtBitmapOffset dflags)) (bHalfWord dflags)
490
491 infoTableClosureType :: DynFlags -> CmmExpr -> CmmExpr
492 -- Takes an info table pointer (from infoTable) and returns the closure type
493 -- field of the info table.
494 infoTableClosureType dflags info_tbl
495 = CmmLoad (cmmOffsetB dflags info_tbl (stdClosureTypeOffset dflags)) (bHalfWord dflags)
496
497 infoTablePtrs :: DynFlags -> CmmExpr -> CmmExpr
498 infoTablePtrs dflags info_tbl
499 = CmmLoad (cmmOffsetB dflags info_tbl (stdPtrsOffset dflags)) (bHalfWord dflags)
500
501 infoTableNonPtrs :: DynFlags -> CmmExpr -> CmmExpr
502 infoTableNonPtrs dflags info_tbl
503 = CmmLoad (cmmOffsetB dflags info_tbl (stdNonPtrsOffset dflags)) (bHalfWord dflags)
504
505 funInfoTable :: DynFlags -> CmmExpr -> CmmExpr
506 -- Takes the info pointer of a function,
507 -- and returns a pointer to the first word of the StgFunInfoExtra struct
508 -- in the info table.
509 funInfoTable dflags info_ptr
510 | tablesNextToCode dflags
511 = cmmOffsetB dflags info_ptr (- stdInfoTableSizeB dflags - sIZEOF_StgFunInfoExtraRev dflags)
512 | otherwise
513 = cmmOffsetW dflags info_ptr (1 + stdInfoTableSizeW dflags)
514 -- Past the entry code pointer
515
516 -- Takes the info pointer of a function, returns the function's arity
517 funInfoArity :: DynFlags -> CmmExpr -> CmmExpr
518 funInfoArity dflags iptr
519 = cmmToWord dflags (cmmLoadIndex dflags rep fun_info (offset `div` rep_bytes))
520 where
521 fun_info = funInfoTable dflags iptr
522 rep = cmmBits (widthFromBytes rep_bytes)
523
524 (rep_bytes, offset)
525 | tablesNextToCode dflags = ( pc_REP_StgFunInfoExtraRev_arity pc
526 , oFFSET_StgFunInfoExtraRev_arity dflags )
527 | otherwise = ( pc_REP_StgFunInfoExtraFwd_arity pc
528 , oFFSET_StgFunInfoExtraFwd_arity dflags )
529
530 pc = sPlatformConstants (settings dflags)
531
532 -----------------------------------------------------------------------------
533 --
534 -- Info table sizes & offsets
535 --
536 -----------------------------------------------------------------------------
537
538 stdInfoTableSizeW :: DynFlags -> WordOff
539 -- The size of a standard info table varies with profiling/ticky etc,
540 -- so we can't get it from Constants
541 -- It must vary in sync with mkStdInfoTable
542 stdInfoTableSizeW dflags
543 = fixedInfoTableSizeW
544 + if gopt Opt_SccProfilingOn dflags
545 then profInfoTableSizeW
546 else 0
547
548 fixedInfoTableSizeW :: WordOff
549 fixedInfoTableSizeW = 2 -- layout, type
550
551 profInfoTableSizeW :: WordOff
552 profInfoTableSizeW = 2
553
554 maxStdInfoTableSizeW :: WordOff
555 maxStdInfoTableSizeW =
556 1 {- entry, when !tablesNextToCode -}
557 + fixedInfoTableSizeW
558 + profInfoTableSizeW
559
560 maxRetInfoTableSizeW :: WordOff
561 maxRetInfoTableSizeW =
562 maxStdInfoTableSizeW
563 + 1 {- srt label -}
564
565 stdInfoTableSizeB :: DynFlags -> ByteOff
566 stdInfoTableSizeB dflags = stdInfoTableSizeW dflags * wORD_SIZE dflags
567
568 stdSrtBitmapOffset :: DynFlags -> ByteOff
569 -- Byte offset of the SRT bitmap half-word which is
570 -- in the *higher-addressed* part of the type_lit
571 stdSrtBitmapOffset dflags = stdInfoTableSizeB dflags - hALF_WORD_SIZE dflags
572
573 stdClosureTypeOffset :: DynFlags -> ByteOff
574 -- Byte offset of the closure type half-word
575 stdClosureTypeOffset dflags = stdInfoTableSizeB dflags - wORD_SIZE dflags
576
577 stdPtrsOffset, stdNonPtrsOffset :: DynFlags -> ByteOff
578 stdPtrsOffset dflags = stdInfoTableSizeB dflags - 2 * wORD_SIZE dflags
579 stdNonPtrsOffset dflags = stdInfoTableSizeB dflags - 2 * wORD_SIZE dflags + hALF_WORD_SIZE dflags
580
581 conInfoTableSizeB :: DynFlags -> Int
582 conInfoTableSizeB dflags = stdInfoTableSizeB dflags + wORD_SIZE dflags