[project @ 1999-01-21 10:31:41 by simonm]
authorsimonm <unknown>
Thu, 21 Jan 1999 10:31:57 +0000 (10:31 +0000)
committersimonm <unknown>
Thu, 21 Jan 1999 10:31:57 +0000 (10:31 +0000)
Resurrect ticky-ticky profiling.  Not quite polished yet, but it
compiles and produces some reasonable-looking stats.

24 files changed:
ghc/compiler/codeGen/CgClosure.lhs
ghc/compiler/codeGen/CgCon.lhs
ghc/compiler/codeGen/CgHeapery.lhs
ghc/compiler/codeGen/CgTailCall.lhs
ghc/includes/Constants.h
ghc/includes/PrimOps.h
ghc/includes/Rts.h
ghc/includes/Stg.h
ghc/includes/StgMacros.h
ghc/includes/StgTicky.h [new file with mode: 0644]
ghc/includes/Ticky.h [deleted file]
ghc/includes/Updates.h
ghc/rts/Main.c
ghc/rts/PrimOps.hc
ghc/rts/RtsFlags.c
ghc/rts/RtsStartup.c
ghc/rts/RtsUtils.c
ghc/rts/Schedule.c
ghc/rts/StgMiscClosures.hc
ghc/rts/Storage.c
ghc/rts/Storage.h
ghc/rts/Ticky.c [new file with mode: 0644]
ghc/rts/Ticky.h [new file with mode: 0644]
ghc/rts/Updates.hc

index 12bbf02..6721172 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgClosure.lhs,v 1.22 1999/01/15 15:57:36 simonm Exp $
+% $Id: CgClosure.lhs,v 1.23 1999/01/21 10:31:55 simonm Exp $
 %
 \section[CgClosure]{Code generation for closures}
 
