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