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