Ticky.c 20.4 KB
Newer Older
1 2
/* -----------------------------------------------------------------------------
 *
3 4
 * (c) The AQUA project, Glasgow University, 1992-1997
 * (c) The GHC Team, 1998-1999
5 6 7 8 9
 *
 * Ticky-ticky profiling
 *-------------------------------------------------------------------------- */

#define TICKY_C			/* define those variables */
10
#include "PosixSource.h"
11
#include "Rts.h"
Simon Marlow's avatar
Simon Marlow committed
12

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/* Catch-all top-level counter struct.  Allocations from CAFs will go
 * here.
 */
StgEntCounter top_ct
        = { 0, 0, 0,
	    "TOP", "",
	    0, 0, NULL };

/* Data structure used in ``registering'' one of these counters. */

StgEntCounter *ticky_entry_ctrs = NULL; /* root of list of them */

/* We want Haskell code compiled with -ticky to be linkable with any
 * version of the RTS, so we have to make sure all the symbols that
 * ticky-compiled code may refer to are defined by every RTS. (#3439)
 * Hence the #ifdef is here, rather than up above.
 */
#if defined(TICKY_TICKY)

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#include "Ticky.h"

/* -----------------------------------------------------------------------------
   Print out all the counters
   -------------------------------------------------------------------------- */

static void printRegisteredCounterInfo (FILE *); /* fwd decl */

#define INTAVG(a,b) ((b == 0) ? 0.0 : ((double) (a) / (double) (b)))
#define PC(a)	    (100.0 * a)

#define AVG(thing) \
	StgDouble avg##thing  = INTAVG(tot##thing,ctr##thing)