@@ -371,12 +371,15 @@ closureCodeBody binder_info srt closure_info cc all_args body
 
        fast_entry_code
          = profCtrC SLIT("TICK_ENT_FUN_DIRECT") [
-                   CLbl (mkRednCountsLabel name) PtrRep,
+                   mkIntCLit stg_arity         -- total # of args
+
+               {-  CLbl (mkRednCountsLabel name) PtrRep,
                    CString (_PK_ (showSDoc (ppr name))),
                    mkIntCLit stg_arity,        -- total # of args
                    mkIntCLit sp_stk_args,      -- # passed on stk
                    CString (_PK_ (map (showTypeCategory . idType) all_args)),
                    CString SLIT(""), CString SLIT("")
+               -}
 
 -- Nuked for now; see comment at end of file
 --                 CString (_PK_ (show_wrapper_name wrapper_maybe)),
index 1d71cd0..0a9a76d 100644 (file)
@@ -344,6 +344,7 @@ cgReturnDataCon con amodes all_zero_size_args
                        ASSERT(not (isUnboxedTupleCon con))
                        buildDynCon binder currentCCS con amodes all_zero_size_args
                                                                `thenFC` \ idinfo ->
+                       profCtrC SLIT("TICK_RET_NEW") [mkIntCLit (length amodes)] `thenC`
                        idInfoToAmode PtrRep idinfo             `thenFC` \ amode ->
                        performReturn (move_to_reg amode node)  jump_to_join_point
 
@@ -361,6 +362,9 @@ cgReturnDataCon con amodes all_zero_size_args
                  let (ret_regs, leftovers) = 
                         assignRegs [] (map getAmodeRep amodes)
                  in
+                 profCtrC SLIT("TICK_RET_UNBOXED_TUP") 
+                               [mkIntCLit (length amodes)] `thenC`
+
                  doTailCall amodes ret_regs 
                        mkUnboxedTupleReturnCode
                        (length leftovers)  {- fast args arity -}
@@ -385,7 +389,7 @@ cgReturnDataCon con amodes all_zero_size_args
 
 
                        -- RETURN
-                 profCtrC SLIT("TICK_RET_CON") [mkIntCLit (length amodes)] `thenC`
+                 profCtrC SLIT("TICK_RET_NEW") [mkIntCLit (length amodes)] `thenC`
                  -- could use doTailCall here.
                  performReturn (move_to_reg amode node) 
                        (mkStaticAlgReturnCode con)
index 6209ac6..f1a0ef2 100644 (file)
@@ -1,14 +1,14 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgHeapery.lhs,v 1.11 1998/12/18 17:40:51 simonpj Exp $
+% $Id: CgHeapery.lhs,v 1.12 1999/01/21 10:31:56 simonm Exp $
 %
 \section[CgHeapery]{Heap management functions}
 
 \begin{code}
 module CgHeapery (
        fastEntryChecks, altHeapCheck, thunkChecks,
-       allocHeap, allocDynClosure
+       allocDynClosure
 
         -- new functions, basically inserting macro calls into Code -- HWL
         ,fetchAndReschedule, yield
@@ -436,10 +436,8 @@ allocDynClosure closure_info use_cc blame_cc amodes_with_offsets
     in
        -- SAY WHAT WE ARE ABOUT TO DO
     profCtrC (allocProfilingMsg closure_info)
-                          [mkIntCLit fixedHdrSize,
-                           mkIntCLit (closureGoodStuffSize closure_info),
-                           mkIntCLit slop_size,
-                           mkIntCLit closure_size]     `thenC`
+                          [mkIntCLit (closureGoodStuffSize closure_info),
+                           mkIntCLit slop_size]        `thenC`
 
        -- GENERATE THE CODE
     absC ( mkAbstractCs (
@@ -468,27 +466,3 @@ cInitHdr closure_info amode cc
   | otherwise          = CInitHdr closure_info amode (panic "absent cc")
        
 \end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection{Allocate uninitialized heap space}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-allocHeap :: HeapOffset                -- Size of the space required
-         -> FCode CAddrMode    -- Addr mode for first word of object
-
-allocHeap space
-  = getVirtAndRealHp                           `thenFC` \ (virtHp, realHp) ->
-    let block_start = virtHp + 1
-    in
-       -- We charge the allocation to "PRIM" (which is probably right)
-    profCtrC SLIT("ALLOC_PRIM2") [mkIntCLit space]     `thenC`
-
-       -- BUMP THE VIRTUAL HEAP POINTER
-    setVirtHp (virtHp + space)                 `thenC`
-
-       -- RETURN PTR TO START OF OBJECT
-    returnFC (CAddr (hpRel realHp block_start))
-\end{code}
index 772d2fe..b6953b1 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgTailCall.lhs,v 1.17 1998/12/18 17:40:53 simonpj Exp $
+% $Id: CgTailCall.lhs,v 1.18 1999/01/21 10:31:57 simonm Exp $
 %
 %********************************************************
 %*                                                     *
@@ -307,6 +307,8 @@ returnUnboxedTuple amodes before_jump
     let (ret_regs, leftovers) = assignRegs [] (map getAmodeRep amodes)
     in
 
+    profCtrC SLIT("TICK_RET_UNBOXED_TUP") [mkIntCLit (length amodes)] `thenC`
+
     doTailCall amodes ret_regs
                mkUnboxedTupleReturnCode
                (length leftovers)  {- fast args arity -}
index c521b76..d970160 100644 (file)
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: Constants.h,v 1.2 1998/12/02 13:21:03 simonm Exp $
+ * $Id: Constants.h,v 1.3 1999/01/21 10:31:41 simonm Exp $
  *
  * Constants
  *
@@ -21,7 +21,7 @@
 #define STD_HDR_SIZE   1
 #define PROF_HDR_SIZE  1
 #define GRAN_HDR_SIZE  1
-#define TICKY_HDR_SIZE 1
+#define TICKY_HDR_SIZE 0
 
 #define ARR_HDR_SIZE   1
 
   
    NOTE: keep these in line with the real definitions in InfoTables.h
 
-   NOTE: the PROF, GRAN and TICKY values are *wrong*  (ToDo)
+   NOTE: the PROF, and GRAN values are *wrong*  (ToDo)
    -------------------------------------------------------------------------- */
 
 #define STD_ITBL_SIZE   3
 #define PROF_ITBL_SIZE  1
 #define GRAN_ITBL_SIZE  1
-#define TICKY_ITBL_SIZE 1
+#define TICKY_ITBL_SIZE 0
 
 /* -----------------------------------------------------------------------------
    Minimum closure sizes
index 1664303..58f2df0 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: PrimOps.h,v 1.7 1999/01/19 09:49:55 simonm Exp $
+ * $Id: PrimOps.h,v 1.8 1999/01/21 10:31:42 simonm Exp $
  *
  * Macros for primitive operations in STG-ish C code.
  *
@@ -278,7 +278,7 @@ typedef union {
   arg2._mp_size        = (s2);                                                 \
   arg2._mp_d   = (unsigned long int *) (BYTE_ARR_CTS(d2));             \
                                                                        \
-  (r) = RET_PRIM_STGCALL2(I_,mpz_cmp,&arg1,&arg2);                             \
+  (r) = RET_PRIM_STGCALL2(I_,mpz_cmp,&arg1,&arg2);                     \
 }
 
 /* A glorious hack: calling mpz_neg would entail allocation and
index 3f7d868..45f66cf 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Rts.h,v 1.3 1999/01/13 17:25:54 simonm Exp $
+ * $Id: Rts.h,v 1.4 1999/01/21 10:31:43 simonm Exp $
  *
  * Top-level include file for the RTS itself
  *
@@ -46,20 +46,6 @@ typedef enum {
    -------------------------------------------------------------------------- */
 
 #ifndef DEBUG
-#define ASSERT(predicate) /* nothing */
-#else
-
-void _stgAssert (char *, unsigned int);
-
-#define ASSERT(predicate)                      \
-       if (predicate)                          \
-           /*null*/;                           \
-       else                                    \
-           _stgAssert(__FILE__, __LINE__)
-
-#endif /* DEBUG */
-
-#ifndef DEBUG
 #define IF_DEBUG(c,s)  doNothing()
 #else
 #define IF_DEBUG(c,s)  if (RtsFlags.DebugFlags.c) { s; }
index 12ccdbe..555c7b1 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Stg.h,v 1.3 1999/01/18 14:37:43 sof Exp $
+ * $Id: Stg.h,v 1.4 1999/01/21 10:31:43 simonm Exp $
  *
  * Top-level include file for everything STG-ish.  
  *
@@ -90,7 +90,7 @@
 #include "StgProf.h"
 #include "PrimOps.h"
 #include "Updates.h"
-#include "Ticky.h"
+#include "StgTicky.h"
 #include "CCall.h"
 
 /* Built-in entry points */
@@ -106,10 +106,27 @@ extern int    prog_argc;
 extern char **environ;
 
 /* Creating and destroying an adjustor thunk.
-   I cannot make myself creating a separate .h file
+   I cannot make myself create a separate .h file
    for these two (sof.)
 */
 extern void* createAdjustor(int cconv, StgStablePtr hptr, StgFunPtr wptr);
 extern void  freeHaskellFunctionPtr(void* ptr);
 
+/* -----------------------------------------------------------------------------
+   Assertions and Debuggery
+   -------------------------------------------------------------------------- */
+
+#ifndef DEBUG
+#define ASSERT(predicate) /* nothing */
+#else
+
+void _stgAssert (char *, unsigned int);
+
+#define ASSERT(predicate)                      \
+       if (predicate)                          \
+           /*null*/;                           \
+       else                                    \
+           _stgAssert(__FILE__, __LINE__)
+#endif /* DEBUG */
+
 #endif /* STG_H */
index 07e5e5f..d17d4ad 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: StgMacros.h,v 1.2 1998/12/02 13:21:35 simonm Exp $
+ * $Id: StgMacros.h,v 1.3 1999/01/21 10:31:43 simonm Exp $
  *
  * Macros used for writing STG-ish C code.
  *
@@ -156,17 +156,19 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
        if ((Hp += headroom) > HpLim) {                         \
            EXTFUN(stg_chk_##layout);                           \
            tag_assts                                           \
-           (r) = (P_)ret;                                              \
+           (r) = (P_)ret;                                      \
            JMP_(stg_chk_##layout);                             \
-       }
+       }                                                       \
+        TICK_ALLOC_HEAP(headroom);
 
 #define HP_STK_CHK(stk_headroom,hp_headroom,ret,r,layout,tag_assts) \
        if (Sp - stk_headroom < SpLim || (Hp += hp_headroom) > HpLim) { \
            EXTFUN(stg_chk_##layout);                           \
            tag_assts                                           \
-           (r) = (P_)ret;                                              \
+           (r) = (P_)ret;                                      \
            JMP_(stg_chk_##layout);                             \
-       }
+       }                                                       \
+        TICK_ALLOC_HEAP(hp_headroom);
 
 /* -----------------------------------------------------------------------------
    A Heap Check in a case alternative are much simpler: everything is
@@ -195,21 +197,24 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
            EXTFUN(stg_gc_enter_##ptrs);                        \
             tag_assts                                          \
            JMP_(stg_gc_enter_##ptrs);                          \
-       }
+       }                                                       \
+        TICK_ALLOC_HEAP(headroom);
 
 #define HP_CHK_SEQ_NP(headroom,ptrs,tag_assts)                 \
        if ((Hp += (headroom)) > HpLim) {                       \
            EXTFUN(stg_gc_seq_##ptrs);                          \
             tag_assts                                          \
            JMP_(stg_gc_seq_##ptrs);                            \
-       }
+       }                                                       \
+        TICK_ALLOC_HEAP(headroom);
 
 #define HP_STK_CHK_NP(stk_headroom, hp_headroom, ptrs, tag_assts) \
        if ((Sp - (stk_headroom)) < SpLim || (Hp += (hp_headroom)) > HpLim) { \
            EXTFUN(stg_gc_enter_##ptrs);                        \
             tag_assts                                          \
            JMP_(stg_gc_enter_##ptrs);                          \
-       }
+       }                                                       \
+        TICK_ALLOC_HEAP(hp_headroom);
 
 /* Heap checks for branches of a primitive case / unboxed tuple return */
 
@@ -218,7 +223,8 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
            EXTFUN(lbl);                                        \
             tag_assts                                          \
            JMP_(lbl);                                          \
-       }
+       }                                                       \
+        TICK_ALLOC_HEAP(headroom);
 
 #define HP_CHK_NOREGS(headroom,tag_assts) \
     GEN_HP_CHK_ALT(headroom,stg_gc_noregs,tag_assts);
@@ -295,30 +301,32 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
 #define R7_PTR   1<<6
 #define R8_PTR   1<<7
 
-#define HP_CHK_GEN(headroom,liveness,reentry,tag_assts) \
-   if ((Hp += (headroom)) > HpLim ) {  \
-       EF_(stg_gen_chk);               \
-        tag_assts                      \
-       R9.w = (W_)LIVENESS_MASK(liveness); \
-        R10.w = (W_)reentry;           \
-        JMP_(stg_gen_chk);             \
-   }
-
-#define STK_CHK_GEN(headroom,liveness,reentry,tag_assts) \
-   if ((Sp - (headroom)) < SpLim) {    \
-       EF_(stg_gen_chk);               \
-        tag_assts                      \
-       R9.w = (W_)LIVENESS_MASK(liveness); \
-        R10.w = (W_)reentry;           \
-        JMP_(stg_gen_chk);             \
-   }
-
-#define MAYBE_GC(liveness,reentry)     \
-   if (doYouWantToGC()) {              \
-       EF_(stg_gen_hp);                \
-       R9.w = (W_)LIVENESS_MASK(liveness); \
-        R10.w = (W_)reentry;           \
-        JMP_(stg_gen_hp);              \
+#define HP_CHK_GEN(headroom,liveness,reentry,tag_assts)        \
+   if ((Hp += (headroom)) > HpLim ) {                  \
+       EF_(stg_gen_chk);                               \
+        tag_assts                                      \
+       R9.w = (W_)LIVENESS_MASK(liveness);             \
+        R10.w = (W_)reentry;                           \
+        JMP_(stg_gen_chk);                             \
+   }                                                   \
+   TICK_ALLOC_HEAP(headroom);
+
+#define STK_CHK_GEN(headroom,liveness,reentry,tag_assts)       \
+   if ((Sp - (headroom)) < SpLim) {                            \
+       EF_(stg_gen_chk);                                       \
+        tag_assts                                              \
+       R9.w = (W_)LIVENESS_MASK(liveness);                     \
+        R10.w = (W_)reentry;                                   \
+        JMP_(stg_gen_chk);                                     \
+   }                                                           \
+   TICK_ALLOC_HEAP(headroom);
+
+#define MAYBE_GC(liveness,reentry)             \
+   if (doYouWantToGC()) {                      \
+       EF_(stg_gen_hp);                        \
+       R9.w = (W_)LIVENESS_MASK(liveness);     \
+        R10.w = (W_)reentry;                   \
+        JMP_(stg_gen_hp);                      \
    }
 
 /* -----------------------------------------------------------------------------
diff --git a/ghc/includes/StgTicky.h b/ghc/includes/StgTicky.h
new file mode 100644 (file)
index 0000000..fe756a1
--- /dev/null
@@ -0,0 +1,528 @@
+/* ----------------------------------------------------------------------------
+ * $Id: StgTicky.h,v 1.1 1999/01/21 10:31:44 simonm Exp $
+ *
+ * Ticky-ticky profiling macros.
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef TICKY_H
+#define TICKY_H
+
+#ifdef TICKY_TICKY
+
+/* -----------------------------------------------------------------------------
+   Allocations
+   -------------------------------------------------------------------------- */
+
+/* How many times we do a heap check and move Hp; comparing this with
+ * the allocations gives an indication of how many things we get per trip
+ * to the well:
+ */
+#define TICK_ALLOC_HEAP(n)     ALLOC_HEAP_ctr++; ALLOC_HEAP_tot += (n)
+
+/* We count things every time we allocate something in the dynamic heap.
+ * For each, we count the number of words of (1) ``admin'' (header),
+ * (2) good stuff (useful pointers and data), and (3) ``slop'' (extra
+ * space, to leave room for an old generation indirection for example).
+ * 
+ * The first five macros are inserted when the compiler generates code
+ * to allocate something; the categories correspond to the @ClosureClass@
+ * datatype (manifest functions, thunks, constructors, big tuples, and
+ * partial applications).
+ */
+
+#define _HS  sizeofW(StgHeader)
+
+#define TICK_ALLOC_FUN(g,s)                            \
+       ALLOC_FUN_ctr++;        ALLOC_FUN_adm += _HS;   \
+       ALLOC_FUN_gds += (g);   ALLOC_FUN_slp += (s);   \
+       TICK_ALLOC_HISTO(FUN,_HS,g,s)
+
+#define TICK_ALLOC_THK(g,s)                            \
+       ALLOC_THK_ctr++;        ALLOC_THK_adm += _HS;   \
+       ALLOC_THK_gds += (g);   ALLOC_THK_slp += (s);   \
+       TICK_ALLOC_HISTO(THK,_HS,g,s)
+
+#define TICK_ALLOC_CON(g,s)                            \
+       ALLOC_CON_ctr++;        ALLOC_CON_adm += _HS;   \
+       ALLOC_CON_gds += (g);   ALLOC_CON_slp += (s);   \
+       TICK_ALLOC_HISTO(CON,_HS,g,s)
+
+#define TICK_ALLOC_TUP(g,s)                            \
+       ALLOC_TUP_ctr++;        ALLOC_TUP_adm += _HS;   \
+       ALLOC_TUP_gds += (g);   ALLOC_TUP_slp += (s);   \
+       TICK_ALLOC_HISTO(TUP,_HS,g,s)
+
+#define TICK_ALLOC_BH(g,s)                             \
+       ALLOC_BH_ctr++;         ALLOC_BH_adm += _HS;    \
+       ALLOC_BH_gds += (g);    ALLOC_BH_slp += (s);    \
+       TICK_ALLOC_HISTO(BH,_HS,g,s)
+
+#define TICK_ALLOC_UPD_PAP(g,s)                                        \
+       ALLOC_UPD_PAP_ctr++;    ALLOC_UPD_PAP_adm += sizeofW(StgPAP)-1; \
+       ALLOC_UPD_PAP_gds += (g); ALLOC_UPD_PAP_slp += (s);     \
+       TICK_ALLOC_HISTO(UPD_PAP,sizeofW(StgPAP)-1,g,s)
+
+#define TICK_ALLOC_TSO(g,s)                                            \
+       ALLOC_TSO_ctr++;        ALLOC_TSO_adm += sizeofW(StgTSO);       \
+       ALLOC_TSO_gds += (g);   ALLOC_TSO_slp += (s);                   \
+       TICK_ALLOC_HISTO(TSO,sizeofW(StgTSO),g,s)
+     
+#ifdef PAR
+#define TICK_ALLOC_FMBQ(a,g,s)                                 \
+       ALLOC_FMBQ_ctr++;       ALLOC_FMBQ_adm += (a);  \
+       ALLOC_FMBQ_gds += (g);  ALLOC_FMBQ_slp += (s);  \
+       TICK_ALLOC_HISTO(FMBQ,a,g,s)
+
+#define TICK_ALLOC_FME(a,g,s)                          \
+       ALLOC_FME_ctr++;        ALLOC_FME_adm += (a);   \
+       ALLOC_FME_gds += (g);   ALLOC_FME_slp += (s);   \
+       TICK_ALLOC_HISTO(FME,a,g,s)
+
+#define TICK_ALLOC_BF(a,g,s)                           \
+       ALLOC_BF_ctr++; ALLOC_BF_adm += (a);            \
+       ALLOC_BF_gds += (g);    ALLOC_BF_slp += (s);    \
+       TICK_ALLOC_HISTO(BF,a,g,s)
+#endif
+     
+/* The histogrammy bit is fairly straightforward; the -2 is: one for
+ * 0-origin C arrays; the other one because we do no one-word
+ * allocations, so we would never inc that histogram slot; so we shift
+ * everything over by one.
+ */
+#define TICK_ALLOC_HISTO(categ,a,g,s)                          \
+       { I_ __idx;                                             \
+         __idx = (a) + (g) + (s) - 2;                          \
+        ALLOC_##categ##_hst[((__idx > 4) ? 4 : __idx)] += 1;} 
+
+/* Some hard-to-account-for words are allocated by/for primitives,
+ * includes Integer support.  ALLOC_PRIM2 tells us about these.  We
+ * count everything as ``goods'', which is not strictly correct.
+ * (ALLOC_PRIM is the same sort of stuff, but we know the
+ * admin/goods/slop breakdown.)
+ */
+#define TICK_ALLOC_PRIM(a,g,s)                         \
+       ALLOC_PRIM_ctr++;       ALLOC_PRIM_adm += (a);  \
+       ALLOC_PRIM_gds += (g);  ALLOC_PRIM_slp += (s);  \
+       TICK_ALLOC_HISTO(PRIM,a,g,s)
+
+#define TICK_ALLOC_PRIM2(w) ALLOC_PRIM_ctr++; ALLOC_PRIM_gds +=(w); \
+                      TICK_ALLOC_HISTO(PRIM,0,w,0)
+
+
+/* -----------------------------------------------------------------------------
+   Enters
+   -------------------------------------------------------------------------- */
+
+#define TICK_ENT_VIA_NODE()    ENT_VIA_NODE_ctr++
+
+#define TICK_ENT_THK()         ENT_THK_ctr++         /* thunk */
+#define TICK_ENT_FUN_STD()     ENT_FUN_STD_ctr++     /* std entry pt */
+#define TICK_ENT_FUN_DIRECT(n)         ENT_FUN_DIRECT_ctr++  /* fast entry pt */
+
+#define TICK_ENT_CON(n)                ENT_CON_ctr++         /* enter constructor */
+#define TICK_ENT_IND(n)                ENT_IND_ctr++         /* enter indirection */
+#define TICK_ENT_PAP(n)                ENT_PAP_ctr++         /* enter PAP */
+#define TICK_ENT_AP_UPD(n)     ENT_AP_UPD_ctr++      /* enter AP_UPD */
+#define TICK_ENT_BH()          ENT_BH_ctr++          /* enter BLACKHOLE */
+
+/* -----------------------------------------------------------------------------
+   Returns
+   -------------------------------------------------------------------------- */
+
+/* Whenever a ``return'' occurs, it is returning the constituent parts of
+ * a data constructor.  The parts can be returned either in registers, or
+ * by allocating some heap to put it in (the TICK_ALLOC_* macros account for
+ * the allocation).  The constructor can either be an existing one
+ * *OLD* or we could have {\em just} figured out this stuff
+ * *NEW*.
+ */
+
+#define TICK_RET_HISTO(categ,n)                                        \
+       { I_ __idx;                                             \
+         __idx = (n);                                          \
+        RET_##categ##_hst[((__idx > 8) ? 8 : __idx)] += 1;} 
+
+#define TICK_RET_NEW(n)        RET_NEW_ctr++; \
+                       TICK_RET_HISTO(NEW,n)
+
+#define TICK_RET_OLD(n)        RET_OLD_ctr++; \
+                       TICK_RET_HISTO(OLD,n)
+
+#define TICK_RET_UNBOXED_TUP(n)  RET_UNBOXED_TUP_ctr++; \
+                         TICK_RET_HISTO(UNBOXED_TUP,n)
+
+#define TICK_RET_SEMI(n) RET_SEMI_IN_HEAP_ctr++; \
+                        TICK_RET_HISTO(SEMI_IN_HEAP,n)
+
+#define TICK_RET_SEMI_BY_DEFAULT()/*???*/ RET_SEMI_BY_DEFAULT_ctr++
+
+#define TICK_RET_SEMI_FAILED(tag)      do {                            \
+                               if ((tag) == INFO_IND_TAG)              \
+                                   RET_SEMI_FAILED_IND_ctr++;          \
+                               else                                    \
+                                   RET_SEMI_FAILED_UNEVAL_ctr++;       \
+                               } while (0)
+
+#define TICK_VEC_RETURN(n)     VEC_RETURN_ctr++;           \
+                               TICK_RET_HISTO(VEC_RETURN,n)
+
+/* -----------------------------------------------------------------------------
+   Stack Frames
+
+   Macro                          Counts
+   ------------------              -------------------------------------------
+   TICK_UPDF_PUSHED               Update frame pushed
+   TICK_SEQF_PUSHED               Seq frame pushed
+   TICK_CATCHF_PUSHED             Catch frame pushed
+   TICK_UPDF_OMITTED              A thunk decided not to push an update frame
+   TICK_UPDF_RCC_PUSHED                   Cost Centre restore frame pushed
+   TICK_UPDF_RCC_OMITTED          Cost Centres not required -- not pushed
+
+   -------------------------------------------------------------------------- */
+
+#define TICK_UPDF_OMITTED()    UPDF_OMITTED_ctr++
+#define TICK_UPDF_PUSHED()     UPDF_PUSHED_ctr++
+#define TICK_SEQF_PUSHED()      SEQF_PUSHED_ctr++
+#define TICK_CATCHF_PUSHED()    CATCHF_PUSHED_ctr++
+#define TICK_UPDF_RCC_PUSHED() UPDF_RCC_PUSHED_ctr++
+#define TICK_UPDF_RCC_OMITTED()        UPDF_RCC_OMITTED_ctr++
+
+/* -----------------------------------------------------------------------------
+   Updates
+
+   These macros record information when we do an update.  We always
+   update either with a data constructor (CON) or a partial application
+   (PAP).
+   
+   
+   Macro                               Where
+   -----------------------     --------------------------------------------
+   TICK_UPD_EXISTING           Updating with an indirection to something
+                               already in the heap
+   TICK_UPD_SQUEEZED           Same as UPD_EXISTING but because
+                               of stack-squeezing
+   TICK_UPD_CON_IN_NEW         Allocating a new CON
+   TICK_UPD_PAP_IN_NEW         Allocating a new PAP
+   TICK_UPD_PAP_IN_PLACE       Updating with a PAP in place
+
+   -------------------------------------------------------------------------- */
+
+#define TICK_UPD_HISTO(categ,n) \
+       { I_ __idx;                                              \
+         __idx = (n);                                           \
+        UPD_##categ##_hst[((__idx > 8) ? 8 : __idx)] += 1;} 
+
+#define TICK_UPD_EXISTING()            UPD_EXISTING_ctr++
+#define TICK_UPD_SQUEEZED()            UPD_SQUEEZED_ctr++
+
+#define TICK_UPD_CON_IN_NEW(n)         UPD_CON_IN_NEW_ctr++ ; \
+                                       TICK_UPD_HISTO(CON_IN_NEW,n)
+
+#define TICK_UPD_PAP_IN_NEW(n)         UPD_PAP_IN_NEW_ctr++ ; \
+                                       TICK_UPD_HISTO(PAP_IN_NEW,n)
+
+#define TICK_UPD_PAP_IN_PLACE()                UPD_PAP_IN_PLACE_ctr++
+
+/* For the generational collector: 
+ */
+#define TICK_UPD_NEW_IND()             UPD_NEW_IND_ctr++
+#define TICK_UPD_OLD_IND()             UPD_OLD_IND_ctr++                       
+
+/* -----------------------------------------------------------------------------
+   Garbage collection counters
+   -------------------------------------------------------------------------- */
+
+/* Selectors:
+ *
+ * GC_SEL_ABANDONED: we could've done the selection, but we gave up
+ * (e.g., to avoid overflowing the C stack); GC_SEL_MINOR: did a
+ * selection in a minor GC; GC_SEL_MAJOR: ditto, but major GC.
+ */
+#define TICK_GC_SEL_ABANDONED()                GC_SEL_ABANDONED_ctr++
+#define TICK_GC_SEL_MINOR()            GC_SEL_MINOR_ctr++
+#define TICK_GC_SEL_MAJOR()            GC_SEL_MAJOR_ctr++
+
+/* Failed promotion: we wanted to promote an object early, but
+ * it had already been evacuated to (or resided in) a younger
+ * generation.
+ */
+#define TICK_GC_FAILED_PROMOTION()     GC_FAILED_PROMOTION_ctr++
+
+/* -----------------------------------------------------------------------------
+   The accumulators (extern decls)
+   -------------------------------------------------------------------------- */
+
+#ifdef TICKY_C
+#define INIT(ializer) = ializer
+#define EXTERN
+#else
+#define INIT(ializer)
+#define EXTERN extern
+#endif
+
+EXTERN unsigned long ALLOC_HEAP_ctr INIT(0);
+EXTERN unsigned long ALLOC_HEAP_tot INIT(0);
+
+EXTERN unsigned long ALLOC_FUN_ctr INIT(0);
+EXTERN unsigned long ALLOC_FUN_adm INIT(0);
+EXTERN unsigned long ALLOC_FUN_gds INIT(0);
+EXTERN unsigned long ALLOC_FUN_slp INIT(0);
+EXTERN unsigned long ALLOC_FUN_hst[5] 
+#ifdef TICKY_C
+   = {0,0,0,0,0}  /* urk, can't use INIT macro 'cause of the commas */
+#endif
+;
+
+EXTERN unsigned long ALLOC_THK_ctr INIT(0);
+EXTERN unsigned long ALLOC_THK_adm INIT(0);
+EXTERN unsigned long ALLOC_THK_gds INIT(0);
+EXTERN unsigned long ALLOC_THK_slp INIT(0);
+EXTERN unsigned long ALLOC_THK_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_CON_ctr INIT(0);
+EXTERN unsigned long ALLOC_CON_adm INIT(0);
+EXTERN unsigned long ALLOC_CON_gds INIT(0);
+EXTERN unsigned long ALLOC_CON_slp INIT(0);
+EXTERN unsigned long ALLOC_CON_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_TUP_ctr INIT(0);
+EXTERN unsigned long ALLOC_TUP_adm INIT(0);
+EXTERN unsigned long ALLOC_TUP_gds INIT(0);
+EXTERN unsigned long ALLOC_TUP_slp INIT(0);
+EXTERN unsigned long ALLOC_TUP_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_BH_ctr INIT(0);
+EXTERN unsigned long ALLOC_BH_adm INIT(0);
+EXTERN unsigned long ALLOC_BH_gds INIT(0);
+EXTERN unsigned long ALLOC_BH_slp INIT(0);
+EXTERN unsigned long ALLOC_BH_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_PRIM_ctr INIT(0);
+EXTERN unsigned long ALLOC_PRIM_adm INIT(0);
+EXTERN unsigned long ALLOC_PRIM_gds INIT(0);
+EXTERN unsigned long ALLOC_PRIM_slp INIT(0);
+EXTERN unsigned long ALLOC_PRIM_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_UPD_PAP_ctr INIT(0);
+EXTERN unsigned long ALLOC_UPD_PAP_adm INIT(0);
+EXTERN unsigned long ALLOC_UPD_PAP_gds INIT(0);
+EXTERN unsigned long ALLOC_UPD_PAP_slp INIT(0);
+EXTERN unsigned long ALLOC_UPD_PAP_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_TSO_ctr INIT(0);
+EXTERN unsigned long ALLOC_TSO_adm INIT(0);
+EXTERN unsigned long ALLOC_TSO_gds INIT(0);
+EXTERN unsigned long ALLOC_TSO_slp INIT(0);
+EXTERN unsigned long ALLOC_TSO_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+# ifdef PAR
+EXTERN unsigned long ALLOC_FMBQ_ctr INIT(0);
+EXTERN unsigned long ALLOC_FMBQ_adm INIT(0);
+EXTERN unsigned long ALLOC_FMBQ_gds INIT(0);
+EXTERN unsigned long ALLOC_FMBQ_slp INIT(0);
+EXTERN unsigned long ALLOC_FMBQ_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_FME_ctr INIT(0);
+EXTERN unsigned long ALLOC_FME_adm INIT(0);
+EXTERN unsigned long ALLOC_FME_gds INIT(0);
+EXTERN unsigned long ALLOC_FME_slp INIT(0);
+EXTERN unsigned long ALLOC_FME_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long ALLOC_BF_ctr INIT(0);
+EXTERN unsigned long ALLOC_BF_adm INIT(0);
+EXTERN unsigned long ALLOC_BF_gds INIT(0);
+EXTERN unsigned long ALLOC_BF_slp INIT(0);
+EXTERN unsigned long ALLOC_BF_hst[5]
+#ifdef TICKY_C
+   = {0,0,0,0,0}
+#endif
+;
+#endif
+
+EXTERN unsigned long ENT_VIA_NODE_ctr INIT(0);
+EXTERN unsigned long ENT_THK_ctr INIT(0);
+EXTERN unsigned long ENT_FUN_STD_ctr INIT(0);
+EXTERN unsigned long ENT_FUN_DIRECT_ctr INIT(0);
+EXTERN unsigned long ENT_CON_ctr INIT(0);
+EXTERN unsigned long ENT_IND_ctr INIT(0);
+EXTERN unsigned long ENT_PAP_ctr INIT(0);
+EXTERN unsigned long ENT_AP_UPD_ctr INIT(0);
+EXTERN unsigned long ENT_BH_ctr INIT(0);
+
+EXTERN unsigned long RET_NEW_ctr INIT(0);
+EXTERN unsigned long RET_OLD_ctr INIT(0);
+EXTERN unsigned long RET_UNBOXED_TUP_ctr INIT(0);
+EXTERN unsigned long RET_SEMI_BY_DEFAULT_ctr INIT(0);
+EXTERN unsigned long RET_SEMI_IN_HEAP_ctr INIT(0);
+EXTERN unsigned long RET_SEMI_FAILED_IND_ctr INIT(0);
+EXTERN unsigned long RET_SEMI_FAILED_UNEVAL_ctr INIT(0);
+
+EXTERN unsigned long VEC_RETURN_ctr INIT(0);
+
+EXTERN unsigned long RET_NEW_hst[9]
+#ifdef TICKY_C
+   = {0,0,0,0,0,0,0,0,0}
+#endif
+;
+EXTERN unsigned long RET_OLD_hst[9]
+#ifdef TICKY_C
+   = {0,0,0,0,0,0,0,0,0}
+#endif
+;
+EXTERN unsigned long RET_UNBOXED_TUP_hst[9]
+#ifdef TICKY_C
+   = {0,0,0,0,0,0,0,0,0}
+#endif
+;
+EXTERN unsigned long RET_SEMI_IN_HEAP_hst[9]
+#ifdef TICKY_C
+   = {0,0,0,0,0,0,0,0,0}
+#endif
+;
+EXTERN unsigned long RET_VEC_RETURN_hst[9]
+#ifdef TICKY_C
+   = {0,0,0,0,0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long RET_SEMI_loads_avoided INIT(0);
+
+EXTERN unsigned long UPDF_OMITTED_ctr INIT(0);
+EXTERN unsigned long UPDF_PUSHED_ctr INIT(0);
+EXTERN unsigned long SEQF_PUSHED_ctr INIT(0);
+EXTERN unsigned long CATCHF_PUSHED_ctr INIT(0);
+EXTERN unsigned long UPDF_RCC_PUSHED_ctr INIT(0);
+EXTERN unsigned long UPDF_RCC_OMITTED_ctr INIT(0);
+
+EXTERN unsigned long UPD_EXISTING_ctr INIT(0);
+EXTERN unsigned long UPD_SQUEEZED_ctr INIT(0);
+EXTERN unsigned long UPD_CON_IN_NEW_ctr INIT(0);
+EXTERN unsigned long UPD_PAP_IN_NEW_ctr INIT(0);
+EXTERN unsigned long UPD_PAP_IN_PLACE_ctr INIT(0);
+
+EXTERN unsigned long UPD_CON_IN_NEW_hst[9]
+#ifdef TICKY_C
+   = {0,0,0,0,0,0,0,0,0}
+#endif
+;
+EXTERN unsigned long UPD_PAP_IN_NEW_hst[9]
+#ifdef TICKY_C
+   = {0,0,0,0,0,0,0,0,0}
+#endif
+;
+
+EXTERN unsigned long UPD_NEW_IND_ctr INIT(0);
+EXTERN unsigned long UPD_OLD_IND_ctr INIT(0);
+
+EXTERN unsigned long GC_SEL_ABANDONED_ctr INIT(0);
+EXTERN unsigned long GC_SEL_MINOR_ctr INIT(0);
+EXTERN unsigned long GC_SEL_MAJOR_ctr INIT(0);
+
+EXTERN unsigned long GC_FAILED_PROMOTION_ctr INIT(0);
+
+#undef INIT
+#undef EXTERN
+
+/* -----------------------------------------------------------------------------
+   Just stubs if no ticky-ticky profiling
+   -------------------------------------------------------------------------- */
+
+#else /* !TICKY_TICKY */
+
+#define TICK_ALLOC_HEAP(words)
+
+#define TICK_ALLOC_FUN(g,s)
+#define TICK_ALLOC_THK(g,s)
+#define TICK_ALLOC_CON(g,s)
+#define TICK_ALLOC_TUP(g,s)
+#define TICK_ALLOC_BH(g,s)
+#define TICK_ALLOC_UPD_PAP(g,s)
+#define TICK_ALLOC_TSO(g,s)
+#define TICK_ALLOC_FMBQ(a,g,s)
+#define TICK_ALLOC_FME(a,g,s)
+#define TICK_ALLOC_BF(a,g,s)
+#define TICK_ALLOC_PRIM(a,g,s)
+#define TICK_ALLOC_PRIM2(w)
+
+#define TICK_ENT_VIA_NODE()    
+                               
+#define TICK_ENT_THK()
+#define TICK_ENT_FUN_STD()
+#define TICK_ENT_FUN_DIRECT(n)
+                               
+#define TICK_ENT_CON(n)
+#define TICK_ENT_IND(n)
+#define TICK_ENT_PAP(n)
+#define TICK_ENT_AP_UPD(n)
+#define TICK_ENT_BH()
+
+#define TICK_RET_NEW(n)
+#define TICK_RET_OLD(n)
+#define TICK_RET_UNBOXED_TUP(n)
+#define TICK_RET_SEMI(n)
+#define TICK_RET_SEMI_BY_DEFAULT()
+#define TICK_RET_SEMI_FAILED(tag)
+#define TICK_VEC_RETURN(n)
+
+#define TICK_UPDF_OMITTED()
+#define TICK_UPDF_PUSHED()
+#define TICK_SEQF_PUSHED()
+#define TICK_CATCHF_PUSHED()
+#define TICK_UPDF_RCC_PUSHED()
+#define TICK_UPDF_RCC_OMITTED()
+
+#define TICK_UPD_EXISTING()
+#define TICK_UPD_SQUEEZED()
+#define TICK_UPD_CON_IN_NEW(n)
+#define TICK_UPD_PAP_IN_NEW(n)
+#define TICK_UPD_PAP_IN_PLACE()
+
+#define TICK_UPD_NEW_IND()
+#define TICK_UPD_OLD_IND()
+
+#define TICK_GC_SEL_ABANDONED()
+#define TICK_GC_SEL_MINOR()
+#define TICK_GC_SEL_MAJOR()
+
+#define TICK_GC_FAILED_PROMOTION()
+
+#endif /* !TICKY_TICKY */
+
+#endif /* TICKY_H */
diff --git a/ghc/includes/Ticky.h b/ghc/includes/Ticky.h
deleted file mode 100644 (file)
index a2bd814..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ----------------------------------------------------------------------------
- * $Id: Ticky.h,v 1.2 1998/12/02 13:21:45 simonm Exp $
- *
- * Closures
- *
- * -------------------------------------------------------------------------- */
-
-#ifndef TICKY_H
-#define TICKY_H
-
-
-#ifndef TICKY
-/* just stubs if no ticky-ticky profiling*/
-#define TICK_ENT_CAF_ENTERED(Node)     /* enter CAF */
-#define TICK_ENT_IND(Node)     /* enter indirection */
-#define TICK_ENT_VIA_NODE()    /* enter node */
-#define TICK_UPD_EXISTING()    /* entering an update frame */
-#define TICK_UPD_SQUEEZED()     /* squeezed an update frame */
-#define TICK_UPDATED_SET_UPDATED(updclosure) /* updating a closure w/ ind */
-#define TICK_ALLOC_HEAP(words)  /* allocate some words on the heap */
-#define TICK_UNALLOC_HEAP(words)  /* unallocate some words on the heap */
-#define TICK_ALLOC_UPD_PAP(DYN_HS,NArgWords,N,PapSize)
-#define TICK_ALLOC_PRIM(hdr,args,n,size)
-#define TICK_ENT_PAP(pap)      /* entering a PAP */
-#define TICK_UPD_PAP_IN_NEW(NArgWords)
-#define TICK_UPD_PAP_IN_PLACE()
-#define TICK_UPDF_PUSHED()
-#define TICK_SEQF_PUSHED()
-#else
-#error ticky-ticky not implemented!
-#endif
-
-#endif /* TICKY_H */
index 5398318..04838e7 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Updates.h,v 1.5 1999/01/18 15:21:42 simonm Exp $
+ * $Id: Updates.h,v 1.6 1999/01/21 10:31:45 simonm Exp $
  *
  * Definitions related to updates.
  *
@@ -25,7 +25,6 @@
  */
 
 #define UPD_IND(updclosure, heapptr)                            \
-        TICK_UPDATED_SET_UPDATED(updclosure);                  \
         AWAKEN_BQ(updclosure);                                  \
        updateWithIndirection((StgClosure *)updclosure,         \
                              (StgClosure *)heapptr);
index 2b7433a..c363eb2 100644 (file)
@@ -1,5 +1,7 @@
 /* -----------------------------------------------------------------------------
- * $Id: Main.c,v 1.2 1998/12/02 13:28:30 simonm Exp $
+ * $Id: Main.c,v 1.3 1999/01/21 10:31:47 simonm Exp $
+ *
+ * (c) The GHC Team 1998-1999
  *
  * Main function for a standalone Haskell program.
  *
@@ -7,6 +9,7 @@
 
 #include "Rts.h"
 #include "RtsAPI.h"
+#include "RtsFlags.h"
 #include "Schedule.h"  /* for MainTSO */
 #include "RtsUtils.h"
 
@@ -35,14 +38,18 @@ int main(int argc, char *argv[])
     startupHaskell(argc,argv);
 
 #ifndef PAR
-    MainTSO = createIOThread(BLOCK_SIZE_W,(StgClosure *)&mainIO_closure);
+    MainTSO = createIOThread(stg_max(BLOCK_SIZE_W,
+                                    RtsFlags.GcFlags.initialStkSize),
+                            (StgClosure *)&mainIO_closure);
     status = schedule(MainTSO,NULL);
 #else
     if (IAmMainThread == rtsTrue) {
     /*Just to show we're alive */
       fprintf(stderr, "Main Thread Started ...\n");
      
-      MainTSO = createIOThread(BLOCK_SIZE_W,(StgClosure *)&mainIO_closure);
+      MainTSO = createIOThread(stg_max(BLOCK_SIZE_W,
+                                      RtsFlags.GcFlags.initialStkSize),
+                              (StgClosure *)&mainIO_closure);
       status = schedule(MainTSO,NULL);
     } else {
       WaitForPEOp(PP_FINISH,SysManTask);
index 31919dc..10f49d5 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: PrimOps.hc,v 1.4 1999/01/15 17:32:22 simonm Exp $
+ * $Id: PrimOps.hc,v 1.5 1999/01/21 10:31:47 simonm Exp $
  *
  * Primitive functions / data
  *
@@ -196,8 +196,10 @@ const
      stuff_size = BYTES_TO_STGWORDS(n*scale);          \
      size = sizeofW(StgArrWords)+ stuff_size;          \
      p = (StgArrWords *)RET_STGCALL1(P_,allocate,size);        \
+     TICK_ALLOC_PRIM(sizeofW(StgArrWords),stuff_size,0); \
      SET_HDR(p, &MUT_ARR_WORDS_info, CCCS);            \
      p->words = stuff_size;                            \
+     TICK_RET_UNBOXED_TUP(1)                           \
      RET_P(p);                                         \
    FE_                                                 \
  }
@@ -222,6 +224,7 @@ FN_(newArrayZh_fast)
 
     size = sizeofW(StgMutArrPtrs) + n;
     arr = (StgMutArrPtrs *)RET_STGCALL1(P_, allocate, size);
+    TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), n, 0);
 
     SET_HDR(arr,&MUT_ARR_PTRS_info,CCCS);
     arr->ptrs = n;
@@ -232,6 +235,7 @@ FN_(newArrayZh_fast)
        *p = (W_)init;
     }
 
+    TICK_RET_UNBOXED_TUP(1);
     RET_P(arr);
   FE_
 }
@@ -243,15 +247,15 @@ FN_(newMutVarZh_fast)
   FB_
 
   HP_CHK_GEN(sizeofW(StgMutVar), R1_PTR, newMutVarZh_fast,);
-  TICK_ALLOC_PRIM(sizeofW(StgMutVar),wibble,wibble,wibble)
+  TICK_ALLOC_PRIM(sizeofW(StgHeader)+1,1, 0); /* hack, dependent on rep. */
   CCS_ALLOC(CCCS,sizeofW(StgMutVar));
 
-  mv = stgCast(StgMutVar*,Hp-sizeofW(StgMutVar)+1);
+  mv = (StgMutVar *)(Hp-sizeofW(StgMutVar)+1);
   SET_HDR(mv,&MUT_VAR_info,CCCS);
   mv->var = R1.cl;
 
+  TICK_RET_UNBOXED_TUP(1);
   RET_P(mv);
-
   FE_
 }
 
@@ -269,7 +273,8 @@ FN_(makeForeignObjZh_fast)
   FB_
 
   HP_CHK_GEN(sizeofW(StgForeignObj), NO_PTRS, makeForeignObjZh_fast,);
-  TICK_ALLOC_PRIM(sizeofW(StgForeignObj),wibble,wibble,wibble)
+  TICK_ALLOC_PRIM(sizeofW(StgHeader),
+                 sizeofW(StgForeignObj)-sizeofW(StgHeader), 0);
   CCS_ALLOC(CCCS,sizeofW(StgForeignObj)); /* ccs prof */
 
   result = (StgForeignObj *) (Hp + 1 - sizeofW(StgForeignObj));
@@ -277,6 +282,7 @@ FN_(makeForeignObjZh_fast)
   result->data = R1.p;
 
   /* returns (# s#, ForeignObj# #) */
+  TICK_RET_UNBOXED_TUP(1);
   RET_P(result);
   FE_
 }
@@ -298,7 +304,8 @@ FN_(mkWeakZh_fast)
   FB_
 
   HP_CHK_GEN(sizeofW(StgWeak), R1_PTR|R2_PTR|R3_PTR, mkWeakZh_fast,);
-  TICK_ALLOC_PRIM(sizeofW(StgWeak),wibble,wibble,wibble);
+  TICK_ALLOC_PRIM(sizeofW(StgHeader)+1,  // +1 is for the link field
+                 sizeofW(StgWeak)-sizeofW(StgHeader)-1, 0);
   CCS_ALLOC(CCCS,sizeofW(StgWeak)); /* ccs prof */
 
   w = (StgWeak *) (Hp + 1 - sizeofW(StgWeak));
@@ -312,6 +319,7 @@ FN_(mkWeakZh_fast)
   weak_ptr_list = w;
   IF_DEBUG(weak, fprintf(stderr,"New weak pointer at %p\n",w));
 
+  TICK_RET_UNBOXED_TUP(1);
   RET_P(w);
   FE_
 }
@@ -323,6 +331,7 @@ FN_(deRefWeakZh_fast)
   StgWeak *w;
   FB_
   
+  TICK_RET_UNBOXED_TUP(2);
   w = (StgWeak *)R1.p;
   if (w->header.info == &WEAK_info) {
        RET_NP(1, w->value);
@@ -347,8 +356,8 @@ FN_(int2IntegerZh_fast)
    FB_
 
    val = R1.i;
-   HP_CHK_GEN(sizeofW(StgArrWords)+1, NO_PTRS, int2IntegerZh_fast,)
-   TICK_ALLOC_PRIM(sizeofW(StgArrWords)+1,wibble,wibble,wibble)
+   HP_CHK_GEN(sizeofW(StgArrWords)+1, NO_PTRS, int2IntegerZh_fast,);
+   TICK_ALLOC_PRIM(sizeofW(StgArrWords),1,0);
    CCS_ALLOC(CCCS,sizeofW(StgArrWords)+1); /* ccs prof */
 
    p = stgCast(StgArrWords*,Hp)-1;
@@ -370,6 +379,7 @@ FN_(int2IntegerZh_fast)
                 data  :: ByteArray# 
               #)
    */
+   TICK_RET_UNBOXED_TUP(3);
    RET_NNP(1,s,p);
    FE_
 }
@@ -385,7 +395,7 @@ FN_(word2IntegerZh_fast)
 
    val = R1.w;
    HP_CHK_GEN(sizeofW(StgArrWords)+1, NO_PTRS, word2IntegerZh_fast,)
-   TICK_ALLOC_PRIM(sizeofW(StgArrWords)+1,wibble,wibble,wibble)
+   TICK_ALLOC_PRIM(sizeofW(StgArrWords),1,0);
    CCS_ALLOC(CCCS,sizeofW(StgArrWords)+1); /* ccs prof */
 
    p = stgCast(StgArrWords*,Hp)-1;
@@ -403,6 +413,7 @@ FN_(word2IntegerZh_fast)
                 data  :: ByteArray# 
               #)
    */
+  TICK_RET_UNBOXED_TUP(3);
    RET_NNP(1,s,p);
    FE_
 }
