[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.git] / ghc / includes / SMInfoTables.lh
1 %
2 % (c) The OBFUSCATION-THROUGH-GRATUITOUS-PREPROCESSOR-ABUSE Project,
3 %     Glasgow University, 1990-1994
4 %
5 %************************************************************************
6 %*                                                                      *
7 \section[info-table-macros]{Info-table macros}
8 %*                                                                      *
9 %************************************************************************
10
11 We define {\em info tables} here.  First, all the different pieces of
12 an info table (entry code, evac code, etc.); then all the different
13 kinds of info tables (SPEC, DYN, etc).  NB: some of the parallel-only
14 kinds are defined in \tr{Parallel.lh}, not here.
15
16 An info-table contains several fields. The first field is
17 the label of the closure's {\em standard-entry code}. This is used by
18 the reducer to ``evaluate'' the closure. The remaining fields are used
19 by the garbage collector and other parts of the runtime
20 system. Info-tables are declared using the C macros defined below.
21 The details of the contents are determined by the storage manager and
22 are not of interest outside it.
23
24 Info tables may either be {\em reversed} or not.  Reversed is normal
25 and preferred, but it requires ``assembler mangling'' of the C
26 compiler output.  (The native-code generator does reversed info-tables
27 automagically.) With reversed info tables, (a)~the words are reversed
28 [obviously], (b)~the info-table's C label addresses the word {\em just
29 after} the info table (where its associated entry code ``happens to be''),
30 and (c)~the entry-code word in the info table is omitted (it's
31 vestigial).
32
33 Info-table reversal is hidden behind the @IREL@ macro.
34
35 The following fields are used when defining particular info-tables.
36 Some sorts of info-table (e.g. @FETCHME_ITBL@) don't need all these
37 fields to be specified.
38
39 \begin{description}
40 \item[@infolbl@]
41 The name used to create labels for the info-table, profiling
42 information, etc.
43
44 \item[\tr{entry_code}:]
45 The function which is called when entering the closure.
46
47 \item[\tr{update_code}:]
48 The function which is called when updating the closure (constructors only).
49
50 \item[\tr{tag}:]
51 (So much for the Spineless {\em Tagless} G-Machine...)  Used for
52 semi-tagging checks.
53
54 \item[\tr{type}:]
55 Similar-but-different info to the \tr{tag} stuff; the
56 parallel world needs more elaborate info.
57
58 \item[\tr{size}:]
59 The size of the closure (see \tr{SMClosures.lh} for a precise
60 definition of ``size'').  Used by the garbage-collector, not the
61 Haskell reducer.
62
63 \item[\tr{ptrs}:]
64 The number of pointers in the closure.  Used by the garbage-collector,
65 not the Haskell reducer.
66
67 \item[@localness@]
68 Whether the info-table is local to this module or not.
69 The field is set to @static@ if the info-table is
70 local, and is empty otherwise.
71
72 \item[@entry_localness@]
73 Whether the @entry_code@ routine is local to this module or not.
74 This field can have the following values:
75   \begin{description}
76   \item [@EXTFUN@]
77   The entry code is global.
78   \item [@INTFUN@]
79   The entry code is local.
80   \end{description}
81
82 \item[@kind@]
83 This identifies the general sort of the closure for profiling purposes.
84 It can have the following values (defined in CostCentre.lh):
85
86   \begin{description}
87   \item[@CON_K@]
88   A constructor.
89   \item[@FN_K@]
90   A literal function.
91   \item[@PAP_K@]
92   A partial application.
93   \item[@THK_K@]
94   A thunk, or suspension.
95   \item[@BH_K@]
96   A black hole.
97   \item[@ARR_K@]
98   An array.
99   \item[@ForeignObj_K@]
100   A Foreign object (non-Haskell heap resident).
101   \item[@SPT_K@]
102   The Stable Pointer table.  (There should only be one of these but it
103   represents a form of weak space leak since it can't shrink to meet
104   non-demand so it may be worth watching separately? ADR)
105   \item[@INTERNAL_KIND@]
106   Something internal to the runtime system.
107   \end{description}
108
109 \item[@descr@]
110 This is a string used to identify the closure for profiling purposes.
111 \end{description}
112
113 So, for example:
114 \begin{pseudocode}
115 SPEC_N_ITBL(RBH_Save_0_info,RBH_Save_0_entry,UpdErr,0,INFO_OTHER_TAG,2,0,,IF_,INTERNAL_KIND,"RBH-SAVE","RBH_Save_0");
116 \end{pseudocode}
117
118 %************************************************************************
119 %*                                                                      *
120 \subsection[info-table-common-up]{The commoned-up info-table world}
121 %*                                                                      *
122 %************************************************************************
123
124 Since lots of info-tables share the same information (which doesn't
125 change at run time) needlessly, we gather this common information
126 together into a rep-table.
127
128 Conditionally present data (concerning the parallel world, and also
129 information for the collectors) are gathered into unique rep-tables,
130 which are pointed to from info-tables.  This saves several words for
131 each closure we build, at the cost of making garbage collection and
132 fetching of data from info-tables a little more hairy.
133
134 Size and pointers fields go away altogether, save for @GEN@ closures
135 where they are tacked on to the end of info-tables.
136
137 %************************************************************************
138 %*                                                                      *
139 \subsection[info-table-common]{Bits common to all info-tables}
140 %*                                                                      *
141 %************************************************************************
142
143 The entry code for a closure, its type, its ``size'', and the number
144 of pointer-words it contains are the same in every info table.  For
145 the parallel system, two flush code-entries are also standard.
146
147 Multi-slurp protection:
148 \begin{code}
149 #ifndef SMInfoTables_H
150 #define SMInfoTables_H
151 \end{code}
152
153 \begin{code}
154 #ifdef __STG_REV_TBLS__
155
156 # define IREL(offset)   (-(offset))
157
158 /* NB: the ENT_ macro (StgMacros.lh) must also be changed */
159
160 # define ENTRY_CODE(infoptr)     ((F_)(infoptr))
161
162 #else /* boring non-reversed info tables */
163
164 # define IREL(offset)   (offset)
165
166 # define ENTRY_CODE(infoptr)     (((FP_)(infoptr))[IREL(0)])
167
168 #endif /* non-fixed size info tables */
169 \end{code}
170
171 \begin{code}
172 #define INFO_TAG(infoptr)       ((I_) ((P_)(infoptr))[IREL(1)])
173 #define EVAL_TAG(infoptr)       (INFO_TAG(infoptr) >= 0)
174 \end{code}
175
176 \begin{code}
177
178 #define INFO_INTERNAL           (~0L)   /* Should never see this */
179
180 #define INFO_UNUSED             (~0L)
181 /* We'd like to see this go away in code pointer fields, with specialized code
182    to print out an appropriate error message instead.
183    WDP 94/11: At least make it an Obviously Weird Value?
184  */
185
186 \end{code}
187
188
189 %************************************************************************
190 %*                                                                      *
191 \subsection[info-table-rtbl]{Rep tables in an info table}
192 %*                                                                      *
193 %************************************************************************
194
195 Common information is pointed to by the rep table pointer.  We want to
196 use extern declarations almost everywhere except for the single module
197 (\tr{Rep.lc}) in which the rep tables are declared locally.
198
199 \begin{code}
200 #if defined(COMPILING_REP_LC) || defined(COMPILING_NCG)
201 # define MAYBE_DECLARE_RTBL(l,s,p)
202 #else
203 # define MAYBE_DECLARE_RTBL(l,s,p)      EXTDATA_RO(MK_REP_REF(l,s,p));
204 #endif
205
206 #define INFO_RTBL(infoptr)      (((PP_)(infoptr))[IREL(2)])
207 \end{code}
208   
209 %************************************************************************
210 %*                                                                      *
211 \subsection{Maybe-there-maybe-not fields in an info table}
212 %*                                                                      *
213 %************************************************************************
214
215 That's about it for the fixed stuff...entry code, a tag and an RTBL pointer.
216
217 \begin{code}
218 #define FIXED_INFO_WORDS                3
219 \end{code}
220
221 %************************************************************************
222 %*                                                                      *
223 \subsubsection{Profiling-only fields in an info table}
224 %*                                                                      *
225 %************************************************************************
226
227 These macros result in the profiling kind and description string being
228 included only if required.
229 \begin{code}
230 #define PROFILING_INFO_OFFSET  (FIXED_INFO_WORDS)
231
232 #if !defined(PROFILING)
233 # define PROFILING_INFO_WORDS   0
234 # define INCLUDE_PROFILING_INFO(base_name)
235 # define INREGS_PROFILING_INFO    
236
237 #else
238 # define PROFILING_INFO_WORDS   1
239
240 # define INCLUDE_PROFILING_INFO(base_name) , (W_)REF_CAT_IDENT(base_name)
241 # define INREGS_PROFILING_INFO  ,INFO_UNUSED
242
243 # define INFO_CAT(infoptr)  (((ClCategory *)(infoptr))[IREL(PROFILING_INFO_OFFSET)])
244
245 #endif
246 \end{code}
247
248 %************************************************************************
249 %*                                                                      *
250 \subsubsection{Non-standard fields in an info table: where they'll be}
251 %*                                                                      *
252 %************************************************************************
253
254 The @UPDATE_CODE@ field is a pointer to the update code for a constructor.
255 I believe that constructors are always of the following types:
256
257 \begin{itemize}
258 \item @CHARLIKE@
259 \item @CONST@
260 \item @GEN_N@
261 \item @INTLIKE@
262 \item @SPEC_N@
263 \item @STATIC@
264 \end{itemize}
265
266 Info tables for these types have non-standard update code fields.  In addition,
267 because @GEN@ closures have further non-standard fields (size, ptrs), the
268 info tables for @GEN_U@ closures also have a non-standard update code field 
269 (which is filled in with @StdErrorCode@).
270
271 When we're in the parallel world, we also have to know which registers are
272 live when we're returning a constructor in registers, so we have a second 
273 word for that as well.
274
275 \begin{code}
276
277 #define UPDATE_INFO_OFFSET  (PROFILING_INFO_OFFSET+PROFILING_INFO_WORDS)
278
279 #ifndef PAR
280 # define UPDATE_INFO_WORDS    1
281 # define INCLUDE_UPDATE_INFO(upd,live)  ,(W_)upd
282 #else
283 # define UPDATE_INFO_WORDS    2
284 # define INCLUDE_UPDATE_INFO(upd,live)  ,(W_)upd,(W_)live
285 #endif
286
287 #define UPDATE_CODE(infoptr)    (((FP_)(infoptr))[IREL(UPDATE_INFO_OFFSET)])
288 #define INFO_LIVENESS(infoptr)  (((P_)(infoptr))[IREL(UPDATE_INFO_OFFSET+1)])
289 \end{code}
290
291 @GEN@ closures have the size and number of pointers in the info table
292 rather than the rep table.  These non-standard fields follow the update
293 code field (which is only required for @GEN_N@ closures, but which we
294 include in @GEN_U@ closures just to keep this other stuff at a consistent
295 offset).
296
297 \begin{code}
298 #define GEN_INFO_OFFSET     (UPDATE_INFO_OFFSET+UPDATE_INFO_WORDS)
299 #define GEN_INFO_WORDS    2
300 #define INCLUDE_GEN_INFO(size,ptrs)     ,(W_)size,(W_)ptrs
301
302 #define GEN_INFO_SIZE(infoptr)   ((I_)((P_)(infoptr))[IREL(GEN_INFO_OFFSET)])
303 #define GEN_INFO_NoPTRS(infoptr) ((I_)((P_)(infoptr))[IREL(GEN_INFO_OFFSET+1)])
304 \end{code}
305
306 @CONST@ closures have a pointer to a static version of the closure in their
307 info tables.  This non-standard field follows their update code field.
308
309 \begin{code}
310 #define CONST_INFO_OFFSET           (UPDATE_INFO_OFFSET+UPDATE_INFO_WORDS)
311 #define CONST_INFO_WORDS    1
312 #define INCLUDE_CONST_INFO(closure)     ,(W_)closure
313
314 #define CONST_STATIC_CLOSURE(infoptr)   (((PP_)(infoptr))[IREL(CONST_INFO_OFFSET)])
315 \end{code}
316
317 @STATIC@ closures are like @GEN@ closures in that they also have the
318 size and number of pointers in the info table rather than the rep
319 table.  Again, these non-standard fields follow the update code field
320 (which I believe is not actually needed for STATIC closures).
321
322 \begin{code}
323 #define STATIC_INFO_OFFSET          (UPDATE_INFO_OFFSET+UPDATE_INFO_WORDS)
324 #define STATIC_INFO_WORDS    2
325 #define INCLUDE_STATIC_INFO(size,ptrs)  ,(W_)size,(W_)ptrs
326
327 #define STATIC_INFO_SIZE(infoptr)   ((I_)((P_)(infoptr))[IREL(STATIC_INFO_OFFSET)])
328 #define STATIC_INFO_NoPTRS(infoptr) ((I_)((P_)(infoptr))[IREL(STATIC_INFO_OFFSET+1)])
329 \end{code}
330
331 In the parallel system, all updatable closures have corresponding
332 revertible black holes.  When we are assembly-mangling, we guarantee that
333 the revertible black hole code precedes the normal entry code, so that
334 the RBH info table resides at a fixed offset from the normal info table.
335 Otherwise, we add the RBH info table pointer to the end of the normal
336 info table and vice versa.
337
338 \begin{code}
339 #if defined(PAR) || defined(GRAN)
340 # define RBH_INFO_OFFSET            (GEN_INFO_OFFSET+GEN_INFO_WORDS)
341
342 # define INCLUDE_SPEC_PADDING                           \
343         INCLUDE_UPDATE_INFO(INFO_UNUSED,INFO_UNUSED)    \
344         INCLUDE_GEN_INFO(INFO_UNUSED,INFO_UNUSED)
345
346 # ifdef RBH_MAGIC_OFFSET
347
348 #  define RBH_INFO_WORDS    0
349 #  define INCLUDE_RBH_INFO(infoptr)
350
351 #  define RBH_INFOPTR(infoptr)      (((P_)infoptr) - RBH_MAGIC_OFFSET)
352 #  define REVERT_INFOPTR(infoptr)   (((P_)infoptr) + RBH_MAGIC_OFFSET)
353
354 # else
355
356 #  define RBH_INFO_WORDS    1
357 #  define INCLUDE_RBH_INFO(infoptr) ,(W_)infoptr
358
359 #  define RBH_INFOPTR(infoptr)      (((PP_)(infoptr))[IREL(RBH_INFO_OFFSET)])
360 #  define REVERT_INFOPTR(infoptr)   (((PP_)(infoptr))[IREL(RBH_INFO_OFFSET)])
361
362 # endif
363
364 EXTFUN(RBH_entry);
365 P_ convertToRBH PROTO((P_ closure));
366 #if defined(GRAN)
367 void convertFromRBH PROTO((P_ closure));
368 #elif defined(PAR)
369 void convertToFetchMe PROTO((P_ closure, globalAddr *ga));
370 #endif
371
372 #endif
373 \end{code}
374
375 %************************************************************************
376 %*                                                                      *
377 \subsection{Maybe-there-maybe-not fields in a rep table}
378 %*                                                                      *
379 %************************************************************************
380
381 %************************************************************************
382 %*                                                                      *
383 \subsubsection{Type field in a rep table}
384 %*                                                                      *
385 %************************************************************************
386
387 The @INFO_TYPE@ field in the rep table tells what sort of animal
388 the closure is.  
389
390 \begin{code}
391 #define TYPE_INFO_OFFSET  0
392 #define TYPE_INFO_WORDS    1
393 #define INCLUDE_TYPE_INFO(kind) (W_)CAT3(INFO_,kind,_TYPE)
394
395 #define INFO_TYPE(infoptr)      (((P_)(INFO_RTBL(infoptr)))[TYPE_INFO_OFFSET])
396 \end{code}
397
398 The least significant 9 bits of the info-type are used as follows:
399
400 \begin{tabular}{||l|l||}                                                   \hline
401 Bit & Interpretation                                                    \\ \hline
402 0   & 1 $\Rightarrow$ Head normal form                                  \\
403 1   & 1 $\Rightarrow$ Don't spark me  (Any HNF will have this set to 1) \\
404 2   & 1 $\Rightarrow$ This is a static closure                          \\
405 3   & 1 $\Rightarrow$ Has mutable pointer fields \\ 
406 4   & 1 $\Rightarrow$ May be updated (inconsistent with being a HNF) \\ 
407 5   & 1 $\Rightarrow$ Is a "primitive" array (a BIG structure) \\
408 6   & 1 $\Rightarrow$ Is a black hole                                   \\
409 7   & 1 $\Rightarrow$ Is an indirection                                 \\
410 8   & 1 $\Rightarrow$ Is a thunk                                        \\
411 \hline
412 \end{tabular}
413
414 Updatable structures (@_UP@) are thunks that may be shared.  Primitive
415 arrays (@_BM@ -- Big Mothers) are structures that are always held
416 in-memory (basically extensions of a closure).  Because there may be
417 offsets into these arrays, a primitive array cannot be handled as a
418 FetchMe in the parallel system, but must be shipped in its entirety if
419 its parent closure is shipped.
420
421 \begin{code}
422 #define IP_TAG_BITS             9
423
424 #define _NF                     0x0001  /* Normal form  */
425 #define _NS                     0x0002  /* Don't spark  */
426 #define _ST                     0x0004  /* Is static    */
427 #define _MU                     0x0008  /* Is mutable   */
428 #define _UP                     0x0010  /* Is updatable (but not mutable) */
429 #define _BM                     0x0020  /* Is a "primitive" array */
430 #define _BH                     0x0040  /* Is a black hole */
431 #define _IN                     0x0080  /* Is an indirection */
432 #define _TH                     0x0100  /* Is a thunk */
433
434 #define IS_NF(infoptr)          ((INFO_TYPE(infoptr)&_NF) != 0)
435 #define IS_MUTABLE(infoptr)     ((INFO_TYPE(infoptr)&_MU) != 0)
436 #define IS_STATIC(infoptr)      ((INFO_TYPE(infoptr)&_ST) != 0)
437 #define IS_UPDATABLE(infoptr)   ((INFO_TYPE(infoptr)&_UP) != 0)
438 #define IS_BIG_MOTHER(infoptr)  ((INFO_TYPE(infoptr)&_BM) != 0)
439 #define IS_BLACK_HOLE(infoptr)  ((INFO_TYPE(infoptr)&_BH) != 0)
440 #define IS_INDIRECTION(infoptr) ((INFO_TYPE(infoptr)&_IN) != 0)
441 #define IS_THUNK(infoptr)       ((INFO_TYPE(infoptr)&_TH) != 0)
442
443 #define SHOULD_SPARK(closure)   ((INFO_TYPE(INFO_PTR(closure))&_NS) == 0)
444 \end{code}
445
446 The other bits in the info-type field simply give a unique bit-pattern
447 to identify the closure type.
448
449 \begin{code}
450 #define IP_TAG_BIT_MASK         ((1L<<IP_TAG_BITS)-1)
451
452 #define BASE_INFO_TYPE(infoptr) (INFO_TYPE(infoptr) & (~IP_TAG_BIT_MASK)) /* Strips out the tag bits */
453
454 #define MAKE_BASE_INFO_TYPE(x)  ((x) << IP_TAG_BITS)
455
456 #define INFO_SPEC_TYPE          (MAKE_BASE_INFO_TYPE(1L))
457 #define INFO_GEN_TYPE           (MAKE_BASE_INFO_TYPE(2L))
458 #define INFO_DYN_TYPE           (MAKE_BASE_INFO_TYPE(3L) | _NF | _NS)
459 #define INFO_TUPLE_TYPE         (MAKE_BASE_INFO_TYPE(4L) | _NF | _NS | _BM)
460 #define INFO_DATA_TYPE          (MAKE_BASE_INFO_TYPE(5L) | _NF | _NS | _BM)
461 #define INFO_MUTUPLE_TYPE       (MAKE_BASE_INFO_TYPE(6L) | _NF | _NS | _MU | _BM)
462 #define INFO_IMMUTUPLE_TYPE     (MAKE_BASE_INFO_TYPE(7L) | _NF | _NS | _BM)
463 #define INFO_STATIC_TYPE        (MAKE_BASE_INFO_TYPE(8L) | _NS | _ST)
464 #define INFO_CONST_TYPE         (MAKE_BASE_INFO_TYPE(9L) | _NF | _NS)
465 #define INFO_CHARLIKE_TYPE      (MAKE_BASE_INFO_TYPE(10L) | _NF | _NS)
466 #define INFO_INTLIKE_TYPE       (MAKE_BASE_INFO_TYPE(11L) | _NF | _NS)
467 #define INFO_BH_TYPE            (MAKE_BASE_INFO_TYPE(12L) | _NS | _BH)
468 #define INFO_BQ_TYPE            (MAKE_BASE_INFO_TYPE(13L) | _NS | _MU | _BH)
469 #define INFO_IND_TYPE           (MAKE_BASE_INFO_TYPE(14L) | _NS | _IN)
470 #define INFO_CAF_TYPE           (MAKE_BASE_INFO_TYPE(15L) | _NF | _NS | _ST | _IN)
471 #define INFO_FM_TYPE            (MAKE_BASE_INFO_TYPE(16L))
472 #define INFO_TSO_TYPE           (MAKE_BASE_INFO_TYPE(17L) | _MU)
473 #define INFO_STKO_TYPE          (MAKE_BASE_INFO_TYPE(18L))
474 #define INFO_SPEC_RBH_TYPE      (MAKE_BASE_INFO_TYPE(19L) | _NS | _MU | _BH)
475 #define INFO_GEN_RBH_TYPE       (MAKE_BASE_INFO_TYPE(20L) | _NS | _MU | _BH)
476 #define INFO_BF_TYPE            (MAKE_BASE_INFO_TYPE(21L) | _NS | _MU | _BH)
477 #define INFO_INTERNAL_TYPE      (MAKE_BASE_INFO_TYPE(22L))
478
479 /* S = single-entry thunk
480    U = updatable thunk
481    N = head normal form */
482
483 #define INFO_SPEC_N_TYPE        (INFO_SPEC_TYPE | _NF | _NS)
484 #define INFO_SPEC_S_TYPE        (INFO_SPEC_TYPE | _TH)
485 #define INFO_SPEC_U_TYPE        (INFO_SPEC_TYPE | _UP | _TH)
486
487 #define INFO_GEN_N_TYPE         (INFO_GEN_TYPE | _NF | _NS)
488 #define INFO_GEN_S_TYPE         (INFO_GEN_TYPE | _TH)
489 #define INFO_GEN_U_TYPE         (INFO_GEN_TYPE | _UP | _TH)
490
491 #define INFO_BH_N_TYPE          (INFO_BH_TYPE)
492 #define INFO_BH_U_TYPE          (INFO_BH_TYPE | _UP)
493
494 #define INFO_STKO_DYNAMIC_TYPE  (INFO_STKO_TYPE | _MU)
495 #define INFO_STKO_STATIC_TYPE   (INFO_STKO_TYPE | _ST)
496
497 #define INFO_FETCHME_TYPE       (INFO_FM_TYPE | _MU)
498 #define INFO_FMBQ_TYPE          (INFO_FM_TYPE | _MU | _BH)
499
500 #define MIN_INFO_TYPE           0
501 #define MAX_INFO_TYPE           INFO_INTERNAL_TYPE
502
503 \end{code}
504
505 Notes:
506
507 An indirection either points to HNF (post update); or is result of
508 overwriting a FetchMe, in which case the thing fetched is either
509 under evaluation (BH), or by now an HNF.  Thus, indirections get @_NS@.
510
511 %************************************************************************
512 %*                                                                      *
513 \subsubsection{Size/no-of-pointers fields in a rep table}
514 %*                                                                      *
515 %************************************************************************
516
517 \begin{code}
518 #define SIZE_INFO_OFFSET  (TYPE_INFO_OFFSET+TYPE_INFO_WORDS)
519 #define SIZE_INFO_WORDS   2
520 #define INCLUDE_SIZE_INFO(size,ptrs) ,(W_)size, (W_)ptrs
521
522 #define INFO_SIZE(infoptr)   ((I_)((FP_)(INFO_RTBL(infoptr)))[SIZE_INFO_OFFSET])
523 #define INFO_NoPTRS(infoptr) ((I_)((FP_)(INFO_RTBL(infoptr)))[SIZE_INFO_OFFSET+1])
524 \end{code}
525
526 %************************************************************************
527 %*                                                                      *
528 \subsubsection{Parallel-only fields in a rep table}
529 %*                                                                      *
530 %************************************************************************
531
532 There is now nothing that is specific to the parallel world (GUM), but
533 this could change so don't go deleting this little lot!  KH
534
535 \begin{code}
536 # define PAR_INFO_OFFSET                (SIZE_INFO_OFFSET+SIZE_INFO_WORDS)
537
538 /* now the bits that are either on or off: */
539
540 # define PAR_INFO_WORDS         0
541 # define INCLUDE_PAR_INFO
542 \end{code}
543
544 %************************************************************************
545 %*                                                                      *
546 \subsubsection{Copying-only fields in a rep table}
547 %*                                                                      *
548 %************************************************************************
549
550 These macros result in the copying garbage collection code being
551 included only if required.
552 \begin{code}
553 #if defined(_INFO_COPYING)
554 # include "SMcopying.h" /* Copying Code Labels */
555 # define COPY_INFO_OFFSET  (PAR_INFO_OFFSET+PAR_INFO_WORDS)
556 # define COPY_INFO_WORDS 2
557 # define INCLUDE_COPYING_INFO(evac, scav) ,(W_)evac,(W_)scav
558
559 /* 
560  * use these if you have an unquenchable urge to dig around in
561  *  info tables (e.g., runtime/.../StgDebug.lc)
562  */
563
564 # define INFO_EVAC_2S(infoptr)  (((FP_)(INFO_RTBL(infoptr)))[COPY_INFO_OFFSET])
565 # define INFO_SCAV_2S(infoptr)  (((FP_)(INFO_RTBL(infoptr)))[COPY_INFO_OFFSET + 1])
566
567 #else  /* ! _INFO_COPYING */
568
569 # define COPY_INFO_WORDS 0
570 # define INCLUDE_COPYING_INFO(evac, scav)
571
572 #endif /* ! _INFO_COPYING */
573 \end{code}
574
575 %************************************************************************
576 %*                                                                      *
577 \subsubsection{Compacting-only fields in a rep table}
578 %*                                                                      *
579 %************************************************************************
580
581 These macros result in the compacting garbage collection code being
582 included only if required. This includes the variable length
583 specialised marking code.
584
585 \begin{code}
586 #if !defined(_INFO_COMPACTING)
587
588 # define INCLUDE_COMPACTING_INFO(scanlink,prmark,scanmove,marking)
589 # define SPEC_COMPACTING_INFO(scanlink,prmark,scanmove,marking)
590
591 #else /* defined(_INFO_COMPACTING) */
592
593 # include "SMcompact.h"         /* Single Space Compacting Code */
594 # include "SMmark.h"            /* Pointer Reversal Marking Code Labels */
595
596 /* For SPEC closures compacting info is variable length -> must come last */
597
598 # define COMPACTING_INFO_OFFSET  (COPY_INFO_OFFSET+COPY_INFO_WORDS)
599
600 # define INCLUDE_COMPACTING_INFO(scanlink,prmark,scanmove,marking) \
601         ,(W_)scanlink,(W_)prmark \
602         ,(W_)scanmove,(W_)marking
603
604 # define SPEC_COMPACTING_INFO(scanlink,prmark,scanmove,prreturn) \
605         ,(W_)scanlink,(W_)prmark \
606         ,(W_)scanmove, \
607          (W_)prreturn
608
609
610 # define INFO_SCAN_LINK_1S(infoptr)     (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET])
611 # define INFO_MARK_1S(infoptr)          (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+1])
612 # define INFO_SCAN_MOVE_1S(infoptr)     (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+2])
613 # define INFO_MARKED_1S(infoptr)        (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+3])
614 # define INFO_MARKING_1S(infoptr)       (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+4])
615
616 #ifndef COMPILING_NCG
617 extern F_ _Dummy_Static_entry(STG_NO_ARGS);
618 extern F_ _Dummy_Ind_entry(STG_NO_ARGS);
619 extern F_ _Dummy_Caf_entry(STG_NO_ARGS);
620 extern F_ _Dummy_Const_entry(STG_NO_ARGS);
621 extern F_ _Dummy_CharLike_entry(STG_NO_ARGS);
622 #endif
623
624 #endif /* _INFO_COMPACTING */
625 \end{code}
626
627 %************************************************************************
628 %*                                                                      *
629 \subsection[SPEC_ITBL]{@SPEC_x_ITBL@: @SPEC@ info-tables}
630 %*                                                                      *
631 %************************************************************************
632
633 Normal-form and updatable (non-normal-form) variants.
634
635 \begin{code}
636
637 #define SPEC_N_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
638     CAT_DECLARE(infolbl,kind,descr,type)        \
639     entry_localness(entry_code);                \
640     localness W_ infolbl[] = {                  \
641         (W_) entry_code                         \
642         ,(W_) tag                               \
643         ,(W_) MK_REP_REF(Spec_N,size,ptrs)      \
644         INCLUDE_PROFILING_INFO(infolbl)         \
645         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
646         }
647
648 MAYBE_DECLARE_RTBL(Spec_N,1,0)
649 MAYBE_DECLARE_RTBL(Spec_N,1,1)
650 MAYBE_DECLARE_RTBL(Spec_N,2,0)
651 MAYBE_DECLARE_RTBL(Spec_N,2,1)
652 MAYBE_DECLARE_RTBL(Spec_N,2,2)
653 MAYBE_DECLARE_RTBL(Spec_N,3,0)
654 MAYBE_DECLARE_RTBL(Spec_N,3,1)
655 MAYBE_DECLARE_RTBL(Spec_N,3,2)
656 MAYBE_DECLARE_RTBL(Spec_N,3,3)
657 MAYBE_DECLARE_RTBL(Spec_N,4,0)
658 MAYBE_DECLARE_RTBL(Spec_N,4,4)
659 MAYBE_DECLARE_RTBL(Spec_N,5,0)
660 MAYBE_DECLARE_RTBL(Spec_N,5,5)
661 MAYBE_DECLARE_RTBL(Spec_N,6,6)
662 MAYBE_DECLARE_RTBL(Spec_N,7,7)
663 MAYBE_DECLARE_RTBL(Spec_N,8,8)
664 MAYBE_DECLARE_RTBL(Spec_N,9,9)
665 MAYBE_DECLARE_RTBL(Spec_N,10,10)
666 MAYBE_DECLARE_RTBL(Spec_N,11,11)
667 MAYBE_DECLARE_RTBL(Spec_N,12,12)
668
669 #define SPEC_N_RTBL(size,ptrs)                                                  \
670     const W_ MK_REP_LBL(Spec_N,size,ptrs)[] = {                                 \
671         INCLUDE_TYPE_INFO(SPEC_N)                                               \
672         INCLUDE_SIZE_INFO(size,ptrs)                                            \
673         INCLUDE_PAR_INFO                                                        \
674         INCLUDE_COPYING_INFO(CAT2(_Evacuate_,size),CAT4(_Scavenge_,size,_,ptrs)) \
675         SPEC_COMPACTING_INFO(CAT4(_ScanLink_,size,_,ptrs),                      \
676                              CAT2(_PRStart_,ptrs),                              \
677                              CAT2(_ScanMove_,size),CAT2(_PRIn_,ptrs))           \
678         }
679
680 #define SPEC_S_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
681     CAT_DECLARE(infolbl,kind,descr,type)        \
682     entry_localness(entry_code);                \
683     localness W_ infolbl[] = {                  \
684         (W_) entry_code                         \
685         ,(W_) tag                               \
686         ,(W_) MK_REP_REF(Spec_S,size,ptrs)      \
687         INCLUDE_PROFILING_INFO(infolbl)         \
688         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
689         }
690
691 MAYBE_DECLARE_RTBL(Spec_S,1,0)
692 MAYBE_DECLARE_RTBL(Spec_S,1,1)
693 MAYBE_DECLARE_RTBL(Spec_S,2,0)
694 MAYBE_DECLARE_RTBL(Spec_S,2,1)
695 MAYBE_DECLARE_RTBL(Spec_S,2,2)
696 MAYBE_DECLARE_RTBL(Spec_S,3,0)
697 MAYBE_DECLARE_RTBL(Spec_S,3,1)
698 MAYBE_DECLARE_RTBL(Spec_S,3,2)
699 MAYBE_DECLARE_RTBL(Spec_S,3,3)
700 MAYBE_DECLARE_RTBL(Spec_S,4,0)
701 MAYBE_DECLARE_RTBL(Spec_S,4,4)
702 MAYBE_DECLARE_RTBL(Spec_S,5,0)
703 MAYBE_DECLARE_RTBL(Spec_S,5,5)
704 MAYBE_DECLARE_RTBL(Spec_S,6,6)
705 MAYBE_DECLARE_RTBL(Spec_S,7,7)
706 MAYBE_DECLARE_RTBL(Spec_S,8,8)
707 MAYBE_DECLARE_RTBL(Spec_S,9,9)
708 MAYBE_DECLARE_RTBL(Spec_S,10,10)
709 MAYBE_DECLARE_RTBL(Spec_S,11,11)
710 MAYBE_DECLARE_RTBL(Spec_S,12,12)
711
712 #define SPEC_S_RTBL(size,ptrs)                                                  \
713     const W_ MK_REP_LBL(Spec_S,size,ptrs)[] = {                                 \
714         INCLUDE_TYPE_INFO(SPEC_S)                                               \
715         INCLUDE_SIZE_INFO(size,ptrs)                                            \
716         INCLUDE_PAR_INFO                                                        \
717         INCLUDE_COPYING_INFO(CAT2(_Evacuate_,size),CAT4(_Scavenge_,size,_,ptrs)) \
718         SPEC_COMPACTING_INFO(CAT4(_ScanLink_,size,_,ptrs),                      \
719                              CAT2(_PRStart_,ptrs),                              \
720                              CAT2(_ScanMove_,size),CAT2(_PRIn_,ptrs))           \
721         }
722
723 #if defined(PAR) || defined(GRAN)
724 # define SPEC_U_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
725     entry_localness(CAT2(RBH_,entry_code));     \
726     localness W_ infolbl[];                     \
727      localness W_ CAT2(RBH_,infolbl)[] = {      \
728         (W_) CAT2(RBH_,entry_code)              \
729         ,(W_) INFO_OTHER_TAG                    \
730         ,(W_) MK_REP_REF(Spec_RBH,size,ptrs)    \
731         INCLUDE_PROFILING_INFO(RBH)             \
732         INCLUDE_SPEC_PADDING                    \
733         INCLUDE_RBH_INFO(infolbl)               \
734         };                                      \
735     STGFUN(CAT2(RBH_,entry_code)) { JMP_(RBH_entry); }\
736     CAT_DECLARE(infolbl,kind,descr,type)        \
737     entry_localness(entry_code);                \
738     localness W_ infolbl[] = {                  \
739         (W_) entry_code                         \
740         ,(W_) tag                               \
741         ,(W_) MK_REP_REF(Spec_U,size,ptrs)      \
742         INCLUDE_PROFILING_INFO(infolbl)         \
743         INCLUDE_SPEC_PADDING                    \
744         INCLUDE_RBH_INFO(CAT2(RBH_,infolbl))    \
745         }
746
747 MAYBE_DECLARE_RTBL(Spec_RBH,1,0)
748 MAYBE_DECLARE_RTBL(Spec_RBH,1,1)
749 MAYBE_DECLARE_RTBL(Spec_RBH,2,0)
750 MAYBE_DECLARE_RTBL(Spec_RBH,2,1)
751 MAYBE_DECLARE_RTBL(Spec_RBH,2,2)
752 MAYBE_DECLARE_RTBL(Spec_RBH,3,0)
753 MAYBE_DECLARE_RTBL(Spec_RBH,3,1)
754 MAYBE_DECLARE_RTBL(Spec_RBH,3,2)
755 MAYBE_DECLARE_RTBL(Spec_RBH,3,3)
756 MAYBE_DECLARE_RTBL(Spec_RBH,4,0)
757 MAYBE_DECLARE_RTBL(Spec_RBH,4,4)
758 MAYBE_DECLARE_RTBL(Spec_RBH,5,0)
759 MAYBE_DECLARE_RTBL(Spec_RBH,5,5)
760 MAYBE_DECLARE_RTBL(Spec_RBH,6,6)
761 MAYBE_DECLARE_RTBL(Spec_RBH,7,7)
762 MAYBE_DECLARE_RTBL(Spec_RBH,8,8)
763 MAYBE_DECLARE_RTBL(Spec_RBH,9,9)
764 MAYBE_DECLARE_RTBL(Spec_RBH,10,10)
765 MAYBE_DECLARE_RTBL(Spec_RBH,11,11)
766 MAYBE_DECLARE_RTBL(Spec_RBH,12,12)
767
768 #define SPEC_RBH_RTBL(size,ptrs)                                                \
769     const W_ MK_REP_LBL(Spec_RBH,size,ptrs)[] = {                               \
770         INCLUDE_TYPE_INFO(SPEC_RBH)                                             \
771         INCLUDE_SIZE_INFO(size,ptrs)                                            \
772         INCLUDE_PAR_INFO                                                        \
773         INCLUDE_COPYING_INFO(CAT2(_Evacuate_RBH_,size),CAT4(_Scavenge_RBH_,size,_,ptrs)) \
774         SPEC_COMPACTING_INFO(CAT4(_ScanLink_RBH_,size,_,ptrs),                  \
775                              CAT2(_PRStart_RBH_,ptrs),                          \
776                              CAT2(_ScanMove_RBH_,size),CAT2(_PRIn_RBH_,ptrs))   \
777         }
778
779 #define _Scavenge_RBH_2_0   _Scavenge_RBH_2_1
780 #define _Scavenge_RBH_2_2   _Scavenge_RBH_2_1
781
782 #define _Scavenge_RBH_3_0   _Scavenge_RBH_3_1
783 #define _Scavenge_RBH_3_2   _Scavenge_RBH_3_1
784
785 #define _Scavenge_RBH_4_0   _Scavenge_RBH_4_1
786 #define _Scavenge_RBH_5_0   _Scavenge_RBH_5_1
787 #define _Scavenge_RBH_6_0   _Scavenge_RBH_6_1
788 #define _Scavenge_RBH_7_0   _Scavenge_RBH_7_1
789 #define _Scavenge_RBH_8_0   _Scavenge_RBH_8_1
790 #define _Scavenge_RBH_9_0   _Scavenge_RBH_9_1
791 #define _Scavenge_RBH_10_0   _Scavenge_RBH_10_1
792 #define _Scavenge_RBH_11_0   _Scavenge_RBH_11_1
793 #define _Scavenge_RBH_12_0   _Scavenge_RBH_12_1
794
795 #define _ScanLink_RBH_2_0   _ScanLink_RBH_2_1
796 #define _ScanLink_RBH_2_2   _ScanLink_RBH_2_1
797
798 #define _ScanLink_RBH_3_0   _ScanLink_RBH_3_1
799 #define _ScanLink_RBH_3_2   _ScanLink_RBH_3_1
800
801 #define _ScanLink_RBH_4_0   _ScanLink_RBH_4_1
802 #define _ScanLink_RBH_5_0   _ScanLink_RBH_5_1
803 #define _ScanLink_RBH_6_0   _ScanLink_RBH_6_1
804 #define _ScanLink_RBH_7_0   _ScanLink_RBH_7_1
805 #define _ScanLink_RBH_8_0   _ScanLink_RBH_8_1
806 #define _ScanLink_RBH_9_0   _ScanLink_RBH_9_1
807 #define _ScanLink_RBH_10_0   _ScanLink_RBH_10_1
808 #define _ScanLink_RBH_11_0   _ScanLink_RBH_11_1
809 #define _ScanLink_RBH_12_0   _ScanLink_RBH_12_1
810
811 #define _PRStart_RBH_0  _PRStart_RBH_2
812 #define _PRStart_RBH_1  _PRStart_RBH_2
813
814 #define _PRIn_RBH_0     _PRIn_RBH_2
815 #define _PRIn_RBH_1     _PRIn_RBH_2
816
817 #else
818
819 # define SPEC_U_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
820     CAT_DECLARE(infolbl,kind,descr,type)        \
821     entry_localness(entry_code);                \
822     localness W_ infolbl[] = {                  \
823         (W_) entry_code                         \
824         ,(W_) tag                               \
825         ,(W_) MK_REP_REF(Spec_U,size,ptrs)      \
826         INCLUDE_PROFILING_INFO(infolbl)         \
827         }
828 #endif
829
830 MAYBE_DECLARE_RTBL(Spec_U,1,0)
831 MAYBE_DECLARE_RTBL(Spec_U,1,1)
832 MAYBE_DECLARE_RTBL(Spec_U,2,0)
833 MAYBE_DECLARE_RTBL(Spec_U,2,1)
834 MAYBE_DECLARE_RTBL(Spec_U,2,2)
835 MAYBE_DECLARE_RTBL(Spec_U,3,0)
836 MAYBE_DECLARE_RTBL(Spec_U,3,1)
837 MAYBE_DECLARE_RTBL(Spec_U,3,2)
838 MAYBE_DECLARE_RTBL(Spec_U,3,3)
839 MAYBE_DECLARE_RTBL(Spec_U,4,0)
840 MAYBE_DECLARE_RTBL(Spec_U,4,4)
841 MAYBE_DECLARE_RTBL(Spec_U,5,0)
842 MAYBE_DECLARE_RTBL(Spec_U,5,5)
843 MAYBE_DECLARE_RTBL(Spec_U,6,6)
844 MAYBE_DECLARE_RTBL(Spec_U,7,7)
845 MAYBE_DECLARE_RTBL(Spec_U,8,8)
846 MAYBE_DECLARE_RTBL(Spec_U,9,9)
847 MAYBE_DECLARE_RTBL(Spec_U,10,10)
848 MAYBE_DECLARE_RTBL(Spec_U,11,11)
849 MAYBE_DECLARE_RTBL(Spec_U,12,12)
850
851 #define SPEC_U_RTBL(size,ptrs)                                                  \
852     const W_ MK_REP_LBL(Spec_U,size,ptrs)[] = {                                 \
853         INCLUDE_TYPE_INFO(SPEC_U)                                               \
854         INCLUDE_SIZE_INFO(size,ptrs)                                            \
855         INCLUDE_PAR_INFO                                                        \
856         INCLUDE_COPYING_INFO(CAT2(_Evacuate_,size),CAT4(_Scavenge_,size,_,ptrs)) \
857         SPEC_COMPACTING_INFO(CAT4(_ScanLink_,size,_,ptrs),                      \
858                              CAT2(_PRStart_,ptrs),                              \
859                              CAT2(_ScanMove_,size),CAT2(_PRIn_,ptrs))           \
860         }
861
862 \end{code}
863
864 %************************************************************************
865 %*                                                                      *
866 \subsection[SELECT_ITBL]{@SELECT_ITBL@: Special @SPEC_U@ info-table for selectors}
867 %*                                                                      *
868 %************************************************************************
869
870 These are different only in having slightly-magic GC code.  The idea
871 is: it is a @MIN_UPD_SIZE@ (==2) thunk with one pointer, which, when
872 entered, will select word $i$ from its pointee.
873
874 When garbage-collecting such a closure, we ``peek'' at the pointee's
875 tag (in its info table).  If it is evaluated, then we go ahead and do
876 the selection---which is {\em just like an indirection}.  If it is not
877 evaluated, we carry on {\em exactly as if it is a size-2/1-ptr thunk}.
878
879 Copying: only the evacuate routine needs to be special.
880
881 Compacting: only the PRStart (marking) routine needs to be special.
882
883 \begin{code}
884
885 #if defined(PAR) || defined(GRAN)
886 # define SELECT_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,select_word_i,kind,descr,type) \
887     entry_localness(CAT2(RBH_,entry_code));     \
888     localness W_ infolbl[];                     \
889     localness W_ CAT2(RBH_,infolbl)[] = {       \
890         (W_) CAT2(RBH_,entry_code)              \
891         ,(W_) INFO_OTHER_TAG                    \
892         ,(W_) MK_REP_REF(Spec_RBH,size,ptrs)    \
893         INCLUDE_PROFILING_INFO(RBH)             \
894         INCLUDE_SPEC_PADDING                    \
895         INCLUDE_RBH_INFO(infolbl)               \
896         };                                      \
897     STGFUN(CAT2(RBH_,entry_code)) { JMP_(RBH_entry); }\
898     CAT_DECLARE(infolbl,kind,descr,type)        \
899     entry_localness(entry_code);                \
900     localness W_ infolbl[] = {                  \
901         (W_) entry_code                         \
902         ,(W_) tag                               \
903         ,(W_) MK_REP_REF(Select,,select_word_i) \
904         INCLUDE_PROFILING_INFO(infolbl)         \
905         INCLUDE_SPEC_PADDING                    \
906         INCLUDE_RBH_INFO(CAT2(RBH_,infolbl))    \
907         }                                       \
908
909 #else
910
911 # define SELECT_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,select_word_i,kind,descr,type) \
912     CAT_DECLARE(infolbl,kind,descr,type)        \
913     entry_localness(entry_code);                \
914     localness W_ infolbl[] = {                  \
915         (W_) entry_code                         \
916         ,(W_) tag                               \
917         ,(W_) MK_REP_REF(Select,,select_word_i) \
918         INCLUDE_PROFILING_INFO(infolbl)         \
919         }
920
921 #endif
922
923 MAYBE_DECLARE_RTBL(Select,,0)
924 MAYBE_DECLARE_RTBL(Select,,1)
925 MAYBE_DECLARE_RTBL(Select,,2)
926 MAYBE_DECLARE_RTBL(Select,,3)
927 MAYBE_DECLARE_RTBL(Select,,4)
928 MAYBE_DECLARE_RTBL(Select,,5)
929 MAYBE_DECLARE_RTBL(Select,,6)
930 MAYBE_DECLARE_RTBL(Select,,7)
931 MAYBE_DECLARE_RTBL(Select,,8)
932 MAYBE_DECLARE_RTBL(Select,,9)
933 MAYBE_DECLARE_RTBL(Select,,10)
934 MAYBE_DECLARE_RTBL(Select,,11)
935 MAYBE_DECLARE_RTBL(Select,,12)
936
937 #define SELECT_RTBL(size,ptrs,select_word_i)                                    \
938     const W_ MK_REP_LBL(Select,,select_word_i)[] = {                            \
939         INCLUDE_TYPE_INFO(SPEC_U)                                               \
940         INCLUDE_SIZE_INFO(size,ptrs)                                            \
941         INCLUDE_PAR_INFO                                                        \
942         INCLUDE_COPYING_INFO(CAT2(_EvacuateSelector_,select_word_i),            \
943                              CAT4(_Scavenge_,size,_,ptrs))                      \
944         SPEC_COMPACTING_INFO(CAT4(_ScanLink_,size,_,ptrs),                      \
945                              CAT2(_PRStartSelector_,select_word_i),             \
946                              CAT2(_ScanMove_,size),                             \
947                              CAT2(_PRIn_,ptrs))                                 \
948         }
949
950 \end{code}
951
952 %************************************************************************
953 %*                                                                      *
954 \subsection[GEN_ITBL]{@GEN_x_ITBL@: Generic/general? info-tables}
955 %*                                                                      *
956 %************************************************************************
957
958 @GEN@ info-table for non-updatable nodes (normal and non-normal forms).
959
960 Size/no-of-ptrs are known at compile time, but we don't have GC
961 routines wired in for those specific sizes.  Hence the size/no-of-ptrs
962 is stored in the info-table.
963
964 \begin{code}
965
966 #define GEN_N_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
967     CAT_DECLARE(infolbl,kind,descr,type)        \
968     entry_localness(entry_code);                \
969     localness W_ infolbl[] = {                  \
970         (W_) entry_code                         \
971         ,(W_) tag                               \
972         ,(W_) MK_REP_REF(Gen_N,,)               \
973         INCLUDE_PROFILING_INFO(infolbl)         \
974         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
975         INCLUDE_GEN_INFO(size,ptrs)             \
976         }
977
978 MAYBE_DECLARE_RTBL(Gen_N,,)
979
980 #define GEN_N_RTBL()                                                            \
981     const W_ MK_REP_LBL(Gen_N,,)[] = {                                          \
982         INCLUDE_TYPE_INFO(GEN_N)                                                \
983         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: in info table */      \
984         INCLUDE_PAR_INFO                                                        \
985         INCLUDE_COPYING_INFO(_Evacuate_S,_Scavenge_S_N)                         \
986         INCLUDE_COMPACTING_INFO(_ScanLink_S_N,_PRStart_N,_ScanMove_S,_PRIn_I)   \
987         }
988
989 #define GEN_S_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
990     CAT_DECLARE(infolbl,kind,descr,type)        \
991     entry_localness(entry_code);                \
992     localness W_ infolbl[] = {                  \
993         (W_) entry_code                         \
994         ,(W_) tag                               \
995         ,(W_) MK_REP_REF(Gen_S,,)               \
996         INCLUDE_PROFILING_INFO(infolbl)         \
997         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
998         INCLUDE_GEN_INFO(size,ptrs)             \
999         }
1000
1001 MAYBE_DECLARE_RTBL(Gen_S,,)
1002
1003 #define GEN_S_RTBL()                                                            \
1004     const W_ MK_REP_LBL(Gen_S,,)[] = {                                          \
1005         INCLUDE_TYPE_INFO(GEN_S)                                                \
1006         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: in info table */      \
1007         INCLUDE_PAR_INFO                                                        \
1008         INCLUDE_COPYING_INFO(_Evacuate_S,_Scavenge_S_N)                         \
1009         INCLUDE_COMPACTING_INFO(_ScanLink_S_N,_PRStart_N,_ScanMove_S,_PRIn_I)   \
1010         }
1011
1012 #if defined(PAR) || defined(GRAN)
1013 # define GEN_U_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
1014     entry_localness(CAT2(RBH_,entry_code));     \
1015     localness W_ infolbl[];                     \
1016     localness W_ CAT2(RBH_,infolbl)[] = {       \
1017         (W_) CAT2(RBH_,entry_code)              \
1018         ,(W_) INFO_OTHER_TAG                    \
1019         ,(W_) MK_REP_REF(Gen_RBH,,)             \
1020         INCLUDE_PROFILING_INFO(RBH)             \
1021         INCLUDE_UPDATE_INFO(INFO_UNUSED,INFO_UNUSED)    \
1022         INCLUDE_GEN_INFO(size,ptrs)             \
1023         INCLUDE_RBH_INFO(infolbl)               \
1024         };                                      \
1025     STGFUN(CAT2(RBH_,entry_code)) { JMP_(RBH_entry); }\
1026     CAT_DECLARE(infolbl,kind,descr,type)        \
1027     entry_localness(entry_code);                \
1028     localness W_ infolbl[] = {                  \
1029         (W_) entry_code                         \
1030         ,(W_) tag                               \
1031         ,(W_) MK_REP_REF(Gen_U,,)               \
1032         INCLUDE_PROFILING_INFO(infolbl)         \
1033         INCLUDE_UPDATE_INFO(INFO_UNUSED,INFO_UNUSED)    \
1034         INCLUDE_GEN_INFO(size,ptrs)             \
1035         INCLUDE_RBH_INFO(CAT2(RBH_,infolbl))    \
1036         }
1037
1038 MAYBE_DECLARE_RTBL(Gen_RBH,,)
1039
1040 # define GEN_RBH_RTBL()                                                         \
1041     const W_ MK_REP_LBL(Gen_RBH,,)[] = {                                        \
1042         INCLUDE_TYPE_INFO(GEN_RBH)                                              \
1043         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: no size/no-ptrs! */   \
1044         INCLUDE_PAR_INFO                                                        \
1045         INCLUDE_COPYING_INFO(_Evacuate_RBH_S,_Scavenge_RBH_N)                   \
1046         INCLUDE_COMPACTING_INFO(_ScanLink_RBH_N,_PRStart_RBH_N,_ScanMove_RBH_S,_PRIn_RBH_I)     \
1047         }
1048
1049 #else
1050
1051 # define GEN_U_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
1052     CAT_DECLARE(infolbl,kind,descr,type)        \
1053     entry_localness(entry_code);                \
1054     localness W_ infolbl[] = {                  \
1055         (W_) entry_code                         \
1056         ,(W_) tag                               \
1057         ,(W_) MK_REP_REF(Gen_U,,)               \
1058         INCLUDE_PROFILING_INFO(infolbl)         \
1059         INCLUDE_UPDATE_INFO(INFO_UNUSED,INFO_UNUSED)    \
1060         INCLUDE_GEN_INFO(size,ptrs)             \
1061         }
1062 #endif
1063
1064 MAYBE_DECLARE_RTBL(Gen_U,,)
1065
1066 #define GEN_U_RTBL()                                                            \
1067     const W_ MK_REP_LBL(Gen_U,,)[] = {                                          \
1068         INCLUDE_TYPE_INFO(GEN_U)                                                \
1069         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: no size/no-ptrs! */   \
1070         INCLUDE_PAR_INFO                                                        \
1071         INCLUDE_COPYING_INFO(_Evacuate_S,_Scavenge_S_N)                         \
1072         INCLUDE_COMPACTING_INFO(_ScanLink_S_N,_PRStart_N,_ScanMove_S,_PRIn_I)   \
1073         }
1074
1075 \end{code}
1076
1077 %************************************************************************
1078 %*                                                                      *
1079 \subsection[DYN_ITBL]{Dynamic-object info tables}
1080 %*                                                                      *
1081 %************************************************************************
1082
1083 For these, the size/no-of-pointers is not known until runtime.  E.g.,
1084 arrays.  Those fields are, therefore, in the closure itself, and not
1085 in the info table.
1086
1087 All @DYN@ closures are @PAP@s, so they are not updatable.
1088
1089 \begin{code}
1090
1091 #define DYN_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
1092     CAT_DECLARE(infolbl,kind,descr,type)        \
1093     entry_localness(entry_code);                \
1094     localness W_ infolbl[] = {                  \
1095         (W_) entry_code                         \
1096         ,(W_) tag                               \
1097         ,(W_) MK_REP_LBL(Dyn,,)                 \
1098         INCLUDE_PROFILING_INFO(infolbl)         \
1099         }
1100
1101 MAYBE_DECLARE_RTBL(Dyn,,)
1102
1103 #define DYN_RTBL()                                                      \
1104     const W_ MK_REP_LBL(Dyn,,)[] = {                                    \
1105         INCLUDE_TYPE_INFO(DYN)                                          \
1106         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* in closure! */    \
1107         INCLUDE_PAR_INFO                                                \
1108         INCLUDE_COPYING_INFO(_Evacuate_Dyn,_Scavenge_Dyn)               \
1109         INCLUDE_COMPACTING_INFO(_ScanLink_Dyn,_PRStart_Dyn,_ScanMove_Dyn,_PRIn_I_Dyn) \
1110         }
1111
1112 \end{code}
1113
1114 %************************************************************************
1115 %*                                                                      *
1116 \subsection[TUPLE_ITBL]{``Tuple'' and ``Data'' info-tables}
1117 %*                                                                      *
1118 %************************************************************************
1119
1120 ``Tuples'' are essentially DYNs with all pointers (no non-pointers).
1121 ``Data things'' are DYNs with all non-pointers.
1122
1123 \begin{code}
1124
1125 #define TUPLE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
1126     CAT_DECLARE(infolbl,kind,descr,type)        \
1127     entry_localness(entry_code);                \
1128     localness W_ infolbl[] = {                  \
1129         (W_) entry_code                         \
1130         ,(W_) tag                               \
1131         ,(W_) MK_REP_REF(Tuple,,)               \
1132         INCLUDE_PROFILING_INFO(infolbl)         \
1133         }
1134
1135 MAYBE_DECLARE_RTBL(Tuple,,)
1136
1137 #define TUPLE_RTBL() \
1138     const W_ MK_REP_LBL(Tuple,,)[] = { \
1139         INCLUDE_TYPE_INFO(TUPLE)                                        \
1140         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: in closure */ \
1141         INCLUDE_PAR_INFO                                                \
1142         INCLUDE_COPYING_INFO(_Evacuate_Tuple,_Scavenge_Tuple) \
1143         INCLUDE_COMPACTING_INFO(_ScanLink_Tuple,_PRStart_Tuple,_ScanMove_Tuple,_PRIn_I_Tuple) \
1144         }
1145
1146 #define DATA_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
1147     CAT_DECLARE(infolbl,kind,descr,type)        \
1148     entry_localness(entry_code);                \
1149     localness W_ infolbl[] = {                  \
1150         (W_) entry_code                         \
1151         ,(W_) tag                               \
1152         ,(W_) MK_REP_REF(Data,,)                \
1153         INCLUDE_PROFILING_INFO(infolbl)         \
1154         }
1155
1156 MAYBE_DECLARE_RTBL(Data,,)
1157
1158 #define DATA_RTBL()                     \
1159     const W_ MK_REP_LBL(Data,,)[] = {   \
1160         INCLUDE_TYPE_INFO(DATA)         \
1161         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: in closure */ \
1162         INCLUDE_PAR_INFO                 \
1163         INCLUDE_COPYING_INFO(_Evacuate_Data,_Scavenge_Data) \
1164         INCLUDE_COMPACTING_INFO(_ScanLink_Data,_PRStart_Data,_ScanMove_Data,_PRIn_Error) \
1165     }
1166
1167 /* Here is the decl for the only DATA info table used! */
1168 #ifndef COMPILING_NCG
1169 EXTDATA_RO(ArrayOfData_info);
1170 #endif
1171 \end{code}
1172
1173 %************************************************************************
1174 %*                                                                      *
1175 \subsection[MUTUPLE_ITBL]{Info-table for (im)mutable [array-ish] objects}
1176 %*                                                                      *
1177 %************************************************************************
1178
1179 ToDo: Integrate with PAR stuff (Kevin) !!
1180 If someone bothers to document this I'll see what I can do! KH
1181
1182 \begin{code}
1183
1184 #if defined(GC_MUT_REQUIRED)
1185
1186 # define MUTUPLE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
1187     CAT_DECLARE(infolbl,kind,descr,type)        \
1188     entry_localness(entry_code);                \
1189     localness W_ infolbl[] = {                  \
1190         (W_) entry_code                         \
1191         ,(W_) tag                               \
1192         ,(W_) MK_REP_REF(MuTuple,,)             \
1193         INCLUDE_PROFILING_INFO(infolbl)         \
1194         }
1195
1196 MAYBE_DECLARE_RTBL(MuTuple,,)
1197
1198 # define MUTUPLE_RTBL()                         \
1199     const W_ MK_REP_LBL(MuTuple,,)[] = {        \
1200         INCLUDE_TYPE_INFO(MUTUPLE)              \
1201         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: in closure! */ \
1202         INCLUDE_PAR_INFO                         \
1203         INCLUDE_COPYING_INFO(_Evacuate_MuTuple,_Scavenge_MuTuple) \
1204         INCLUDE_COMPACTING_INFO(_ScanLink_MuTuple,_PRStart_MuTuple,_ScanMove_MuTuple,_PRIn_I_MuTuple) \
1205         }
1206
1207 # define IMMUTUPLE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
1208     CAT_DECLARE(infolbl,kind,descr,type)        \
1209     entry_localness(entry_code);                \
1210     localness W_ infolbl[] = {                  \
1211         (W_) entry_code                         \
1212         ,(W_) tag                               \
1213         ,(W_) MK_REP_REF(ImmuTuple,,)           \
1214         INCLUDE_PROFILING_INFO(infolbl)         \
1215         }
1216
1217 MAYBE_DECLARE_RTBL(ImmuTuple,,)
1218
1219 # define IMMUTUPLE_RTBL() \
1220     const W_ MK_REP_LBL(ImmuTuple,,)[] = {  \
1221         INCLUDE_TYPE_INFO(IMMUTUPLE)        \
1222         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: in closure! */ \
1223         INCLUDE_PAR_INFO                         \
1224         INCLUDE_COPYING_INFO(_Evacuate_MuTuple,_Scavenge_MuTuple) \
1225         INCLUDE_COMPACTING_INFO(_ScanLink_MuTuple,_PRStart_MuTuple,_ScanMove_ImmuTuple,_PRIn_I_MuTuple) \
1226     }
1227   
1228 #else   /* ! GC_MUT_REQUIRED --- define as TUPLE closure */
1229
1230 # define MUTUPLE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
1231         TUPLE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type)
1232 # define IMMUTUPLE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
1233         TUPLE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type)
1234
1235 # define MUTUPLE_RTBL()
1236 # define IMMUTUPLE_RTBL()
1237 #endif
1238
1239 /* Here are the decls for the only MUTUPLE info tables used. */
1240 #ifndef COMPILING_NCG
1241 EXTDATA_RO(ArrayOfPtrs_info);
1242 EXTDATA_RO(ImMutArrayOfPtrs_info);
1243 EXTDATA_RO(EmptySVar_info);
1244 EXTDATA_RO(FullSVar_info);
1245 #endif
1246 \end{code}
1247
1248 %************************************************************************
1249 %*                                                                      *
1250 \subsection[STATIC_ITBL]{Info tables for static objects (outside the heap)}
1251 %*                                                                      *
1252 %************************************************************************
1253
1254 Size and ptrs fields are used by interpretive code, such as @ghci@,
1255 the parallel Pack code (@Pack.lc@) and possibly to-be-written debug
1256 code.
1257
1258 \begin{code}
1259 #define STATIC_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
1260     CAT_DECLARE(infolbl,kind,descr,type)        \
1261     entry_localness(entry_code);                \
1262     localness W_ infolbl[] = {                  \
1263         (W_) entry_code                         \
1264         ,(W_) tag                               \
1265         ,(W_) MK_REP_REF(Static,,)              \
1266         INCLUDE_PROFILING_INFO(infolbl)         \
1267         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
1268         INCLUDE_STATIC_INFO(size,ptrs)          \
1269         }
1270
1271 MAYBE_DECLARE_RTBL(Static,,)
1272
1273 #define STATIC_RTBL() \
1274     const W_ MK_REP_LBL(Static,,)[] = { \
1275         INCLUDE_TYPE_INFO(STATIC)       \
1276         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) /* NB: in info table! */ \
1277         INCLUDE_PAR_INFO                 \
1278         INCLUDE_COPYING_INFO(_Evacuate_Static,_Dummy_Static_entry) \
1279         INCLUDE_COMPACTING_INFO(_Dummy_Static_entry,_PRStart_Static, \
1280                                 _Dummy_Static_entry,_Dummy_Static_entry) \
1281         }
1282 \end{code}
1283
1284 %************************************************************************
1285 %*                                                                      *
1286 \subsection[ForeignObj_ITBL]{@ForeignObj_TBL@: @ForeignObj@ info-table}
1287 %*                                                                      *
1288 %************************************************************************
1289
1290 The following table is a bit like that for @SPEC@ with 0 pointers and
1291 a small number of non-ptrs.  However, the garbage collection routines
1292 are a bit special.
1293
1294 I'm assuming @SPEC_N@, so that we don't need to pad out the info table. (JSM)
1295
1296 \begin{code}
1297 #if !defined(PAR)
1298
1299 # define ForeignObj_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
1300     CAT_DECLARE(infolbl,kind,descr,type)        \
1301     entry_localness(entry_code);                \
1302     localness W_ infolbl[] = {                  \
1303         (W_) entry_code                         \
1304         ,(W_) tag                               \
1305         ,(W_) MK_REP_REF(ForeignObj,,)          \
1306         INCLUDE_PROFILING_INFO(infolbl)         \
1307     }
1308
1309 MAYBE_DECLARE_RTBL(ForeignObj,,)
1310
1311 # define ForeignObj_RTBL() \
1312     const W_ MK_REP_LBL(ForeignObj,,)[] = { \
1313         INCLUDE_TYPE_INFO(INTERNAL)                             \
1314         INCLUDE_SIZE_INFO(ForeignObj_SIZE, 0L)                  \
1315         INCLUDE_PAR_INFO                                        \
1316         INCLUDE_COPYING_INFO(_Evacuate_ForeignObj,_Scavenge_ForeignObj)         \
1317         SPEC_COMPACTING_INFO(_ScanLink_ForeignObj,_PRStart_ForeignObj,_ScanMove_ForeignObj,_PRIn_0) \
1318         }
1319
1320 #endif /* !PAR */
1321 \end{code}
1322
1323 %************************************************************************
1324 %*                                                                      *
1325 \subsection[BH_ITBL]{Info tables for ``black holes''}
1326 %*                                                                      *
1327 %************************************************************************
1328
1329 Special info-table for black holes. It is possible to describe these
1330 using @SPEC@ closures but this requires explicit use of the value of
1331 @MIN_UPD_SIZE@. For now we have a special macro and code.
1332
1333 \begin{code}
1334
1335 #define BH_ITBL(infolbl,bh_code,kind,localness,entry_localness) \
1336     entry_localness(bh_code);                   \
1337     localness W_ infolbl[] = {                  \
1338         (W_) bh_code                            \
1339         ,(W_) INFO_OTHER_TAG                    \
1340         ,(W_) MK_REP_REF(BH,kind,)              \
1341         INCLUDE_PROFILING_INFO(BH)              \
1342     }
1343
1344 MAYBE_DECLARE_RTBL(BH,U,)
1345 MAYBE_DECLARE_RTBL(BH,N,)
1346
1347 #define BH_RTBL(kind)                                                           \
1348     const W_ MK_REP_LBL(BH,kind,)[] = {                                         \
1349         INCLUDE_TYPE_INFO(BH)                                                   \
1350         INCLUDE_SIZE_INFO(CAT3(BH_,kind,_SIZE),0L)                              \
1351         INCLUDE_PAR_INFO                                                        \
1352         INCLUDE_COPYING_INFO(CAT2(_Evacuate_BH_,kind),CAT2(_Scavenge_BH_,kind)) \
1353         INCLUDE_COMPACTING_INFO(CAT2(_ScanLink_BH_,kind),_PRStart_BH,           \
1354                                 CAT2(_ScanMove_BH_,kind),_PRIn_Error)           \
1355     }
1356
1357 \end{code}
1358
1359 %************************************************************************
1360 %*                                                                      *
1361 \subsection[IND_ITBL]{Info table for indirections}
1362 %*                                                                      *
1363 %************************************************************************
1364
1365 An indirection simply extracts the pointer from the
1366 @IND_CLOSURE_PTR(closure)@ field. The garbage collection routines will
1367 short out the indirection (normally).
1368 \begin{code}
1369
1370 #define IND_ITBL(infolbl,ind_code,localness,entry_localness) \
1371     CAT_DECLARE(infolbl,INTERNAL_KIND,"IND","IND")      \
1372     entry_localness(ind_code);                          \
1373     localness W_ infolbl[] = {                          \
1374         (W_) ind_code                                   \
1375         ,(W_) INFO_IND_TAG                              \
1376         ,(W_) MK_REP_REF(Ind,,)                         \
1377         INCLUDE_PROFILING_INFO(infolbl)                 \
1378         }
1379
1380 MAYBE_DECLARE_RTBL(Ind,,)
1381
1382 #define IND_RTBL()                                                              \
1383     const W_ MK_REP_LBL(Ind,,)[] = {                                            \
1384         INCLUDE_TYPE_INFO(IND)                                                  \
1385         INCLUDE_SIZE_INFO(MIN_UPD_SIZE,INFO_UNUSED) /* #ptrs not here! */       \
1386         INCLUDE_PAR_INFO                                                        \
1387         INCLUDE_COPYING_INFO(_Evacuate_Ind,_Scavenge_Ind)                       \
1388         INCLUDE_COMPACTING_INFO(_Dummy_Ind_entry,_PRStart_Ind,                  \
1389                                 _Dummy_Ind_entry,_Dummy_Ind_entry)              \
1390     }
1391
1392 \end{code}
1393
1394 Lexical-scoped profiling (now more-or-less the default... 94/06)
1395 requires a special permanent indirection for PAP closures.  These 
1396 look exactly like regular indirections, but they are not short-circuited
1397 on garbage collection.
1398
1399 \begin{code}
1400 #if defined(PROFILING) || defined(TICKY_TICKY)
1401
1402 # define PERM_IND_ITBL(infolbl,ind_code,localness,entry_localness) \
1403     entry_localness(ind_code);                          \
1404     CAT_DECLARE(infolbl,INTERNAL_KIND,"IND","IND")      \
1405     localness W_ infolbl[] = {                          \
1406         (W_) ind_code                                   \
1407         ,(W_) INFO_IND_TAG                              \
1408         ,(W_) MK_REP_REF(Perm_Ind,,)                    \
1409         INCLUDE_PROFILING_INFO(infolbl)                 \
1410     }
1411
1412 MAYBE_DECLARE_RTBL(Perm_Ind,,)
1413
1414 # define PERM_IND_RTBL()                                                        \
1415     const W_ MK_REP_LBL(Perm_Ind,,)[] = {                                       \
1416         INCLUDE_TYPE_INFO(IND)                                                  \
1417         INCLUDE_SIZE_INFO(MIN_UPD_SIZE,INFO_UNUSED) /* #ptrs not here! */       \
1418         INCLUDE_PAR_INFO                                                        \
1419         INCLUDE_COPYING_INFO(_Evacuate_PI,_Scavenge_PI)                         \
1420         SPEC_COMPACTING_INFO(_ScanLink_PI,_PRStart_PI,                          \
1421                              _ScanMove_PI,_PRIn_PI)                             \
1422         }
1423
1424 #else
1425 # define PERM_IND_RTBL()
1426 #endif
1427 \end{code}
1428
1429 %************************************************************************
1430 %*                                                                      *
1431 \subsection[CAF_ITBL]{Info table for updated @CAF@s}
1432 %*                                                                      *
1433 %************************************************************************
1434
1435 Garbage collection of @CAF@s is tricky.  We have to cope with explicit
1436 collection from the @CAFlist@ as well as potential references from the
1437 stack and heap which will cause the @CAF@ evacuation code to be
1438 called.  They are treated like indirections which are shorted out.
1439 However they must also be updated to point to the new location of the
1440 new closure as the @CAF@ may still be used by references which
1441 reside in the code.
1442
1443 \subsubsection{Copying Collection}
1444
1445 A first scheme might use evacuation code which evacuates the reference
1446 and updates the indirection. This is no good as subsequent evacuations
1447 will result in an already evacuated closure being evacuated. This will
1448 leave a forward reference in to-space!
1449
1450 An alternative scheme evacuates the @CAFlist@ first. The closures
1451 referenced are evacuated and the @CAF@ indirection updated to point to
1452 the evacuated closure. The @CAF@ evacuation code simply returns the
1453 updated indirection pointer --- the pointer to the evacuated closure.
1454 Unfortunately the closure the @CAF@ references may be a static
1455 closure, in fact, it may be another @CAF@. This will cause the second
1456 @CAF@'s evacuation code to be called before the @CAF@ has been
1457 evacuated, returning an unevacuated pointer.
1458
1459 Another scheme leaves updating the @CAF@ indirections to the end of
1460 the garbage collection.  All the references are evacuated and
1461 scavenged as usual (including the @CAFlist@). Once collection is
1462 complete the @CAFlist@ is traversed updating the @CAF@ references with
1463 the result of evacuating the referenced closure again. This will
1464 immediately return as it must be a forward reference, a static
1465 closure, or a @CAF@ which will indirect by evacuating its reference.
1466
1467 The crux of the problem is that the @CAF@ evacuation code needs to
1468 know if its reference has already been evacuated and updated. If not,
1469 then the reference can be evacuated, updated and returned safely
1470 (possibly evacuating another @CAF@). If it has, then the updated
1471 reference can be returned. This can be done using two @CAF@
1472 info-tables. At the start of a collection the @CAFlist@ is traversed
1473 and set to an internal {\em evacuate and update} info-table. During
1474 collection, evacution of such a @CAF@ also results in the info-table
1475 being reset back to the standard @CAF@ info-table. Thus subsequent
1476 evacuations will simply return the updated reference. On completion of
1477 the collection all @CAF@s will have {\em return reference} info-tables
1478 again.
1479
1480 This is the scheme we adopt. A @CAF@ indirection has evacuation code
1481 which returns the evacuated and updated reference. During garbage
1482 collection, all the @CAF@s are overwritten with an internal @CAF@ info
1483 table which has evacuation code which performs this evacuate and
1484 update and restores the original @CAF@ code. At some point during the
1485 collection we must ensure that all the @CAF@s are indeed evacuated.
1486
1487 The only potential problem with this scheme is a cyclic list of @CAF@s
1488 all directly referencing (possibly via indirections) another @CAF@!
1489 Evacuation of the first @CAF@ will fail in an infinite loop of @CAF@
1490 evacuations. This is solved by ensuring that the @CAF@ info-table is
1491 updated to a {\em return reference} info-table before performing the
1492 evacuate and update. If this {\em return reference} evacuation code is
1493 called before the actual evacuation is complete it must be because
1494 such a cycle of references exists. Returning the still unevacuated
1495 reference is OK --- all the @CAF@s will now reference the same
1496 @CAF@ which will reference itself! Construction of such a structure
1497 indicates the program must be in an infinite loop.
1498
1499 \subsubsection{Compacting Collector}
1500
1501 When shorting out a @CAF@, its reference must be marked. A first
1502 attempt might explicitly mark the @CAF@s, updating the reference with
1503 the marked reference (possibly short circuting indirections). The
1504 actual @CAF@ marking code can indicate that they have already been
1505 marked (though this might not have actually been done yet) and return
1506 the indirection pointer so it is shorted out. Unfortunately the @CAF@
1507 reference might point to an indirection which will be subsequently
1508 shorted out. Rather than returning the @CAF@ reference we treat the
1509 @CAF@ as an indirection, calling the mark code of the reference, which
1510 will return the appropriately shorted reference.
1511
1512 Problem: Cyclic list of @CAF@s all directly referencing (possibly via
1513 indirections) another @CAF@!
1514
1515 Before compacting, the locations of the @CAF@ references are
1516 explicitly linked to the closures they reference (if they reference
1517 heap allocated closures) so that the compacting process will update
1518 them to the closure's new location. Unfortunately these locations'
1519 @CAF@ indirections are static.  This causes premature termination
1520 since the test to find the info pointer at the end of the location
1521 list will match more than one value.  This can be solved by using an
1522 auxiliary dynamic array (on the top of the A stack).  One location for
1523 each @CAF@ indirection is linked to the closure that the @CAF@
1524 references. Once collection is complete this array is traversed and
1525 the corresponding @CAF@ is then updated with the updated pointer from
1526 the auxiliary array.
1527
1528 \begin{code}
1529
1530 #define CAF_ITBL(infolbl,ind_code,localness,entry_localness) \
1531     CAT_DECLARE(infolbl,INTERNAL_KIND,"CAF","CAF")      \
1532     entry_localness(ind_code);                          \
1533     localness W_ infolbl[] = {                          \
1534         (W_) ind_code                                   \
1535         ,(W_) INFO_IND_TAG                              \
1536         ,(W_) MK_REP_REF(Caf,,)                         \
1537         INCLUDE_PROFILING_INFO(infolbl)                 \
1538     }
1539
1540 MAYBE_DECLARE_RTBL(Caf,,)
1541
1542 #define CAF_RTBL()                                                              \
1543     const W_ MK_REP_LBL(Caf,,)[] = {                                            \
1544         INCLUDE_TYPE_INFO(CAF)                                                  \
1545         INCLUDE_SIZE_INFO(MIN_UPD_SIZE,INFO_UNUSED) /* #ptrs not here! */       \
1546         INCLUDE_PAR_INFO                                                        \
1547         INCLUDE_COPYING_INFO(_Evacuate_Caf,_Scavenge_Caf)                       \
1548         INCLUDE_COMPACTING_INFO(_Dummy_Caf_entry,_PRStart_Caf,                  \
1549                                 _Dummy_Caf_entry,_Dummy_Caf_entry)              \
1550         }
1551 \end{code}
1552
1553
1554 It is possible to use an alternative marking scheme, using a similar
1555 idea to the copying solution. This scheme avoids the need to update
1556 the @CAF@ references explicitly. We introduce an auxillary {\em mark
1557 and update} @CAF@ info-table which is used to update all @CAF@s at the
1558 start of a collection. The new code marks the @CAF@ reference,
1559 updating it with the returned reference.  The returned reference is
1560 itself returned so the @CAF@ is shorted out.  The code also modifies the
1561 @CAF@ info-table to be a {\em return reference}.  Subsequent attempts to
1562 mark the @CAF@ simply return the updated reference.
1563
1564 A cyclic @CAF@ reference will result in an attempt to mark the @CAF@
1565 before the marking has been completed and the reference updated. We
1566 cannot start marking the @CAF@ as it is already being marked. Nor can
1567 we return the reference as it has not yet been updated. Neither can we
1568 treat the CAF as an indirection since the @CAF@ reference has been
1569 obscured by the pointer reversal stack. All we can do is return the
1570 @CAF@ itself. This will result in some @CAF@ references not being
1571 shorted out.
1572
1573 This scheme has not been adopted but has been implemented. The code is
1574 commented out with @#if 0@.
1575
1576 %************************************************************************
1577 %*                                                                      *
1578 \subsection[CONST_ITBL]{@CONST_ITBL@}
1579 %*                                                                      *
1580 %************************************************************************
1581
1582 This declares an info table for @CONST@ closures (size 0).  It is the
1583 info table for a dynamicaly-allocated closure which will redirect
1584 references to the corresponding static closure @<infolbl>_closure@
1585 during garbage collection.  A pointer to the static closure is kept in
1586 the info table.  (It is assumed that this closure is declared
1587 elsewhere.)
1588
1589 Why do such @CONST@ objects ever exist?  Why don't we just use the
1590 static object in the first place?  @CONST@ objects are used only for
1591 updating existing objects.  We could use an indirection, but that
1592 risks costing extra run-time indirections until the next GC shorts it
1593 out.  So we update with a @CONST@, and the next GC gets rid of it.
1594
1595 \begin{code}
1596 #define CONST_ITBL(infolbl,closurelbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
1597     CAT_DECLARE(infolbl,kind,descr,type)        \
1598     entry_localness(entry_code);                \
1599     EXTDATA(closurelbl);                        \
1600     localness W_ infolbl[] = {                  \
1601         (W_) entry_code                         \
1602         ,(W_) tag                               \
1603         ,(W_) MK_REP_REF(Const,,)               \
1604         INCLUDE_PROFILING_INFO(infolbl)         \
1605         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
1606         INCLUDE_CONST_INFO(closurelbl)          \
1607         }
1608
1609 MAYBE_DECLARE_RTBL(Const,,)
1610
1611 #ifdef TICKY_TICKY
1612     /* we need real routines if we may not be commoning up */
1613 #define CONST_Scav _Scavenge_0_0
1614 #define CONST_Link _ScanLink_0_0
1615 #define CONST_Move _ScanMove_0
1616 #else
1617 #define CONST_Scav _Dummy_Const_entry
1618 #define CONST_Link _Dummy_Const_entry
1619 #define CONST_Move _Dummy_Const_entry
1620 #endif
1621
1622 #define CONST_RTBL()                                            \
1623     const W_ MK_REP_LBL(Const,,)[] = {                          \
1624         INCLUDE_TYPE_INFO(CONST)                                \
1625         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED)              \
1626         INCLUDE_PAR_INFO                                        \
1627         INCLUDE_COPYING_INFO(_Evacuate_Const,CONST_Scav)        \
1628         INCLUDE_COMPACTING_INFO(CONST_Link,_PRStart_Const,      \
1629                                 CONST_Move,_Dummy_Const_entry)  \
1630     }
1631 \end{code}
1632
1633 This builds an info-table which will have pointers to the closure
1634 replaced with @closure_lbl@ during garbage collection. @closure_lbl@
1635 must be the label of a static closure, whose entry code has identical
1636 behaviour to that in the corresponding @CONST_ITBL@.  Usually
1637 the info pointer of this closure will be the very one defined by this
1638 macro!
1639
1640 These closures always consist only of an info pointer; that is, its
1641 size is zero.
1642
1643 A copying collection implements this with evacuation code which
1644 returns @closure_lbl@, without actually evacuating the object at all.
1645 A compacting collector uses marking code which returns
1646 @closure_lbl@, without marking the closure.
1647
1648 %************************************************************************
1649 %*                                                                      *
1650 \subsection[FOOLIKE_ITBL]{``Char-like'' and ``Int-like'' info-tables}
1651 %*                                                                      *
1652 %************************************************************************
1653
1654 Char-like: This builds an info-table which, when GC happens, will have
1655 pointers to the closure replaced with the appropriate element of the
1656 @CHARLIKE_closures@ array.
1657
1658 \begin{code}
1659 #define CHARLIKE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*tag,size,ptrs unused*/ \
1660     CAT_DECLARE(infolbl,kind,descr,type)        \
1661     entry_localness(entry_code);                \
1662     localness W_ infolbl[] = {                  \
1663         (W_) entry_code                         \
1664         ,(W_) INFO_FIRST_TAG                    \
1665         ,(W_) MK_REP_REF(CharLike,,)            \
1666         INCLUDE_PROFILING_INFO(infolbl)         \
1667         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
1668         }
1669
1670 MAYBE_DECLARE_RTBL(CharLike,,)
1671
1672 #ifdef TICKY_TICKY
1673     /* we need real routines if we may not be commoning up */
1674 #define CHARLIKE_Scav _Scavenge_1_0
1675 #define CHARLIKE_Link _ScanLink_1_0
1676 #define CHARLIKE_Move _ScanMove_1
1677 #else
1678 #define CHARLIKE_Scav _Dummy_CharLike_entry
1679 #define CHARLIKE_Link _Dummy_CharLike_entry
1680 #define CHARLIKE_Move _Dummy_CharLike_entry
1681 #endif
1682
1683 #define CHARLIKE_RTBL()                                                 \
1684     const W_ MK_REP_LBL(CharLike,,)[] = {                               \
1685         INCLUDE_TYPE_INFO(CHARLIKE)                                     \
1686         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED)                      \
1687         INCLUDE_PAR_INFO                                                \
1688         INCLUDE_COPYING_INFO(_Evacuate_CharLike,CHARLIKE_Scav)          \
1689         INCLUDE_COMPACTING_INFO(CHARLIKE_Link,_PRStart_CharLike,        \
1690                                 CHARLIKE_Move,_PRIn_Error)              \
1691         }
1692 \end{code}
1693
1694 Int-like: this builds the info-table required for intlike closures.
1695 The normal heap-allocated info-table for fixed-size integers (size
1696 @1@); it is used for updates too.  At GC, this is redirected to a
1697 static intlike closure if one is available.
1698
1699 \begin{code}
1700 #define INTLIKE_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*tag,size,ptrs unused*/ \
1701     CAT_DECLARE(infolbl,kind,descr,type)        \
1702     entry_localness(entry_code);                \
1703     localness W_ infolbl[] = {                  \
1704         (W_) entry_code                         \
1705         ,(W_) INFO_FIRST_TAG                    \
1706         ,(W_) MK_REP_REF(IntLike,,)             \
1707         INCLUDE_PROFILING_INFO(infolbl)         \
1708         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
1709     }
1710
1711 MAYBE_DECLARE_RTBL(IntLike,,)
1712
1713 #define INTLIKE_RTBL()                                                  \
1714     const W_ MK_REP_LBL(IntLike,,)[] = {                                \
1715         INCLUDE_TYPE_INFO(INTLIKE)                                      \
1716         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED)                      \
1717         INCLUDE_PAR_INFO                                                \
1718         INCLUDE_COPYING_INFO(_Evacuate_IntLike,_Scavenge_1_0)           \
1719         INCLUDE_COMPACTING_INFO(_ScanLink_1_0,_PRStart_IntLike,         \
1720                                 _ScanMove_1,_PRIn_Error)                \
1721     }
1722 \end{code}
1723
1724 %************************************************************************
1725 %*                                                                      *
1726 \subsection[INREGS_ITBL]{@INREGS_ITBL@s}
1727 %*                                                                      *
1728 %************************************************************************
1729
1730 The emaciated info table for a phantom closure that lives only in regs.
1731 We don't need any GC information, because these closures never make it into
1732 the heap (not with this info table, anyway).  Similarly, we don't need an
1733 entry address, because these closures are never entered...they only exist
1734 during a return.
1735
1736 \begin{code}
1737
1738 #define INREGS_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*mostly unused*/ \
1739     localness W_ infolbl[] = {                  \
1740         (W_) INFO_UNUSED                        \
1741         ,(W_) tag                               \
1742         ,(W_) INFO_UNUSED                       \
1743         INREGS_PROFILING_INFO                   \
1744         INCLUDE_UPDATE_INFO(upd_code,liveness)  \
1745     }
1746
1747 /* Declare the phantom info table vectors (just Bool at the moment) */
1748 #ifndef COMPILING_NCG
1749 #ifndef aix_TARGET_OS /* AIX gives link errors with this as a const (RO assembler section) */
1750 EXTDATA_RO(PrelBase_Bool_itblvtbl);
1751 #else
1752 extern W_ PrelBase_Bool_itblvtbl[];
1753 #endif
1754 #endif
1755
1756 \end{code}
1757
1758 End multi-slurp protection:
1759 \begin{code}
1760 #endif /* SMInfoTables_H */
1761 \end{code}