Changes between Version 23 and Version 24 of Commentary/Rts/Storage/HeapObjects
- Timestamp:
- 03/07/13 20:42:35 (2 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Commentary/Rts/Storage/HeapObjects
v23 v24 433 433 == How to add new heap objects == 434 434 435 There are quite a lot of files to touch if you add a heap object. Here is an (incomplete!) list: 435 There are two “levels” at which a new object can be added. The simplest way to add a new object is to simply define a custom new info table: 436 437 * [[GhcFile(includes/stg/MiscClosures.h)]]: Define your info tables with {{{RTS_ENTRY}}}. 438 * [[GhcFile(rts/StgMiscClosures.cmm)]]: Actually define the info tables for your objects, also, provide entry points if they represent runnable code. To find out what {{{INFO_TABLE}}} and all its variants do, check the C-- parser at [[GhcFile(compiler/cmm/CmmParse.y)]] 439 * [[GhcFile(includes/Cmm.h)]]: Update so you can refer to it from C-- code 440 441 An object defined this way is completely unknown to the code generator, so it tends to be pretty inflexible. However, GHC defines lots of these, esp. of the nullary kind; they’re a convenient way of getting non-NULL sentinel values for important pieces of the runtime. A particularly complicated example of an object of this kind is {{{StgMVarTSOQueue}}, which even has a definition in [[GhcFile(includes/rts/storage/Closures.h)]], but is simply has closure type {{{PRIM}}}. You must have pointers first, non-pointers later, and you can’t do anything fancy (like have attached variable size payloads, e.g. for arrays.) 442 443 To go the whole hog, you need to add a new closure type. This is considerably more involved: 436 444 437 445 * [[GhcFile(includes/rts/storage/ClosureTypes.h)]]: Add the new closure type 446 * [[GhcFile(includes/rts/storage/ClosureMacros.h)]]: Add a case to {{{closure_sizeW}}} for your struct. However, if your structure is really simple (i.e. can be completely described by the info table, an entry here is not necessary. 438 447 * [[GhcFile(includes/rts/storage/Closures.h)]]: Define a struct for the closure, including the ''header'' as well as your payloads. Sometimes, you will have more than one info table per struct, e.g. if you have {{{DIRTY}}} and {{{CLEAN}}} variants. As a general rule, GC'd pointers should go before general fields. 439 * [[GhcFile(includes/rts/storage/ClosureMacros.h)]]: Add a case to {{{closure_sizeW}}} for your struct. However, if your structure is really simple (i.e. can be completely described by the info table, an entry here is not necessary.440 * [[GhcFile(includes/stg/MiscClosures.h)]]: Define your info tables with {{{RTS_ENTRY}}}.441 448 * [[GhcFile(rts/ClosureFlags.c)]]: Update the closure flags (see [[GhcFile(includes/rts/storage/InfoTables.h)]] for info on what the flags mean "Closure flags") and the sanity check at the bottom of the file 442 449 * [[GhcFile(rts/Linker.c)]]: Add your info tables so they are linked correctly 443 450 * [[GhcFile(rts/Printer.c)]]: Print out a description of the closure. You need to handle all of the info tables you defined. 444 * [[GhcFile(rts/StgMiscClosures.cmm)]]: Actually define the info tables for your objects, also, provide entry points if they represent runnable code. To find out what {{{INFO_TABLE}}} and all its variants do, check the C-- parser at [[GhcFile(compiler/cmm/CmmParse.y)]]445 451 * [[GhcFile(rts/sm/Sanity.c)]]: Update sanity checks so they know about your new closure type 446 452 * [[GhcFile(rts/sm/Scav.c)]], [[GhcFile(rts/sm/Evac.c)]], [[GhcFile(rts/sm/Compact.c)]]: teach the garbage collector how to follow live pointers from your object. 447 453 * [[GhcFile(rts/LdvProfile.c)]], [[GhcFile(rts/RetainerProfile.c)]], [[GhcFile(rts/ProfHeap.c)]]: teach the profiler how to recognize your closure 448 * If you add any nullary closures (e.g. {{{END_TSO_QUEUE}}}), you need to register these too:449 * [[GhcFile(includes/stg/MiscClosures.h)]]: Add an ''RTS_CLOSURE'' for the closure450 * [[GhcFile(includes/Cmm.h)]]: so you can refer to it from C-- code451 454 452 455 When in doubt, look at how an existing heap object similar to the one you are implementing is implemented. (Of course, if they're identical, why are you defining a new heap object...)