@@ -422,6 +433,7 @@ FN_(addr2IntegerZh_fast)
   if (RET_STGCALL3(int, mpz_init_set_str,&result,(str),/*base*/10))
       abort();
 
+  TICK_RET_UNBOXED_TUP(3);
   RET_NNP(result._mp_alloc, result._mp_size, 
          result._mp_d - sizeofW(StgArrWords));
   FE_
@@ -453,7 +465,7 @@ FN_(int64ToIntegerZh_fast)
        words_needed = 1;
    }
    HP_CHK_GEN(sizeofW(StgArrWords)+words_needed, NO_PTRS, int64ToIntegerZh_fast,)
-   TICK_ALLOC_PRIM(sizeofW(StgArrWords)+words_needed,wibble,wibble,wibble)
+   TICK_ALLOC_PRIM(sizeofW(StgArrWords),words_needed,0);
    CCS_ALLOC(CCCS,sizeofW(StgArrWords)+words_needed); /* ccs prof */
 
    p = stgCast(StgArrWords*,Hp)-1;
@@ -484,6 +496,7 @@ FN_(int64ToIntegerZh_fast)
                 data  :: ByteArray# 
               #)
    */
+   TICK_RET_UNBOXED_TUP(3);
    RET_NNP(a,s,p);
    FE_
 }
