+Unsafe C calls are performed by pushing the arguments onto the C stack
+and jumping to the C function's entry point. On exit, the result of
+the function is in a register which is returned to the Haskell code as
+an unboxed value.
+
+\item[``Safe'' C calls] are used if the programmer suspects that the
+thread may do something dangerous. Safe C calls are relatively slow
+but are less problematic.
+
+Safe C calls are performed by pushing the arguments onto the Haskell
+stack, pushing a return continuation and returning a \emph{C function
+descriptor} to the scheduler. The scheduler suspends the Haskell thread,
+spawns a new operating system thread which pops the arguments off the
+Haskell stack onto the C stack, calls the C function, pushes the
+function result onto the Haskell stack and informs the scheduler that
+the C function has completed and the Haskell thread is now runnable.
+
+\end{description}
+
+The bytecode evaluator will probably treat all C calls as being safe.
+
+\ToDo{It might be good for the programmer to indicate how the program
+is unsafe. For example, if we distinguish between C functions which
+might call Haskell functions and those which might block, we could
+perform an unsafe call for blocking functions in a single-threaded
+system or, perhaps, in a multi-threaded system which only happens to
+have a single thread at the moment.}
+
+
+
+\Section{The Storage Manager}{sm-overview}
+
+The storage manager is responsible for managing the heap and all
+objects stored in it. It provides special support for lazy evaluation
+and for foreign function calls.
+
+\Subsection{SM support for lazy evaluation}{sm-lazy-evaluation}
+
+\begin{itemize}
+\item
+
+Indirections are shorted out.
+
+\item
+
+Update frames pointing to unreachable objects are squeezed out.
+
+\item
+
+Adjacent update frames (for different closures) are compressed to a
+single update frame pointing to a single black hole.
+
+\end{itemize}
+
+
+\Subsection{SM support for foreign function calls}{sm-foreign-calls}
+
+\begin{itemize}
+
+\item
+
+Stable pointers allow other languages to access Haskell objects.
+
+\item
+
+Weak pointers and foreign objects provide finalisation support for
+Haskell references to external objects.
+
+\end{itemize}
+
+\Subsection{Misc}{sm-misc}
+
+\begin{itemize}
+
+\item
+
+If the stack contains a large amount of free space, the storage
+manager may shrink the stack. If it shrinks the stack, it guarantees
+never to leave less than @MIN_SIZE_SHRUNKEN_STACK@ empty words on the
+stack when it does so.
+
+\item
+
+For efficiency reasons, very large objects (eg large arrays and TSOs)
+are not moved if possible.
+
+\end{itemize}
+
+
+\Section{The Compilers}{compilers-overview}
+
+Need to describe interface files, format of bytecode files, symbols
+defined by machine code files.
+
+\Subsection{Interface Files}{interface-files}
+
+Here's an example - but I don't know the grammar - ADR.
+@
+_interface_ Main 1
+_exports_
+Main main ;
+_declarations_
+1 main _:_ IOBase.IO PrelBase.();;
+@
+
+\Subsection{Bytecode files}{bytecode-files}
+
+(All that matters here is what the loader sees.)
+
+\Subsection{Machine code files}{asm-files}
+
+(Again, all that matters is what the loader sees.)
+
+\Section{The Loader}{loader-overview}
+
+In a batch mode system, we can statically link all the modules
+together. In an interactive system we need a loader which will
+explicitly load and unload individual modules (or, perhaps, blocks of
+mutually dependent modules) and resolve references between modules.
+
+While many operating systems provide support for dynamic loading and
+will automatically resolve cross-module references for us, we generally
+cannot rely on being able to load mutually dependent modules.
+
+A portable solution is to perform some of the linking ourselves. Each module
+should provide three global symbols:
+\begin{itemize}
+\item
+An initialisation routine. (Might also be used for finalisation.)
+\item
+A table of symbols it exports.
+Entries in this table consist of the symbol name and the address of the
+names value.
+\item
+A table of symbols it imports.
+Entries in this table consist of the symbol name and a list of references
+to that symbol.
+\end{itemize}
+
+On loading a group of modules, the loader adds the contents of the
+export lists to a symbol table and then fills in all the references in the
+import lists.
+
+References in import lists are of two types:
+\begin{description}
+\item[ References in machine code ]
+
+The most efficient approach is to patch the machine code directly, but
+this will be a lot of work, very painful to port and rather fragile.
+
+Alternatively, the loader could store the value of each symbol in the
+import table for each module and the compiled code can access all
+external objects through the import table. This requires that the
+import table be writable but does not require that the machine code or
+info tables be writable.
+
+\item[ References in data structures (SRTs and static data constructors) ]
+
+Either we patch the SRTs and constructors directly or we somehow use
+indirections through the symbol table. Patching the SRTs requires
+that we make them writable and prevents us from making effective use
+of virtual memories that use copy-on-write policies (this only makes a
+difference if we want to run several copies of the same program
+simultaneously). Using an indirection is possible but tricky.
+
+Note: We could avoid patching machine code if all references to
+external references went through the SRT --- then we just have one
+thing to patch. But the SRT always contains a pointer to the closure
+rather than the fast entry point (say), so we'd take a big performance
+hit for doing this.
+
+\end{description}
+
+Using the above scheme, all accesses to ``external'' objects involve a
+layer of indirection. To avoid this overhead, the machine code
+compiler might provide a way for the programmer to specify which
+modules will be statically linked and which will be dynamically linked
+--- the idea being that statically linked code and data will be
+accessed directly.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\part{Internal details}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+This part is concerned with the internal details of the components
+described in the previous part.
+
+The major components of the system are:
+\begin{itemize}
+\item The scheduler (\secref{storage-manager-internals})
+\item The storage manager (\secref{storage-manager-internals})
+\item The evaluators
+\item The loader
+\item The compilers
+\end{itemize}
+
+\Section{The Scheduler}{scheduler-internals}
+
+\ToDo{Detailed description of scheduler}
+
+Many heap objects contain fields allowing them to be inserted onto lists
+during evaluation or during garbage collection. The lists required by
+the evaluator and storage manager are as follows.
+
+\begin{itemize}
+
+\item 4 lists of threads: runnable threads, sleeping threads, threads
+waiting for timeout and threads waiting for I/O.
+
+\item The \emph{mutables list} is a list of all objects in the old
+generation which might contain pointers into the new generation. Most
+of the objects on this list are indirections (\secref{IND})
+or ``mutable.'' (\secref{mutables}.)
+
+\item The \emph{Foreign Object list} is a list of all foreign objects
+ which have not yet been deallocated. (\secref{FOREIGN}.)
+
+\item The \emph{Spark pool} is a doubly(?) linked list of Spark objects
+maintained by the parallel system. (\secref{SPARK}.)
+
+\item The \emph{Blocked Fetch list} (or
+lists?). (\secref{BLOCKED_FETCH}.)
+
+\item For each thread, there is a list of all update frames on the
+stack. (\secref{data-updates}.)
+
+\item The Stable Pointer Table is a table of pointers to objects which
+are known to the outside world and must be retained by the garbage
+collector even if they are not accessible from within the heap.
+
+\end{itemize}
+
+\ToDo{The links for these fields are usually inserted immediately
+after the fixed header except ...}
+
+
+
+\Section{The Storage Manager}{storage-manager-internals}
+
+\subsection{Misc Text looking for a home}
+
+A \emph{value} may be:
+\begin{itemize}
+\item \emph{Boxed}, i.e.~represented indirectly by a pointer to a heap object (e.g.~foreign objects, arrays); or
+\item \emph{Unboxed}, i.e.~represented directly by a bit-pattern in one or more registers (e.g.~@Int#@ and @Float#@).
+\end{itemize}
+All \emph{pointed} values are \emph{boxed}.
+
+
+\Subsection{Heap Objects}{heap-objects}
+\label{sec:fixed-header}
+
+\begin{figure}
+\begin{center}
+\input{closure}
+\end{center}
+\ToDo{Fix this picture}
+\caption{A closure}
+\label{fig:closure}
+\end{figure}
+
+Every \emph{heap object} is a contiguous block of memory, consisting
+of a fixed-format \emph{header} followed by zero or more \emph{data
+words}.
+
+The header consists of the following fields:
+\begin{itemize}
+\item A one-word \emph{info pointer}, which points to
+the object's static \emph{info table}.
+\item Zero or more \emph{admin words} that support
+\begin{itemize}
+\item Profiling (notably a \emph{cost centre} word).
+ \note{We could possibly omit the cost centre word from some
+ administrative objects.}
+\item Parallelism (e.g. GranSim keeps the object's global address here,
+though GUM keeps a separate hash table).
+\item Statistics (e.g. a word to track how many times a thunk is entered.).
+
+We add a Ticky word to the fixed-header part of closures. This is
+used to indicate if a closure has been updated but not yet entered. It
+is set when the closure is updated and cleared when subsequently
+entered. \footnote{% NB: It is \emph{not} an ``entry count'', it is
+an ``entries-after-update count.'' The commoning up of @CONST@,
+@CHARLIKE@ and @INTLIKE@ closures is turned off(?) if this is
+required. This has only been done for 2s collection. }
+
+\end{itemize}
+\end{itemize}
+
+Most of the RTS is completely insensitive to the number of admin
+words. The total size of the fixed header is given by
+@sizeof(StgHeader)@.
+
+\Subsection{Info Tables}{info-tables}
+
+An \emph{info table} is a contiguous block of memory, laid out as follows:
+
+\begin{center}
+\begin{tabular}{|r|l|}
+ \hline Parallelism Info & variable
+\\ \hline Profile Info & variable
+\\ \hline Debug Info & variable
+\\ \hline Static reference table & pointer word (optional)
+\\ \hline Storage manager layout info & pointer word
+\\ \hline Closure flags & 8 bits
+\\ \hline Closure type & 8 bits
+\\ \hline Constructor Tag / SRT length & 16 bits
+\\ \hline entry code
+\\ \vdots
+\end{tabular}
+\end{center}
+
+On a 64-bit machine the tag, type and flags fields will all be doubled
+in size, so the info table is a multiple of 64 bits.
+
+An info table has the following contents (working backwards in memory
+addresses):
+
+\begin{itemize}
+
+\item The \emph{entry code} for the closure. This code appears
+literally as the (large) last entry in the info table, immediately
+preceded by the rest of the info table. An \emph{info pointer} always
+points to the first byte of the entry code.
+
+\item A 16-bit constructor tag / SRT length. For a constructor info
+table this field contains the tag of the constructor, in the range
+$0..n-1$ where $n$ is the number of constructors in the datatype.
+Otherwise, it contains the number of entries in this closure's Static
+Reference Table (\secref{srt}).
+
+\item An 8-bit {\em closure type field}, which identifies what kind of
+closure the object is. The various types of closure are described in
+\secref{closures}.
+
+\item an 8-bit flags field, which holds various flags pertaining to
+the closure type.
+
+\item A single pointer or word --- the {\em storage manager info
+field}, contains auxiliary information describing the closure's
+precise layout, for the benefit of the garbage collector and the code
+that stuffs graph into packets for transmission over the network.
+There are three kinds of layout information:
+
+\begin{itemize}
+\item Standard layout information is for closures which place pointers
+before non-pointers in instances of the closure (this applies to most
+heap-based and static closures, but not activation records). The
+layout information for standard closures is
+
+ \begin{itemize}
+ \item Number of pointer fields (16 bits).
+ \item Number of non-pointer fields (16 bits).
+ \end{itemize}
+
+\item Activation records don't have pointers before non-pointers,
+since stack-stubbing requires that the record has holes in it. The
+layout is therefore represented by a bitmap in which each '1' bit
+represents a non-pointer word. This kind of layout info is used for
+@RET_SMALL@ and @RET_VEC_SMALL@ closures.
+
+\item If an activation record is longer than 32 words, then the layout
+field contains a pointer to a bitmap record, consisting of a length
+field followed by two or more bitmap words. This layout information
+is used for @RET_BIG@ and @RET_VEC_BIG@ closures.
+
+\item Selector Thunks (\secref{THUNK_SELECTOR}) use the closure
+layout field to hold the selector index, since the layout is always
+known (the closure contains a single pointer field).
+\end{itemize}
+
+\item A one-word {\em Static Reference Table} field. This field
+points to the static reference table for the closure (\secref{srt}),
+and is only present for the following closure types:
+
+ \begin{itemize}
+ \item @FUN_*@
+ \item @THUNK_*@
+ \item @RET_*@
+ \end{itemize}
+
+\item \emph{Profiling info\/}
+
+\ToDo{The profiling info is completely bogus. I've not deleted it
+from the document but I've commented it all out.}
+
+% change to \iftrue to uncomment this section
+\iffalse
+
+Closure category records are attached to the info table of the
+closure. They are declared with the info table. We put pointers to
+these ClCat things in info tables. We need these ClCat things because
+they are mutable, whereas info tables are immutable. Hashing will map
+similar categories to the same hash value allowing statistics to be
+grouped by closure category.
+
+Cost Centres and Closure Categories are hashed to provide indexes
+against which arbitrary information can be stored. These indexes are
+memoised in the appropriate cost centre or category record and
+subsequent hashes avoided by the index routine (it simply returns the
+memoised index).
+
+There are different features which can be hashed allowing information
+to be stored for different groupings. Cost centres have the cost
+centre recorded (using the pointer), module and group. Closure
+categories have the closure description and the type
+description. Records with the same feature will be hashed to the same
+index value.
+
+The initialisation routines, @init_index_<feature>@, allocate a hash
+table in which the cost centre / category records are stored. The
+lower bound for the table size is taken from @max_<feature>_no@. They
+return the actual table size used (the next power of 2). Unused
+locations in the hash table are indicated by a 0 entry. Successive
+@init_index_<feature>@ calls just return the actual table size.
+
+Calls to @index_<feature>@ will insert the cost centre / category
+record in the @<feature>@ hash table, if not already inserted. The hash
+index is memoised in the record and returned.
+
+CURRENTLY ONLY ONE MEMOISATION SLOT IS AVILABLE IN EACH RECORD SO
+HASHING CAN ONLY BE DONE ON ONE FEATURE FOR EACH RECORD. This can be
+easily relaxed at the expense of extra memoisation space or continued
+rehashing.
+
+The initialisation routines must be called before initialisation of
+the stacks and heap as they require to allocate storage. It is also
+expected that the caller may want to allocate additional storage in
+which to store profiling information based on the return table size
+value(s).
+
+\begin{center}
+\begin{tabular}{|l|}
+ \hline Hash Index
+\\ \hline Selected
+\\ \hline Kind
+\\ \hline Description String
+\\ \hline Type String
+\\ \hline
+\end{tabular}
+\end{center}
+
+\begin{description}
+\item[Hash Index] Memoised copy
+\item[Selected]
+ Is this category selected (-1 == not memoised, selected? 0 or 1)
+\item[Kind]
+One of the following values (defined in CostCentre.lh):
+
+\begin{description}
+\item[@CON_K@]
+A constructor.
+\item[@FN_K@]
+A literal function.
+\item[@PAP_K@]
+A partial application.
+\item[@THK_K@]
+A thunk, or suspension.
+\item[@BH_K@]
+A black hole.
+\item[@ARR_K@]
+An array.
+\item[@ForeignObj_K@]
+A Foreign object (non-Haskell heap resident).
+\item[@SPT_K@]
+The Stable Pointer table. (There should only be one of these but it
+represents a form of weak space leak since it can't shrink to meet
+non-demand so it may be worth watching separately? ADR)
+\item[@INTERNAL_KIND@]
+Something internal to the runtime system.
+\end{description}
+
+
+\item[Description] Source derived string detailing closure description.
+\item[Type] Source derived string detailing closure type.
+\end{description}
+
+\fi % end of commented out stuff
+
+\item \emph{Parallelism info\/}
+\ToDo{}
+
+\item \emph{Debugging info\/}
+\ToDo{}
+
+\end{itemize}
+
+
+%-----------------------------------------------------------------------------
+\Subsection{Kinds of Heap Object}{closures}
+
+Heap objects can be classified in several ways, but one useful one is
+this:
+\begin{itemize}
+\item
+\emph{Static closures} occupy fixed, statically-allocated memory
+locations, with globally known addresses.
+
+\item
+\emph{Dynamic closures} are individually allocated in the heap.
+
+\item
+\emph{Stack closures} are closures allocated within a thread's stack
+(which is itself a heap object). Unlike other closures, there are
+never any pointers to stack closures. Stack closures are discussed in
+\secref{TSO}.
+
+\end{itemize}
+A second useful classification is this:
+\begin{itemize}
+
+\item \emph{Executive objects}, such as thunks and data constructors,
+participate directly in a program's execution. They can be subdivided
+into three kinds of objects according to their type: \begin{itemize}
+
+\item \emph{Pointed objects}, represent values of a \emph{pointed}
+type (<.pointed types launchbury.>) --i.e.~a type that includes
+$\bottom$ such as @Int@ or @Int# -> Int#@.
+
+\item \emph{Unpointed objects}, represent values of a \emph{unpointed}
+type --i.e.~a type that does not include $\bottom$ such as @Int#@ or
+@Array#@.
+
+\item \emph{Activation frames}, represent ``continuations''. They are
+always stored on the stack and are never pointed to by heap objects or
+passed as arguments. \note{It's not clear if this will still be true
+once we support speculative evaluation.}
+
+\end{itemize}
+
+\item \emph{Administrative objects}, such as stack objects and thread
+state objects, do not represent values in the original program.
+\end{itemize}
+
+Only pointed objects can be entered. If an unpointed object is
+entered the program will usually terminate with a fatal error.
+
+This section enumerates all the kinds of heap objects in the system.
+Each is identified by a distinct closure type field in its info table.
+
+\begin{tabular}{|l|l|l|l|l|l|l|l|l|l|l|}
+\hline
+
+closure type & Section \\
+
+\hline
+\emph{Pointed} \\
+\hline
+
+@CONSTR@ & \ref{sec:CONSTR} \\
+@CONSTR_p_n@ & \ref{sec:CONSTR} \\
+@CONSTR_STATIC@ & \ref{sec:CONSTR} \\
+@CONSTR_NOCAF_STATIC@ & \ref{sec:CONSTR} \\
+
+@FUN@ & \ref{sec:FUN} \\
+@FUN_p_n@ & \ref{sec:FUN} \\
+@FUN_STATIC@ & \ref{sec:FUN} \\
+
+@THUNK@ & \ref{sec:THUNK} \\
+@THUNK_p_n@ & \ref{sec:THUNK} \\
+@THUNK_STATIC@ & \ref{sec:THUNK} \\
+@THUNK_SELECTOR@ & \ref{sec:THUNK_SELECTOR} \\
+
+@BCO@ & \ref{sec:BCO} \\
+
+@AP_UPD@ & \ref{sec:AP_UPD} \\
+@PAP@ & \ref{sec:PAP} \\
+
+@IND@ & \ref{sec:IND} \\
+@IND_OLDGEN@ & \ref{sec:IND} \\
+@IND_PERM@ & \ref{sec:IND} \\
+@IND_OLDGEN_PERM@ & \ref{sec:IND} \\
+@IND_STATIC@ & \ref{sec:IND} \\
+
+@CAF_UNENTERED@ & \ref{sec:CAF} \\
+@CAF_ENTERED@ & \ref{sec:CAF} \\
+@CAF_BLACKHOLE@ & \ref{sec:CAF} \\
+
+\hline
+\emph{Unpointed} \\
+\hline
+
+@BLACKHOLE@ & \ref{sec:BLACKHOLE} \\
+@BLACKHOLE_BQ@ & \ref{sec:BLACKHOLE_BQ} \\
+
+@MVAR@ & \ref{sec:MVAR} \\
+
+@ARR_WORDS@ & \ref{sec:ARR_WORDS} \\
+
+@MUTARR_PTRS@ & \ref{sec:MUT_ARR_PTRS} \\
+@MUTARR_PTRS_FROZEN@ & \ref{sec:MUT_ARR_PTRS_FROZEN} \\
+
+@MUT_VAR@ & \ref{sec:MUT_VAR} \\
+
+@WEAK@ & \ref{sec:WEAK} \\
+@FOREIGN@ & \ref{sec:FOREIGN} \\
+@STABLE_NAME@ & \ref{sec:STABLE_NAME} \\
+\hline
+\end{tabular}
+
+Activation frames do not live (directly) on the heap --- but they have
+a similar organisation.
+
+\begin{tabular}{|l|l|}\hline
+closure type & Section \\ \hline
+@RET_SMALL@ & \ref{sec:activation-records} \\
+@RET_VEC_SMALL@ & \ref{sec:activation-records} \\
+@RET_BIG@ & \ref{sec:activation-records} \\
+@RET_VEC_BIG@ & \ref{sec:activation-records} \\
+@UPDATE_FRAME@ & \ref{sec:activation-records} \\
+@CATCH_FRAME@ & \ref{sec:activation-records} \\
+@SEQ_FRAME@ & \ref{sec:activation-records} \\
+@STOP_FRAME@ & \ref{sec:activation-records} \\
+\hline
+\end{tabular}
+
+There are also a number of administrative objects. It is an error to
+enter one of these objects.
+
+\begin{tabular}{|l|l|}\hline
+closure type & Section \\ \hline
+@TSO@ & \ref{sec:TSO} \\
+@SPARK_OBJECT@ & \ref{sec:SPARK} \\
+@BLOCKED_FETCH@ & \ref{sec:BLOCKED_FETCH} \\
+@FETCHME@ & \ref{sec:FETCHME} \\
+\hline
+\end{tabular}
+
+\Subsection{Predicates}{closure-predicates}
+
+The runtime system sometimes needs to be able to distinguish objects
+according to their properties: is the object updateable? is it in weak
+head normal form? etc. These questions can be answered by examining
+the closure type field of the object's info table.
+
+We define the following predicates to detect families of related
+info types. They are mutually exclusive and exhaustive.
+
+\begin{itemize}
+\item @isCONSTR@ is true for @CONSTR@s.
+\item @isFUN@ is true for @FUN@s.
+\item @isTHUNK@ is true for @THUNK@s.
+\item @isBCO@ is true for @BCO@s.
+\item @isAP@ is true for @AP@s.
+\item @isPAP@ is true for @PAP@s.
+\item @isINDIRECTION@ is true for indirection objects.
+\item @isBH@ is true for black holes.
+\item @isFOREIGN_OBJECT@ is true for foreign objects.
+\item @isARRAY@ is true for array objects.
+\item @isMVAR@ is true for @MVAR@s.
+\item @isIVAR@ is true for @IVAR@s.
+\item @isFETCHME@ is true for @FETCHME@s.
+\item @isSLOP@ is true for slop objects.
+\item @isRET_ADDR@ is true for return addresses.
+\item @isUPD_ADDR@ is true for update frames.
+\item @isTSO@ is true for @TSO@s.
+\item @isSTABLE_PTR_TABLE@ is true for the stable pointer table.
+\item @isSPARK_OBJECT@ is true for spark objects.
+\item @isBLOCKED_FETCH@ is true for blocked fetch objects.
+\item @isINVALID_INFOTYPE@ is true for all other info types.
+
+\end{itemize}
+
+The following predicates detect other interesting properties:
+
+\begin{itemize}
+
+\item @isPOINTED@ is true if an object has a pointed type.
+
+If an object is pointed, the following predicates may be true
+(otherwise they are false). @isWHNF@ and @isUPDATEABLE@ are
+mutually exclusive.
+
+\begin{itemize}
+\item @isWHNF@ is true if the object is in Weak Head Normal Form.
+Note that unpointed objects are (arbitrarily) not considered to be in WHNF.
+
+@isWHNF@ is true for @PAP@s, @CONSTR@s, @FUN@s and all @BCO@s.
+
+\ToDo{Need to distinguish between whnf BCOs and non-whnf BCOs in their
+closure type}
+
+\item @isUPDATEABLE@ is true if the object may be overwritten with an
+ indirection object.
+
+@isUPDATEABLE@ is true for @THUNK@s, @AP@s and @BH@s.
+
+\end{itemize}
+
+It is possible for a pointed object to be neither updatable nor in
+WHNF. For example, indirections.
+
+\item @isUNPOINTED@ is true if an object has an unpointed type.
+All such objects are boxed since only boxed objects have info pointers.
+
+It is true for @ARR_WORDS@, @ARR_PTRS@, @MUTVAR@, @MUTARR_PTRS@,
+@MUTARR_PTRS_FROZEN@, @FOREIGN@ objects, @MVAR@s and @IVAR@s.
+
+\item @isACTIVATION_FRAME@ is true for activation frames of all sorts.
+
+It is true for return addresses and update frames.
+\begin{itemize}
+\item @isVECTORED_RETADDR@ is true for vectored return addresses.
+\item @isDIRECT_RETADDR@ is true for direct return addresses.
+\end{itemize}
+
+\item @isADMINISTRATIVE@ is true for administrative objects:
+@TSO@s, the stable pointer table, spark objects and blocked fetches.
+
+\item @hasSRT@ is true if the info table for the object contains an
+SRT pointer.
+
+@hasSRT@ is true for @THUNK@s, @FUN@s, and @RET@s.
+
+\end{itemize}
+
+\begin{itemize}
+
+\item @isSTATIC@ is true for any statically allocated closure.
+
+\item @isMUTABLE@ is true for objects with mutable pointer fields:
+ @MUT_ARR@s, @MUTVAR@s, @MVAR@s and @IVAR@s.
+
+\item @isSparkable@ is true if the object can (and should) be sparked.
+It is true of updateable objects which are not in WHNF with the
+exception of @THUNK_SELECTOR@s and black holes.
+
+\end{itemize}
+
+As a minor optimisation, we might use the top bits of the @INFO_TYPE@
+field to ``cache'' the answers to some of these predicates.
+
+An indirection either points to HNF (post update); or is result of
+overwriting a FetchMe, in which case the thing fetched is either under
+evaluation (BLACKHOLE), or by now an HNF. Thus, indirections get
+NoSpark flag.
+
+\subsection{Closures (aka Pointed Objects)}
+
+An object can be entered iff it is a closure.
+
+\Subsubsection{Function closures}{FUN}
+
+Function closures represent lambda abstractions. For example,
+consider the top-level declaration:
+@
+ f = \x -> let g = \y -> x+y
+ in g x
+@
+Both @f@ and @g@ are represented by function closures. The closure
+for @f@ is \emph{static} while that for @g@ is \emph{dynamic}.
+
+The layout of a function closure is as follows:
+\begin{center}
+\begin{tabular}{|l|l|l|l|}\hline
+\emph{Fixed header} & \emph{Pointers} & \emph{Non-pointers} \\ \hline
+\end{tabular}
+\end{center}
+
+The data words (pointers and non-pointers) are the free variables of
+the function closure. The number of pointers and number of
+non-pointers are stored in @info->layout.ptrs@ and
+@info->layout.nptrs@ respecively.
+
+There are several different sorts of function closure, distinguished
+by their closure type field:
+
+\begin{itemize}
+
+\item @FUN@: a vanilla, dynamically allocated on the heap.
+
+\item $@FUN_@p@_@np$: to speed up garbage collection a number of
+specialised forms of @FUN@ are provided, for particular $(p,np)$
+pairs, where $p$ is the number of pointers and $np$ the number of
+non-pointers.
+
+\item @FUN_STATIC@. Top-level, static, function closures (such as @f@
+above) have a different layout than dynamic ones:
+
+\begin{center}
+\begin{tabular}{|l|l|l|}\hline
+\emph{Fixed header} & \emph{Static object link} \\ \hline
+\end{tabular}
+\end{center}
+
+Static function closures have no free variables. (However they may
+refer to other static closures; these references are recorded in the
+function closure's SRT.) They have one field that is not present in
+dynamic closures, the \emph{static object link} field. This is used
+by the garbage collector in the same way that to-space is, to gather
+closures that have been determined to be live but that have not yet
+been scavenged.
+
+\note{Static function closures that have no static references, and
+hence a null SRT pointer, don't need the static object link field. We
+don't take advantage of this at the moment, but we could. See
+@CONSTR_NOCAF_STATIC@.}
+\end{itemize}
+
+Each lambda abstraction, $f$, in the STG program has its own private
+info table. The following labels are relevant:
+
+\begin{itemize}
+
+\item $f$@_info@ is $f$'s info table.
+
+\item $f$@_entry@ is $f$'s slow entry point (i.e. the entry code of
+its info table; so it will label the same byte as $f$@_info@).
+
+\item $f@_fast_@k$ is $f$'s fast entry point. $k$ is the number of
+arguments $f$ takes; encoding this number in the fast-entry label
+occasionally catches some nasty code-generation errors.
+
+\end{itemize}
+
+\Subsubsection{Data constructors}{CONSTR}
+
+Data-constructor closures represent values constructed with algebraic
+data type constructors. The general layout of data constructors is
+the same as that for function closures. That is
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|}\hline
+\emph{Fixed header} & \emph{Pointers} & \emph{Non-pointers} \\ \hline
+\end{tabular}
+\end{center}
+
+There are several different sorts of constructor:
+
+\begin{itemize}
+
+\item @CONSTR@: a vanilla, dynamically allocated constructor.
+
+\item @CONSTR_@$p$@_@$np$: just like $@FUN_@p@_@np$.
+
+\item @CONSTR_INTLIKE@. A dynamically-allocated heap object that
+looks just like an @Int@. The garbage collector checks to see if it
+can common it up with one of a fixed set of static int-like closures,
+thus getting it out of the dynamic heap altogether.
+
+\item @CONSTR_CHARLIKE@: same deal, but for @Char@.
+
+\item @CONSTR_STATIC@ is similar to @FUN_STATIC@, with the
+complication that the layout of the constructor must mimic that of a
+dynamic constructor, because a static constructor might be returned to
+some code that unpacks it. So its layout is like this:
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|}\hline
+\emph{Fixed header} & \emph{Pointers} & \emph{Non-pointers} & \emph{Static object link}\\ \hline
+\end{tabular}
+\end{center}
+
+The static object link, at the end of the closure, serves the same purpose
+as that for @FUN_STATIC@. The pointers in the static constructor can point
+only to other static closures.
+
+The static object link occurs last in the closure so that static
+constructors can store their data fields in exactly the same place as
+dynamic constructors.
+
+\item @CONSTR_NOCAF_STATIC@. A statically allocated data constructor
+that guarantees not to point (directly or indirectly) to any CAF
+(\secref{CAF}). This means it does not need a static object
+link field. Since we expect that there might be quite a lot of static
+constructors this optimisation makes sense. Furthermore, the @NOCAF@
+tag allows the compiler to indicate that no CAFs can be reached
+anywhere \emph{even indirectly}.
+
+\end{itemize}
+
+For each data constructor $Con$, two info tables are generated:
+
+\begin{itemize}
+\item $Con$@_con_info@ labels $Con$'s dynamic info table,
+shared by all dynamic instances of the constructor.
+\item $Con$@_static@ labels $Con$'s static info table,
+shared by all static instances of the constructor.
+\end{itemize}
+
+Each constructor also has a \emph{constructor function}, which is a
+curried function which builds an instance of the constructor. The
+constructor function has an info table labelled as @$Con$_info@, and
+entry code pointed to by @$Con$_entry@.
+
+Nullary constructors are represented by a single static info table,
+which everyone points to. Thus for a nullary constructor we can omit
+the dynamic info table and the constructor function.
+
+\subsubsection{Thunks}
+\label{sec:THUNK}
+\label{sec:THUNK_SELECTOR}
+
+A thunk represents an expression that is not obviously in head normal
+form. For example, consider the following top-level definitions:
+@
+ range = between 1 10
+ f = \x -> let ys = take x range
+ in sum ys
+@
+Here the right-hand sides of @range@ and @ys@ are both thunks; the former
+is static while the latter is dynamic.
+
+The layout of a thunk is the same as that for a function closure.
+However, thunks must have a payload of at least @MIN_UPD_SIZE@
+words to allow it to be overwritten with a black hole and an
+indirection. The compiler may have to add extra non-pointer fields to
+satisfy this constraint.
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|}\hline
+\emph{Fixed header} & \emph{Pointers} & \emph{Non-pointers} \\ \hline
+\end{tabular}
+\end{center}
+
+The layout word in the info table contains the same information as for
+function closures; that is, number of pointers and number of
+non-pointers.
+
+A thunk differs from a function closure in that it can be updated.
+
+There are several forms of thunk:
+
+\begin{itemize}
+
+\item @THUNK@ and $@THUNK_@p@_@np$: vanilla, dynamically allocated
+thunks. Dynamic thunks are overwritten with normal indirections
+(@IND@), or old generation indirections (@IND_OLDGEN@): see
+\secref{IND}.
+
+\item @THUNK_STATIC@. A static thunk is also known as a
+\emph{constant applicative form}, or \emph{CAF}. Static thunks are
+overwritten with static indirections.
+
+\begin{center}
+\begin{tabular}{|l|l|}\hline
+\emph{Fixed header} & \emph{Static object link}\\ \hline
+\end{tabular}
+\end{center}
+
+\item @THUNK_SELECTOR@ is a (dynamically allocated) thunk whose entry
+code performs a simple selection operation from a data constructor
+drawn from a single-constructor type. For example, the thunk
+@
+ x = case y of (a,b) -> a
+@
+is a selector thunk. A selector thunk is laid out like this:
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|}\hline
+\emph{Fixed header} & \emph{Selectee pointer} \\ \hline
+\end{tabular}
+\end{center}
+
+The layout word contains the byte offset of the desired word in the
+selectee. Note that this is different from all other thunks.
+
+The garbage collector ``peeks'' at the selectee's tag (in its info
+table). If it is evaluated, then it goes ahead and does the
+selection, and then behaves just as if the selector thunk was an
+indirection to the selected field. If it is not evaluated, it treats
+the selector thunk like any other thunk of that shape.
+[Implementation notes. Copying: only the evacuate routine needs to be
+special. Compacting: only the PRStart (marking) routine needs to be
+special.]
+
+There is a fixed set of pre-compiled selector thunks built into the
+RTS, representing offsets from 0 to @MAX_SPEC_SELECTOR_THUNK@. The
+info tables are labelled @sel_info_$n$@ where $n$ is the offset.
+
+\end{itemize}
+
+The only label associated with a thunk is its info table:
+
+\begin{description}
+\item[$f$@_info@] is $f$'s info table.
+\end{description}
+
+
+\Subsubsection{Byte-code objects}{BCO}
+
+A Byte-Code Object (BCO) is a container for a a chunk of byte-code,
+which can be executed by Hugs. The byte-code represents a
+supercombinator in the program: when Hugs compiles a module, it
+performs lambda lifting and each resulting supercombinator becomes a
+byte-code object in the heap.
+
+BCOs are not updateable; the bytecode compiler represents updatable
+thunks using a combination of @AP@s and @BCO@s.
+
+The semantics of BCOs are described in \secref{hugs-heap-objects}. A
+BCO has the following structure:
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|l|}
+\hline
+\emph{Fixed Header} & \emph{Layout} & \emph{Offset} & \emph{Size} &
+\emph{Literals} & \emph{Byte code} \\
+\hline
+\end{tabular}
+\end{center}
+
+\noindent where:
+\begin{itemize}
+\item The entry code is a static code fragment/info table that returns
+to the scheduler to invoke Hugs (\secref{ghc-to-hugs-switch}).
+\item \emph{Layout} contains the number of pointer literals in the
+\emph{Literals} field.
+\item \emph{Offset} is the offset to the byte code from the start of
+the object.
+\item \emph{Size} is the number of words of byte code in the object.
+\item \emph{Literals} contains any pointer and non-pointer literals used in
+the byte-codes (including jump addresses), pointers first.
+\item \emph{Byte code} contains \emph{Size} words of non-pointer byte
+code.
+\end{itemize}
+
+
+\Subsubsection{Partial applications}{PAP}
+
+A partial application (PAP) represents a function applied to too few
+arguments. It is only built as a result of updating after an
+argument-satisfaction check failure. A PAP has the following shape:
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|}\hline
+\emph{Fixed header} & \emph{No of words of stack} & \emph{Function closure} & \emph{Stack chunk ...} \\ \hline
+\end{tabular}
+\end{center}
+
+The ``Stack chunk'' is a copy of the chunk of stack above the update
+frame; ``No of words of stack'' tells how many words it consists of.
+The function closure is (a pointer to) the closure for the function
+whose argument-satisfaction check failed.
+
+In the normal case where a PAP is built as a result of an argument
+satisfaction check failure, the stack chunk will just contain
+``pending arguments'', ie. pointers and tagged non-pointers. It may
+in fact also contain activation records, but not update frames, seq
+frames, or catch frames. The reason is the garbage collector uses the
+same code to scavenge a stack as it does to scavenge the payload of a
+PAP, but an update frame contains a link to the next update frame in
+the chain and this link would need to be relocated during garbage
+collection. Revertible black holes and asynchronous exceptions use
+the more general form of PAPs (see Section \ref{revertible-bh}).
+
+There is just one standard form of PAP. There is just one info table
+too, called @PAP_info@. Its entry code simply copies the arg stack
+chunk back on top of the stack and enters the function closure. (It
+has to do a stack overflow test first.)
+
+There is just one way to build a PAP: by calling @stg_update_PAP@ with
+the function closure in register @R1@ and the pending arguments on the
+stack. The @stg_update_PAP@ function will build the PAP, perform the
+update, and return to the next activation record on the stack. If
+there are \emph{no} pending arguments on the stack, then no PAP need
+be built: in this case @stg_update_PAP@ just overwrites the updatee
+with an indirection to the function closure.
+
+PAPs are also used to implement Hugs functions (where the arguments
+are free variables). PAPs generated by Hugs can be static so we need
+both @PAP@ and @PAP_STATIC@.
+
+\Subsubsection{@AP_UPD@ objects}{AP_UPD}
+
+@AP_UPD@ objects are used to represent thunks built by Hugs. The only
+distintion between an @AP_UPD@ and a @PAP@ is that an @AP_UPD@ is
+updateable.
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|}
+\hline
+\emph{Fixed Header} & \emph{No of stack words} & \emph{Function closure} & \emph{Stack chunk} \\
+\hline
+\end{tabular}
+\end{center}
+
+The entry code pushes an update frame, copies the arg stack chunk on
+top of the stack, and enters the function closure. (It has to do a
+stack overflow test first.)
+
+The ``stack chunk'' is a block of stack not containing update frames,
+seq frames or catch frames (just like a PAP). In the case of Hugs,
+the stack chunk will contain the free variables of the thunk, and the
+function closure is (a pointer to) the closure for the thunk. The
+argument stack may be empty if the thunk has no free variables.
+
+\note{Since @AP_UPD@s are updateable, the @MIN_UPD_SIZE@ constraint
+applies here too.}
+
+\Subsubsection{Indirections}{IND}
+
+Indirection closures just point to other closures. They are introduced
+when a thunk is updated to point to its value. The entry code for all
+indirections simply enters the closure it points to.
+
+There are several forms of indirection:
+
+\begin{description}
+\item[@IND@] is the vanilla, dynamically-allocated indirection.
+It is removed by the garbage collector. It has the following
+shape:
+\begin{center}
+\begin{tabular}{|l|l|l|}\hline
+\emph{Fixed header} & \emph{Target closure} \\ \hline
+\end{tabular}
+\end{center}
+
+An @IND@ only exists in the youngest generation. In older
+generations, we have @IND_OLDGEN@s. The update code
+(@Upd_frame_$n$_entry@) checks whether the updatee is in the youngest
+generation before deciding which kind of indirection to use.
+
+\item[@IND_OLDGEN@] is the vanilla, dynamically-allocated indirection.
+It is removed by the garbage collector. It has the following
+shape:
+\begin{center}
+\begin{tabular}{|l|l|l|}\hline
+\emph{Fixed header} & \emph{Target closure} & \emph{Mutable link field} \\ \hline
+\end{tabular}
+\end{center}
+It contains a \emph{mutable link field} that is used to string together
+mutable objects in each old generation.
+
+\item[@IND_PERM@]
+for lexical profiling, it is necessary to maintain cost centre
+information in an indirection, so ``permanent indirections'' are
+retained forever. Otherwise they are just like vanilla indirections.
+\note{If a permanent indirection points to another permanent
+indirection or a @CONST@ closure, it is possible to elide the indirection
+since it will have no effect on the profiler.}
+
+\note{Do we still need @IND@ in the profiling build, or do we just
+need @IND@ but its behaviour changes when profiling is on?}
+
+\item[@IND_OLDGEN_PERM@]
+Just like an @IND_OLDGEN@, but sticks around like an @IND_PERM@.
+
+\item[@IND_STATIC@] is used for overwriting CAFs when they have been
+evaluated. Static indirections are not removed by the garbage
+collector; and are statically allocated outside the heap (and should
+stay there). Their static object link field is used just as for
+@FUN_STATIC@ closures.
+
+\begin{center}
+\begin{tabular}{|l|l|l|}
+\hline
+\emph{Fixed header} & \emph{Target closure} & \emph{Static link field} \\
+\hline
+\end{tabular}
+\end{center}
+
+\end{description}
+
+\subsubsection{Black holes and blocking queues}
+\label{sec:BLACKHOLE}
+\label{sec:BLACKHOLE_BQ}
+
+Black hole closures are used to overwrite closures currently being
+evaluated. They inform the garbage collector that there are no live
+roots in the closure, thus removing a potential space leak.
+
+Black holes also become synchronization points in the concurrent
+world. When a thread attempts to enter a blackhole, it must wait for
+the result of the computation, which is presumably in progress in
+another thread.
+
+\note{In a single-threaded system, entering a black hole indicates an
+infinite loop. In a concurrent system, entering a black hole
+indicates an infinite loop only if the hole is being entered by the
+same thread that originally entered the closure. It could also bring
+about a deadlock situation where several threads are waiting
+circularly on computations in progress.}
+
+There are two types of black hole:
+
+\begin{description}
+
+\item[@BLACKHOLE@]
+A straightforward blackhole just consists of an info pointer and some
+padding to allow updating with an @IND_OLDGEN@ if necessary. This
+type of blackhole has no waiting threads.
+
+\begin{center}
+\begin{tabular}{|l|l|l|}
+\hline
+\emph{Fixed header} & \emph{Padding} & \emph{Padding} \\
+\hline
+\end{tabular}
+\end{center}
+
+If we're doing \emph{eager blackholing} then a thunk's info pointer is
+overwritten with @BLACKHOLE_info@ at the time of entry; hence the need
+for blackholes to be small, otherwise we'd be overwriting part of the
+thunk itself.
+
+\item[@BLACKHOLE_BQ@]
+When a thread enters a @BLACKHOLE@, it is turned into a @BLACKHOLE_BQ@
+(blocking queue), which contains a linked list of blocked threads in
+addition to the info pointer.
+
+\begin{center}
+\begin{tabular}{|l|l|l|}
+\hline
+\emph{Fixed header} & \emph{Blocked thread link} & \emph{Mutable link field} \\
+\hline
+\end{tabular}
+\end{center}
+
+The \emph{Blocked thread link} points to the TSO of the first thread
+waiting for the value of this thunk. All subsequent TSOs in the list
+are linked together using their @tso->link@ field, ending in
+@END_TSO_QUEUE_closure@.
+
+Because new threads can be added to the \emph{Blocked thread link}, a
+blocking queue is \emph{mutable}, so we need a mutable link field in
+order to chain it on to a mutable list for the generational garbage
+collector.
+
+\end{description}
+
+\Subsubsection{FetchMes}{FETCHME}
+
+In the parallel systems, FetchMes are used to represent pointers into
+the global heap. When evaluated, the value they point to is read from
+the global heap.
+
+\ToDo{Describe layout}
+
+Because there may be offsets into these arrays, a primitive array
+cannot be handled as a FetchMe in the parallel system, but must be
+shipped in its entirety if its parent closure is shipped.
+
+
+
+\Subsection{Unpointed Objects}{unpointed-objects}
+
+A variable of unpointed type is always bound to a \emph{value}, never
+to a \emph{thunk}. For this reason, unpointed objects cannot be
+entered.
+
+\subsubsection{Immutable objects}
+\label{sec:ARR_WORDS}
+
+\begin{description}
+\item[@ARR_WORDS@] is a variable-sized object consisting solely of
+non-pointers. It is used for arrays of all sorts of things (bytes,
+words, floats, doubles... it doesn't matter).
+
+Strictly speaking, an @ARR_WORDS@ could be mutable, but because it
+only contains non-pointers we don't need to track this fact.
+
+\begin{center}
+\begin{tabular}{|c|c|c|c|}
+\hline
+\emph{Fixed Hdr} & \emph{No of non-pointers} & \emph{Non-pointers\ldots} \\ \hline
+\end{tabular}
+\end{center}
+\end{description}
+
+\subsubsection{Mutable objects}
+\label{sec:mutables}
+\label{sec:MUT_VAR}
+\label{sec:MUT_ARR_PTRS}
+\label{sec:MUT_ARR_PTRS_FROZEN}
+\label{sec:MVAR}
+
+Some of these objects are \emph{mutable}; they represent objects which
+are explicitly mutated by Haskell code through the @ST@ or @IO@
+monads. They're not used for thunks which are updated precisely once.
+Depending on the garbage collector, mutable closures may contain extra
+header information which allows a generational collector to implement
+the ``write barrier.''
+
+Notice that mutable objects all have the same general layout: there is
+a mutable link field as the second word after the header. This is so
+that code to process old-generation mutable lists doesn't need to look
+at the type of the object to determine where its link field is.
+
+\begin{description}
+
+\item[@MUT_VAR@] is a mutable variable.
+\begin{center}
+\begin{tabular}{|c|c|c|}
+\hline
+\emph{Fixed Hdr} \emph{Pointer} & \emph{Mutable link} & \\ \hline
+\end{tabular}
+\end{center}
+
+\item[@MUT_ARR_PTRS@] is a mutable array of pointers. Such an array
+may be \emph{frozen}, becoming an @MUT_ARR_PTRS_FROZEN@, with a
+different info-table.
+
+\begin{center}
+\begin{tabular}{|c|c|c|c|}
+\hline
+\emph{Fixed Hdr} & \emph{No of ptrs} & \emph{Mutable link} & \emph{Pointers\ldots} \\ \hline
+\end{tabular}
+\end{center}
+
+\item[@MUT_ARR_PTRS_FROZEN@] This is the immutable version of
+@MUT_ARR_PTRS@. It still has a mutable link field for two reasons: we
+need to keep it on the mutable list for an old generation at least
+until the next garbage collection, and it may become mutable again via
+@thawArray@.
+
+\begin{center}
+\begin{tabular}{|c|c|c|c|}
+\hline
+\emph{Fixed Hdr} & \emph{No of ptrs} & \emph{Mutable link} & \emph{Pointers\ldots} \\ \hline
+\end{tabular}
+\end{center}
+
+\item[@MVAR@]
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|}
+\hline
+\emph{Fixed header} & \emph{Head} & \emph{Mutable link} & \emph{Tail}
+& \emph{Value}\\
+\hline
+\end{tabular}
+\end{center}
+
+\ToDo{MVars}
+
+\end{description}
+
+
+\Subsubsection{Foreign objects}{FOREIGN}
+
+Here's what a ForeignObj looks like:
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|}
+\hline
+\emph{Fixed header} & \emph{Data} \\
+\hline
+\end{tabular}
+\end{center}
+
+A foreign object is simple a boxed pointer to an address outside the
+Haskell heap, possible to @malloc@ed data. The only reason foreign
+objects exist is so that we can track the lifetime of one using weak
+pointers (see \secref{WEAK}) and run a finaliser when the foreign
+object is unreachable.
+
+\subsubsection{Weak pointers}
+\label{sec:WEAK}
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|}
+\hline
+\emph{Fixed header} & \emph{Key} & \emph{Value} & \emph{Finaliser}
+& \emph{Link}\\
+\hline
+\end{tabular}
+\end{center}
+
+\ToDo{Weak poitners}
+
+\subsubsection{Stable names}
+\label{sec:STABLE_NAME}
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|}
+\hline
+\emph{Fixed header} & \emph{Index} \\
+\hline
+\end{tabular}
+\end{center}
+
+\ToDo{Stable names}
+
+The remaining objects types are all administrative --- none of them
+may be entered.
+
+\subsection{Other weird objects}
+\label{sec:SPARK}
+\label{sec:BLOCKED_FETCH}
+
+\begin{description}
+\item[@BlockedFetch@ heap objects (`closures')] (parallel only)
+
+@BlockedFetch@s are inbound fetch messages blocked on local closures.
+They arise as entries in a local blocking queue when a fetch has been
+received for a local black hole. When awakened, we look at their
+contents to figure out where to send a resume.
+
+A @BlockedFetch@ closure has the form:
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|l|}\hline
+\emph{Fixed header} & link & node & gtid & slot & weight \\ \hline
+\end{tabular}
+\end{center}
+
+\item[Spark Closures] (parallel only)
+
+Spark closures are used to link together all closures in the spark pool. When
+the current processor is idle, it may choose to speculatively evaluate some of
+the closures in the pool. It may also choose to delete sparks from the pool.
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|l|}\hline
+\emph{Fixed header} & \emph{Spark pool link} & \emph{Sparked closure} \\ \hline
+\end{tabular}
+\end{center}
+
+\item[Slop Objects]\label{sec:slop-objects}
+
+Slop objects are used to overwrite the end of an updatee if it is
+larger than an indirection. Normal slop objects consist of an info
+pointer a size word and a number of slop words.
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|l|}\hline
+\emph{Info Pointer} & \emph{Size} & \emph{Slop Words} \\ \hline
+\end{tabular}
+\end{center}
+
+This is too large for single word slop objects which consist of a
+single info table.
+
+Note that slop objects only contain an info pointer, not a standard
+fixed header. This doesn't cause problems because slop objects are
+always unreachable --- they can only be accessed by linearly scanning
+the heap.
+
+\note{Currently we don't use slop objects because the storage manager
+isn't reliant on objects being adjacent, but if we move to a ``mostly
+copying'' style collector, this will become an issue.}
+
+\end{description}
+
+\Subsection{Thread State Objects (TSOs)}{TSO}
+
+In the multi-threaded system, the state of a suspended thread is
+packed up into a Thread State Object (TSO) which contains all the
+information needed to restart the thread and for the garbage collector
+to find all reachable objects. When a thread is running, it may be
+``unpacked'' into machine registers and various other memory locations
+to provide faster access.
+
+Single-threaded systems don't really \emph{need\/} TSOs --- but they do
+need some way to tell the storage manager about live roots so it is
+convenient to use a single TSO to store the mutator state even in
+single-threaded systems.
+
+Rather than manage TSOs' alloc/dealloc, etc., in some \emph{ad hoc}
+way, we instead alloc/dealloc/etc them in the heap; then we can use
+all the standard garbage-collection/fetching/flushing/etc machinery on
+them. So that's why TSOs are ``heap objects,'' albeit very special
+ones.
+\begin{center}
+\begin{tabular}{|l|l|}
+ \hline \emph{Fixed header}
+\\ \hline \emph{Link field}
+\\ \hline \emph{Mutable link field}
+\\ \hline \emph{What next}
+\\ \hline \emph{State}
+\\ \hline \emph{Thread Id}
+\\ \hline \emph{Exception Handlers}
+\\ \hline \emph{Ticky Info}
+\\ \hline \emph{Profiling Info}
+\\ \hline \emph{Parallel Info}
+\\ \hline \emph{GranSim Info}
+\\ \hline \emph{Stack size}
+\\ \hline \emph{Max Stack size}
+\\ \hline \emph{Sp}
+\\ \hline \emph{Su}
+\\ \hline \emph{SpLim}
+\\ \hline
+\\
+ \emph{Stack}
+\\
+\\ \hline
+\end{tabular}
+\end{center}
+The contents of a TSO are:
+\begin{description}
+
+\item[\emph{Link field}] This is a pointer used to maintain a list of
+threads with a similar state (e.g.~all runnable, all sleeping, all
+blocked on the same black hole, all blocked on the same MVar,
+etc.)
+
+\item[\emph{Mutable link field}] Because the stack is mutable by
+definition, the generational collector needs to track TSOs in older
+generations that may point into younger ones (which is just about any
+TSO for a thread that has run recently). Hence the need for a mutable
+link field (see \secref{mutables}).
+
+\item[\emph{What next}]
+This field has five values:
+\begin{description}
+\item[@ThreadEnterGHC@] The thread can be started by entering the
+closure pointed to by the word on the top of the stack.
+\item[@ThreadRunGHC@] The thread can be started by jumping to the
+address on the top of the stack.
+\item[@ThreadEnterHugs@] The stack has a pointer to a Hugs-built
+closure on top of the stack: enter the closure to run the thread.
+\item[@ThreadKilled@] The thread has been killed (by @killThread#@).
+It is probably still around because it is on some queue somewhere and
+hasn't been garbage collected yet.
+\item[@ThreadComplete@] The thread has finished. Its @TSO@ hasn't
+been garbage collected yet.
+\end{description}
+
+\item[\emph{Thread Id}]
+This field contains a (not necessarily unique) integer that identifies
+the thread. It can be used eg. for hashing.
+
+\item[\emph{Ticky Info}] Optional information for ``Ticky Ticky''
+statistics: @TSO_STK_HWM@ is the maximum number of words allocated to
+this thread.
+
+\item[\emph{Profiling Info}] Optional information for profiling:
+@TSO_CCC@ is the current cost centre.
+
+\item[\emph{Parallel Info}]
+Optional information for parallel execution.
+
+% \begin{itemize}
+%
+% \item The types of threads (@TSO_TYPE@):
+% \begin{description}
+% \item[@T_MAIN@] Must be executed locally.
+% \item[@T_REQUIRED@] A required thread -- may be exported.
+% \item[@T_ADVISORY@] An advisory thread -- may be exported.
+% \item[@T_FAIL@] A failure thread -- may be exported.
+% \end{description}
+%
+% \item I've no idea what else
+%
+% \end{itemize}
+
+\item[\emph{GranSim Info}]
+Optional information for gransim execution.
+
+% \item Optional information for GranSim execution:
+% \begin{itemize}
+% \item locked
+% \item sparkname
+% \item started at
+% \item exported
+% \item basic blocks
+% \item allocs
+% \item exectime
+% \item fetchtime
+% \item fetchcount
+% \item blocktime
+% \item blockcount
+% \item global sparks
+% \item local sparks
+% \item queue
+% \item priority
+% \item clock (gransim light only)
+% \end{itemize}
+%
+%
+% Here are the various queues for GrAnSim-type events.
+%
+% Q_RUNNING
+% Q_RUNNABLE
+% Q_BLOCKED
+% Q_FETCHING
+% Q_MIGRATING
+%
+
+\item[\emph{Stack Info}] Various fields contain information on the
+stack: its current size, its maximum size (to avoid infinite loops
+overflowing the memory), the current stack pointer (\emph{Sp}), the
+current stack update frame pointer (\emph{Su}), and the stack limit
+(\emph{SpLim}). The latter three fields are loaded into the relevant
+registers when the thread is run.
+
+\item[\emph{Stack}] This is the actual stack for the thread,
+\emph{Stack size} words long. It grows downwards from higher
+addresses to lower addresses. When the stack overflows, it will
+generally be relocated into larger premises unless \emph{Max stack
+size} is reached.
+
+\end{description}
+
+The garbage collector needs to be able to find all the
+pointers in a stack. How does it do this?
+
+\begin{itemize}
+
+\item Within the stack there are return addresses, pushed
+by @case@ expressions. Below a return address (i.e. at higher
+memory addresses, since the stack grows downwards) is a chunk
+of stack that the return address ``knows about'', namely the
+activation record of the currently running function.
+
+\item Below each such activation record is a \emph{pending-argument
+section}, a chunk of
+zero or more words that are the arguments to which the result
+of the function should be applied. The return address does not
+statically
+``know'' how many pending arguments there are, or their types.
+(For example, the function might return a result of type $\alpha$.)
+
+\item Below each pending-argument section is another return address,
+and so on. Actually, there might be an update frame instead, but we
+can consider update frames as a special case of a return address with
+a well-defined activation record.
+
+\end{itemize}