Add several new record features
[ghc-hetmet.git] / 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 extern void freeStorage(void);
113
114 /* -----------------------------------------------------------------------------
115    Generic allocation
116
117    StgPtr allocate(nat n)       Allocates a chunk of contiguous store
118                                 n words long, returning a pointer to
119                                 the first word.  Always succeeds.
120                                 
121    StgPtr allocateLocal(Capability *cap, nat n)
122                                 Allocates memory from the nursery in
123                                 the current Capability.  This can be
124                                 done without taking a global lock,
125                                 unlike allocate().
126
127    StgPtr allocatePinned(nat n) Allocates a chunk of contiguous store
128                                 n words long, which is at a fixed
129                                 address (won't be moved by GC).  
130                                 Returns a pointer to the first word.
131                                 Always succeeds.
132                                 
133                                 NOTE: the GC can't in general handle
134                                 pinned objects, so allocatePinned()
135                                 can only be used for ByteArrays at the
136                                 moment.
137
138                                 Don't forget to TICK_ALLOC_XXX(...)
139                                 after calling allocate or
140                                 allocatePinned, for the
141                                 benefit of the ticky-ticky profiler.
142
143    rtsBool doYouWantToGC(void)  Returns True if the storage manager is
144                                 ready to perform a GC, False otherwise.
145
146    lnat  allocatedBytes(void)  Returns the number of bytes allocated
147                                 via allocate() since the last GC.
148                                 Used in the reporting of statistics.
149
150    -------------------------------------------------------------------------- */
151
152 extern StgPtr  allocate        ( nat n );
153 extern StgPtr  allocateLocal   ( Capability *cap, nat n );
154 extern StgPtr  allocatePinned  ( nat n );
155 extern lnat    allocatedBytes  ( void );
156
157 extern bdescr * RTS_VAR(small_alloc_list);
158 extern bdescr * RTS_VAR(large_alloc_list);
159 extern bdescr * RTS_VAR(pinned_object_block);
160
161 extern StgPtr RTS_VAR(alloc_Hp);
162 extern StgPtr RTS_VAR(alloc_HpLim);
163
164 extern nat RTS_VAR(alloc_blocks);
165 extern nat RTS_VAR(alloc_blocks_lim);
166
167 INLINE_HEADER rtsBool
168 doYouWantToGC( void )
169 {
170   return (alloc_blocks >= alloc_blocks_lim);
171 }
172
173 /* memory allocator for executable memory */
174 extern void *allocateExec (nat bytes);
175 extern void freeExec (void *p);
176
177 /* -----------------------------------------------------------------------------
178    Performing Garbage Collection
179
180    GarbageCollect(get_roots)    Performs a garbage collection.  
181                                 'get_roots' is called to find all the 
182                                 roots that the system knows about.
183
184    StgClosure                   Called by get_roots on each root.       
185    MarkRoot(StgClosure *p)      Returns the new location of the root.
186    -------------------------------------------------------------------------- */
187
188 extern void GarbageCollect(rtsBool force_major_gc);
189
190 /* -----------------------------------------------------------------------------
191    Generational garbage collection support
192
193    recordMutable(StgPtr p)       Informs the garbage collector that a
194                                  previously immutable object has
195                                  become (permanently) mutable.  Used
196                                  by thawArray and similar.
197
198    updateWithIndirection(p1,p2)  Updates the object at p1 with an
199                                  indirection pointing to p2.  This is
200                                  normally called for objects in an old
201                                  generation (>0) when they are updated.
202
203    updateWithPermIndirection(p1,p2)  As above but uses a permanent indir.
204
205    -------------------------------------------------------------------------- */
206
207 /*
208  * Storage manager mutex
209  */
210 #if defined(THREADED_RTS)
211 extern Mutex sm_mutex;
212 extern Mutex atomic_modify_mutvar_mutex;
213 #endif
214
215 #if defined(THREADED_RTS)
216 #define ACQUIRE_SM_LOCK   ACQUIRE_LOCK(&sm_mutex);
217 #define RELEASE_SM_LOCK   RELEASE_LOCK(&sm_mutex);
218 #define ASSERT_SM_LOCK()  ASSERT_LOCK_HELD(&sm_mutex);
219 #else
220 #define ACQUIRE_SM_LOCK
221 #define RELEASE_SM_LOCK
222 #define ASSERT_SM_LOCK()
223 #endif
224
225 INLINE_HEADER void
226 recordMutableGen(StgClosure *p, generation *gen)
227 {
228     bdescr *bd;
229
230     bd = gen->mut_list;
231     if (bd->free >= bd->start + BLOCK_SIZE_W) {
232         bdescr *new_bd;
233         new_bd = allocBlock();
234         new_bd->link = bd;
235         bd = new_bd;
236         gen->mut_list = bd;
237     }
238     *bd->free++ = (StgWord)p;
239
240 }
241
242 INLINE_HEADER void
243 recordMutableGenLock(StgClosure *p, generation *gen)
244 {
245     ACQUIRE_SM_LOCK;
246     recordMutableGen(p,gen);
247     RELEASE_SM_LOCK;
248 }
249
250 INLINE_HEADER void
251 recordMutable(StgClosure *p)
252 {
253     bdescr *bd;
254     ASSERT(closure_MUTABLE(p));
255     bd = Bdescr((P_)p);
256     if (bd->gen_no > 0) recordMutableGen(p, &RTS_DEREF(generations)[bd->gen_no]);
257 }
258
259 INLINE_HEADER void
260 recordMutableLock(StgClosure *p)
261 {
262     ACQUIRE_SM_LOCK;
263     recordMutable(p);
264     RELEASE_SM_LOCK;
265 }
266
267 /* -----------------------------------------------------------------------------
268    The CAF table - used to let us revert CAFs in GHCi
269    -------------------------------------------------------------------------- */
270
271 /* set to disable CAF garbage collection in GHCi. */
272 /* (needed when dynamic libraries are used). */
273 extern rtsBool keepCAFs;
274
275 /* -----------------------------------------------------------------------------
276    This is the write barrier for MUT_VARs, a.k.a. IORefs.  A
277    MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY
278    is.  When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY
279    and is put on the mutable list.
280    -------------------------------------------------------------------------- */
281
282 void dirty_MUT_VAR(StgRegTable *reg, StgClosure *p);
283
284 /* -----------------------------------------------------------------------------
285    DEBUGGING predicates for pointers
286
287    LOOKS_LIKE_INFO_PTR(p)    returns False if p is definitely not an info ptr
288    LOOKS_LIKE_CLOSURE_PTR(p) returns False if p is definitely not a closure ptr
289
290    These macros are complete but not sound.  That is, they might
291    return false positives.  Do not rely on them to distinguish info
292    pointers from closure pointers, for example.
293
294    We don't use address-space predicates these days, for portability
295    reasons, and the fact that code/data can be scattered about the
296    address space in a dynamically-linked environment.  Our best option
297    is to look at the alleged info table and see whether it seems to
298    make sense...
299    -------------------------------------------------------------------------- */
300
301 #define LOOKS_LIKE_INFO_PTR(p) \
302    (p && ((StgInfoTable *)(INFO_PTR_TO_STRUCT(p)))->type != INVALID_OBJECT && \
303     ((StgInfoTable *)(INFO_PTR_TO_STRUCT(p)))->type < N_CLOSURE_TYPES)
304
305 #define LOOKS_LIKE_CLOSURE_PTR(p) \
306    (LOOKS_LIKE_INFO_PTR(((StgClosure *)(p))->header.info))
307
308 /* -----------------------------------------------------------------------------
309    Macros for calculating how big a closure will be (used during allocation)
310    -------------------------------------------------------------------------- */
311
312 INLINE_HEADER StgOffset PAP_sizeW   ( nat n_args )
313 { return sizeofW(StgPAP) + n_args; }
314
315 INLINE_HEADER StgOffset AP_sizeW   ( nat n_args )
316 { return sizeofW(StgAP) + n_args; }
317
318 INLINE_HEADER StgOffset AP_STACK_sizeW ( nat size )
319 { return sizeofW(StgAP_STACK) + size; }
320
321 INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np )
322 { return sizeofW(StgHeader) + p + np; }
323
324 INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void )
325 { return sizeofW(StgSelector); }
326
327 INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void )
328 { return sizeofW(StgHeader)+MIN_PAYLOAD_SIZE; }
329
330 /* --------------------------------------------------------------------------
331    Sizes of closures
332    ------------------------------------------------------------------------*/
333
334 INLINE_HEADER StgOffset sizeW_fromITBL( const StgInfoTable* itbl ) 
335 { return sizeofW(StgClosure) 
336        + sizeofW(StgPtr)  * itbl->layout.payload.ptrs 
337        + sizeofW(StgWord) * itbl->layout.payload.nptrs; }
338
339 INLINE_HEADER StgOffset thunk_sizeW_fromITBL( const StgInfoTable* itbl ) 
340 { return sizeofW(StgThunk) 
341        + sizeofW(StgPtr)  * itbl->layout.payload.ptrs 
342        + sizeofW(StgWord) * itbl->layout.payload.nptrs; }
343
344 INLINE_HEADER StgOffset ap_stack_sizeW( StgAP_STACK* x )
345 { return AP_STACK_sizeW(x->size); }
346
347 INLINE_HEADER StgOffset ap_sizeW( StgAP* x )
348 { return AP_sizeW(x->n_args); }
349
350 INLINE_HEADER StgOffset pap_sizeW( StgPAP* x )
351 { return PAP_sizeW(x->n_args); }
352
353 INLINE_HEADER StgOffset arr_words_sizeW( StgArrWords* x )
354 { return sizeofW(StgArrWords) + x->words; }
355
356 INLINE_HEADER StgOffset mut_arr_ptrs_sizeW( StgMutArrPtrs* x )
357 { return sizeofW(StgMutArrPtrs) + x->ptrs; }
358
359 INLINE_HEADER StgWord tso_sizeW ( StgTSO *tso )
360 { return TSO_STRUCT_SIZEW + tso->stack_size; }
361
362 INLINE_HEADER StgWord bco_sizeW ( StgBCO *bco )
363 { return bco->size; }
364
365 INLINE_HEADER nat
366 closure_sizeW_ (StgClosure *p, StgInfoTable *info)
367 {
368     switch (info->type) {
369     case THUNK_0_1:
370     case THUNK_1_0:
371         return sizeofW(StgThunk) + 1;
372     case FUN_0_1:
373     case CONSTR_0_1:
374     case FUN_1_0:
375     case CONSTR_1_0:
376         return sizeofW(StgHeader) + 1;
377     case THUNK_0_2:
378     case THUNK_1_1:
379     case THUNK_2_0:
380         return sizeofW(StgThunk) + 2;
381     case FUN_0_2:
382     case CONSTR_0_2:
383     case FUN_1_1:
384     case CONSTR_1_1:
385     case FUN_2_0:
386     case CONSTR_2_0:
387         return sizeofW(StgHeader) + 2;
388     case THUNK:
389         return thunk_sizeW_fromITBL(info);
390     case THUNK_SELECTOR:
391         return THUNK_SELECTOR_sizeW();
392     case AP_STACK:
393         return ap_stack_sizeW((StgAP_STACK *)p);
394     case AP:
395         return ap_sizeW((StgAP *)p);
396     case PAP:
397         return pap_sizeW((StgPAP *)p);
398     case IND:
399     case IND_PERM:
400     case IND_OLDGEN:
401     case IND_OLDGEN_PERM:
402         return sizeofW(StgInd);
403     case ARR_WORDS:
404         return arr_words_sizeW((StgArrWords *)p);
405     case MUT_ARR_PTRS_CLEAN:
406     case MUT_ARR_PTRS_DIRTY:
407     case MUT_ARR_PTRS_FROZEN:
408     case MUT_ARR_PTRS_FROZEN0:
409         return mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
410     case TSO:
411         return tso_sizeW((StgTSO *)p);
412     case BCO:
413         return bco_sizeW((StgBCO *)p);
414     case TVAR_WATCH_QUEUE:
415         return sizeofW(StgTVarWatchQueue);
416     case TVAR:
417         return sizeofW(StgTVar);
418     case TREC_CHUNK:
419         return sizeofW(StgTRecChunk);
420     case TREC_HEADER:
421         return sizeofW(StgTRecHeader);
422     case ATOMIC_INVARIANT:
423         return sizeofW(StgAtomicInvariant);
424     case INVARIANT_CHECK_QUEUE:
425         return sizeofW(StgInvariantCheckQueue);
426     default:
427         return sizeW_fromITBL(info);
428     }
429 }
430
431 // The definitive way to find the size, in words, of a heap-allocated closure
432 INLINE_HEADER nat
433 closure_sizeW (StgClosure *p)
434 {
435     return closure_sizeW_(p, get_itbl(p));
436 }
437
438 /* -----------------------------------------------------------------------------
439    Sizes of stack frames
440    -------------------------------------------------------------------------- */
441
442 INLINE_HEADER StgWord stack_frame_sizeW( StgClosure *frame )
443 {
444     StgRetInfoTable *info;
445
446     info = get_ret_itbl(frame);
447     switch (info->i.type) {
448
449     case RET_DYN:
450     {
451         StgRetDyn *dyn = (StgRetDyn *)frame;
452         return  sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE + 
453             RET_DYN_NONPTR_REGS_SIZE +
454             RET_DYN_PTRS(dyn->liveness) + RET_DYN_NONPTRS(dyn->liveness);
455     }
456             
457     case RET_FUN:
458         return sizeofW(StgRetFun) + ((StgRetFun *)frame)->size;
459
460     case RET_BIG:
461         return 1 + GET_LARGE_BITMAP(&info->i)->size;
462
463     case RET_BCO:
464         return 2 + BCO_BITMAP_SIZE((StgBCO *)((P_)frame)[1]);
465
466     default:
467         return 1 + BITMAP_SIZE(info->i.layout.bitmap);
468     }
469 }
470
471 /* -----------------------------------------------------------------------------
472    Nursery manipulation
473    -------------------------------------------------------------------------- */
474
475 extern void     allocNurseries       ( void );
476 extern void     resetNurseries       ( void );
477 extern void     resizeNurseries      ( nat blocks );
478 extern void     resizeNurseriesFixed ( nat blocks );
479 extern void     tidyAllocateLists    ( void );
480 extern lnat     countNurseryBlocks   ( void );
481
482 /* -----------------------------------------------------------------------------
483    Functions from GC.c 
484    -------------------------------------------------------------------------- */
485
486 typedef void (*evac_fn)(StgClosure **);
487
488 extern void         threadPaused ( Capability *cap, StgTSO * );
489 extern StgClosure * isAlive      ( StgClosure *p );
490 extern void         markCAFs     ( evac_fn evac );
491
492 /* -----------------------------------------------------------------------------
493    Stats 'n' DEBUG stuff
494    -------------------------------------------------------------------------- */
495
496 extern ullong RTS_VAR(total_allocated);
497
498 extern lnat calcAllocated  ( void );
499 extern lnat calcLive       ( void );
500 extern lnat calcNeeded     ( void );
501
502 #if defined(DEBUG)
503 extern void memInventory(void);
504 extern void checkSanity(void);
505 extern nat  countBlocks(bdescr *);
506 extern void checkNurserySanity( step *stp );
507 #endif
508
509 #if defined(DEBUG)
510 void printMutOnceList(generation *gen);
511 void printMutableList(generation *gen);
512 #endif
513
514 /* ----------------------------------------------------------------------------
515    Storage manager internal APIs and globals
516    ------------------------------------------------------------------------- */
517
518 #define END_OF_STATIC_LIST stgCast(StgClosure*,1)
519
520 extern void newDynCAF(StgClosure *);
521
522 extern void move_TSO(StgTSO *src, StgTSO *dest);
523 extern StgTSO *relocate_stack(StgTSO *dest, ptrdiff_t diff);
524
525 extern StgClosure * RTS_VAR(scavenged_static_objects);
526 extern StgWeak    * RTS_VAR(old_weak_ptr_list);
527 extern StgWeak    * RTS_VAR(weak_ptr_list);
528 extern StgClosure * RTS_VAR(caf_list);
529 extern StgClosure * RTS_VAR(revertible_caf_list);
530 extern StgTSO     * RTS_VAR(resurrected_threads);
531
532 #endif /* STORAGE_H */