Ticky.c 20.5 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 10 11
 *
 * Ticky-ticky profiling
 *-------------------------------------------------------------------------- */

#if defined(TICKY_TICKY)

#define TICKY_C			/* define those variables */
12
#include "PosixSource.h"
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#include "Rts.h"
#include "RtsFlags.h"
#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)
{
  unsigned long i;
  unsigned long tot_allocs = /* total number of things allocated */
34
	ALLOC_FUN_ctr + ALLOC_SE_THK_ctr + ALLOC_UP_THK_ctr + ALLOC_CON_ctr + ALLOC_TUP_ctr +
35
    	+ ALLOC_TSO_ctr + ALLOC_BH_ctr  + ALLOC_PAP_ctr + ALLOC_PRIM_ctr
36
#ifdef PAR
37
	+ ALLOC_FMBQ_ctr + ALLOC_FME_ctr + ALLOC_BF_ctr
38
#endif
39
      ;	
40 41

  unsigned long tot_adm_wds = /* total number of admin words allocated */
42 43
	ALLOC_FUN_adm + ALLOC_THK_adm + ALLOC_CON_adm + ALLOC_TUP_adm
    	+ ALLOC_TSO_adm + ALLOC_BH_adm  + ALLOC_PAP_adm + ALLOC_PRIM_adm
44
#ifdef PAR
45
	+ ALLOC_FMBQ_adm + ALLOC_FME_adm + ALLOC_BF_adm
46
#endif
47
      ;
48 49

  unsigned long tot_gds_wds = /* total number of words of ``good stuff'' allocated */
50 51
	ALLOC_FUN_gds + ALLOC_THK_gds + ALLOC_CON_gds + ALLOC_TUP_gds
    	+ ALLOC_TSO_gds + ALLOC_BH_gds  + ALLOC_PAP_gds + ALLOC_PRIM_gds
52
#ifdef PAR
53
	+ ALLOC_FMBQ_gds + ALLOC_FME_gds + ALLOC_BF_gds
54
#endif
55
      ;
56 57

  unsigned long tot_slp_wds = /* total number of ``slop'' words allocated */
58 59
	ALLOC_FUN_slp + ALLOC_THK_slp + ALLOC_CON_slp + ALLOC_TUP_slp
    	+ ALLOC_TSO_slp + ALLOC_BH_slp  + ALLOC_PAP_slp + ALLOC_PRIM_slp
60
#ifdef PAR
61
	+ ALLOC_FMBQ_slp + ALLOC_FME_slp + ALLOC_BF_slp
62
#endif
63
      ;
64 65 66 67

  unsigned long tot_wds = /* total words */
	tot_adm_wds + tot_gds_wds + tot_slp_wds;

njn's avatar
njn committed
68 69 70 71 72
  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;
  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;
  
73 74 75 76 77 78 79 80 81 82 83 84 85
  // 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.
  unsigned long tot_fun_slow_enters = 
      SLOW_CALL_ctr - 
      SLOW_CALL_FUN_TOO_FEW_ctr -
      SLOW_CALL_PAP_TOO_FEW_ctr;

  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;
86

87
  unsigned long tot_enters =
njn's avatar
njn committed
88 89
	tot_con_enters + tot_fun_direct_enters +
	tot_ind_enters + ENT_PERM_IND_ctr + ENT_PAP_ctr + tot_thk_enters;
90 91 92 93
  unsigned long jump_direct_enters =
	tot_enters - ENT_VIA_NODE_ctr;

  unsigned long tot_returns =
94
      RET_NEW_ctr + RET_OLD_ctr + RET_UNBOXED_TUP_ctr;
95 96 97

  unsigned long tot_returns_of_new = RET_NEW_ctr;

98
  unsigned long con_updates = UPD_CON_IN_NEW_ctr + UPD_CON_IN_PLACE_ctr;
99 100
  unsigned long pap_updates = UPD_PAP_IN_NEW_ctr + UPD_PAP_IN_PLACE_ctr;

101
  unsigned long tot_updates = UPD_SQUEEZED_ctr + pap_updates + con_updates;
102

103 104
  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;
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
  unsigned long tot_gengc_updates = tot_new_updates + tot_old_updates;

  FILE *tf = RtsFlags.TickyFlags.tickyFile;

  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)))

  fprintf(tf,"%7ld (%5.1f%%) function values",
	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));

  fprintf(tf,"\n%7ld (%5.1f%%) thunks",
127 128 129 130 131 132
	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)
