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