2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 %************************************************************************
6 \section[Ticky.lh]{Interface (and macros) for reduction-count statistics}
8 %************************************************************************
10 Multi-slurp protection:
16 There are macros in here for:
19 ``Ticky-ticky profiling'' (\tr{TICKY_TICKY}), counting the
20 number of various STG-events (updates, enters, etc.)
22 This file goes with \tr{Ticky.lc}, which initialises the counters
23 and does the printing [ticky-ticky only].
25 %************************************************************************
27 \subsection{Macros for using the `ticky' field in the fixed header}
29 %************************************************************************
32 #define TICKY_FIXED_HDR (TICKY_HDR_SIZE)
33 #define TICKY_HDR_POSN AFTER_PROF_HDR
34 #define AFTER_TICKY_HDR (TICKY_FIXED_HDR+TICKY_HDR_POSN)
40 #define TICKY_HDR_SIZE 0
41 #define TICKY_HDR(closure)
42 #define SET_TICKY_HDR(closure,to)
43 #define SET_STATIC_TICKY_HDR()
47 #define TICKY_HDR_SIZE 1
48 #define TICKY_HDR(closure) (((P_)(closure))[TICKY_HDR_POSN])
49 #define SET_TICKY_HDR(closure,to) TICKY_HDR(closure) = (to)
50 #define SET_STATIC_TICKY_HDR() ,0
52 #endif /* TICKY_TICKY */
55 Here, we add the Ticky word to the fixed-header part of closures.
56 This is used to record indicate if a closure has been updated but not
57 yet entered. It is set when the closure is updated and cleared when
60 NB: It is {\em not} an ``entry count'', it is an
61 ``entries-after-update count.''
63 The commoning up of @CONST@, @CHARLIKE@ and @INTLIKE@ closures is
64 turned off(?) if this is required. This has only been done for 2s
65 collection. It is done using a nasty hack which defines the
66 @_Evacuate@ and @_Scavenge@ code for @CONST@, @CHARLIKE@ and @INTLIKE@
67 info tables to be @_Evacuate_1@ and @_Scavenge_1_0@.
72 #define UPDATED_SET_UPDATED(n) /* nothing */
73 #define ENTERED_CHECK_UPDATED(n) /* nothing */
77 #define UPDATED_SET_UPDATED(n) do { TICKY_HDR(n) = 1; } while(0)
79 #define ENT_UPD_HISTO(n) \
83 /* once 9th enter is recorded, we do not tick anymore;*/\
84 /* we want "TotUpdates - <all 9 cols>" to equal */ \
85 /* "updates that were never entered" */ \
87 UPD_ENTERED_hst[__idx] += 1; \
89 /* now undo tick in previous histo slot ... */ \
90 if ( __idx >= 1 && __idx <= 8 ) \
91 UPD_ENTERED_hst[(__idx - 1)] -= 1; \
94 #define ENTERED_CHECK_UPDATED(n) \
96 I_ t_hdr = TICKY_HDR(n); \
98 if (t_hdr != 0 && AllFlags.doUpdEntryCounts) { \
99 ENT_UPD_HISTO(t_hdr); \
103 #endif /* TICKY_TICKY */
106 %************************************************************************
108 \subsection[ticky-ticky-macros]{Stuff for ``ticky-ticky'' profiling}
110 %************************************************************************
116 Measure what proportion of ...:
119 ... Enters are to data values, function values, thunks.
121 ... allocations are for data values, functions values, thunks.
123 ... updates are for data values, function values.
127 ... return-in-heap (dynamic)
129 ... vectored return (dynamic)
131 ... updates are wasted (never re-entered).
133 ... constructor returns get away without hitting an update.
136 %************************************************************************
138 \subsubsection[ticky-stk-heap-use]{Stack and heap usage}
140 %************************************************************************
142 Things we are interested in here:
145 How many times we do a heap check and move @Hp@; comparing this with
146 the allocations gives an indication of how many things we get per trip
149 #define ALLOC_HEAP(n) ALLOC_HEAP_ctr++; ALLOC_HEAP_tot += (n)
152 If we do a ``heap lookahead,'' we haven't really allocated any
153 heap, so we need to undo the effects of an \tr{ALLOC_HEAP}:
155 #define UN_ALLOC_HEAP(n) ALLOC_HEAP_ctr--; ALLOC_HEAP_tot -= (n)
159 The stack high-water marks. This is {\em direction-sensitive}!!
160 (A stack grows downward, B stack upwards)
163 #define DO_ASTK_HWM() if (SpA < max_SpA) { max_SpA = SpA; }
164 #define DO_BSTK_HWM() if (SpB > max_SpB) { max_SpB = SpB; }
167 * This is not direction sensitive, because we threads people are well-behaved.
168 * However, it might be a good idea to cache the constant bits (DEP + BOT and
169 * HWM) from the STKO and TSO in more readily accessible places. -- ToDo!
171 #define DO_ASTK_HWM() { \
172 I_ depth = STKO_ADEP(StkOReg) + AREL((I_) STKO_ASTK_BOT(StkOReg) - (I_) SpA);\
173 if (depth > TSO_AHWM(CurrentTSO)) \
174 TSO_AHWM(CurrentTSO) = depth; \
176 #define DO_BSTK_HWM() { \
177 I_ depth = STKO_BDEP(StkOReg) + BREL((I_) STKO_BSTK_BOT(StkOReg) - (I_) SpB);\
178 if (depth > TSO_BHWM(CurrentTSO)) \
179 TSO_BHWM(CurrentTSO) = depth; \
185 Re-use of stack slots, and stubbing of stack slots:
187 #define A_STK_STUB(n) A_STK_STUB_ctr += (n)
188 #define A_STK_REUSE(n) A_STK_REUSE_ctr += (n) /* not used at all? */
189 #define B_STK_REUSE(n) B_STK_REUSE_ctr += (n) /* not used at all? */
193 %************************************************************************
195 \subsubsection[ticky-allocs]{Allocations}
197 %************************************************************************
199 We count things every time we allocate something in the dynamic heap.
200 For each, we count the number of words of (1)~``admin'' (header),
201 (2)~good stuff (useful pointers and data), and (3)~``slop'' (extra
202 space, in hopes it will allow an in-place update).
204 The first five macros are inserted when the compiler generates code
205 to allocate something; the categories correspond to the @ClosureClass@
206 datatype (manifest functions, thunks, constructors, big tuples, and
207 partial applications).
209 #define ALLOC_FUN(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
210 ALLOC_FUN_ctr++; ALLOC_FUN_adm += (a); \
211 ALLOC_FUN_gds += (g); ALLOC_FUN_slp += (s); \
212 ALLOC_HISTO(FUN,a,g,s)
213 #define ALLOC_THK(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
214 ALLOC_THK_ctr++; ALLOC_THK_adm += (a); \
215 ALLOC_THK_gds += (g); ALLOC_THK_slp += (s); \
216 ALLOC_HISTO(THK,a,g,s)
217 #define ALLOC_CON(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
218 ALLOC_CON_ctr++; ALLOC_CON_adm += (a); \
219 ALLOC_CON_gds += (g); ALLOC_CON_slp += (s); \
220 ALLOC_HISTO(CON,a,g,s)
221 #define ALLOC_TUP(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
222 ALLOC_TUP_ctr++; ALLOC_TUP_adm += (a); \
223 ALLOC_TUP_gds += (g); ALLOC_TUP_slp += (s); \
224 ALLOC_HISTO(TUP,a,g,s)
225 #define ALLOC_BH(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
226 ALLOC_BH_ctr++; ALLOC_BH_adm += (a); \
227 ALLOC_BH_gds += (g); ALLOC_BH_slp += (s); \
228 ALLOC_HISTO(BH,a,g,s)
230 #define ALLOC_PAP(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
231 ALLOC_PAP_ctr++; ALLOC_PAP_adm += (a); \
232 ALLOC_PAP_gds += (g); ALLOC_PAP_slp += (s); \
233 ALLOC_HISTO(PAP,a,g,s)
237 We may also allocate space when we do an update, and there isn't
238 enough space. These macros suffice (for: updating with a partial
239 application and a constructor):
241 #define ALLOC_UPD_PAP(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
242 ALLOC_UPD_PAP_ctr++; ALLOC_UPD_PAP_adm += (a); \
243 ALLOC_UPD_PAP_gds += (g); ALLOC_UPD_PAP_slp += (s); \
244 ALLOC_HISTO(UPD_PAP,a,g,s)
246 #define ALLOC_UPD_CON(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
247 ALLOC_UPD_CON_ctr++; ALLOC_UPD_CON_adm += (a); \
248 ALLOC_UPD_CON_gds += (g); ALLOC_UPD_CON_slp += (s); \
249 ALLOC_HISTO(UPD_CON,a,g,s)
253 In the threaded world, we allocate space for the spark pool, stack objects,
254 and thread state objects.
258 #define ALLOC_STK(a,g,s) ALLOC_STK_ctr++; ALLOC_STK_adm += (a); \
259 ALLOC_STK_gds += (g); ALLOC_STK_slp += (s); \
260 ALLOC_HISTO(STK,a,g,s)
262 #define ALLOC_TSO(a,g,s) ALLOC_TSO_ctr++; ALLOC_TSO_adm += (a); \
263 ALLOC_TSO_gds += (g); ALLOC_TSO_slp += (s); \
264 ALLOC_HISTO(TSO,a,g,s)
266 #define ALLOC_FMBQ(a,g,s) ALLOC_FMBQ_ctr++; ALLOC_FMBQ_adm += (a); \
267 ALLOC_FMBQ_gds += (g); ALLOC_FMBQ_slp += (s); \
268 ALLOC_HISTO(FMBQ,a,g,s)
270 #define ALLOC_FME(a,g,s) ALLOC_FME_ctr++; ALLOC_FME_adm += (a); \
271 ALLOC_FME_gds += (g); ALLOC_FME_slp += (s); \
272 ALLOC_HISTO(FME,a,g,s)
274 #define ALLOC_BF(a,g,s) ALLOC_BF_ctr++; ALLOC_BF_adm += (a); \
275 ALLOC_BF_gds += (g); ALLOC_BF_slp += (s); \
276 ALLOC_HISTO(BF,a,g,s)
280 The histogrammy bit is fairly straightforward; the \tr{-2} is: one for
281 0-origin C arrays; the other one because we do {\em no} one-word
282 allocations, so we would never inc that histogram slot; so we shift
283 everything over by one.
285 #define ALLOC_HISTO(categ,a,g,s) \
287 __idx = (a) + (g) + (s) - 2; \
288 CAT3(ALLOC_,categ,_hst)[((__idx > 4) ? 4 : __idx)] += 1;}
291 Some hard-to-account-for words are allocated by/for primitives,
292 includes Integer support. @ALLOC_PRIM2@ tells us about these. We
293 count everything as ``goods'', which is not strictly correct.
294 (@ALLOC_PRIM@ is the same sort of stuff, but we know the
295 admin/goods/slop breakdown.)
297 #define ALLOC_PRIM(a,g,s,t) ASSERT((t) == (a)+(g)+(s)); \
298 ALLOC_PRIM_ctr++; ALLOC_PRIM_adm += (a); \
299 ALLOC_PRIM_gds += (g); ALLOC_PRIM_slp += (s); \
300 ALLOC_HISTO(PRIM,a,g,s)
301 #define ALLOC_PRIM2(w) ALLOC_PRIM_ctr++; ALLOC_PRIM_gds +=(w); \
302 ALLOC_HISTO(PRIM,0,w,0)
305 %************************************************************************
307 \subsubsection[ticky-enters]{Enters}
309 %************************************************************************
312 #define ENT_VIA_NODE() ENT_VIA_NODE_ctr++ /* via ENT_ macro */
314 #define ENT_THK() ENT_THK_ctr++
315 #define ENT_FUN_STD() ENT_FUN_STD_ctr++ /* manifest fun; std entry pt */
317 #define ENT_CON(n) ENTERED_CHECK_UPDATED(n); ENT_CON_ctr++ /* enter code for constructor */
318 #define ENT_IND(n) ENTERED_CHECK_UPDATED(n); ENT_IND_ctr++ /* enter indirection */
319 #define ENT_PAP(n) ENTERED_CHECK_UPDATED(n); ENT_PAP_ctr++ /* enter partial application */
322 We do more magical things with @ENT_FUN_DIRECT@. Besides simply knowing
323 how many ``fast-entry-point'' enters there were, we'd like {\em simple}
324 information about where those enters were, and the properties thereof.
327 unsigned registeredp:16, /* 0 == no, 1 == yes */
328 arity:16, /* arity (static info) */
329 Astk_args:16, /* # of args off A stack */
330 Bstk_args:16; /* # of args off B stack */
331 /* (rest of args are in registers) */
332 StgChar *f_str; /* name of the thing */
333 StgChar *f_arg_kinds; /* info about the args types */
334 StgChar *wrap_str; /* name of its wrapper (if any) */
335 StgChar *wrap_arg_kinds;/* info about the orig wrapper's arg types */
336 I_ ctr; /* the actual counter */
337 struct ent_counter *link; /* link to chain them all together */
340 /* OLD: extern void RegisterEntryPt PROTO((struct ent_counter *)); */
341 extern struct ent_counter *ListOfEntryCtrs;
343 #define ENT_FUN_DIRECT(f_ct,f_str,f_arity,Aargs,Bargs,arg_kinds,wrap,wrap_kinds) \
344 static struct ent_counter f_ct \
346 (f_arity), (Aargs), (Bargs), (f_str), (arg_kinds),\
347 (wrap), (wrap_kinds), \
349 if ( ! f_ct.registeredp ) { \
350 /* hook this one onto the front of the list */ \
351 f_ct.link = ListOfEntryCtrs; \
352 ListOfEntryCtrs = & (f_ct); \
354 /* mark it as "registered" */ \
355 f_ct.registeredp = 1; \
358 ENT_FUN_DIRECT_ctr++ /* the old boring one */
361 %************************************************************************
363 \subsubsection[ticky-returns]{Returns}
365 %************************************************************************
367 Whenever a ``return'' occurs, it is returning the constituent parts of
368 a data constructor. The parts can be returned either in registers, or
369 by allocating some heap to put it in (the @ALLOC_*@ macros account for
370 the allocation). The constructor can either be an existing one
371 (\tr{*OLD*}) or we could have {\em just} figured out this stuff
374 Here's some special magic that Simon wants [edited to match names
377 From: Simon L Peyton Jones <simonpj>
379 Subject: counting updates
380 Date: Wed, 25 Mar 92 08:39:48 +0000
382 I'd like to count how many times we update in place when actually Node
383 points to the thing. Here's how:
385 \tr{RET_OLD_IN_REGS} sets the variable \tr{ReturnInRegsNodeValid} to \tr{True};
386 \tr{RET_NEW_IN_REGS} sets it to \tr{False}.
388 \tr{RET_SEMI_???} sets it to??? ToDo [WDP]
390 \tr{UPD_CON_IN_PLACE} tests the variable, and increments \tr{UPD_IN_PLACE_COPY_ctr}
393 Then we need to report it along with the update-in-place info.
397 #define RET_HISTO(categ,n,offset) \
399 __idx = (n) - (offset); \
400 CAT3(RET_,categ,_hst)[((__idx > 8) ? 8 : __idx)] += 1;}
402 /* "slide" histogramming by (__STG_REGS_AVAIL__ - 1) -- usually 7 --
403 so we do not collect lots and lots of useless zeros for _IN_HEAP.
406 #define RET_NEW_IN_HEAP(n) RET_NEW_IN_HEAP_ctr++; \
407 RET_HISTO(NEW_IN_HEAP,n,__STG_REGS_AVAIL__ - 1)
408 #define RET_OLD_IN_HEAP(n) RET_OLD_IN_HEAP_ctr++; \
409 RET_HISTO(OLD_IN_HEAP,n,__STG_REGS_AVAIL__ - 1)
410 #define RET_SEMI_IN_HEAP(n) RET_SEMI_IN_HEAP_ctr++; \
411 RET_HISTO(SEMI_IN_HEAP,n,__STG_REGS_AVAIL__ - 1)
413 #define RET_NEW_IN_REGS(n) RET_NEW_IN_REGS_ctr++; \
414 ReturnInRegsNodeValid = 0; \
415 RET_HISTO(NEW_IN_REGS,n,0)
416 #define RET_OLD_IN_REGS(n) RET_OLD_IN_REGS_ctr++; \
417 ReturnInRegsNodeValid = 1; \
418 RET_HISTO(OLD_IN_REGS,n,0)
419 #define RET_SEMI_IN_REGS(n,u) RET_SEMI_IN_REGS_ctr++; \
420 RET_SEMI_loads_avoided += ((n) - (u)); \
421 RET_HISTO(SEMI_IN_REGS,u,0)
423 #define RET_SEMI_BY_DEFAULT()/*???*/ RET_SEMI_BY_DEFAULT_ctr++
425 #define RET_SEMI_FAILED(tag) do { \
426 if ((tag) == INFO_IND_TAG) \
427 RET_SEMI_FAILED_IND_ctr++; \
429 RET_SEMI_FAILED_UNEVAL_ctr++; \
434 Of all the returns (sum of four categories above), how many were
435 vectored? (The rest were obviously unvectored).
437 #define VEC_RETURN(n) VEC_RETURN_ctr++; \
438 RET_HISTO(VEC_RETURN,n,0)
441 %************************************************************************
443 \subsubsection[ticky-update-frames]{Update frames}
445 %************************************************************************
447 These macros count up the following update information.
449 %partain:\begin{center}
450 \begin{tabular}{ll} \hline
451 Macro & Counts \\ \hline
453 \tr{UPDF_STD_PUSHED} & Update frame pushed \\
454 \tr{UPDF_CON_PUSHED} & Constructor update frame pushed \\
455 \tr{UPDF_HOLE_PUSHED} & An update frame to update a black hole \\
456 \tr{UPDF_OMITTED} & A thunk decided not to push an update frame \\
457 & (all subsets of \tr{ENT_THK}) \\
458 \tr{UPDF_RCC_PUSHED} & Cost Centre restore frame pushed \\
459 \tr{UPDF_RCC_OMITTED} & Cost Centres not required -- not pushed \\\hline
461 %partain:\end{center}
464 #define UPDF_OMITTED() UPDF_OMITTED_ctr++
466 #define UPDF_STD_PUSHED() UPDF_STD_PUSHED_ctr++
467 #define UPDF_CON_PUSHED() UPDF_CON_PUSHED_ctr++
468 #define UPDF_HOLE_PUSHED() UPDF_HOLE_PUSHED_ctr++
470 #define UPDF_RCC_PUSHED() UPDF_RCC_PUSHED_ctr++
471 #define UPDF_RCC_OMITTED() UPDF_RCC_OMITTED_ctr++
474 %************************************************************************
476 \subsubsection[ticky-updates]{Updates}
478 %************************************************************************
480 These macros record information when we do an update. We always
481 update either with a data constructor (CON) or a partial application
484 %partain:\begin{center}
485 \begin{tabular}{|l|l|}\hline
486 Macro & Where \\ \hline
488 \tr{UPD_EXISTING} & Updating with an indirection to something \\
489 & already in the heap \\
490 \tr{UPD_SQUEEZED} & Same as \tr{UPD_EXISTING} but because \\
491 & of stack-squeezing \\
492 \tr{UPD_CON_W_NODE} & Updating with a CON: by indirecting to Node \\
493 \tr{UPD_CON_IN_PLACE} & Ditto, but in place \\
494 \tr{UPD_CON_IN_NEW} & Ditto, but allocating the object \\
495 \tr{UPD_PAP_IN_PLACE} & Same, but updating w/ a PAP \\
496 \tr{UPD_PAP_IN_NEW} & \\\hline
498 %partain:\end{center}
501 #define UPD_HISTO(categ,n) \
504 CAT3(UPD_,categ,_hst)[((__idx > 8) ? 8 : __idx)] += 1;}
506 #define UPD_EXISTING() UPD_EXISTING_ctr++
507 #define UPD_SQUEEZED() UPD_SQUEEZED_ctr++
509 #define UPD_CON_W_NODE() UPD_CON_W_NODE_ctr++
511 #define UPD_CON_IN_NEW(n) UPD_CON_IN_NEW_ctr++ ; \
512 UPD_HISTO(CON_IN_NEW,n)
513 #define UPD_PAP_IN_NEW(n) UPD_PAP_IN_NEW_ctr++ ; \
514 UPD_HISTO(PAP_IN_NEW,n)
515 /* ToDo: UPD_NEW_COPY_ctr, as below */
517 #define UPD_CON_IN_PLACE(n) UPD_CON_IN_PLACE_ctr++ ; \
518 UPD_IN_PLACE_COPY_ctr += ReturnInRegsNodeValid ; \
519 /* increments if True; otherwise, no */ \
520 UPD_HISTO(CON_IN_PLACE,n)
521 #define UPD_PAP_IN_PLACE() UPD_PAP_IN_PLACE_ctr++ ; \
522 UPD_IN_PLACE_COPY_ctr += ReturnInRegsNodeValid
523 /* increments if True; otherwise, no */
526 For a generational collector:
528 #define UPD_NEW_IND() UPD_NEW_IND_ctr++;
529 #define UPD_NEW_IN_PLACE_PTRS() UPD_NEW_IN_PLACE_PTRS_ctr++;
530 #define UPD_NEW_IN_PLACE_NOPTRS() UPD_NEW_IN_PLACE_NOPTRS_ctr++;
531 #define UPD_OLD_IND() UPD_OLD_IND_ctr++;
532 #define UPD_OLD_IN_PLACE_PTRS() UPD_OLD_IN_PLACE_PTRS_ctr++;
533 #define UPD_OLD_IN_PLACE_NOPTRS() UPD_OLD_IN_PLACE_NOPTRS_ctr++;
536 %************************************************************************
538 \subsubsection[ticky-selectors]{Doing selectors at GC time}
540 %************************************************************************
542 @GC_SEL_ABANDONED@: we could've done the selection, but we gave up
543 (e.g., to avoid overflowing the C stack); @GC_SEL_MINOR@: did a
544 selection in a minor GC; @GC_SEL_MAJOR@: ditto, but major GC.
547 #define GC_SEL_ABANDONED() GC_SEL_ABANDONED_ctr++;
548 #define GC_SEL_MINOR() GC_SEL_MINOR_ctr++;
549 #define GC_SEL_MAJOR() GC_SEL_MAJOR_ctr++;
551 #define GC_SHORT_IND() GC_SHORT_IND_ctr++;
552 #define GC_SHORT_CAF() GC_SHORT_CAF_ctr++;
553 #define GC_COMMON_CHARLIKE() GC_COMMON_CHARLIKE_ctr++;
554 #define GC_COMMON_INTLIKE() GC_COMMON_INTLIKE_ctr++;
555 #define GC_COMMON_INTLIKE_FAIL() GC_COMMON_INTLIKE_FAIL_ctr++;
556 #define GC_COMMON_CONST() GC_COMMON_CONST_ctr++;
559 %************************************************************************
561 \subsubsection[ticky-counters]{The accumulators (extern decls)}
563 %************************************************************************
566 extern I_ ALLOC_HEAP_ctr;
567 extern I_ ALLOC_HEAP_tot;
572 extern I_ A_STK_STUB_ctr;
574 extern I_ A_STK_REUSE_ctr;
575 extern I_ B_STK_REUSE_ctr;
578 extern I_ ALLOC_FUN_ctr;
579 extern I_ ALLOC_FUN_adm;
580 extern I_ ALLOC_FUN_gds;
581 extern I_ ALLOC_FUN_slp;
582 extern I_ ALLOC_FUN_hst[5];
583 extern I_ ALLOC_THK_ctr;
584 extern I_ ALLOC_THK_adm;
585 extern I_ ALLOC_THK_gds;
586 extern I_ ALLOC_THK_slp;
587 extern I_ ALLOC_THK_hst[5];
588 extern I_ ALLOC_CON_ctr;
589 extern I_ ALLOC_CON_adm;
590 extern I_ ALLOC_CON_gds;
591 extern I_ ALLOC_CON_slp;
592 extern I_ ALLOC_CON_hst[5];
593 extern I_ ALLOC_TUP_ctr;
594 extern I_ ALLOC_TUP_adm;
595 extern I_ ALLOC_TUP_gds;
596 extern I_ ALLOC_TUP_slp;
597 extern I_ ALLOC_TUP_hst[5];
598 extern I_ ALLOC_BH_ctr;
599 extern I_ ALLOC_BH_adm;
600 extern I_ ALLOC_BH_gds;
601 extern I_ ALLOC_BH_slp;
602 extern I_ ALLOC_BH_hst[5];
604 extern I_ ALLOC_PAP_ctr;
605 extern I_ ALLOC_PAP_adm;
606 extern I_ ALLOC_PAP_gds;
607 extern I_ ALLOC_PAP_slp;
608 extern I_ ALLOC_PAP_hst[5];
611 extern I_ ALLOC_UPD_CON_ctr;
612 extern I_ ALLOC_UPD_CON_adm;
613 extern I_ ALLOC_UPD_CON_gds;
614 extern I_ ALLOC_UPD_CON_slp;
615 extern I_ ALLOC_UPD_CON_hst[5];
617 extern I_ ALLOC_UPD_PAP_ctr;
618 extern I_ ALLOC_UPD_PAP_adm;
619 extern I_ ALLOC_UPD_PAP_gds;
620 extern I_ ALLOC_UPD_PAP_slp;
621 extern I_ ALLOC_UPD_PAP_hst[5];
622 extern I_ ALLOC_PRIM_ctr;
623 extern I_ ALLOC_PRIM_adm;
624 extern I_ ALLOC_PRIM_gds;
625 extern I_ ALLOC_PRIM_slp;
626 extern I_ ALLOC_PRIM_hst[5];
629 extern I_ ALLOC_STK_ctr;
630 extern I_ ALLOC_STK_adm;
631 extern I_ ALLOC_STK_gds;
632 extern I_ ALLOC_STK_slp;
633 extern I_ ALLOC_STK_hst[5];
634 extern I_ ALLOC_TSO_ctr;
635 extern I_ ALLOC_TSO_adm;
636 extern I_ ALLOC_TSO_gds;
637 extern I_ ALLOC_TSO_slp;
638 extern I_ ALLOC_TSO_hst[5];
640 extern I_ ALLOC_FMBQ_ctr;
641 extern I_ ALLOC_FMBQ_adm;
642 extern I_ ALLOC_FMBQ_gds;
643 extern I_ ALLOC_FMBQ_slp;
644 extern I_ ALLOC_FMBQ_hst[5];
645 extern I_ ALLOC_FME_ctr;
646 extern I_ ALLOC_FME_adm;
647 extern I_ ALLOC_FME_gds;
648 extern I_ ALLOC_FME_slp;
649 extern I_ ALLOC_FME_hst[5];
650 extern I_ ALLOC_BF_ctr;
651 extern I_ ALLOC_BF_adm;
652 extern I_ ALLOC_BF_gds;
653 extern I_ ALLOC_BF_slp;
654 extern I_ ALLOC_BF_hst[5];
658 extern I_ ENT_VIA_NODE_ctr;
660 extern I_ ENT_CON_ctr;
661 extern I_ ENT_FUN_STD_ctr;
662 extern I_ ENT_FUN_DIRECT_ctr;
663 extern I_ ENT_IND_ctr;
664 extern I_ ENT_PAP_ctr;
665 extern I_ ENT_THK_ctr;
667 extern I_ UPD_ENTERED_hst[9];
669 extern I_ RET_NEW_IN_HEAP_ctr;
670 extern I_ RET_NEW_IN_REGS_ctr;
671 extern I_ RET_OLD_IN_HEAP_ctr;
672 extern I_ RET_OLD_IN_REGS_ctr;
673 extern I_ RET_SEMI_BY_DEFAULT_ctr;
674 extern I_ RET_SEMI_IN_HEAP_ctr;
675 extern I_ RET_SEMI_IN_REGS_ctr;
676 extern I_ VEC_RETURN_ctr;
678 extern I_ RET_SEMI_FAILED_IND_ctr;
679 extern I_ RET_SEMI_FAILED_UNEVAL_ctr;
681 extern I_ RET_SEMI_loads_avoided;
683 extern I_ RET_NEW_IN_HEAP_hst[9];
684 extern I_ RET_NEW_IN_REGS_hst[9];
685 extern I_ RET_OLD_IN_HEAP_hst[9];
686 extern I_ RET_OLD_IN_REGS_hst[9];
687 /*no such thing: extern I_ RET_SEMI_BY_DEFAULT_hst[9]; */
688 extern I_ RET_SEMI_IN_HEAP_hst[9];
689 extern I_ RET_SEMI_IN_REGS_hst[9];
690 extern I_ RET_VEC_RETURN_hst[9];
692 extern I_ ReturnInRegsNodeValid; /* see below */
694 extern I_ UPDF_OMITTED_ctr;
695 extern I_ UPDF_STD_PUSHED_ctr;
696 extern I_ UPDF_CON_PUSHED_ctr;
697 extern I_ UPDF_HOLE_PUSHED_ctr;
699 extern I_ UPDF_RCC_PUSHED_ctr;
700 extern I_ UPDF_RCC_OMITTED_ctr;
702 extern I_ UPD_EXISTING_ctr;
703 extern I_ UPD_SQUEEZED_ctr;
704 extern I_ UPD_CON_W_NODE_ctr;
705 extern I_ UPD_CON_IN_PLACE_ctr;
706 extern I_ UPD_PAP_IN_PLACE_ctr;
707 extern I_ UPD_CON_IN_NEW_ctr;
708 extern I_ UPD_PAP_IN_NEW_ctr;
710 extern I_ UPD_CON_IN_PLACE_hst[9];
711 extern I_ UPD_CON_IN_NEW_hst[9];
712 extern I_ UPD_PAP_IN_NEW_hst[9];
714 extern I_ UPD_NEW_IND_ctr;
715 extern I_ UPD_NEW_IN_PLACE_PTRS_ctr;
716 extern I_ UPD_NEW_IN_PLACE_NOPTRS_ctr;
717 extern I_ UPD_OLD_IND_ctr;
718 extern I_ UPD_OLD_IN_PLACE_PTRS_ctr;
719 extern I_ UPD_OLD_IN_PLACE_NOPTRS_ctr;
721 extern I_ UPD_IN_PLACE_COPY_ctr; /* see below */
723 extern I_ GC_SEL_ABANDONED_ctr;
724 extern I_ GC_SEL_MINOR_ctr;
725 extern I_ GC_SEL_MAJOR_ctr;
726 extern I_ GC_SHORT_IND_ctr;
727 extern I_ GC_SHORT_CAF_ctr;
728 extern I_ GC_COMMON_CHARLIKE_ctr;
729 extern I_ GC_COMMON_INTLIKE_ctr;
730 extern I_ GC_COMMON_INTLIKE_FAIL_ctr;
731 extern I_ GC_COMMON_CONST_ctr;
733 #endif /* TICKY_TICKY */
736 %************************************************************************
738 \subsection[Ticky-nonmacros]{Un-macros for ``none of the above''}
740 %************************************************************************
745 #define ALLOC_HEAP(n) /* nothing */
746 #define UN_ALLOC_HEAP(n) /* nothing */
747 #define DO_ASTK_HWM() /* nothing */
748 #define DO_BSTK_HWM() /* nothing */
750 #define A_STK_STUB(n) /* nothing */
751 #define A_STK_REUSE(n) /* not used at all */
752 #define B_STK_REUSE(n) /* not used at all */
754 #define ALLOC_FUN(a,g,s,t) /* nothing */
755 #define ALLOC_THK(a,g,s,t) /* nothing */
756 #define ALLOC_CON(a,g,s,t) /* nothing */
757 #define ALLOC_TUP(a,g,s,t) /* nothing */
758 #define ALLOC_BH(a,g,s,t) /* nothing */
759 /*#define ALLOC_PAP(a,g,s,t) /? nothing */
760 #define ALLOC_PRIM(a,g,s,t) /* nothing */
761 #define ALLOC_PRIM2(w) /* nothing */
762 #define ALLOC_UPD_PAP(a,g,s,t) /* nothing */
763 /*#define ALLOC_UPD_CON(a,g,s,t) /? nothing */
764 #define ALLOC_STK(a,g,s) /* nothing */
765 #define ALLOC_TSO(a,g,s) /* nothing */
766 #define ALLOC_FMBQ(a,g,s) /* nothing */
767 #define ALLOC_FME(a,g,s) /* nothing */
768 #define ALLOC_BF(a,g,s) /* nothing */
770 #define ENT_VIA_NODE() /* nothing */
771 #define ENT_THK() /* nothing */
772 #define ENT_FUN_STD() /* nothing */
773 #define ENT_FUN_DIRECT(f,f_str,f_arity,Aargs,Bargs,arg_kinds,wrap,wrap_kinds) \
775 #define ENT_CON(n) /* nothing */
776 #define ENT_IND(n) /* nothing */
777 #define ENT_PAP(n) /* nothing */
779 #define RET_NEW_IN_HEAP(n) /* nothing */
780 #define RET_NEW_IN_REGS(n) /* nothing */
781 #define RET_OLD_IN_HEAP(n) /* nothing */
782 #define RET_OLD_IN_REGS(n) /* nothing */
783 #define RET_SEMI_BY_DEFAULT() /* nothing */
784 #define RET_SEMI_IN_HEAP(n) /* nothing */
785 #define RET_SEMI_IN_REGS(n,u) /* nothing */
786 #define RET_SEMI_FAILED(t) /* nothing */
787 #define VEC_RETURN(n) /* nothing */
789 #define UPDF_OMITTED() /* nothing */
790 #define UPDF_STD_PUSHED() /* nothing */
791 #define UPDF_CON_PUSHED() /* nothing */
792 #define UPDF_HOLE_PUSHED() /* nothing */
794 #define UPDF_RCC_PUSHED() /* nothing */
795 #define UPDF_RCC_OMITTED() /* nothing */
797 #define UPD_EXISTING() /* nothing */
798 #define UPD_SQUEEZED() /* nothing */
799 #define UPD_CON_W_NODE() /* nothing */
800 #define UPD_CON_IN_PLACE(n) /* nothing */
801 #define UPD_PAP_IN_PLACE() /* nothing */
802 #define UPD_CON_IN_NEW(n) /* nothing */
803 #define UPD_PAP_IN_NEW(n) /* nothing */
805 #define GC_SEL_ABANDONED() /* nothing */
806 #define GC_SEL_MINOR() /* nothing */
807 #define GC_SEL_MAJOR() /* nothing */
809 #define GC_SHORT_IND() /* nothing */
810 #define GC_SHORT_CAF() /* nothing */
811 #define GC_COMMON_CHARLIKE() /* nothing */
812 #define GC_COMMON_INTLIKE() /* nothing */
813 #define GC_COMMON_INTLIKE_FAIL()/* nothing */
814 #define GC_COMMON_CONST() /* nothing */
817 For a generational collector:
819 #define UPD_NEW_IND() /* nothing */
820 #define UPD_NEW_IN_PLACE_PTRS() /* nothing */
821 #define UPD_NEW_IN_PLACE_NOPTRS() /* nothing */
822 #define UPD_OLD_IND() /* nothing */
823 #define UPD_OLD_IN_PLACE_PTRS() /* nothing */
824 #define UPD_OLD_IN_PLACE_NOPTRS() /* nothing */
826 #endif /* <none-of-the-above> */
829 End of file multi-slurp protection:
831 #endif /* ! TICKY_H */