133
      fprintf(tf,"\t\t\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(THK));
134
#undef ALLOC_THK_ctr
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

  fprintf(tf,"\n%7ld (%5.1f%%) data values",
	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));

  fprintf(tf,"\n%7ld (%5.1f%%) big tuples",
	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));

  fprintf(tf,"\n%7ld (%5.1f%%) black holes",
	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));

  fprintf(tf,"\n%7ld (%5.1f%%) prim things",
	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));

  fprintf(tf,"\n%7ld (%5.1f%%) partial applications",
161 162 163 164
	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));
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198

  fprintf(tf,"\n%7ld (%5.1f%%) thread state objects",
	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));
#ifdef PAR
  fprintf(tf,"\n%7ld (%5.1f%%) thread state objects",
	ALLOC_FMBQ_ctr,
	PC(INTAVG(ALLOC_FMBQ_ctr, tot_allocs)));
  if (ALLOC_FMBQ_ctr != 0)
      fprintf(tf,"\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(FMBQ));
  fprintf(tf,"\n%7ld (%5.1f%%) thread state objects",
	ALLOC_FME_ctr,
	PC(INTAVG(ALLOC_FME_ctr, tot_allocs)));
  if (ALLOC_FME_ctr != 0)
      fprintf(tf,"\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(FME));
  fprintf(tf,"\n%7ld (%5.1f%%) thread state objects",
	ALLOC_BF_ctr,
	PC(INTAVG(ALLOC_BF_ctr, tot_allocs)));
  if (ALLOC_BF_ctr != 0)
      fprintf(tf,"\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(BF));
#endif
  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);

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

  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)));
  fprintf(tf,"%7ld (%5.1f%%) thunks\n",
njn's avatar
njn committed
199 200
	tot_thk_enters,
	PC(INTAVG(tot_thk_enters,tot_enters)));
201
  fprintf(tf,"%7ld (%5.1f%%) data values\n",
njn's avatar
njn committed
202 203
	tot_con_enters,
	PC(INTAVG(tot_con_enters,tot_enters)));
204
  fprintf(tf,"%7ld (%5.1f%%) normal indirections\n",
njn's avatar
njn committed
205 206
	tot_ind_enters,
	PC(INTAVG(tot_ind_enters,tot_enters)));
207 208 209
  fprintf(tf,"%7ld (%5.1f%%) permanent indirections\n",
	ENT_PERM_IND_ctr,
	PC(INTAVG(ENT_PERM_IND_ctr,tot_enters)));
210

211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
  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)));

  fprintf(tf, "\nSLOW APPLICATIONS: %ld evaluated, %ld unevaluated\n",
	  SLOW_CALL_ctr, SLOW_CALL_UNEVALD_ctr);
  fprintf(tf, "\n");
  fprintf(tf, "         Too few args   Correct args   Too many args\n");
  fprintf(tf, "   FUN     %8ld       %8ld        %8ld\n", 
	  SLOW_CALL_FUN_TOO_FEW_ctr, SLOW_CALL_FUN_CORRECT_ctr, SLOW_CALL_FUN_TOO_MANY_ctr);
  fprintf(tf, "   PAP     %8ld       %8ld        %8ld\n", 
	  SLOW_CALL_PAP_TOO_FEW_ctr, SLOW_CALL_PAP_CORRECT_ctr, SLOW_CALL_PAP_TOO_MANY_ctr);
  fprintf(tf, "\n");
226