@@ -505,7 +518,7 @@ FN_(word64ToIntegerZh_fast)
       words_needed = 1;
    }
    HP_CHK_GEN(sizeofW(StgArrWords)+words_needed, NO_PTRS, word64ToIntegerZh_fast,)
-   TICK_ALLOC_PRIM(sizeofW(StgArrWords)+words_needed,wibble,wibble,wibble)
+   TICK_ALLOC_PRIM(sizeofW(StgArrWords),words_needed,0);
    CCS_ALLOC(CCCS,sizeofW(StgArrWords)+words_needed); /* ccs prof */
 
    p = stgCast(StgArrWords*,Hp)-1;
@@ -531,6 +544,7 @@ FN_(word64ToIntegerZh_fast)
                 data  :: ByteArray# 
               #)
    */
+   TICK_RET_UNBOXED_TUP(3);
    RET_NNP(a,s,p);
    FE_
 }
@@ -571,6 +585,7 @@ FN_(name)                                                           \
   /* Perform the operation */                                          \
   STGCALL3(mp_fun,&result,&arg1,&arg2);                                        \
                                                                        \
+  TICK_RET_UNBOXED_TUP(3);                                             \
   RET_NNP(result._mp_alloc,                                            \
          result._mp_size,                                              \
           result._mp_d-sizeofW(StgArrWords));                          \
