remove accidental extra in previous patch
[ghc-hetmet.git] / ghc / includes / Storage.h
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2004
4  *
5  * External Storage Manger Interface
6  *
7  * ---------------------------------------------------------------------------*/
8
9 #ifndef STORAGE_H
10 #define STORAGE_H
11
12 #include <stddef.h>
13 #include "OSThreads.h"
14
15 /* -----------------------------------------------------------------------------
16  * Generational GC
17  *
18  * We support an arbitrary number of generations, with an arbitrary number
19  * of steps per generation.  Notes (in no particular order):
20  *
21  *       - all generations except the oldest should have two steps.  This gives
22  *         objects a decent chance to age before being promoted, and in
23  *         particular will ensure that we don't end up with too many
24  *         thunks being updated in older generations.
25  *
26  *       - the oldest generation has one step.  There's no point in aging
27  *         objects in the oldest generation.
28  *
29  *       - generation 0, step 0 (G0S0) is the allocation area.  It is given
30  *         a fixed set of blocks during initialisation, and these blocks
31  *         are never freed.
32  *
33  *       - during garbage collection, each step which is an evacuation
34  *         destination (i.e. all steps except G0S0) is allocated a to-space.
35  *         evacuated objects are allocated into the step's to-space until
36  *         GC is finished, when the original step's contents may be freed
37  *         and replaced by the to-space.
38  *
39  *       - the mutable-list is per-generation (not per-step).  G0 doesn't 
40  *         have one (since every garbage collection collects at least G0).
41  * 
42  *       - block descriptors contain pointers to both the step and the
43  *         generation that the block belongs to, for convenience.
44  *
45  *       - static objects are stored in per-generation lists.  See GC.c for
46  *         details of how we collect CAFs in the generational scheme.
47  *
48  *       - large objects are per-step, and are promoted in the same way
49  *         as small objects, except that we may allocate large objects into
50  *         generation 1 initially.
51  *
52  * ------------------------------------------------------------------------- */
53
54 typedef struct step_ {
55   unsigned int         no;              /* step number */
56   bdescr *             blocks;          /* blocks in this step */
57   unsigned int         n_blocks;        /* number of blocks */
58   struct step_ *       to;              /* destination step for live objects */
59   struct generation_ * gen;             /* generation this step belongs to */
60   unsigned int         gen_no;          /* generation number (cached) */
61   bdescr *             large_objects;   /* large objects (doubly linked) */
62   unsigned int         n_large_blocks;  /* no. of blocks used by large objs */
63   int                  is_compacted;    /* compact this step? (old gen only) */
64
65   /* During GC, if we are collecting this step, blocks and n_blocks
66    * are copied into the following two fields.  After GC, these blocks
67    * are freed. */
68   bdescr *     old_blocks;              /* bdescr of first from-space block */
69   unsigned int n_old_blocks;            /* number of blocks in from-space */
70
71   /* temporary use during GC: */
72   StgPtr       hp;                      /* next free locn in to-space */
73   StgPtr       hpLim;                   /* end of current to-space block */
74   bdescr *     hp_bd;                   /* bdescr of current to-space block */
75   StgPtr       scavd_hp;                /* ... same as above, but already */
76   StgPtr       scavd_hpLim;             /*     scavenged.  */
77   bdescr *     scan_bd;                 /* block currently being scanned */
78   StgPtr       scan;                    /* scan pointer in current block */
79   bdescr *     new_large_objects;       /* large objects collected so far */
80   bdescr *     scavenged_large_objects; /* live large objs after GC (d-link) */
81   unsigned int n_scavenged_large_blocks;/* size of above */
82   bdescr *     bitmap;                  /* bitmap for compacting collection */
83 } step;
84
85 typedef struct generation_ {
86   unsigned int   no;                    /* generation number */
87   step *         steps;                 /* steps */
88   unsigned int   n_steps;               /* number of steps */
89   unsigned int   max_blocks;            /* max blocks in step 0 */
90   bdescr        *mut_list;              /* mut objects in this gen (not G0)*/
91
92   /* temporary use during GC: */
93   bdescr        *saved_mut_list;
94
95   /* stats information */
96   unsigned int collections;
97   unsigned int failed_promotions;
98 } generation;
99
100 extern generation * RTS_VAR(generations);
101
102 extern generation * RTS_VAR(g0);
103 extern step * RTS_VAR(g0s0);
104 extern generation * RTS_VAR(oldest_gen);
105
106 /* -----------------------------------------------------------------------------
107    Initialisation / De-initialisation
108    -------------------------------------------------------------------------- */
109
110 extern void initStorage(void);
111 extern void exitStorage(void);
112
113 /* -----------------------------------------------------------------------------
114    Generic allocation
115
116    StgPtr allocate(nat n)       Allocates a chunk of contiguous store
117                                 n words long, returning a pointer to
118                                 the first word.  Always succeeds.
119                                 
120    StgPtr allocatePinned(nat n) Allocates a chunk of contiguous store
121                                 n words long, which is at a fixed
122                                 address (won't be moved by GC).  
123                                 Returns a pointer to the first word.
124                                 Always succeeds.
125                                 
126                                 NOTE: the GC can't in general handle
127                                 pinned objects, so allocatePinned()
128                                 can only be used for ByteArrays at the
129                                 moment.
130
131                                 Don't forget to TICK_ALLOC_XXX(...)
132                                 after calling allocate or
133                                 allocatePinned, for the
134                                 benefit of the ticky-ticky profiler.
135
136    rtsBool doYouWantToGC(void)  Returns True if the storage manager is
137                                 ready to perform a GC, False otherwise.
138
139    lnat  allocated_bytes(void)  Returns the number of bytes allocated
140                                 via allocate() since the last GC.
141                                 Used in the reporting of statistics.
142
143    THREADED_RTS: allocate and doYouWantToGC can be used from STG code, they are
144    surrounded by a mutex.
145    -------------------------------------------------------------------------- */
146
147 extern StgPtr  allocate        ( nat n );
148 extern StgPtr  allocateLocal   ( Capability *cap, nat n );
149 extern StgPtr  allocatePinned  ( nat n );
150 extern lnat    allocated_bytes ( void );
151
152 extern bdescr * RTS_VAR(small_alloc_list);
153 extern bdescr * RTS_VAR(large_alloc_list);
154 extern bdescr * RTS_VAR(pinned_object_block);
155
156 extern StgPtr RTS_VAR(alloc_Hp);
157 extern StgPtr RTS_VAR(alloc_HpLim);
158
159 extern nat RTS_VAR(alloc_blocks);
160 extern nat RTS_VAR(alloc_blocks_lim);
161
162 INLINE_HEADER rtsBool
163 doYouWantToGC( void )
164 {
165   return (alloc_blocks >= alloc_blocks_lim);
166 }
167
168 /* -----------------------------------------------------------------------------
169    Performing Garbage Collection
170
171    GarbageCollect(get_roots)    Performs a garbage collection.  
172                                 'get_roots' is called to find all the 
173                                 roots that the system knows about.
174
175    StgClosure                   Called by get_roots on each root.       
176    MarkRoot(StgClosure *p)      Returns the new location of the root.
177    -------------------------------------------------------------------------- */
178
179 extern void GarbageCollect(void (*get_roots)(evac_fn),rtsBool force_major_gc);
180
181 /* -----------------------------------------------------------------------------
182    Generational garbage collection support
183
184    recordMutable(StgPtr p)       Informs the garbage collector that a
185                                  previously immutable object has
186                                  become (permanently) mutable.  Used
187                                  by thawArray and similar.
188
189    updateWithIndirection(p1,p2)  Updates the object at p1 with an
190                                  indirection pointing to p2.  This is
191                                  normally called for objects in an old
192                                  generation (>0) when they are updated.
193
194    updateWithPermIndirection(p1,p2)  As above but uses a permanent indir.
195
196    -------------------------------------------------------------------------- */
197
198 /*
199  * Storage manager mutex
200  */
201 #if defined(THREADED_RTS)
202 extern Mutex sm_mutex;
203 extern Mutex atomic_modify_mutvar_mutex;
204 #endif
205
206 #if defined(THREADED_RTS)
207 #define ACQUIRE_SM_LOCK   ACQUIRE_LOCK(&sm_mutex);
208 #define RELEASE_SM_LOCK   RELEASE_LOCK(&sm_mutex);
209 #define ASSERT_SM_LOCK()  ASSERT_LOCK_HELD(&sm_mutex);
210 #else
211 #define ACQUIRE_SM_LOCK
212 #define RELEASE_SM_LOCK
213 #define ASSERT_SM_LOCK()
214 #endif
215
216 INLINE_HEADER void
217 recordMutableGen(StgClosure *p, generation *gen)
218 {
219     bdescr *bd;
220
221     bd = gen->mut_list;
222     if (bd->free >= bd->start + BLOCK_SIZE_W) {
223         bdescr *new_bd;
224         new_bd = allocBlock();
225         new_bd->link = bd;
226         bd = new_bd;
227         gen->mut_list = bd;
228     }
229     *bd->free++ = (StgWord)p;
230
231 }
232
233 INLINE_HEADER void
234 recordMutableGenLock(StgClosure *p, generation *gen)
235 {
236     ACQUIRE_SM_LOCK;
237     recordMutableGen(p,gen);
238     RELEASE_SM_LOCK;
239 }
240
241 INLINE_HEADER void
242 recordMutable(StgClosure *p)
243 {
244     bdescr *bd;
245     ASSERT(closure_MUTABLE(p));
246     bd = Bdescr((P_)p);
247     if (bd->gen_no > 0) recordMutableGen(p, &RTS_DEREF(generations)[bd->gen_no]);
248 }
249
250 INLINE_HEADER void
251 recordMutableLock(StgClosure *p)
252 {
253     ACQUIRE_SM_LOCK;
254     recordMutable(p);
255     RELEASE_SM_LOCK;
256 }
257
258 /* -----------------------------------------------------------------------------
259    The CAF table - used to let us revert CAFs in GHCi
260    -------------------------------------------------------------------------- */
261
262 /* set to disable CAF garbage collection in GHCi. */
263 /* (needed when dynamic libraries are used). */
264 extern rtsBool keepCAFs;
265
266 /* -----------------------------------------------------------------------------
267    This is the write barrier for MUT_VARs, a.k.a. IORefs.  A
268    MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY
269    is.  When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY
270    and is put on the mutable list.
271    -------------------------------------------------------------------------- */
272
273 void dirty_MUT_VAR(StgRegTable *reg, StgClosure *p);
274
275 /* -----------------------------------------------------------------------------
276    DEBUGGING predicates for pointers
277
278    LOOKS_LIKE_INFO_PTR(p)    returns False if p is definitely not an info ptr
279    LOOKS_LIKE_CLOSURE_PTR(p) returns False if p is definitely not a closure ptr
280
281    These macros are complete but not sound.  That is, they might
282    return false positives.  Do not rely on them to distinguish info
283    pointers from closure pointers, for example.
284
285    We don't use address-space predicates these days, for portability
286    reasons, and the fact that code/data can be scattered about the
287    address space in a dynamically-linked environment.  Our best option
288    is to look at the alleged info table and see whether it seems to
289    make sense...
290    -------------------------------------------------------------------------- */
291
292 #define LOOKS_LIKE_INFO_PTR(p) \
293    (p && ((StgInfoTable *)(INFO_PTR_TO_STRUCT(p)))->type != INVALID_OBJECT && \
294     ((StgInfoTable *)(INFO_PTR_TO_STRUCT(p)))->type < N_CLOSURE_TYPES)
295
296 #define LOOKS_LIKE_CLOSURE_PTR(p) \
297    (LOOKS_LIKE_INFO_PTR(((StgClosure *)(p))->header.info))
298
299 /* -----------------------------------------------------------------------------
300    Macros for calculating how big a closure will be (used during allocation)
301    -------------------------------------------------------------------------- */
302
303 INLINE_HEADER StgOffset PAP_sizeW   ( nat n_args )
304 { return sizeofW(StgPAP) + n_args; }
305
306 INLINE_HEADER StgOffset AP_sizeW   ( nat n_args )
307 { return sizeofW(StgAP) + n_args; }
308
309 INLINE_HEADER StgOffset AP_STACK_sizeW ( nat size )
310 { return sizeofW(StgAP_STACK) + size; }
311
312 INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np )
313 { return sizeofW(StgHeader) + p + np; }
314
315 INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void )
316 { return sizeofW(StgSelector); }
317
318 INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void )
319 { return sizeofW(StgHeader)+MIN_PAYLOAD_SIZE; }
320
321 /* --------------------------------------------------------------------------
322    Sizes of closures
323    ------------------------------------------------------------------------*/
324
325 INLINE_HEADER StgOffset sizeW_fromITBL( const StgInfoTable* itbl ) 
326 { return sizeofW(StgClosure) 
327        + sizeofW(StgPtr)  * itbl->layout.payload.ptrs 
328        + sizeofW(StgWord) * itbl->layout.payload.nptrs; }
329
330 INLINE_HEADER StgOffset thunk_sizeW_fromITBL( const StgInfoTable* itbl ) 
331 { return sizeofW(StgThunk) 
332        + sizeofW(StgPtr)  * itbl->layout.payload.ptrs 
333        + sizeofW(StgWord) * itbl->layout.payload.nptrs; }
334
335 INLINE_HEADER StgOffset ap_stack_sizeW( StgAP_STACK* x )
336 { return AP_STACK_sizeW(x->size); }
337
338 INLINE_HEADER StgOffset ap_sizeW( StgAP* x )
339 { return AP_sizeW(x->n_args); }
340
341 INLINE_HEADER StgOffset pap_sizeW( StgPAP* x )
342 { return PAP_sizeW(x->n_args); }
343
344 INLINE_HEADER StgOffset arr_words_sizeW( StgArrWords* x )
345 { return sizeofW(StgArrWords) + x->words; }
346
347 INLINE_HEADER StgOffset mut_arr_ptrs_sizeW( StgMutArrPtrs* x )
348 { return sizeofW(StgMutArrPtrs) + x->ptrs; }
349
350 INLINE_HEADER StgWord tso_sizeW ( StgTSO *tso )
351 { return TSO_STRUCT_SIZEW + tso->stack_size; }
352
353 INLINE_HEADER StgWord bco_sizeW ( StgBCO *bco )
354 { return bco->size; }
355
356 STATIC_INLINE nat
357 closure_sizeW_ (StgClosure *p, StgInfoTable *info)
358 {
359     switch (info->type) {
360     case THUNK_0_1:
361     case THUNK_1_0:
362         return sizeofW(StgThunk) + 1;
363     case FUN_0_1:
364     case CONSTR_0_1:
365     case FUN_1_0:
366     case CONSTR_1_0:
367         return sizeofW(StgHeader) + 1;
368     case THUNK_0_2:
369     case THUNK_1_1:
370     case THUNK_2_0:
371         return sizeofW(StgThunk) + 2;
372     case FUN_0_2:
373     case CONSTR_0_2:
374     case FUN_1_1:
375     case CONSTR_1_1:
376     case FUN_2_0:
377     case CONSTR_2_0:
378         return sizeofW(StgHeader) + 2;
379     case THUNK:
380         return thunk_sizeW_fromITBL(info);
381     case THUNK_SELECTOR:
382         return THUNK_SELECTOR_sizeW();
383     case AP_STACK:
384         return ap_stack_sizeW((StgAP_STACK *)p);
385     case AP:
386     case PAP:
387         return pap_sizeW((StgPAP *)p);
388     case IND:
389     case IND_PERM:
390     case IND_OLDGEN:
391     case IND_OLDGEN_PERM:
392         return sizeofW(StgInd);
393     case ARR_WORDS:
394         return arr_words_sizeW((StgArrWords *)p);
395     case MUT_ARR_PTRS_CLEAN:
396     case MUT_ARR_PTRS_DIRTY:
397     case MUT_ARR_PTRS_FROZEN:
398     case MUT_ARR_PTRS_FROZEN0:
399         return mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
400     case TSO:
401         return tso_sizeW((StgTSO *)p);
402     case BCO:
403         return bco_sizeW((StgBCO *)p);
404     case TVAR_WAIT_QUEUE:
405         return sizeofW(StgTVarWaitQueue);
406     case TVAR:
407         return sizeofW(StgTVar);
408     case TREC_CHUNK:
409         return sizeofW(StgTRecChunk);
410     case TREC_HEADER:
411         return sizeofW(StgTRecHeader);
412     default:
413         return sizeW_fromITBL(info);
414     }
415 }
416
417 // The definitive way to find the size, in words, of a heap-allocated closure
418 STATIC_INLINE nat
419 closure_sizeW (StgClosure *p)
420 {
421     return closure_sizeW_(p, get_itbl(p));
422 }
423
424 /* -----------------------------------------------------------------------------
425    Sizes of stack frames
426    -------------------------------------------------------------------------- */
427
428 INLINE_HEADER StgWord stack_frame_sizeW( StgClosure *frame )
429 {
430     StgRetInfoTable *info;
431
432     info = get_ret_itbl(frame);
433     switch (info->i.type) {
434
435     case RET_DYN:
436     {
437         StgRetDyn *dyn = (StgRetDyn *)frame;
438         return  sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE + 
439             RET_DYN_NONPTR_REGS_SIZE +
440             RET_DYN_PTRS(dyn->liveness) + RET_DYN_NONPTRS(dyn->liveness);
441     }
442             
443     case RET_FUN:
444         return sizeofW(StgRetFun) + ((StgRetFun *)frame)->size;
445
446     case RET_BIG:
447     case RET_VEC_BIG:
448         return 1 + GET_LARGE_BITMAP(&info->i)->size;
449
450     case RET_BCO:
451         return 2 + BCO_BITMAP_SIZE((StgBCO *)((P_)frame)[1]);
452
453     default:
454         return 1 + BITMAP_SIZE(info->i.layout.bitmap);
455     }
456 }
457
458 /* -----------------------------------------------------------------------------
459    Nursery manipulation
460    -------------------------------------------------------------------------- */
461
462 extern void     allocNurseries       ( void );
463 extern void     resetNurseries       ( void );
464 extern void     resizeNurseries      ( nat blocks );
465 extern void     resizeNurseriesFixed ( nat blocks );
466 extern void     tidyAllocateLists    ( void );
467 extern lnat     countNurseryBlocks   ( void );
468
469 /* -----------------------------------------------------------------------------
470    Functions from GC.c 
471    -------------------------------------------------------------------------- */
472
473 extern void         threadPaused ( Capability *cap, StgTSO * );
474 extern StgClosure * isAlive      ( StgClosure *p );
475 extern void         markCAFs     ( evac_fn evac );
476
477 /* -----------------------------------------------------------------------------
478    Stats 'n' DEBUG stuff
479    -------------------------------------------------------------------------- */
480
481 extern ullong RTS_VAR(total_allocated);
482
483 extern lnat calcAllocated  ( void );
484 extern lnat calcLive       ( void );
485 extern lnat calcNeeded     ( void );
486
487 #if defined(DEBUG)
488 extern void memInventory(void);
489 extern void checkSanity(void);
490 extern nat  countBlocks(bdescr *);
491 extern void checkNurserySanity( step *stp );
492 #endif
493
494 #if defined(DEBUG)
495 void printMutOnceList(generation *gen);
496 void printMutableList(generation *gen);
497 #endif
498
499 /* ----------------------------------------------------------------------------
500    Storage manager internal APIs and globals
501    ------------------------------------------------------------------------- */
502
503 #define END_OF_STATIC_LIST stgCast(StgClosure*,1)
504
505 extern void newDynCAF(StgClosure *);
506
507 extern void move_TSO(StgTSO *src, StgTSO *dest);
508 extern StgTSO *relocate_stack(StgTSO *dest, ptrdiff_t diff);
509
510 extern StgClosure * RTS_VAR(scavenged_static_objects);
511 extern StgWeak    * RTS_VAR(old_weak_ptr_list);
512 extern StgWeak    * RTS_VAR(weak_ptr_list);
513 extern StgClosure * RTS_VAR(caf_list);
514 extern StgClosure * RTS_VAR(revertible_caf_list);
515 extern StgTSO     * RTS_VAR(resurrected_threads);
516
517 #endif /* STORAGE_H */