Eliminate zero_static_objects_list()
[ghc.git] / rts / sm / Storage.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2009
4 *
5 * External Storage Manger Interface
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #ifndef SM_STORAGE_H
10 #define SM_STORAGE_H
11
12 #include "Capability.h"
13
14 #include "BeginPrivate.h"
15
16 /* -----------------------------------------------------------------------------
17 Initialisation / De-initialisation
18 -------------------------------------------------------------------------- */
19
20 void initStorage(void);
21 void exitStorage(void);
22 void freeStorage(rtsBool free_heap);
23
24 // Adding more Capabilities later: this function allocates nurseries
25 // and initialises other storage-related things.
26 void storageAddCapabilities (nat from, nat to);
27
28 /* -----------------------------------------------------------------------------
29 Storage manager state
30 -------------------------------------------------------------------------- */
31
32 INLINE_HEADER rtsBool
33 doYouWantToGC( Capability *cap )
34 {
35 return (cap->r.rCurrentNursery->link == NULL ||
36 g0->n_new_large_words >= large_alloc_lim);
37 }
38
39 /* for splitting blocks groups in two */
40 bdescr * splitLargeBlock (bdescr *bd, W_ blocks);
41
42 /* -----------------------------------------------------------------------------
43 Generational garbage collection support
44
45 updateWithIndirection(p1,p2) Updates the object at p1 with an
46 indirection pointing to p2. This is
47 normally called for objects in an old
48 generation (>0) when they are updated.
49
50 updateWithPermIndirection(p1,p2) As above but uses a permanent indir.
51
52 -------------------------------------------------------------------------- */
53
54 /*
55 * Storage manager mutex
56 */
57 #if defined(THREADED_RTS)
58 extern Mutex sm_mutex;
59 #endif
60
61 #if defined(THREADED_RTS)
62 #define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex);
63 #define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex);
64 #define ASSERT_SM_LOCK() ASSERT_LOCK_HELD(&sm_mutex);
65 #else
66 #define ACQUIRE_SM_LOCK
67 #define RELEASE_SM_LOCK
68 #define ASSERT_SM_LOCK()
69 #endif
70
71 /* -----------------------------------------------------------------------------
72 The write barrier for MVARs and TVARs
73 -------------------------------------------------------------------------- */
74
75 void dirty_MVAR(StgRegTable *reg, StgClosure *p);
76 void dirty_TVAR(Capability *cap, StgTVar *p);
77
78 /* -----------------------------------------------------------------------------
79 Nursery manipulation
80 -------------------------------------------------------------------------- */
81
82 extern nursery *nurseries;
83 extern nat n_nurseries;
84
85 void resetNurseries ( void );
86 void clearNursery ( Capability *cap );
87 void resizeNurseries ( W_ blocks );
88 void resizeNurseriesFixed ( void );
89 W_ countNurseryBlocks ( void );
90 rtsBool getNewNursery ( Capability *cap );
91
92 /* -----------------------------------------------------------------------------
93 Allocation accounting
94
95 See [Note allocation accounting] in Storage.c
96 -------------------------------------------------------------------------- */
97
98 //
99 // Called when we are finished allocating into a block; account for the amount
100 // allocated in cap->total_allocated.
101 //
102 INLINE_HEADER void finishedNurseryBlock (Capability *cap, bdescr *bd) {
103 cap->total_allocated += bd->free - bd->start;
104 }
105
106 INLINE_HEADER void newNurseryBlock (bdescr *bd) {
107 bd->free = bd->start;
108 }
109
110 void updateNurseriesStats (void);
111 StgWord calcTotalAllocated (void);
112
113 /* -----------------------------------------------------------------------------
114 Stats 'n' DEBUG stuff
115 -------------------------------------------------------------------------- */
116
117 W_ countLargeAllocated (void);
118 W_ countOccupied (bdescr *bd);
119 W_ calcNeeded (rtsBool force_major, W_ *blocks_needed);
120
121 W_ gcThreadLiveWords (nat i, nat g);
122 W_ gcThreadLiveBlocks (nat i, nat g);
123
124 W_ genLiveWords (generation *gen);
125 W_ genLiveBlocks (generation *gen);
126
127 W_ calcLiveBlocks (void);
128 W_ calcLiveWords (void);
129
130 /* ----------------------------------------------------------------------------
131 Storage manager internal APIs and globals
132 ------------------------------------------------------------------------- */
133
134 extern bdescr *exec_block;
135
136 void move_STACK (StgStack *src, StgStack *dest);
137
138 /* -----------------------------------------------------------------------------
139 Note [STATIC_LINK fields]
140
141 The low 2 bits of the static link field have the following meaning:
142
143 00 we haven't seen this static object before
144
145 01/10 if it equals static_flag, then we saw it in this GC, otherwise
146 we saw it in the previous GC.
147
148 11 ignore during GC. This value is used in two ways
149 - When we put CAFs on a list (see Note [CAF lists])
150 - a static constructor that was determined to have no CAF
151 references at compile time is given this value, so we
152 don't traverse it during GC
153
154 This choice of values is quite deliberate, because it means we can
155 decide whether a static object should be traversed during GC using a
156 single test:
157
158 bits = link_field & 3;
159 if ((bits | prev_static_flag) != 3) { ... }
160
161 -------------------------------------------------------------------------- */
162
163 #define STATIC_BITS 3
164
165 #define STATIC_FLAG_A 1
166 #define STATIC_FLAG_B 2
167 #define STATIC_FLAG_LIST 3
168
169 #define END_OF_CAF_LIST ((StgClosure*)STATIC_FLAG_LIST)
170
171 // The previous and current values of the static flag. These flip
172 // between STATIC_FLAG_A and STATIC_FLAG_B at each major GC.
173 extern nat prev_static_flag, static_flag;
174
175 // In the chain of static objects built up during GC, all the link
176 // fields are tagged with the current static_flag value. How to mark
177 // the end of the chain? It must be a special value so that we can
178 // tell it is the end of the chain, but note that we're going to store
179 // this value in the link field of a static object, which means that
180 // during the NEXT GC we should treat it like any other object that
181 // has not been visited during this GC. Therefore, we use static_flag
182 // as the sentinel value.
183 #define END_OF_STATIC_OBJECT_LIST ((StgClosure*)(StgWord)static_flag)
184
185 #define UNTAG_STATIC_LIST_PTR(p) ((StgClosure*)((StgWord)(p) & ~STATIC_BITS))
186
187 /* -----------------------------------------------------------------------------
188 Note [CAF lists]
189
190 dyn_caf_list (CAFs chained through static_link)
191 This is a chain of all CAFs in the program, used for
192 dynamically-linked GHCi.
193 See Note [dyn_caf_list].
194
195 debug_caf_list (CAFs chained through saved_info)
196 A chain of all *live* CAFs in the program, that does not keep
197 the CAFs alive. Used for detecting when we enter a GC'd CAF,
198 and to give diagnostics with +RTS -DG.
199
200 revertible_caf_list (CAFs chained through static_link)
201 A chain of CAFs in object code loaded with the RTS linker.
202 These CAFs can be reverted to their unevaluated state using
203 revertCAFs.
204
205 Pointers in these lists are tagged with STATIC_FLAG_LIST, so when
206 traversing the list remember to untag each pointer with
207 UNTAG_STATIC_LIST_PTR().
208 --------------------------------------------------------------------------- */
209
210 extern StgIndStatic * dyn_caf_list;
211 extern StgIndStatic * debug_caf_list;
212 extern StgIndStatic * revertible_caf_list;
213
214 #include "EndPrivate.h"
215
216 #endif /* SM_STORAGE_H */