... | ... | @@ -575,7 +575,7 @@ Forwarding pointers appear temporarily during [garbage collection](commentary/rt |
|
|
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:
|
|
|
|
|
|
- [includes/stg/MiscClosures.h](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/includes/stg/MiscClosures.h): Declare your info table with `RTS_ENTRY`.
|
|
|
- [rts/StgMiscClosures.cmm](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/StgMiscClosures.cmm): Define the info table, also, provide entry points if they represent runnable code (though this is pretty uncommon if you’re not also adding a new closure type; most just error). To find out what `INFO_TABLE` and all its variants do, check the C-- parser at [compiler/cmm/CmmParse.y](/trac/ghc/browser/ghc/compiler/cmm/CmmParse.y) The most important thing is to pick the correct closure type.
|
|
|
- [rts/StgMiscClosures.cmm](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/StgMiscClosures.cmm): Define the info table, also, provide entry points if they represent runnable code (though this is pretty uncommon if you’re not also adding a new closure type; most just error). To find out what `INFO_TABLE` and all its variants do, check the C-- parser at [compiler/cmm/CmmParse.y](https://gitlab.haskell.org/ghc/ghc/blob/master/compiler/cmm/CmmParse.y) The most important thing is to pick the correct closure type.
|
|
|
|
|
|
|
|
|
You also will need to define primops to manipulate your new object type, if you want to manipulate it from Haskell-land (and not have it be RTS-only). See [wiki:Commentary/PrimOps](commentary/prim-ops) for more details.
|
... | ... | @@ -590,12 +590,12 @@ To go the whole hog, you need to add a new closure type. This is considerably mo |
|
|
- [includes/rts/storage/ClosureMacros.h](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/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.
|
|
|
- [includes/rts/storage/Closures.h](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/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.
|
|
|
- [utils/deriveConstants/Main.hs](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/utils/deriveConstants/Main.hs): Tell the deriveConstants script to generate a bunch of accessors so you can manipulate the struct from C-- code.
|
|
|
- [rts/ClosureFlags.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/ClosureFlags.c): Update the closure flags (see [includes/rts/storage/InfoTables.h](/trac/ghc/browser/ghc/includes/rts/storage/InfoTables.h) for info on what the flags mean "Closure flags") and the sanity check at the bottom of the file
|
|
|
- [rts/ClosureFlags.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/ClosureFlags.c): Update the closure flags (see [includes/rts/storage/InfoTables.h](https://gitlab.haskell.org/ghc/ghc/blob/master/includes/rts/storage/InfoTables.h) for info on what the flags mean "Closure flags") and the sanity check at the bottom of the file
|
|
|
- [rts/Linker.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/Linker.c): Add your info tables so they are linked correctly
|
|
|
- [rts/Printer.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/Printer.c): Print out a description of the closure. You need to handle all of the info tables you defined.
|
|
|
- [rts/sm/Sanity.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/sm/Sanity.c): Update sanity checks so they know about your new closure type
|
|
|
- [rts/sm/Scav.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/sm/Scav.c), [rts/sm/Evac.c](/trac/ghc/browser/ghc/rts/sm/Evac.c), [rts/sm/Compact.c](/trac/ghc/browser/ghc/rts/sm/Compact.c): teach the garbage collector how to follow live pointers from your object.
|
|
|
- [rts/LdvProfile.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/LdvProfile.c), [rts/RetainerProfile.c](/trac/ghc/browser/ghc/rts/RetainerProfile.c), [rts/ProfHeap.c](/trac/ghc/browser/ghc/rts/ProfHeap.c): teach the profiler how to recognize your closure
|
|
|
- [rts/sm/Scav.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/sm/Scav.c), [rts/sm/Evac.c](https://gitlab.haskell.org/ghc/ghc/blob/master/rts/sm/Evac.c), [rts/sm/Compact.c](https://gitlab.haskell.org/ghc/ghc/blob/master/rts/sm/Compact.c): teach the garbage collector how to follow live pointers from your object.
|
|
|
- [rts/LdvProfile.c](https://gitlab.haskell.org/ghc/ghc/tree/master/ghc/rts/LdvProfile.c), [rts/RetainerProfile.c](https://gitlab.haskell.org/ghc/ghc/blob/master/rts/RetainerProfile.c), [rts/ProfHeap.c](https://gitlab.haskell.org/ghc/ghc/blob/master/rts/ProfHeap.c): teach the profiler how to recognize your closure
|
|
|
|
|
|
|
|
|
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...) |