227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
  fprintf(tf,"\nRETURNS: %ld\n", tot_returns);
  fprintf(tf,"%7ld (%5.1f%%) from entering a new constructor\n\t\t  [the rest from entering an existing constructor]\n",
	tot_returns_of_new,
	PC(INTAVG(tot_returns_of_new,tot_returns)));
  fprintf(tf,"%7ld (%5.1f%%) vectored [the rest unvectored]\n",
	VEC_RETURN_ctr,
	PC(INTAVG(VEC_RETURN_ctr,tot_returns)));

  fprintf(tf, "\nRET_NEW:         %7ld: ", RET_NEW_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%5.1f%%",
				PC(INTAVG(RET_NEW_hst[i],RET_NEW_ctr))); }
  fprintf(tf, "\n");
  fprintf(tf, "RET_OLD:         %7ld: ", RET_OLD_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%5.1f%%",
				PC(INTAVG(RET_OLD_hst[i],RET_OLD_ctr))); }
  fprintf(tf, "\n");
  fprintf(tf, "RET_UNBOXED_TUP: %7ld: ", RET_UNBOXED_TUP_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%5.1f%%",
				    PC(INTAVG(RET_UNBOXED_TUP_hst[i],
					      RET_UNBOXED_TUP_ctr))); }
  fprintf(tf, "\n");
  fprintf(tf, "\nRET_VEC_RETURN : %7ld: ", VEC_RETURN_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%5.1f%%",
				PC(INTAVG(RET_VEC_RETURN_hst[i],VEC_RETURN_ctr))); }
  fprintf(tf, "\n");

  fprintf(tf,"\nUPDATE FRAMES: %ld (%ld omitted from thunks)",
	UPDF_PUSHED_ctr,
	UPDF_OMITTED_ctr);

  fprintf(tf,"\nCATCH FRAMES:  %ld", CATCHF_PUSHED_ctr);

  if (UPDF_RCC_PUSHED_ctr != 0)
     fprintf(tf,"%7ld restore cost centre frames (%ld omitted)\n",
	UPDF_RCC_PUSHED_ctr,
	UPDF_RCC_OMITTED_ctr);

  fprintf(tf,"\nUPDATES: %ld\n", tot_updates);
265 266 267 268
  fprintf(tf,"%7ld (%5.1f%%) data values\n\t\t  [%ld in place, %ld allocated new space]\n",
	con_updates,
	PC(INTAVG(con_updates,tot_updates)),
	UPD_CON_IN_PLACE_ctr, UPD_CON_IN_NEW_ctr);
269 270 271 272
  fprintf(tf,"%7ld (%5.1f%%) partial applications\n\t\t  [%ld in place, %ld allocated new space]\n",
	pap_updates,
	PC(INTAVG(pap_updates,tot_updates)),
	UPD_PAP_IN_PLACE_ctr, UPD_PAP_IN_NEW_ctr);
273 274 275
  fprintf(tf,"%7ld (%5.1f%%) updates by squeezing\n",
	UPD_SQUEEZED_ctr,
	PC(INTAVG(UPD_SQUEEZED_ctr, tot_updates)));
276

277
  fprintf(tf, "\nUPD_CON_IN_NEW:   %7ld: ", UPD_CON_IN_NEW_ctr);
278 279
  for (i = 0; i < 9; i++) { fprintf(tf, "%7ld", UPD_CON_IN_NEW_hst[i]); }
  fprintf(tf, "\n");
