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