%
% (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}
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)),
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
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 -}
-- 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)
%
% (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
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 (
| 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}
%
% (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 $
%
%********************************************************
%* *
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 -}
/* ----------------------------------------------------------------------------
- * $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
*
#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
/* -----------------------------------------------------------------------------
- * $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.
*
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
/* -----------------------------------------------------------------------------
- * $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
*
-------------------------------------------------------------------------- */
#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; }
/* -----------------------------------------------------------------------------
- * $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.
*
#include "StgProf.h"
#include "PrimOps.h"
#include "Updates.h"
-#include "Ticky.h"
+#include "StgTicky.h"
#include "CCall.h"
/* Built-in entry points */
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 */
/* -----------------------------------------------------------------------------
- * $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.
*
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
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 */
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);
#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); \
}
/* -----------------------------------------------------------------------------
--- /dev/null
+/* ----------------------------------------------------------------------------
+ * $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 */
+++ /dev/null
-/* ----------------------------------------------------------------------------
- * $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 */
/* -----------------------------------------------------------------------------
- * $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.
*
*/
#define UPD_IND(updclosure, heapptr) \
- TICK_UPDATED_SET_UPDATED(updclosure); \
AWAKEN_BQ(updclosure); \
updateWithIndirection((StgClosure *)updclosure, \
(StgClosure *)heapptr);
/* -----------------------------------------------------------------------------
- * $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.
*
#include "Rts.h"
#include "RtsAPI.h"
+#include "RtsFlags.h"
#include "Schedule.h" /* for MainTSO */
#include "RtsUtils.h"
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);
/* -----------------------------------------------------------------------------
- * $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
*
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_ \
}
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;
*p = (W_)init;
}
+ TICK_RET_UNBOXED_TUP(1);
RET_P(arr);
FE_
}
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_
}
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));
result->data = R1.p;
/* returns (# s#, ForeignObj# #) */
+ TICK_RET_UNBOXED_TUP(1);
RET_P(result);
FE_
}
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));
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_
}
StgWeak *w;
FB_
+ TICK_RET_UNBOXED_TUP(2);
w = (StgWeak *)R1.p;
if (w->header.info == &WEAK_info) {
RET_NP(1, w->value);
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;
data :: ByteArray#
#)
*/
+ TICK_RET_UNBOXED_TUP(3);
RET_NNP(1,s,p);
FE_
}
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;
data :: ByteArray#
#)
*/
+ TICK_RET_UNBOXED_TUP(3);
RET_NNP(1,s,p);
FE_
}
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_
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;
data :: ByteArray#
#)
*/
+ TICK_RET_UNBOXED_TUP(3);
RET_NNP(a,s,p);
FE_
}
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;
data :: ByteArray#
#)
*/
+ TICK_RET_UNBOXED_TUP(3);
RET_NNP(a,s,p);
FE_
}
/* 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)); \
/* 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), \
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 */
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_
}
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 */
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_
}
context_switch = 1;
}
- JMP_(*Sp);
-
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
/* 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);
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 */
}
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_
}
}
/* ToDo: yield here for better communication performance? */
- JMP_(ENTRY_CODE(*Sp));
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
/* -----------------------------------------------------------------------------
- * $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.
*
#ifdef TICKY_TICKY
RtsFlags.TickyFlags.showTickyStats = rtsFalse;
RtsFlags.TickyFlags.tickyFile = NULL;
-
- AllFlags.doUpdEntryCounts = rtsTrue; /*ToDo:move? */
#endif
}
/* -----------------------------------------------------------------------------
- * $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.
*
#include "Schedule.h" /* initScheduler */
#include "Stats.h" /* initStats */
#include "Weak.h"
+#include "Ticky.h"
#if defined(PROFILING)
# include "ProfRTS.h"
#endif
#if defined(TICKY_TICKY)
- #error FixMe.
- if (RTSflags.TickyFlags.showTickyStats) PrintTickyInfo();
+ if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
#endif
/*
/* -----------------------------------------------------------------------------
- * $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.
*
#include "Hooks.h"
#include "Main.h"
#include "RtsUtils.h"
+#include "Ticky.h"
#ifdef HAVE_TIME_H
#include <time.h>
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);
RtsFlags.GcFlags.maxHeapSize * BLOCK_SIZE);
#if defined(TICKY_TICKY)
- if (Rtsflags.TickyFlags.showTickyStats) PrintTickyInfo();
+ if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
#endif
stg_exit(EXIT_FAILURE);
/* -----------------------------------------------------------------------------
- * $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
*
}
tso = (StgTSO *)allocate(stack_size);
+ TICK_ALLOC_TSO(stack_size-sizeofW(StgTSO),0);
initThread(tso, stack_size - TSO_STRUCT_SIZEW);
return 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
/* 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;
/* 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);
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);
/* -----------------------------------------------------------------------------
- * $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.
*
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));
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 */
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;
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 */
/* -----------------------------------------------------------------------------
- * $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
*
bdescr *bd;
StgPtr p;
- TICK_ALLOC_PRIM(n,wibble,wibble,wibble)
+ TICK_ALLOC_HEAP(n);
CCS_ALLOC(CCCS,n);
/* big allocation (>LARGE_OBJECT_THRESHOLD) */
/* -----------------------------------------------------------------------------
- * $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
*
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.
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)
{
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();
}
}
--- /dev/null
+/* -----------------------------------------------------------------------------
+ * $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 */
--- /dev/null
+/* -----------------------------------------------------------------------------
+ * $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);
/* -----------------------------------------------------------------------------
- * $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.
*
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);
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();
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 */
fp -> handler = R2.cl;
fp -> link = Su;
Su = (StgUpdateFrame *)fp;
+ TICK_CATCHF_PUSHED();
TICK_ENT_VIA_NODE();
JMP_(ENTRY_CODE(*R1.p));