280 281 282
  fprintf(tf, "UPD_CON_IN_PLACE: %7ld: ", UPD_CON_IN_PLACE_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%7ld", UPD_CON_IN_PLACE_hst[i]); }
  fprintf(tf, "\n");
283 284 285 286 287
  fprintf(tf, "UPD_PAP_IN_NEW:   %7ld: ", UPD_PAP_IN_NEW_ctr);
  for (i = 0; i < 9; i++) { fprintf(tf, "%7ld", UPD_PAP_IN_NEW_hst[i]); }
  fprintf(tf, "\n");

  if (tot_gengc_updates != 0) {
288
      fprintf(tf,"\nNEW GEN UPDATES: %9ld (%5.1f%%)\n",
289 290
	      tot_new_updates,
	      PC(INTAVG(tot_new_updates,tot_gengc_updates)));
291
      fprintf(tf,"OLD GEN UPDATES: %9ld (%5.1f%%)\n",
292 293 294 295
	      tot_old_updates,
	      PC(INTAVG(tot_old_updates,tot_gengc_updates)));
  }

296 297 298
  fprintf(tf,"\nTotal bytes copied during GC: %ld\n",
	  GC_WORDS_COPIED_ctr * sizeof(W_));

299 300 301 302 303 304 305 306 307 308 309
  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) \
  do { fprintf(tf,"%7ld " #ctr "\n", ctr); } while(0)
310 311 312
/* COND_PR_CTR takes a boolean; if false then msg is the printname rather than ctr */
#define COND_PR_CTR(ctr,b,msg) \
    if (b) { fprintf(tf,"%7ld " #ctr "\n", ctr); } else { fprintf(tf,"%7ld " msg "\n", ctr); }
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
#define PR_HST(hst,i) \
  do { fprintf(tf,"%7ld " #hst "_" #i "\n", hst[i]); } while(0)

  PR_CTR(ALLOC_HEAP_ctr);
  PR_CTR(ALLOC_HEAP_tot);

  PR_CTR(ALLOC_FUN_ctr);
  PR_CTR(ALLOC_FUN_adm);
  PR_CTR(ALLOC_FUN_gds);
  PR_CTR(ALLOC_FUN_slp);
  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);
328 329
  PR_CTR(ALLOC_UP_THK_ctr);
  PR_CTR(ALLOC_SE_THK_ctr);
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
  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);
374 375 376 377 378 379 380 381 382
  PR_CTR(ALLOC_PAP_ctr);
  PR_CTR(ALLOC_PAP_adm);
  PR_CTR(ALLOC_PAP_gds);
  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);
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 409 410 411 412 413 414 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);

#ifdef PAR
  PR_CTR(ALLOC_FMBQ_ctr);
  PR_CTR(ALLOC_FMBQ_adm);
  PR_CTR(ALLOC_FMBQ_gds);
  PR_CTR(ALLOC_FMBQ_slp);
  PR_HST(ALLOC_FMBQ_hst,0);
  PR_HST(ALLOC_FMBQ_hst,1);
  PR_HST(ALLOC_FMBQ_hst,2);
  PR_HST(ALLOC_FMBQ_hst,3);
  PR_HST(ALLOC_FMBQ_hst,4);
  PR_CTR(ALLOC_FME_ctr);
  PR_CTR(ALLOC_FME_adm);
  PR_CTR(ALLOC_FME_gds);
  PR_CTR(ALLOC_FME_slp);
  PR_HST(ALLOC_FME_hst,0);
  PR_HST(ALLOC_FME_hst,1);
  PR_HST(ALLOC_FME_hst,2);
  PR_HST(ALLOC_FME_hst,3);
  PR_HST(ALLOC_FME_hst,4);
  PR_CTR(ALLOC_BF_ctr);
  PR_CTR(ALLOC_BF_adm);
  PR_CTR(ALLOC_BF_gds);
  PR_CTR(ALLOC_BF_slp);
  PR_HST(ALLOC_BF_hst,0);
  PR_HST(ALLOC_BF_hst,1);
  PR_HST(ALLOC_BF_hst,2);
  PR_HST(ALLOC_BF_hst,3);
  PR_HST(ALLOC_BF_hst,4);
#endif

  PR_CTR(ENT_VIA_NODE_ctr);
njn's avatar
njn committed
425 426 427 428 429 430
  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);
  PR_CTR(ENT_STATIC_IND_ctr);
  PR_CTR(ENT_DYN_IND_ctr);
431 432 433 434 435 436 437 438 439 440 441 442 443 444

/* 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.  */
445
  COND_PR_CTR(ENT_PERM_IND_ctr,RtsFlags.GcFlags.squeezeUpdFrames == rtsFalse,"E!NT_PERM_IND_ctr requires +RTS -Z");
446

447
  PR_CTR(ENT_AP_ctr);
448
  PR_CTR(ENT_PAP_ctr);
449
  PR_CTR(ENT_AP_STACK_ctr);
450
  PR_CTR(ENT_BH_ctr);
njn's avatar
njn committed
451 452
  PR_CTR(ENT_STATIC_THK_ctr);
  PR_CTR(ENT_DYN_THK_ctr);
453

454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
  PR_CTR(SLOW_CALL_v_ctr);
  PR_CTR(SLOW_CALL_f_ctr);
  PR_CTR(SLOW_CALL_d_ctr);
  PR_CTR(SLOW_CALL_l_ctr);
  PR_CTR(SLOW_CALL_n_ctr);
  PR_CTR(SLOW_CALL_p_ctr);
  PR_CTR(SLOW_CALL_pv_ctr);
  PR_CTR(SLOW_CALL_pp_ctr);
  PR_CTR(SLOW_CALL_ppv_ctr);
  PR_CTR(SLOW_CALL_ppp_ctr);
  PR_CTR(SLOW_CALL_pppv_ctr);
  PR_CTR(SLOW_CALL_pppp_ctr);
  PR_CTR(SLOW_CALL_ppppp_ctr);
  PR_CTR(SLOW_CALL_pppppp_ctr);
  PR_CTR(SLOW_CALL_OTHER_ctr);

  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);
