1 /* -----------------------------------------------------------------------------
2 * $Id: StgLdvProf.h,v 1.1 2001/11/22 14:25:11 simonmar Exp $
4 * (c) The GHC Team, 2001
7 * Lag/Drag/Void profiling.
9 * ---------------------------------------------------------------------------*/
18 // declared in LdvProfile.c
21 // LdvGenInfo stores the statistics for one specific census.
23 double time; // the time in MUT time at the corresponding census is made
25 // We employ int instead of nat, for some values may be negative temporarily,
28 // computed at each census
29 int inherentlyUsed; // total size of 'inherently used' closures
30 int notUsed; // total size of 'never used' closures
31 int used; // total size of 'used at least once' closures
34 voidNew and dragNew are updated when a closure is destroyed.
35 For instance, when a 'never used' closure of size s and creation time
36 t is destroyed at time u, voidNew of eras t through u - 1 is increased
38 Likewise, when a 'used at least once' closure of size s and last use time
39 t is destroyed at time u, dragNew of eras t + 1 through u - 1 is increase
41 In our implementation, voidNew and dragNew are computed indirectly: instead
42 of updating voidNew or dragNew of all intervening eras, we update that
43 of the end two eras (one is increased and the other is decreased).
45 int voidNew; // current total size of 'destroyed without being used' closures
46 int dragNew; // current total size of 'used at least once and waiting to die'
49 // computed post-mortem
50 int voidTotal; // total size of closures in 'void' state
51 // lagTotal == notUsed - voidTotal // in 'lag' state
52 int dragTotal; // total size of closures in 'drag' state
53 // useTotal == used - dragTotal // in 'use' state
56 extern LdvGenInfo *gi;
58 // retrieves the LDV word from closure c
59 #define LDVW(c) (((StgClosure *)(c))->header.prof.hp.ldvw)
62 An LDV word is divided into 3 parts: state bits (LDV_STATE_MASK), creation
63 time bits (LDV_CREATE_MASK), and last use time bits (LDV_LAST_MASK).
65 #if SIZEOF_VOID_P == 8
67 #define LDV_STATE_MASK 0x1000000000000000
68 #define LDV_CREATE_MASK 0x0FFFFFFFC0000000
69 #define LDV_LAST_MASK 0x000000003FFFFFFF
70 #define LDV_STATE_CREATE 0x0000000000000000
71 #define LDV_STATE_USE 0x1000000000000000
74 #define LDV_STATE_MASK 0x40000000
75 #define LDV_CREATE_MASK 0x3FFF8000
76 #define LDV_LAST_MASK 0x00007FFF
77 #define LDV_STATE_CREATE 0x00000000
78 #define LDV_STATE_USE 0x40000000
79 #endif // SIZEOF_VOID_P
81 // Stores the creation time for closure c.
82 // This macro is called at the very moment of closure creation.
84 // NOTE: this initializes LDVW(c) to zero, which ensures that there
85 // is no conflict between retainer profiling and LDV profiling,
86 // because retainer profiling also expects LDVW(c) to be initialised
88 #define LDV_recordCreate(c) \
89 LDVW((c)) = (ldvTime << LDV_SHIFT) | LDV_STATE_CREATE
91 // Stores the last use time for closure c.
92 // This macro *must* be called whenever a closure is used, that is, it is
94 #define LDV_recordUse(c) \
97 LDVW((c)) = (LDVW((c)) & LDV_CREATE_MASK) | \
102 // Creates a 0-filled slop of size 'howManyBackwards' backwards from the
106 // 1) Hp is incremented and exceeds HpLim (in Updates.hc).
107 // 2) copypart() is called (in GC.c).
108 #define FILL_SLOP(from, howManyBackwards) \
111 for (i = 0;i < (howManyBackwards); i++) \
112 ((StgWord *)(from))[-i] = 0; \
115 // Informs the LDV profiler that closure c has just been evacuated.
116 // Evacuated objects are no longer needed, so we just store its original size in
118 #define SET_EVACUAEE_FOR_LDV(c, size) \
121 // Macros called when a closure is entered.
122 // The closure is not an 'inherently used' one.
123 // The closure is not IND or IND_OLDGEN because neither is considered for LDV
125 #define LDV_ENTER(c) LDV_recordUse((c))
132 #endif // STGLDVPROF_H