@@ -609,6 +624,7 @@ FN_(name)                                                           \
   /* Perform the operation */                                          \
   STGCALL4(mp_fun,&result1,&result2,&arg1,&arg2);                      \
                                                                        \
+  TICK_RET_UNBOXED_TUP(6);                                             \
   RET_NNPNNP(result1._mp_alloc,                                                \
             result1._mp_size,                                          \
              result1._mp_d-sizeofW(StgArrWords),                       \
@@ -639,7 +655,7 @@ FN_(decodeFloatZh_fast)
   arg = F1;
 
   HP_CHK_GEN(sizeof(StgArrWords)+1, NO_PTRS, decodeFloatZh_fast,);
-  TICK_ALLOC_PRIM(sizeofW(StgArrWords)+1,wibble,wibble,wibble)
+  TICK_ALLOC_PRIM(sizeofW(StgArrWords),1,0);
   CCS_ALLOC(CCCS,sizeofW(StgArrWords)+1); /* ccs prof */
 
   /* Be prepared to tell Lennart-coded __decodeFloat   */
@@ -652,6 +668,7 @@ FN_(decodeFloatZh_fast)
   STGCALL3(__decodeFloat,&mantissa,&exponent,arg);
 
   /* returns: (R1 = Int# (expn), R2 = Int#, R3 = Int#, R4 = ByteArray#) */
+  TICK_RET_UNBOXED_TUP(4);
   RET_NNNP(exponent,mantissa._mp_alloc,mantissa._mp_size,p);
   FE_
 }