void
PrintTickyInfo(void)
{
49 50
  // XXX This is only used in commented out or #if FALSE'd out code currently:
  // unsigned long i;
51

52 53
/* XXX These are used only in an #if FALSE block below */
#if FALSE
54
  unsigned long tot_allocs = /* total number of things allocated */
55
	ALLOC_FUN_ctr + ALLOC_SE_THK_ctr + ALLOC_UP_THK_ctr + ALLOC_CON_ctr + ALLOC_TUP_ctr +
56 57
    	+ ALLOC_TSO_ctr + ALLOC_BH_ctr  + ALLOC_PAP_ctr + ALLOC_PRIM_ctr
      ;	
58 59

  unsigned long tot_adm_wds = /* total number of admin words allocated */
60 61 62
	ALLOC_FUN_adm + ALLOC_THK_adm + ALLOC_CON_adm + ALLOC_TUP_adm
    	+ ALLOC_TSO_adm + ALLOC_BH_adm  + ALLOC_PAP_adm + ALLOC_PRIM_adm
      ;
63 64

  unsigned long tot_gds_wds = /* total number of words of ``good stuff'' allocated */
65 66 67
	ALLOC_FUN_gds + ALLOC_THK_gds + ALLOC_CON_gds + ALLOC_TUP_gds
    	+ ALLOC_TSO_gds + ALLOC_BH_gds  + ALLOC_PAP_gds + ALLOC_PRIM_gds
      ;
68 69

  unsigned long tot_slp_wds = /* total number of ``slop'' words allocated */
70 71 72
	ALLOC_FUN_slp + ALLOC_THK_slp + ALLOC_CON_slp + ALLOC_TUP_slp
    	+ ALLOC_TSO_slp + ALLOC_BH_slp  + ALLOC_PAP_slp + ALLOC_PRIM_slp
      ;
73 74 75

  unsigned long tot_wds = /* total words */
	tot_adm_wds + tot_gds_wds + tot_slp_wds;
76
#endif
77

njn's avatar
njn committed
78 79
  unsigned long tot_thk_enters = ENT_STATIC_THK_ctr + ENT_DYN_THK_ctr;
  unsigned long tot_con_enters = ENT_STATIC_CON_ctr + ENT_DYN_CON_ctr;
80

njn's avatar
njn committed
81 82 83
  unsigned long tot_fun_direct_enters = ENT_STATIC_FUN_DIRECT_ctr + ENT_DYN_FUN_DIRECT_ctr;
  unsigned long tot_ind_enters = ENT_STATIC_IND_ctr + ENT_DYN_IND_ctr;
  
84 85 86
  // This is the number of times we entered a function via some kind
  // of slow call.  It amounts to all the slow applications, not
  // counting those that were to too few arguments.
87 88
  /*
  XXX This us unused - can we delete it? -- IGL 2008-04-25
89 90 91 92
  unsigned long tot_fun_slow_enters = 
      SLOW_CALL_ctr - 
      SLOW_CALL_FUN_TOO_FEW_ctr -
      SLOW_CALL_PAP_TOO_FEW_ctr;
93
  */
94 95 96 97 98 99

  unsigned long tot_known_calls =
      KNOWN_CALL_ctr + KNOWN_CALL_TOO_FEW_ARGS_ctr + 
      + KNOWN_CALL_EXTRA_ARGS_ctr;
  unsigned long tot_tail_calls =
      UNKNOWN_CALL_ctr + tot_known_calls;
100

101 102
  unsigned long tot_enters = 
      tot_con_enters + tot_fun_direct_enters +
njn's avatar
njn committed
103
	tot_ind_enters + ENT_PERM_IND_ctr + ENT_PAP_ctr + tot_thk_enters;
104 105 106
  unsigned long jump_direct_enters =
	tot_enters - ENT_VIA_NODE_ctr;

107

108
  unsigned long tot_returns =
109
      RET_NEW_ctr + RET_OLD_ctr + RET_UNBOXED_TUP_ctr;
110 111 112

  unsigned long tot_returns_of_new = RET_NEW_ctr;

113
  unsigned long con_updates = UPD_CON_IN_NEW_ctr + UPD_CON_IN_PLACE_ctr;
114 115
  unsigned long pap_updates = UPD_PAP_IN_NEW_ctr + UPD_PAP_IN_PLACE_ctr;

116
  unsigned long tot_updates = UPD_SQUEEZED_ctr + pap_updates + con_updates;
117

118 119
  unsigned long tot_new_updates   = UPD_NEW_IND_ctr + UPD_NEW_PERM_IND_ctr;
  unsigned long tot_old_updates   = UPD_OLD_IND_ctr + UPD_OLD_PERM_IND_ctr;
120 121 122 123
  unsigned long tot_gengc_updates = tot_new_updates + tot_old_updates;

  FILE *tf = RtsFlags.TickyFlags.tickyFile;

124 125 126 127 128 129 130 131
  /* If tf = NULL, that means the user passed in stderr for the ticky stats
     file. According to a comment in RtsFlags.c, this means to use 
     debugBelch to print out messages. But this function prints out a lot
     of stuff so in order to avoid changing a lot of code, we just dump
     the same output to stderr (for now). */
  if( tf == NULL )
    tf = stderr;

132 133
  /* krc: avoid dealing with this just now */
#if FALSE
134 135 136 137 138 139 140 141 142 143 144
  fprintf(tf,"\n\nALLOCATIONS: %ld (%ld words total: %ld admin, %ld goods, %ld slop)\n",
	  tot_allocs, tot_wds, tot_adm_wds, tot_gds_wds, tot_slp_wds);
  fprintf(tf,"\t\t\t\ttotal words:\t    2     3     4     5    6+\n");

#define ALLOC_HISTO_MAGIC(categ) \
	(PC(INTAVG(ALLOC_##categ##_hst[0], ALLOC_##categ##_ctr))), \
	(PC(INTAVG(ALLOC_##categ##_hst[1], ALLOC_##categ##_ctr))), \
	(PC(INTAVG(ALLOC_##categ##_hst[2], ALLOC_##categ##_ctr))), \
	(PC(INTAVG(ALLOC_##categ##_hst[3], ALLOC_##categ##_ctr))), \
	(PC(INTAVG(ALLOC_##categ##_hst[4], ALLOC_##categ##_ctr)))

nfrisby's avatar
nfrisby committed
145
  fprintf(tf,"%11ld (%5.1f%%) function values",
146 147 148 149
	ALLOC_FUN_ctr,
	PC(INTAVG(ALLOC_FUN_ctr, tot_allocs)));
  if (ALLOC_FUN_ctr != 0)
      fprintf(tf,"\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(FUN));
150
 
151

nfrisby's avatar
nfrisby committed
152
  fprintf(tf,"\n%11ld (%5.1f%%) thunks",
153 154 155 156 157 158
	ALLOC_SE_THK_ctr + ALLOC_UP_THK_ctr,
	PC(INTAVG(ALLOC_SE_THK_ctr + ALLOC_UP_THK_ctr, tot_allocs)));

#define ALLOC_THK_ctr (ALLOC_UP_THK_ctr + ALLOC_SE_THK_ctr)
  /* hack to make ALLOC_HISTO_MAGIC still work for THK */
  if ((ALLOC_SE_THK_ctr + ALLOC_UP_THK_ctr) != 0)
159
      fprintf(tf,"\t\t\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(THK));
160
#undef ALLOC_THK_ctr
161

nfrisby's avatar
nfrisby committed
162
  fprintf(tf,"\n%11ld (%5.1f%%) data values",
163 164 165 166 167
	ALLOC_CON_ctr,
	PC(INTAVG(ALLOC_CON_ctr, tot_allocs)));
  if (ALLOC_CON_ctr != 0)
      fprintf(tf,"\t\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(CON));

nfrisby's avatar
nfrisby committed
168
  fprintf(tf,"\n%11ld (%5.1f%%) big tuples",
169 170 171 172 173
	ALLOC_TUP_ctr,
	PC(INTAVG(ALLOC_TUP_ctr, tot_allocs)));
  if (ALLOC_TUP_ctr != 0)
      fprintf(tf,"\t\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(TUP));

nfrisby's avatar
nfrisby committed
174
  fprintf(tf,"\n%11ld (%5.1f%%) black holes",
175 176 177 178 179
	ALLOC_BH_ctr,
	PC(INTAVG(ALLOC_BH_ctr, tot_allocs)));
  if (ALLOC_BH_ctr != 0)
      fprintf(tf,"\t\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(BH));

nfrisby's avatar
nfrisby committed
180
  fprintf(tf,"\n%11ld (%5.1f%%) prim things",
181 182 183 184 185
	ALLOC_PRIM_ctr,
	PC(INTAVG(ALLOC_PRIM_ctr, tot_allocs)));
  if (ALLOC_PRIM_ctr != 0)
      fprintf(tf,"\t\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(PRIM));

nfrisby's avatar
nfrisby committed
186
  fprintf(tf,"\n%11ld (%5.1f%%) partial applications",
187 188 189 190
	ALLOC_PAP_ctr,
	PC(INTAVG(ALLOC_PAP_ctr, tot_allocs)));
  if (ALLOC_PAP_ctr != 0)
      fprintf(tf,"\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(PAP));
191

nfrisby's avatar
nfrisby committed
192
  fprintf(tf,"\n%11ld (%5.1f%%) thread state objects",
193 194 195 196
	ALLOC_TSO_ctr,
	PC(INTAVG(ALLOC_TSO_ctr, tot_allocs)));
  if (ALLOC_TSO_ctr != 0)
      fprintf(tf,"\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(TSO));
197

198 199 200
  fprintf(tf,"\n");

  fprintf(tf,"\nTotal storage-manager allocations: %ld (%ld words)\n\t[%ld words lost to speculative heap-checks]\n", ALLOC_HEAP_ctr, ALLOC_HEAP_tot, ALLOC_HEAP_tot - tot_wds);
201 202
#endif /* FALSE */

203 204 205

  fprintf(tf,"\nSTACK USAGE:\n"); /* NB: some bits are direction sensitive */

206

207 208 209 210
  fprintf(tf,"\nENTERS: %ld  of which %ld (%.1f%%) direct to the entry code\n\t\t  [the rest indirected via Node's info ptr]\n",
	tot_enters,
	jump_direct_enters,
	PC(INTAVG(jump_direct_enters,tot_enters)));
nfrisby's avatar
nfrisby committed
211
  fprintf(tf,"%11ld (%5.1f%%) thunks\n",
njn's avatar
njn committed
212 213
	tot_thk_enters,
	PC(INTAVG(tot_thk_enters,tot_enters)));
nfrisby's avatar
nfrisby committed
214
  fprintf(tf,"%11ld (%5.1f%%) data values\n",
njn's avatar
njn committed
215 216
	tot_con_enters,
	PC(INTAVG(tot_con_enters,tot_enters)));
nfrisby's avatar
nfrisby committed
217
  fprintf(tf,"%11ld (%5.1f%%) normal indirections\n",
njn's avatar
njn committed
218 219
	tot_ind_enters,
	PC(INTAVG(tot_ind_enters,tot_enters)));
nfrisby's avatar
nfrisby committed
220
  fprintf(tf,"%11" FMT_Int " (%5.1f%%) permanent indirections\n",
221 222
	ENT_PERM_IND_ctr,
	PC(INTAVG(ENT_PERM_IND_ctr,tot_enters)));
223

224

225 226 227 228 229 230
  fprintf(tf,"\nFUNCTION ENTRIES: %ld\n", tot_fun_direct_enters);

  fprintf(tf, "\nTAIL CALLS: %ld, of which %ld (%.lf%%) were to known functions\n", 
	  tot_tail_calls, tot_known_calls,
	  PC(INTAVG(tot_known_calls,tot_tail_calls)));

Ian Lynagh's avatar
Ian Lynagh committed
231
  fprintf(tf, "\nSLOW APPLICATIONS: %" FMT_Int " evaluated, %" FMT_Int " unevaluated\n",
232 233 234
	  SLOW_CALL_ctr, SLOW_CALL_UNEVALD_ctr);
  fprintf(tf, "\n");
  fprintf(tf, "         Too few args   Correct args   Too many args\n");
Ian Lynagh's avatar
Ian Lynagh committed
235
  fprintf(tf, "   FUN     %8" FMT_Int "       %8" FMT_Int "        %8" FMT_Int "\n", 
236
	  SLOW_CALL_FUN_TOO_FEW_ctr, SLOW_CALL_FUN_CORRECT_ctr, SLOW_CALL_FUN_TOO_MANY_ctr);
Ian Lynagh's avatar
Ian Lynagh committed
237
  fprintf(tf, "   PAP     %8" FMT_Int "       %8" FMT_Int "        %8" FMT_Int "\n", 
238 239
	  SLOW_CALL_PAP_TOO_FEW_ctr, SLOW_CALL_PAP_CORRECT_ctr, SLOW_CALL_PAP_TOO_MANY_ctr);
  fprintf(tf, "\n");
240

241
  fprintf(tf,"\nRETURNS: %ld\n", tot_returns);
nfrisby's avatar
nfrisby committed
242
  fprintf(tf,"%11ld (%5.1f%%) from entering a new constructor\n\t\t  [the rest from entering an existing constructor]\n",
243 244 245
	tot_returns_of_new,
	PC(INTAVG(tot_returns_of_new,tot_returns)));

246 247 248
  /* krc: comment out some of this stuff temporarily */

  /*
nfrisby's avatar
nfrisby committed
249
  fprintf(tf, "\nRET_NEW:         %11ld: ", RET_NEW_ctr);
250 251 252
  for (i = 0; i < 9; i++) { fprintf(tf, "%5.1f%%",
				PC(INTAVG(RET_NEW_hst[i],RET_NEW_ctr))); }
  fprintf(tf, "\n");
nfrisby's avatar
nfrisby committed
253
  fprintf(tf, "RET_OLD:         %11ld: ", RET_OLD_ctr);
254 255 256
  for (i = 0; i < 9; i++) { fprintf(tf, "%5.1f%%",
				PC(INTAVG(RET_OLD_hst[i],RET_OLD_ctr))); }
  fprintf(tf, "\n");
nfrisby's avatar
nfrisby committed
257
  fprintf(tf, "RET_UNBOXED_TUP: %11ld: ", RET_UNBOXED_TUP_ctr);
258 259 260 261
  for (i = 0; i < 9; i++) { fprintf(tf, "%5.1f%%",
				    PC(INTAVG(RET_UNBOXED_TUP_hst[i],
					      RET_UNBOXED_TUP_ctr))); }
  fprintf(tf, "\n");
262
  */
263

Ian Lynagh's avatar
Ian Lynagh committed
264
  fprintf(tf,"\nUPDATE FRAMES: %" FMT_Int " (%" FMT_Int " omitted from thunks)",
265 266 267
	UPDF_PUSHED_ctr,
	UPDF_OMITTED_ctr);

Ian Lynagh's avatar
Ian Lynagh committed
268
  fprintf(tf,"\nCATCH FRAMES:  %" FMT_Int "", CATCHF_PUSHED_ctr);
269 270

  if (UPDF_RCC_PUSHED_ctr != 0)
nfrisby's avatar
nfrisby committed
271
     fprintf(tf,"%11" FMT_Int " restore cost centre frames (%" FMT_Int " omitted)\n",
272 273 274 275
	UPDF_RCC_PUSHED_ctr,
	UPDF_RCC_OMITTED_ctr);

  fprintf(tf,"\nUPDATES: %ld\n", tot_updates);
nfrisby's avatar
nfrisby committed
276
  fprintf(tf,"%11ld (%5.1f%%) data values\n\t\t  [%" FMT_Int " in place, %" FMT_Int " allocated new space]\n",
277 278 279
	con_updates,
	PC(INTAVG(con_updates,tot_updates)),
	UPD_CON_IN_PLACE_ctr, UPD_CON_IN_NEW_ctr);
nfrisby's avatar
nfrisby committed
280
  fprintf(tf,"%11ld (%5.1f%%) partial applications\n\t\t  [%" FMT_Int " in place, %" FMT_Int " allocated new space]\n",
281 282 283
	pap_updates,
	PC(INTAVG(pap_updates,tot_updates)),
	UPD_PAP_IN_PLACE_ctr, UPD_PAP_IN_NEW_ctr);
nfrisby's avatar
nfrisby committed
284
  fprintf(tf,"%11" FMT_Int " (%5.1f%%) updates by squeezing\n",
285 286
	UPD_SQUEEZED_ctr,
	PC(INTAVG(UPD_SQUEEZED_ctr, tot_updates)));
287

288 289
  /* krc: also avoid dealing with this for now */
#if FALSE
nfrisby's avatar
nfrisby committed
290 291
  fprintf(tf, "\nUPD_CON_IN_NEW:   %11ld: ", UPD_CON_IN_NEW_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%11ld", UPD_CON_IN_NEW_hst[i]); }
292
  fprintf(tf, "\n");
nfrisby's avatar
nfrisby committed
293 294
  fprintf(tf, "UPD_CON_IN_PLACE: %11ld: ", UPD_CON_IN_PLACE_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%11ld", UPD_CON_IN_PLACE_hst[i]); }
295
  fprintf(tf, "\n");
nfrisby's avatar
nfrisby committed
296 297
  fprintf(tf, "UPD_PAP_IN_NEW:   %11ld: ", UPD_PAP_IN_NEW_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%11ld", UPD_PAP_IN_NEW_hst[i]); }
298
  fprintf(tf, "\n");
299
#endif
300 301

  if (tot_gengc_updates != 0) {
302
      fprintf(tf,"\nNEW GEN UPDATES: %9ld (%5.1f%%)\n",
303 304
	      tot_new_updates,
	      PC(INTAVG(tot_new_updates,tot_gengc_updates)));
305
      fprintf(tf,"OLD GEN UPDATES: %9ld (%5.1f%%)\n",
306 307 308 309 310 311 312 313 314 315 316 317 318 319
	      tot_old_updates,
	      PC(INTAVG(tot_old_updates,tot_gengc_updates)));
  }

  printRegisteredCounterInfo(tf);

  fprintf(tf,"\n**************************************************\n");

  /* here, we print out all the raw numbers; these are really
    more useful when we want to snag them for subsequent
    rdb-etc processing. WDP 95/11
  */

#define PR_CTR(ctr) \
nfrisby's avatar
nfrisby committed
320
  do { fprintf(tf,"%11" FMT_Int " " #ctr "\n", ctr); } while(0)
321 322
/* COND_PR_CTR takes a boolean; if false then msg is the printname rather than ctr */
#define COND_PR_CTR(ctr,b,msg) \
nfrisby's avatar
nfrisby committed
323
    if (b) { fprintf(tf,"%11" FMT_Int " " #ctr "\n", ctr); } else { fprintf(tf,"%11" FMT_Int " " msg "\n", ctr); }
324
#define PR_HST(hst,i) \
nfrisby's avatar
nfrisby committed
325 326 327 328
  do { fprintf(tf,"%11ld " #hst "_" #i "\n", hst[i]); } while(0)

  ALLOC_HEAP_ctr = (StgInt)ALLOC_HEAP_ctr + (StgInt)ALLOC_RTS_ctr;
  ALLOC_HEAP_tot = (StgInt)ALLOC_HEAP_tot + (StgInt)ALLOC_RTS_tot;
329 330 331 332

  PR_CTR(ALLOC_HEAP_ctr);
  PR_CTR(ALLOC_HEAP_tot);

333 334 335
  PR_CTR(HEAP_CHK_ctr);
  PR_CTR(STK_CHK_ctr);

nfrisby's avatar
nfrisby committed
336 337 338
  PR_CTR(ALLOC_RTS_ctr);
  PR_CTR(ALLOC_RTS_tot);

339 340
  PR_CTR(ALLOC_FUN_ctr);
  PR_CTR(ALLOC_FUN_gds);
nfrisby's avatar
nfrisby committed
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355

  PR_CTR(ALLOC_PAP_ctr);
  PR_CTR(ALLOC_PAP_adm);
  PR_CTR(ALLOC_PAP_gds);

  PR_CTR(ALLOC_UP_THK_ctr);
  PR_CTR(ALLOC_SE_THK_ctr);
  PR_CTR(ALLOC_THK_gds);

  PR_CTR(ALLOC_CON_ctr);
  PR_CTR(ALLOC_CON_gds);

  PR_CTR(ALLOC_PRIM_ctr);
  PR_CTR(ALLOC_PRIM_gds);
  PR_CTR(ALLOC_PRIM_slp);
356 357

  /* krc: comment out some of this stuff temporarily
358 359 360 361 362
  PR_HST(ALLOC_FUN_hst,0);
  PR_HST(ALLOC_FUN_hst,1);
  PR_HST(ALLOC_FUN_hst,2);
  PR_HST(ALLOC_FUN_hst,3);
  PR_HST(ALLOC_FUN_hst,4);
363 364
  PR_CTR(ALLOC_UP_THK_ctr);
  PR_CTR(ALLOC_SE_THK_ctr);
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
  PR_CTR(ALLOC_THK_adm);
  PR_CTR(ALLOC_THK_gds);
  PR_CTR(ALLOC_THK_slp);
  PR_HST(ALLOC_THK_hst,0);
  PR_HST(ALLOC_THK_hst,1);
  PR_HST(ALLOC_THK_hst,2);
  PR_HST(ALLOC_THK_hst,3);
  PR_HST(ALLOC_THK_hst,4);
  PR_CTR(ALLOC_CON_ctr);
  PR_CTR(ALLOC_CON_adm);
  PR_CTR(ALLOC_CON_gds);
  PR_CTR(ALLOC_CON_slp);
  PR_HST(ALLOC_CON_hst,0);
  PR_HST(ALLOC_CON_hst,1);
  PR_HST(ALLOC_CON_hst,2);
  PR_HST(ALLOC_CON_hst,3);
  PR_HST(ALLOC_CON_hst,4);
  PR_CTR(ALLOC_TUP_ctr);
  PR_CTR(ALLOC_TUP_adm);
  PR_CTR(ALLOC_TUP_gds);
  PR_CTR(ALLOC_TUP_slp);
  PR_HST(ALLOC_TUP_hst,0);
  PR_HST(ALLOC_TUP_hst,1);
  PR_HST(ALLOC_TUP_hst,2);
  PR_HST(ALLOC_TUP_hst,3);
  PR_HST(ALLOC_TUP_hst,4);
  PR_CTR(ALLOC_BH_ctr);
  PR_CTR(ALLOC_BH_adm);
  PR_CTR(ALLOC_BH_gds);
  PR_CTR(ALLOC_BH_slp);
  PR_HST(ALLOC_BH_hst,0);
  PR_HST(ALLOC_BH_hst,1);
  PR_HST(ALLOC_BH_hst,2);
  PR_HST(ALLOC_BH_hst,3);
  PR_HST(ALLOC_BH_hst,4);
  PR_CTR(ALLOC_PRIM_ctr);
  PR_CTR(ALLOC_PRIM_adm);
  PR_CTR(ALLOC_PRIM_gds);
  PR_CTR(ALLOC_PRIM_slp);
  PR_HST(ALLOC_PRIM_hst,0);
  PR_HST(ALLOC_PRIM_hst,1);
  PR_HST(ALLOC_PRIM_hst,2);
  PR_HST(ALLOC_PRIM_hst,3);
  PR_HST(ALLOC_PRIM_hst,4);
409 410 411 412 413 414
  PR_CTR(ALLOC_PAP_slp);
  PR_HST(ALLOC_PAP_hst,0);
  PR_HST(ALLOC_PAP_hst,1);
  PR_HST(ALLOC_PAP_hst,2);
  PR_HST(ALLOC_PAP_hst,3);
  PR_HST(ALLOC_PAP_hst,4);
415 416 417 418 419 420 421 422 423 424

  PR_CTR(ALLOC_TSO_ctr);
  PR_CTR(ALLOC_TSO_adm);
  PR_CTR(ALLOC_TSO_gds);
  PR_CTR(ALLOC_TSO_slp);
  PR_HST(ALLOC_TSO_hst,0);
  PR_HST(ALLOC_TSO_hst,1);
  PR_HST(ALLOC_TSO_hst,2);
  PR_HST(ALLOC_TSO_hst,3);
  PR_HST(ALLOC_TSO_hst,4);
425
  */
426 427

  PR_CTR(ENT_VIA_NODE_ctr);
njn's avatar
njn committed
428 429 430 431
  PR_CTR(ENT_STATIC_CON_ctr);
  PR_CTR(ENT_DYN_CON_ctr);
  PR_CTR(ENT_STATIC_FUN_DIRECT_ctr);
  PR_CTR(ENT_DYN_FUN_DIRECT_ctr);
nfrisby's avatar
nfrisby committed
432
  PR_CTR(ENT_LNE_ctr);
njn's avatar
njn committed
433 434
  PR_CTR(ENT_STATIC_IND_ctr);
  PR_CTR(ENT_DYN_IND_ctr);
435 436 437 438 439 440 441 442 443 444 445 446 447 448

/* The counters ENT_PERM_IND and UPD_{NEW,OLD}_PERM_IND are not dumped
 * at the end of execution unless update squeezing is turned off (+RTS
 * -Z =RtsFlags.GcFlags.squeezeUpdFrames), as they will be wrong
 * otherwise.  Why?  Because for each update frame squeezed out, we
 * count an UPD_NEW_PERM_IND *at GC time* (i.e., too early).  And
 * further, when we enter the closure that has been updated, we count
 * the ENT_PERM_IND, but we then enter the PERM_IND that was built for
 * the next update frame below, and so on down the chain until we
 * finally reach the value.  Thus we count many new ENT_PERM_INDs too
 * early.  
 * 
 * This of course refers to the -ticky version that uses PERM_INDs to
 * determine the number of closures entered 0/1/>1.  KSW 1999-04.  */
449
  COND_PR_CTR(ENT_PERM_IND_ctr,RtsFlags.GcFlags.squeezeUpdFrames == rtsFalse,"E!NT_PERM_IND_ctr requires +RTS -Z");
450

451
  PR_CTR(ENT_AP_ctr);
452
  PR_CTR(ENT_PAP_ctr);
453
  PR_CTR(ENT_AP_STACK_ctr);
454
  PR_CTR(ENT_BH_ctr);
njn's avatar
njn committed
455 456
  PR_CTR(ENT_STATIC_THK_ctr);
  PR_CTR(ENT_DYN_THK_ctr);
457

nfrisby's avatar
nfrisby committed
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
  PR_CTR(SLOW_CALL_fast_v16_ctr);
  PR_CTR(SLOW_CALL_fast_v_ctr);
  PR_CTR(SLOW_CALL_fast_f_ctr);
  PR_CTR(SLOW_CALL_fast_d_ctr);
  PR_CTR(SLOW_CALL_fast_l_ctr);
  PR_CTR(SLOW_CALL_fast_n_ctr);
  PR_CTR(SLOW_CALL_fast_p_ctr);
  PR_CTR(SLOW_CALL_fast_pv_ctr);
  PR_CTR(SLOW_CALL_fast_pp_ctr);
  PR_CTR(SLOW_CALL_fast_ppv_ctr);
  PR_CTR(SLOW_CALL_fast_ppp_ctr);
  PR_CTR(SLOW_CALL_fast_pppv_ctr);
  PR_CTR(SLOW_CALL_fast_pppp_ctr);
  PR_CTR(SLOW_CALL_fast_ppppp_ctr);
  PR_CTR(SLOW_CALL_fast_pppppp_ctr);
  PR_CTR(VERY_SLOW_CALL_ctr);
474 475 476 477 478 479 480

  PR_CTR(UNKNOWN_CALL_ctr);
  PR_CTR(KNOWN_CALL_ctr);
  PR_CTR(KNOWN_CALL_TOO_FEW_ARGS_ctr);
  PR_CTR(KNOWN_CALL_EXTRA_ARGS_ctr);
  PR_CTR(MULTI_CHUNK_SLOW_CALL_ctr);
  PR_CTR(MULTI_CHUNK_SLOW_CALL_CHUNKS_ctr);
481
  PR_CTR(SLOW_CALL_ctr);
482 483 484 485 486 487 488
  PR_CTR(SLOW_CALL_FUN_TOO_FEW_ctr);
  PR_CTR(SLOW_CALL_FUN_CORRECT_ctr);
  PR_CTR(SLOW_CALL_FUN_TOO_MANY_ctr);
  PR_CTR(SLOW_CALL_PAP_TOO_FEW_ctr);
  PR_CTR(SLOW_CALL_PAP_CORRECT_ctr);
  PR_CTR(SLOW_CALL_PAP_TOO_MANY_ctr);
  PR_CTR(SLOW_CALL_UNEVALD_ctr);
489 490 491

  /* krc: put off till later... */
#if FALSE
492 493 494 495 496 497 498 499
  PR_HST(SLOW_CALL_hst,0);
  PR_HST(SLOW_CALL_hst,1);
  PR_HST(SLOW_CALL_hst,2);
  PR_HST(SLOW_CALL_hst,3);
  PR_HST(SLOW_CALL_hst,4);
  PR_HST(SLOW_CALL_hst,5);
  PR_HST(SLOW_CALL_hst,6);
  PR_HST(SLOW_CALL_hst,7);
500
#endif
501

502 503
  PR_CTR(RET_NEW_ctr);
  PR_CTR(RET_OLD_ctr);
504
  PR_CTR(RET_UNBOXED_TUP_ctr);
505

506 507
  /* krc: put off till later... */
#if FALSE
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
  PR_HST(RET_NEW_hst,0);
  PR_HST(RET_NEW_hst,1);
  PR_HST(RET_NEW_hst,2);
  PR_HST(RET_NEW_hst,3);
  PR_HST(RET_NEW_hst,4);
  PR_HST(RET_NEW_hst,5);
  PR_HST(RET_NEW_hst,6);
  PR_HST(RET_NEW_hst,7);
  PR_HST(RET_NEW_hst,8);
  PR_HST(RET_OLD_hst,0);
  PR_HST(RET_OLD_hst,1);
  PR_HST(RET_OLD_hst,2);
  PR_HST(RET_OLD_hst,3);
  PR_HST(RET_OLD_hst,4);
  PR_HST(RET_OLD_hst,5);
  PR_HST(RET_OLD_hst,6);
  PR_HST(RET_OLD_hst,7);
  PR_HST(RET_OLD_hst,8);
526 527 528 529 530 531 532 533 534
  PR_HST(RET_UNBOXED_TUP_hst,0);
  PR_HST(RET_UNBOXED_TUP_hst,1);
  PR_HST(RET_UNBOXED_TUP_hst,2);
  PR_HST(RET_UNBOXED_TUP_hst,3);
  PR_HST(RET_UNBOXED_TUP_hst,4);
  PR_HST(RET_UNBOXED_TUP_hst,5);
  PR_HST(RET_UNBOXED_TUP_hst,6);
  PR_HST(RET_UNBOXED_TUP_hst,7);
  PR_HST(RET_UNBOXED_TUP_hst,8);
535
#endif /* FALSE */
536 537 538 539 540 541 542 543 544 545

  PR_CTR(UPDF_OMITTED_ctr);
  PR_CTR(UPDF_PUSHED_ctr);
  PR_CTR(CATCHF_PUSHED_ctr);

  PR_CTR(UPDF_RCC_PUSHED_ctr);
  PR_CTR(UPDF_RCC_OMITTED_ctr);

  PR_CTR(UPD_SQUEEZED_ctr);
  PR_CTR(UPD_CON_IN_NEW_ctr);
546
  PR_CTR(UPD_CON_IN_PLACE_ctr);
547
  PR_CTR(UPD_PAP_IN_NEW_ctr);
548
  PR_CTR(UPD_PAP_IN_PLACE_ctr);
549

550 551 552 553 554
  PR_CTR(UPD_BH_UPDATABLE_ctr);
  PR_CTR(UPD_BH_SINGLE_ENTRY_ctr);
  PR_CTR(UPD_CAF_BH_UPDATABLE_ctr);
  PR_CTR(UPD_CAF_BH_SINGLE_ENTRY_ctr);

555 556
  /* krc: put off till later...*/
#if FALSE
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
  PR_HST(UPD_CON_IN_NEW_hst,0);
  PR_HST(UPD_CON_IN_NEW_hst,1);
  PR_HST(UPD_CON_IN_NEW_hst,2);
  PR_HST(UPD_CON_IN_NEW_hst,3);
  PR_HST(UPD_CON_IN_NEW_hst,4);
  PR_HST(UPD_CON_IN_NEW_hst,5);
  PR_HST(UPD_CON_IN_NEW_hst,6);
  PR_HST(UPD_CON_IN_NEW_hst,7);
  PR_HST(UPD_CON_IN_NEW_hst,8);
  PR_HST(UPD_PAP_IN_NEW_hst,0);
  PR_HST(UPD_PAP_IN_NEW_hst,1);
  PR_HST(UPD_PAP_IN_NEW_hst,2);
  PR_HST(UPD_PAP_IN_NEW_hst,3);
  PR_HST(UPD_PAP_IN_NEW_hst,4);
  PR_HST(UPD_PAP_IN_NEW_hst,5);
  PR_HST(UPD_PAP_IN_NEW_hst,6);
  PR_HST(UPD_PAP_IN_NEW_hst,7);
  PR_HST(UPD_PAP_IN_NEW_hst,8);
575
#endif /* FALSE */
576 577

  PR_CTR(UPD_NEW_IND_ctr);
578
  /* see comment on ENT_PERM_IND_ctr */
579
  COND_PR_CTR(UPD_NEW_PERM_IND_ctr,RtsFlags.GcFlags.squeezeUpdFrames == rtsFalse,"U!PD_NEW_PERM_IND_ctr requires +RTS -Z");
580
  PR_CTR(UPD_OLD_IND_ctr);
581
  /* see comment on ENT_PERM_IND_ctr */
582
  COND_PR_CTR(UPD_OLD_PERM_IND_ctr,RtsFlags.GcFlags.squeezeUpdFrames == rtsFalse,"U!PD_OLD_PERM_IND_ctr requires +RTS -Z");
583 584 585 586 587 588 589 590 591 592 593 594

  PR_CTR(GC_SEL_ABANDONED_ctr);
  PR_CTR(GC_SEL_MINOR_ctr);
  PR_CTR(GC_SEL_MAJOR_ctr);
  PR_CTR(GC_FAILED_PROMOTION_ctr);
}

/* To print out all the registered-counter info: */

static void
printRegisteredCounterInfo (FILE *tf)
{
595
    StgEntCounter *p;
596

597
    if ( ticky_entry_ctrs != NULL ) {
nfrisby's avatar
nfrisby committed
598
      fprintf(tf,"\nThe following table is explained by http://hackage.haskell.org/trac/ghc/wiki/Debugging/TickyTicky\nAll allocation numbers are in bytes.\n");
599
      fprintf(tf,"\n**************************************************\n\n");
600
    }
nfrisby's avatar
nfrisby committed
601 602
    fprintf(tf, "%11s%11s%11s  %-23s %s\n",
	    "Entries", "Alloc", "Alloc'd", "Non-void Arguments", "STG Name");
603
    fprintf(tf, "--------------------------------------------------------------------------------\n");
604
    /* Function name at the end so it doesn't mess up the tabulation */
605

606
    for (p = ticky_entry_ctrs; p != NULL; p = p->link) {
nfrisby's avatar
nfrisby committed
607
	fprintf(tf, "%11" FMT_Int "%11" FMT_Int "%11" FMT_Int " %3lu %-20.20s %s",
608
		p->entry_count,
609
		p->allocs,
nfrisby's avatar
nfrisby committed
610
		p->allocd,
Simon Marlow's avatar
Simon Marlow committed
611
		(unsigned long)p->arity,
612
		p->arg_kinds,
613
		p->str);
614

615
	fprintf(tf, "\n");
616 617 618 619

    }
}
#endif /* TICKY_TICKY */
620