Small simplification (#11777)
[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 /* ----------------------------------------------------------------------------
128 Storage manager internal APIs and globals
129 ------------------------------------------------------------------------- */
130
131 extern bdescr *exec_block;
132
133 void move_STACK (StgStack *src, StgStack *dest);
134
135 /* -----------------------------------------------------------------------------
136 Note [STATIC_LINK fields]
137
138 The low 2 bits of the static link field have the following meaning:
139
140 00 we haven't seen this static object before
141
142 01/10 if it equals static_flag, then we saw it in this GC, otherwise
143 we saw it in the previous GC.
144
145 11 ignore during GC. This value is used in two ways
146 - When we put CAFs on a list (see Note [CAF lists])
147 - a static constructor that was determined to have no CAF
148 references at compile time is given this value, so we
149 don't traverse it during GC
150
151 This choice of values is quite deliberate, because it means we can
152 decide whether a static object should be traversed during GC using a
153 single test:
154
155 bits = link_field & 3;
156 if ((bits | prev_static_flag) != 3) { ... }
157
158 -------------------------------------------------------------------------- */
159
160 #define STATIC_BITS 3
161
162 #define STATIC_FLAG_A 1
163 #define STATIC_FLAG_B 2
164 #define STATIC_FLAG_LIST 3
165
166 #define END_OF_CAF_LIST ((StgClosure*)STATIC_FLAG_LIST)
167
168 // The previous and current values of the static flag. These flip
169 // between STATIC_FLAG_A and STATIC_FLAG_B at each major GC.
170 extern nat prev_static_flag, static_flag;
171
172 // In the chain of static objects built up during GC, all the link
173 // fields are tagged with the current static_flag value. How to mark
174 // the end of the chain? It must be a special value so that we can
175 // tell it is the end of the chain, but note that we're going to store
176 // this value in the link field of a static object, which means that
177 // during the NEXT GC we should treat it like any other object that
178 // has not been visited during this GC. Therefore, we use static_flag
179 // as the sentinel value.
180 #define END_OF_STATIC_OBJECT_LIST ((StgClosure*)(StgWord)static_flag)
181
182 #define UNTAG_STATIC_LIST_PTR(p) ((StgClosure*)((StgWord)(p) & ~STATIC_BITS))
183
184 /* -----------------------------------------------------------------------------
185 Note [CAF lists]
186
187 dyn_caf_list (CAFs chained through static_link)
188 This is a chain of all CAFs in the program, used for
189 dynamically-linked GHCi.
190 See Note [dyn_caf_list].
191
192 debug_caf_list (CAFs chained through saved_info)
193 A chain of all *live* CAFs in the program, that does not keep
194 the CAFs alive. Used for detecting when we enter a GC'd CAF,
195 and to give diagnostics with +RTS -DG.
196
197 revertible_caf_list (CAFs chained through static_link)
198 A chain of CAFs in object code loaded with the RTS linker.
199 These CAFs can be reverted to their unevaluated state using
200 revertCAFs.
201
202 Pointers in these lists are tagged with STATIC_FLAG_LIST, so when
203 traversing the list remember to untag each pointer with
204 UNTAG_STATIC_LIST_PTR().
205 --------------------------------------------------------------------------- */
206
207 extern StgIndStatic * dyn_caf_list;
208 extern StgIndStatic * debug_caf_list;
209 extern StgIndStatic * revertible_caf_list;
210
211 #include "EndPrivate.h"
212
213 #endif /* SM_STORAGE_H */