@@ -671,7 +688,7 @@ FN_(decodeDoubleZh_fast)
   arg = D1;
 
   HP_CHK_GEN(ARR_SIZE, NO_PTRS, decodeDoubleZh_fast,);
-  TICK_ALLOC_PRIM(ARR_SIZE,wibble,wibble,wibble)
+  TICK_ALLOC_PRIM(sizeof(StgArrWords),DOUBLE_MANTISSA_SIZE,0);
   CCS_ALLOC(CCCS,ARR_SIZE); /* ccs prof */
 
   /* Be prepared to tell Lennart-coded __decodeDouble  */
@@ -684,6 +701,7 @@ FN_(decodeDoubleZh_fast)
   STGCALL3(__decodeDouble,&mantissa,&exponent,arg);
 
   /* returns: (R1 = Int# (expn), R2 = Int#, R3 = Int#, R4 = ByteArray#) */
+  TICK_RET_UNBOXED_TUP(4);
   RET_NNNP(exponent,mantissa._mp_alloc,mantissa._mp_size,p);
   FE_
 }
@@ -709,8 +727,7 @@ FN_(forkZh_fast)
     context_switch = 1;
   }
   
-  JMP_(*Sp);
-
+  JMP_(ENTRY_CODE(Sp[0]));
   FE_
 }
 
@@ -743,7 +760,8 @@ FN_(newMVarZh_fast)
   /* args: none */
 
   HP_CHK_GEN(sizeofW(StgMVar), NO_PTRS, newMVarZh_fast,);
-  TICK_ALLOC_PRIM(sizeofW(StgMVar),wibble,wibble,wibble)
+  TICK_ALLOC_PRIM(sizeofW(StgMutVar)-1, // consider head,tail,link as admin wds
+                 1, 0);
   CCS_ALLOC(CCCS,sizeofW(StgMVar)); /* ccs prof */
   
   mvar = (StgMVar *) (Hp - sizeofW(StgMVar) + 1);
@@ -751,15 +769,15 @@ FN_(newMVarZh_fast)
   mvar->head = mvar->tail = (StgTSO *)&END_TSO_QUEUE_closure;
   mvar->value = (StgClosure *)&END_TSO_QUEUE_closure;
 
-  R1.p = (P_)mvar;
-
-  JMP_(ENTRY_CODE(Sp[0]));
+  TICK_RET_UNBOXED_TUP(1);
+  RET_P(mvar);
   FE_
 }
 
 FN_(takeMVarZh_fast)
 {
   StgMVar *mvar;
+  StgClosure *val;
 
   FB_
   /* args: R1 = MVar closure */
@@ -782,10 +800,11 @@ FN_(takeMVarZh_fast)
   }
 
   SET_INFO(mvar,&EMPTY_MVAR_info);
-  R1.cl = mvar->value;
+  val = mvar->value;
   mvar->value = (StgClosure *)&END_TSO_QUEUE_closure;
 
-  JMP_(ENTRY_CODE(Sp[0]));
+  TICK_RET_UNBOXED_TUP(1);
+  RET_P(val);
   FE_
 }
 
@@ -822,7 +841,7 @@ FN_(putMVarZh_fast)
   }
 
   /* ToDo: yield here for better communication performance? */
-  JMP_(ENTRY_CODE(*Sp));
+  JMP_(ENTRY_CODE(Sp[0]));
   FE_
 }
 
index 3d0d866..089efd2 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: RtsFlags.c,v 1.5 1999/01/19 17:06:04 simonm Exp $
+ * $Id: RtsFlags.c,v 1.6 1999/01/21 10:31:48 simonm Exp $
  *
  * Functions for parsing the argument list.
  *
@@ -190,8 +190,6 @@ void initRtsFlagsDefaults(void)
 #ifdef TICKY_TICKY
     RtsFlags.TickyFlags.showTickyStats = rtsFalse;
     RtsFlags.TickyFlags.tickyFile      = NULL;
-
-    AllFlags.doUpdEntryCounts          = rtsTrue; /*ToDo:move? */
 #endif
 }
 
index e075c9d..b9018aa 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: RtsStartup.c,v 1.2 1998/12/02 13:28:41 simonm Exp $
+ * $Id: RtsStartup.c,v 1.3 1999/01/21 10:31:49 simonm Exp $
  *
  * Main function for a standalone Haskell program.
  *
@@ -14,6 +14,7 @@
 #include "Schedule.h"   /* initScheduler */
 #include "Stats.h"      /* initStats */
 #include "Weak.h"
+#include "Ticky.h"
 
 #if defined(PROFILING)
 # include "ProfRTS.h"
@@ -132,8 +133,7 @@ shutdownHaskell(void)
 #endif
 
 #if defined(TICKY_TICKY)
-  #error FixMe.
-  if (RTSflags.TickyFlags.showTickyStats) PrintTickyInfo();
+  if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
 #endif
 
   /*
index e67cd46..2ed09d3 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: RtsUtils.c,v 1.2 1998/12/02 13:28:41 simonm Exp $
+ * $Id: RtsUtils.c,v 1.3 1999/01/21 10:31:49 simonm Exp $
  *
  * General utility functions used in the RTS.
  *
@@ -11,6 +11,7 @@
 #include "Hooks.h"
 #include "Main.h"
 #include "RtsUtils.h"
+#include "Ticky.h"
 
 #ifdef HAVE_TIME_H
 #include <time.h>
@@ -114,7 +115,7 @@ stackOverflow(nat max_stack_size)
     StackOverflowHook(max_stack_size * sizeof(W_)); /*msg*/
 
 #if defined(TICKY_TICKY)
-    if (RTSflags.TickyFlags.showTickyStats) PrintTickyInfo();
+    if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
 #endif
 
     stg_exit(EXIT_FAILURE);
@@ -128,7 +129,7 @@ heapOverflow(void)
                  RtsFlags.GcFlags.maxHeapSize * BLOCK_SIZE);
 
 #if defined(TICKY_TICKY)
-    if (Rtsflags.TickyFlags.showTickyStats) PrintTickyInfo();
+    if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
 #endif
 
     stg_exit(EXIT_FAILURE);
index d3af459..4ee0892 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Schedule.c,v 1.4 1999/01/13 17:25:44 simonm Exp $
+ * $Id: Schedule.c,v 1.5 1999/01/21 10:31:50 simonm Exp $
  *
  * Scheduler
  *
@@ -92,6 +92,7 @@ createThread(nat stack_size)
   }
 
   tso = (StgTSO *)allocate(stack_size);
+  TICK_ALLOC_TSO(stack_size-sizeofW(StgTSO),0);
   
   initThread(tso, stack_size - TSO_STRUCT_SIZEW);
   return tso;