476
  PR_CTR(SLOW_CALL_ctr);
477 478 479 480 481 482 483
  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);
484 485 486 487 488 489 490 491 492
  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);

493 494
  PR_CTR(RET_NEW_ctr);
  PR_CTR(RET_OLD_ctr);
495
  PR_CTR(RET_UNBOXED_TUP_ctr);
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
  PR_CTR(VEC_RETURN_ctr);

  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);
516 517 518 519 520 521 522 523 524
  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);
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
  PR_HST(RET_VEC_RETURN_hst,0);
  PR_HST(RET_VEC_RETURN_hst,1);
  PR_HST(RET_VEC_RETURN_hst,2);
  PR_HST(RET_VEC_RETURN_hst,3);
  PR_HST(RET_VEC_RETURN_hst,4);
  PR_HST(RET_VEC_RETURN_hst,5);
  PR_HST(RET_VEC_RETURN_hst,6);
  PR_HST(RET_VEC_RETURN_hst,7);
  PR_HST(RET_VEC_RETURN_hst,8);

  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);
544
  PR_CTR(UPD_CON_IN_PLACE_ctr);
545
  PR_CTR(UPD_PAP_IN_NEW_ctr);
546
  PR_CTR(UPD_PAP_IN_PLACE_ctr);
547

548 549 550 551 552
  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);

553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
  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);

  PR_CTR(UPD_NEW_IND_ctr);
573
  /* see comment on ENT_PERM_IND_ctr */
574
  COND_PR_CTR(UPD_NEW_PERM_IND_ctr,RtsFlags.GcFlags.squeezeUpdFrames == rtsFalse,"U!PD_NEW_PERM_IND_ctr requires +RTS -Z");
575
  PR_CTR(UPD_OLD_IND_ctr);
576
  /* see comment on ENT_PERM_IND_ctr */
577
  COND_PR_CTR(UPD_OLD_PERM_IND_ctr,RtsFlags.GcFlags.squeezeUpdFrames == rtsFalse,"U!PD_OLD_PERM_IND_ctr requires +RTS -Z");
578 579 580 581 582

  PR_CTR(GC_SEL_ABANDONED_ctr);
  PR_CTR(GC_SEL_MINOR_ctr);
  PR_CTR(GC_SEL_MAJOR_ctr);
  PR_CTR(GC_FAILED_PROMOTION_ctr);
583
  PR_CTR(GC_WORDS_COPIED_ctr);
584 585 586 587
}

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

588
StgEntCounter *ticky_entry_ctrs = NULL; /* root of list of them */
589 590 591 592 593 594

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

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

597
    if ( ticky_entry_ctrs != NULL ) {
598
      fprintf(tf,"\n**************************************************\n\n");
599
    }
600 601
    fprintf(tf, "%11s%11s %6s%6s    %-11s%-30s\n",
	    "Entries", "Allocs", "Arity", "Stack", "Kinds", "Function");
602
    fprintf(tf, "--------------------------------------------------------------------------------\n");
603
    /* Function name at the end so it doesn't mess up the tabulation */
604

605
    for (p = ticky_entry_ctrs; p != NULL; p = p->link) {
606
	fprintf(tf, "%11ld%11ld %6u%6u    %-11s%-30s",
607
		p->entry_count,
608
		p->allocs,
609
		p->arity,
610
		p->stk_args,
611
		p->arg_kinds,
612
		p->str);
613

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

    }
}

619 620 621 622
/* Catch-all top-level counter struct.  Allocations from CAFs will go
 * here.
 */
StgEntCounter top_ct
623
        = { 0, 0, 0,
624
	    "TOP", "",
625
	    0, 0, NULL };
626

627
#endif /* TICKY_TICKY */
628