@@ -192,6 +193,7 @@ void deleteThread(StgTSO *tso)
       int words = (stgCast(StgPtr,su) - stgCast(StgPtr,sp)) - 1;
       nat i;
       StgAP_UPD* ap = stgCast(StgAP_UPD*,allocate(AP_sizeW(words)));
+      TICK_ALLOC_THK(words+1,0);
 
       /* First build an AP_UPD consisting of the stack chunk above the
        * current update frame, with the top word on the stack as the
@@ -245,6 +247,7 @@ void deleteThread(StgTSO *tso)
          
          /* now build o = FUN(catch,ap,handler) */
          o = stgCast(StgClosure*, allocate(sizeofW(StgClosure)+2));
+         TICK_ALLOC_THK(2,0);
          SET_HDR(o,&catch_info,su->header.prof.ccs /* ToDo */);
          payloadCPtr(o,0) = stgCast(StgClosure*,ap);
          payloadCPtr(o,1) = cf->handler;
@@ -270,6 +273,7 @@ void deleteThread(StgTSO *tso)
          
          /* now build o = FUN(seq,ap) */
           o = stgCast(StgClosure*, allocate(sizeofW(StgClosure)+1));
+         TICK_ALLOC_THK(1,0);
          SET_HDR(o,&seq_info,su->header.prof.ccs /* ToDo */);
          payloadCPtr(o,0) = stgCast(StgClosure*,ap);
          
@@ -678,6 +682,7 @@ threadStackOverflow(StgTSO *tso)
   IF_DEBUG(scheduler, fprintf(stderr,"increasing stack size from %d words to %d.\n", tso->stack_size, new_stack_size));
 
   dest = (StgTSO *)allocate(new_tso_size);
+  TICK_ALLOC_TSO(new_tso_size-sizeofW(StgTSO),0);
 
   /* copy the TSO block and the old stack into the new area */
   memcpy(dest,tso,TSO_STRUCT_SIZE);
index 195fcb6..94dc96c 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: StgMiscClosures.hc,v 1.6 1999/01/18 15:21:39 simonm Exp $
+ * $Id: StgMiscClosures.hc,v 1.7 1999/01/21 10:31:51 simonm Exp $
  *
  * Entry code for various built-in closure types.
  *
@@ -111,8 +111,6 @@ INFO_TABLE(CAF_ENTERED_info,CAF_ENTERED_entry,2,1,CAF_ENTERED,const,EF_,0,0);
 STGFUN(CAF_ENTERED_entry)
 {
     FB_
-    TICK_ENT_CAF_ENTERED(Node);        /* tick */
-
     R1.p = (P_) ((StgCAF*)R1.p)->value; /* just a fancy indirection */
     TICK_ENT_VIA_NODE();
     JMP_(GET_ENTRY(R1.cl));
@@ -138,6 +136,8 @@ INFO_TABLE(BLACKHOLE_info, BLACKHOLE_entry,0,2,BLACKHOLE,const,EF_,0,0);
 STGFUN(BLACKHOLE_entry)
 {
   FB_
+    TICK_ENT_BH();
+
     /* Change the BLACKHOLE into a BLACKHOLE_BQ */
     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
     /* Put ourselves on the blocking queue for this black hole */
@@ -155,6 +155,8 @@ INFO_TABLE(BLACKHOLE_BQ_info, BLACKHOLE_BQ_entry,1,1,BLACKHOLE_BQ,const,EF_,0,0)
 STGFUN(BLACKHOLE_BQ_entry)
 {
   FB_
+    TICK_ENT_BH();
+
     /* Put ourselves on the blocking queue for this black hole */
     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
@@ -169,6 +171,8 @@ INFO_TABLE(CAF_BLACKHOLE_info, CAF_BLACKHOLE_entry,0,2,CAF_BLACKHOLE,const,EF_,0
 STGFUN(CAF_BLACKHOLE_entry)
 {
   FB_
+    TICK_ENT_BH();
+
     /* Change the BLACKHOLE into a BLACKHOLE_BQ */
     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
     /* Put ourselves on the blocking queue for this black hole */
index e093888..6b44104 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Storage.c,v 1.5 1999/01/19 17:06:05 simonm Exp $
+ * $Id: Storage.c,v 1.6 1999/01/21 10:31:51 simonm Exp $
  *
  * Storage manager front end
  *
@@ -248,7 +248,7 @@ allocate(nat n)
   bdescr *bd;
   StgPtr p;
 
-  TICK_ALLOC_PRIM(n,wibble,wibble,wibble)
+  TICK_ALLOC_HEAP(n);
   CCS_ALLOC(CCCS,n);
 
   /* big allocation (>LARGE_OBJECT_THRESHOLD) */
index 60df8b9..35c46b3 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Storage.h,v 1.4 1999/01/18 15:21:40 simonm Exp $
+ * $Id: Storage.h,v 1.5 1999/01/21 10:31:52 simonm Exp $
  *
  * External Storage Manger Interface
  *
@@ -25,6 +25,10 @@ extern void exitStorage(void);
    StgPtr allocate(int n)       Allocates a chunk of contiguous store
                                n words long, returning a pointer to
                                the first word.  Always succeeds.
+                               
+                               Don't forget to TICK_ALLOC_XXX(...)
+                               after calling allocate, for the
+                               benefit of the ticky-ticky profiler.
 
    rtsBool doYouWantToGC(void)  Returns True if the storage manager is
                                ready to perform a GC, False otherwise.
@@ -89,12 +93,6 @@ extern StgClosure *MarkRoot(StgClosure *p);
 
 extern void recordMutable(StgMutClosure *p);
 
-#ifdef TICKY_TICKY
-#error updateWithIndirection: maybe permanent indirection?
-# define Ind_info_TO_USE ((AllFlags.doUpdEntryCounts) ? &IND_PERM_info : &IND_info
-)
-#endif
-
 static inline void
 updateWithIndirection(StgClosure *p1, StgClosure *p2) 
 {
@@ -104,11 +102,13 @@ updateWithIndirection(StgClosure *p1, StgClosure *p2)
   if (bd->gen->no == 0) {
     SET_INFO(p1,&IND_info);
     ((StgInd *)p1)->indirectee = p2;
+    TICK_UPD_NEW_IND();
   } else {
     SET_INFO(p1,&IND_OLDGEN_info);
     ((StgIndOldGen *)p1)->indirectee = p2;
     ((StgIndOldGen *)p1)->mut_link = bd->gen->mut_list;
     bd->gen->mut_list = (StgMutClosure *)p1;
+    TICK_UPD_OLD_IND();
   }
 }
 
diff --git a/ghc/rts/Ticky.c b/ghc/rts/Ticky.c
new file mode 100644 (file)
index 0000000..1cfe5c7
--- /dev/null
@@ -0,0 +1,521 @@
+/* -----------------------------------------------------------------------------
+ * $Id: Ticky.c,v 1.1 1999/01/21 10:31:52 simonm Exp $
+ *
+ * (c) The GHC Team, Glasgow University, 1992-1998
+ *
+ * Ticky-ticky profiling
+ *-------------------------------------------------------------------------- */
+
+#if defined(TICKY_TICKY)
+
+#define TICKY_C                        /* define those variables */
+#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 */
+       ALLOC_FUN_ctr + ALLOC_THK_ctr + ALLOC_CON_ctr + ALLOC_TUP_ctr +
+       ALLOC_TSO_ctr +
+#ifdef PAR
+       ALLOC_FMBQ_ctr + ALLOC_FME_ctr + ALLOC_BF_ctr +
+#endif
+       ALLOC_BH_ctr  + ALLOC_UPD_PAP_ctr + ALLOC_PRIM_ctr;
+
+  unsigned long tot_adm_wds = /* total number of admin words allocated */
+       ALLOC_FUN_adm + ALLOC_THK_adm + ALLOC_CON_adm + ALLOC_TUP_adm +
+       ALLOC_TSO_adm +
+#ifdef PAR
+       ALLOC_FMBQ_adm + ALLOC_FME_adm + ALLOC_BF_adm +
+#endif
+       ALLOC_BH_adm  + ALLOC_UPD_PAP_adm + ALLOC_PRIM_adm;
+
+  unsigned long tot_gds_wds = /* total number of words of ``good stuff'' allocated */
+       ALLOC_FUN_gds + ALLOC_THK_gds + ALLOC_CON_gds + ALLOC_TUP_gds +
+       ALLOC_TSO_gds +
+#ifdef PAR
+       ALLOC_FMBQ_gds + ALLOC_FME_gds + ALLOC_BF_gds +
+#endif
+
+       ALLOC_BH_gds  + ALLOC_UPD_PAP_gds + ALLOC_PRIM_gds;
+
+  unsigned long tot_slp_wds = /* total number of ``slop'' words allocated */
+       ALLOC_FUN_slp + ALLOC_THK_slp + ALLOC_CON_slp + ALLOC_TUP_slp +
+       ALLOC_TSO_slp +
+#ifdef PAR
+       ALLOC_FMBQ_slp + ALLOC_FME_slp + ALLOC_BF_slp +
+#endif
+       ALLOC_BH_slp  + ALLOC_UPD_PAP_slp + ALLOC_PRIM_slp;
+
+  unsigned long tot_wds = /* total words */
+       tot_adm_wds + tot_gds_wds + tot_slp_wds;
+
+  unsigned long tot_enters =
+       ENT_CON_ctr + ENT_FUN_DIRECT_ctr +
+       ENT_IND_ctr + ENT_PAP_ctr + ENT_THK_ctr;
+  unsigned long jump_direct_enters =
+       tot_enters - ENT_VIA_NODE_ctr;
+  unsigned long bypass_enters =
+       ENT_FUN_DIRECT_ctr -
+       (ENT_FUN_STD_ctr - UPD_PAP_IN_NEW_ctr);
+
+  unsigned long tot_returns =
+       RET_NEW_ctr + RET_OLD_ctr + RET_UNBOXED_TUP_ctr +
+        RET_SEMI_IN_HEAP_ctr + RET_SEMI_BY_DEFAULT_ctr/*?*/;
+
+  unsigned long tot_returns_of_new = RET_NEW_ctr;
+
+  unsigned long pap_updates = UPD_PAP_IN_NEW_ctr + UPD_PAP_IN_PLACE_ctr;
+
+  unsigned long tot_updates = UPD_EXISTING_ctr + UPD_SQUEEZED_ctr + pap_updates;
+
+  unsigned long tot_new_updates   = UPD_NEW_IND_ctr;
+  unsigned long tot_old_updates   = UPD_OLD_IND_ctr;
+  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",
+       ALLOC_THK_ctr,
+       PC(INTAVG(ALLOC_THK_ctr, tot_allocs)));
+  if (ALLOC_THK_ctr != 0)
+      fprintf(tf,"\t\t\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(THK));
+
+  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",
+       ALLOC_UPD_PAP_ctr,
+       PC(INTAVG(ALLOC_UPD_PAP_ctr, tot_allocs)));
+  if (ALLOC_UPD_PAP_ctr != 0)
+      fprintf(tf,"\t\t%5.1f %5.1f %5.1f %5.1f %5.1f", ALLOC_HISTO_MAGIC(UPD_PAP));
+
+  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",
+       ENT_THK_ctr,
+       PC(INTAVG(ENT_THK_ctr,tot_enters)));
+  fprintf(tf,"%7ld (%5.1f%%) data values\n",
+       ENT_CON_ctr,
+       PC(INTAVG(ENT_CON_ctr,tot_enters)));
+  fprintf(tf,"%7ld (%5.1f%%) function values\n\t\t  [of which %ld (%.1f%%) bypassed arg-satisfaction chk]\n",
+       ENT_FUN_DIRECT_ctr,
+       PC(INTAVG(ENT_FUN_DIRECT_ctr,tot_enters)),
+       bypass_enters,
+       PC(INTAVG(bypass_enters,ENT_FUN_DIRECT_ctr)));
+  fprintf(tf,"%7ld (%5.1f%%) partial applications\n",
+       ENT_PAP_ctr,
+       PC(INTAVG(ENT_PAP_ctr,tot_enters)));
+  fprintf(tf,"%7ld (%5.1f%%) indirections\n",
+       ENT_IND_ctr,
+       PC(INTAVG(ENT_IND_ctr,tot_enters)));
+
+  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,"\nSEQ FRAMES:    %ld", SEQF_PUSHED_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);
+  fprintf(tf,"%7ld (%5.1f%%) data values\n",
+       UPD_CON_IN_NEW_ctr,
+       PC(INTAVG(UPD_CON_IN_NEW_ctr,tot_updates)));
+  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);
+  fprintf(tf,"%7ld (%5.1f%%) updates to existing heap objects (%ld by squeezing)\n",
+       UPD_EXISTING_ctr + UPD_SQUEEZED_ctr,
+       PC(INTAVG(UPD_EXISTING_ctr + UPD_SQUEEZED_ctr, tot_updates)),
+       UPD_SQUEEZED_ctr);
+
+  fprintf(tf, "UPD_CON_IN_NEW:   %7ld: ", UPD_CON_IN_NEW_ctr);
+  for (i = 0; i < 9; i++) { fprintf(tf, "%7ld", UPD_CON_IN_NEW_hst[i]); }
+  fprintf(tf, "\n");
+  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) {
+      fprintf(tf,"\nNEW GEN UPDATES: %ld (%5.1f%%)\n",
+             tot_new_updates,
+             PC(INTAVG(tot_new_updates,tot_gengc_updates)));
+      fprintf(tf,"\nOLD GEN UPDATES: %ld (%5.1f%%)\n",
+             tot_old_updates,
+             PC(INTAVG(tot_old_updates,tot_gengc_updates)));
+  }
+
+#if 0
+  printRegisteredCounterInfo(tf);
+#endif
+
+  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)
+#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);
+  PR_CTR(ALLOC_THK_ctr);
+  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);
+  PR_CTR(ALLOC_UPD_PAP_ctr);
+  PR_CTR(ALLOC_UPD_PAP_adm);
+  PR_CTR(ALLOC_UPD_PAP_gds);
+  PR_CTR(ALLOC_UPD_PAP_slp);
+  PR_HST(ALLOC_UPD_PAP_hst,0);
+  PR_HST(ALLOC_UPD_PAP_hst,1);
+  PR_HST(ALLOC_UPD_PAP_hst,2);
+  PR_HST(ALLOC_UPD_PAP_hst,3);
+  PR_HST(ALLOC_UPD_PAP_hst,4);
+
+  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);
+  PR_CTR(ENT_CON_ctr);
+  PR_CTR(ENT_FUN_STD_ctr);
+  PR_CTR(ENT_FUN_DIRECT_ctr);
+  PR_CTR(ENT_IND_ctr);
+  PR_CTR(ENT_PAP_ctr);
+  PR_CTR(ENT_THK_ctr);
+
+  PR_CTR(RET_NEW_ctr);
+  PR_CTR(RET_OLD_ctr);
+  PR_CTR(RET_SEMI_BY_DEFAULT_ctr);
+  PR_CTR(RET_SEMI_IN_HEAP_ctr);
+  PR_CTR(RET_SEMI_FAILED_IND_ctr);
+  PR_CTR(RET_SEMI_FAILED_UNEVAL_ctr);
+  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);
+  PR_HST(RET_SEMI_IN_HEAP_hst,0);
+  PR_HST(RET_SEMI_IN_HEAP_hst,1);
+  PR_HST(RET_SEMI_IN_HEAP_hst,2);
+  PR_HST(RET_SEMI_IN_HEAP_hst,3);
+  PR_HST(RET_SEMI_IN_HEAP_hst,4);
+  PR_HST(RET_SEMI_IN_HEAP_hst,5);
+  PR_HST(RET_SEMI_IN_HEAP_hst,6);
+  PR_HST(RET_SEMI_IN_HEAP_hst,7);
+  PR_HST(RET_SEMI_IN_HEAP_hst,8);
+  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(RET_SEMI_loads_avoided);
+
+  PR_CTR(UPDF_OMITTED_ctr);
+  PR_CTR(UPDF_PUSHED_ctr);
+  PR_CTR(SEQF_PUSHED_ctr);
+  PR_CTR(CATCHF_PUSHED_ctr);
+
+  PR_CTR(UPDF_RCC_PUSHED_ctr);
+  PR_CTR(UPDF_RCC_OMITTED_ctr);
+
+  PR_CTR(UPD_EXISTING_ctr);
+  PR_CTR(UPD_SQUEEZED_ctr);
+  PR_CTR(UPD_CON_IN_NEW_ctr);
+  PR_CTR(UPD_PAP_IN_NEW_ctr);
+
+  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);
+  PR_CTR(UPD_OLD_IND_ctr);
+
+  PR_CTR(GC_SEL_ABANDONED_ctr);
+  PR_CTR(GC_SEL_MINOR_ctr);
+  PR_CTR(GC_SEL_MAJOR_ctr);
+  PR_CTR(GC_FAILED_PROMOTION_ctr);
+}
+
+#if 0
+/* Data structure used in ``registering'' one of these counters. */
+
+struct ent_counter *ListOfEntryCtrs = NULL; /* root of list of them */
+
+/* To print out all the registered-counter info: */
+
+static void
+printRegisteredCounterInfo (FILE *tf)
+{
+    struct ent_counter *p;
+
+    if ( ListOfEntryCtrs != NULL ) {
+       fprintf(tf,"\n**************************************************\n");
+    }
+
+    for (p = ListOfEntryCtrs; p != NULL; p = p->link) {
+       /* common stuff first; then the wrapper info if avail */
+       fprintf(tf, "%-40s%u\t%u\t%u\t%-16s%ld",
+               p->f_str,
+               p->arity,
+               p->Astk_args,
+               p->Bstk_args,
+               p->f_arg_kinds,
+               p->ctr);
+
+       if ( p->wrap_str == NULL ) {
+           fprintf(tf, "\n");
+
+       } else {
+           fprintf(tf, "\t%s\t%s\n",
+               p->wrap_str,
+               p->wrap_arg_kinds);
+       }
+    }
+}
+#endif
+
+#endif /* TICKY_TICKY */
diff --git a/ghc/rts/Ticky.h b/ghc/rts/Ticky.h
new file mode 100644 (file)
index 0000000..9f93e29
--- /dev/null
@@ -0,0 +1,10 @@
+/* -----------------------------------------------------------------------------
+ * $Id: Ticky.h,v 1.1 1999/01/21 10:31:53 simonm Exp $
+ *
+ * (c) The GHC Team 1999
+ *
+ * Header for Ticky.c
+ *
+ * ---------------------------------------------------------------------------*/
+
+extern void PrintTickyInfo(void);
index c98dfa1..cbebe92 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Updates.hc,v 1.6 1999/01/15 17:57:11 simonm Exp $
+ * $Id: Updates.hc,v 1.7 1999/01/21 10:31:53 simonm Exp $
  *
  * Code to perform updates.
  *
@@ -273,11 +273,11 @@ EXTFUN(stg_update_PAP)
          JMP_(stg_gc_entertop);
        }
 
-       TICK_ALLOC_UPD_PAP(DYN_HS, NArgWords, 0, PapSize);
+       TICK_ALLOC_UPD_PAP(1/*fun*/ + Words, 0);
 #ifdef PROFILING
        CCS_ALLOC(CCS_pap, PapSize);
 #endif
-    
+
        PapClosure = (StgPAP *)(Hp + 1 - PapSize); /* The new PapClosure */
 
        SET_HDR(PapClosure,&PAP_info,CCS_pap);
@@ -335,7 +335,7 @@ EXTFUN(stg_update_PAP)
       UPD_IND(Updatee,PapClosure);
       
       if (Words != 0) {
-       TICK_UPD_PAP_IN_NEW(NArgWords);
+       TICK_UPD_PAP_IN_NEW(Words+1);
        
       } else {
        TICK_UPD_PAP_IN_PLACE();
@@ -418,7 +418,7 @@ STGFUN(AP_UPD_entry)
   PUSH_UPD_FRAME(R1.p, 0);
   Sp -= sizeofW(StgUpdateFrame) + Words;
 
-  TICK_ENT_PAP(ap);  /* ToDo: TICK_ENT_AP_UPD */
+  TICK_ENT_AP_UPD(ap);
 
   /* Enter PAP cost centre -- lexical scoping only */
   ENTER_CCS_PAP_CL(ap);   /* ToDo: ENTER_CC_AP_UPD_CL */
@@ -571,6 +571,7 @@ FN_(catchZh_fast)
     fp -> handler = R2.cl;
     fp -> link = Su;
     Su = (StgUpdateFrame *)fp;
+    TICK_CATCHF_PUSHED();
     TICK_ENT_VIA_NODE();
     JMP_(ENTRY_CODE(*R1.p));