[project @ 2001-07-23 17:23:19 by simonmar]
[ghc-hetmet.git] / ghc / rts / Storage.h
1 /* -----------------------------------------------------------------------------
2  * $Id: Storage.h,v 1.34 2001/07/23 17:23:20 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * External Storage Manger Interface
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #ifndef STORAGE_H
11 #define STORAGE_H
12
13 #include "Block.h"
14 #include "BlockAlloc.h"
15 #include "StoragePriv.h"
16
17 /* -----------------------------------------------------------------------------
18    Initialisation / De-initialisation
19    -------------------------------------------------------------------------- */
20
21 extern void initStorage(void);
22 extern void exitStorage(void);
23
24 /* -----------------------------------------------------------------------------
25    Generic allocation
26
27    StgPtr allocate(int n)       Allocates a chunk of contiguous store
28                                 n words long, returning a pointer to
29                                 the first word.  Always succeeds.
30                                 
31                                 Don't forget to TICK_ALLOC_XXX(...)
32                                 after calling allocate, for the
33                                 benefit of the ticky-ticky profiler.
34
35    rtsBool doYouWantToGC(void)  Returns True if the storage manager is
36                                 ready to perform a GC, False otherwise.
37
38    lnat  allocated_bytes(void)  Returns the number of bytes allocated
39                                 via allocate() since the last GC.
40                                 Used in the reoprting of statistics.
41
42    SMP: allocate and doYouWantToGC can be used from STG code, they are
43    surrounded by a mutex.
44    -------------------------------------------------------------------------- */
45
46 extern StgPtr  allocate(nat n);
47 static inline rtsBool doYouWantToGC(void)
48 {
49   return (alloc_blocks >= alloc_blocks_lim);
50 }
51 extern lnat allocated_bytes(void);
52
53 /* -----------------------------------------------------------------------------
54    ExtendNursery(hp,hplim)      When hplim is reached, try to grab
55                                 some more allocation space.  Returns
56                                 False if the allocation space is
57                                 exhausted, and the application should
58                                 call GarbageCollect().
59   -------------------------------------------------------------------------- */
60
61 #define ExtendNursery(hp,hplim)                 \
62   (CurrentNursery->free = (P_)(hp)+1,           \
63    CurrentNursery->link == NULL ? rtsFalse :    \
64    (CurrentNursery = CurrentNursery->link,      \
65     OpenNursery(hp,hplim),                      \
66     rtsTrue))
67
68 extern void PleaseStopAllocating(void);
69
70 /* -----------------------------------------------------------------------------
71    Performing Garbage Collection
72
73    GarbageCollect(get_roots)    Performs a garbage collection.  
74                                 'get_roots' is called to find all the 
75                                 roots that the system knows about.
76
77    StgClosure                   Called by get_roots on each root.       
78    MarkRoot(StgClosure *p)      Returns the new location of the root.
79    -------------------------------------------------------------------------- */
80
81 extern void GarbageCollect(void (*get_roots)(evac_fn),rtsBool force_major_gc);
82
83 /* -----------------------------------------------------------------------------
84    Generational garbage collection support
85
86    recordMutable(StgPtr p)       Informs the garbage collector that a
87                                  previously immutable object has
88                                  become (permanently) mutable.  Used
89                                  by thawArray and similar.
90
91    updateWithIndirection(p1,p2)  Updates the object at p1 with an
92                                  indirection pointing to p2.  This is
93                                  normally called for objects in an old
94                                  generation (>0) when they are updated.
95
96    updateWithPermIndirection(p1,p2)  As above but uses a permanent indir.
97
98    -------------------------------------------------------------------------- */
99
100 /*
101  * Storage manager mutex
102  */
103 #ifdef SMP
104 extern pthread_mutex_t sm_mutex;
105 #endif
106
107 /* ToDo: shouldn't recordMutable and recordOldToNewPtrs acquire some
108  * kind of lock in the SMP case?
109  */
110 static inline void
111 recordMutable(StgMutClosure *p)
112 {
113   bdescr *bd;
114
115 #ifdef SMP
116   ASSERT(p->header.info == &stg_WHITEHOLE_info || closure_MUTABLE(p));
117 #else
118   ASSERT(closure_MUTABLE(p));
119 #endif
120
121   bd = Bdescr((P_)p);
122   if (bd->gen_no > 0) {
123     p->mut_link = generations[bd->gen_no].mut_list;
124     generations[bd->gen_no].mut_list = p;
125   }
126 }
127
128 static inline void
129 recordOldToNewPtrs(StgMutClosure *p)
130 {
131   bdescr *bd;
132   
133   bd = Bdescr((P_)p);
134   if (bd->gen_no > 0) {
135     p->mut_link = generations[bd->gen_no].mut_once_list;
136     generations[bd->gen_no].mut_once_list = p;
137   }
138 }
139
140 #ifndef DEBUG
141 #define updateWithIndirection(info, p1, p2)                             \
142   {                                                                     \
143     bdescr *bd;                                                         \
144                                                                         \
145     bd = Bdescr((P_)p1);                                                \
146     if (bd->gen_no == 0) {                                              \
147       ((StgInd *)p1)->indirectee = p2;                                  \
148       SET_INFO(p1,&stg_IND_info);                                       \
149       TICK_UPD_NEW_IND();                                               \
150     } else {                                                            \
151       ((StgIndOldGen *)p1)->indirectee = p2;                            \
152       if (info != &stg_BLACKHOLE_BQ_info) {                             \
153         ACQUIRE_LOCK(&sm_mutex);                                        \
154         ((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list; \
155         generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1;                    \
156         RELEASE_LOCK(&sm_mutex);                                        \
157       }                                                                 \
158       SET_INFO(p1,&stg_IND_OLDGEN_info);                                \
159       TICK_UPD_OLD_IND();                                               \
160     }                                                                   \
161   }
162 #else
163
164 /* In the DEBUG case, we also zero out the slop of the old closure,
165  * so that the sanity checker can tell where the next closure is.
166  *
167  * Two important invariants: we should never try to update a closure
168  * to point to itself, and the closure being updated should not
169  * already have been updated (the mutable list will get messed up
170  * otherwise).
171  */
172 #define updateWithIndirection(info, p1, p2)                             \
173   {                                                                     \
174     bdescr *bd;                                                         \
175                                                                         \
176     ASSERT( p1 != p2 && !closure_IND(p1) );                             \
177     bd = Bdescr((P_)p1);                                                \
178     if (bd->gen_no == 0) {                                              \
179       ((StgInd *)p1)->indirectee = p2;                                  \
180       SET_INFO(p1,&stg_IND_info);                                       \
181       TICK_UPD_NEW_IND();                                               \
182     } else {                                                            \
183       if (info != &stg_BLACKHOLE_BQ_info) {                             \
184         {                                                               \
185           StgInfoTable *inf = get_itbl(p1);                             \
186           nat np = inf->layout.payload.ptrs,                            \
187               nw = inf->layout.payload.nptrs, i;                        \
188           if (inf->type != THUNK_SELECTOR) {                            \
189              for (i = np; i < np + nw; i++) {                           \
190                 ((StgClosure *)p1)->payload[i] = 0;                     \
191              }                                                          \
192           }                                                             \
193         }                                                               \
194         ACQUIRE_LOCK(&sm_mutex);                                        \
195         ((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list; \
196         generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1;                    \
197         RELEASE_LOCK(&sm_mutex);                                        \
198       }                                                                 \
199       ((StgIndOldGen *)p1)->indirectee = p2;                            \
200       SET_INFO(p1,&stg_IND_OLDGEN_info);                                \
201       TICK_UPD_OLD_IND();                                               \
202     }                                                                   \
203   }
204 #endif
205
206 /* Static objects all live in the oldest generation
207  */
208 #define updateWithStaticIndirection(info, p1, p2)                       \
209   {                                                                     \
210     ASSERT( p1 != p2 && !closure_IND(p1) );                             \
211     ASSERT( ((StgMutClosure*)p1)->mut_link == NULL );                   \
212                                                                         \
213     ACQUIRE_LOCK(&sm_mutex);                                            \
214     ((StgMutClosure *)p1)->mut_link = oldest_gen->mut_once_list;        \
215     oldest_gen->mut_once_list = (StgMutClosure *)p1;                    \
216     RELEASE_LOCK(&sm_mutex);                                            \
217                                                                         \
218     ((StgInd *)p1)->indirectee = p2;                                    \
219     SET_INFO((StgInd *)p1, &stg_IND_STATIC_info);                       \
220     TICK_UPD_STATIC_IND();                                              \
221   }
222
223 #if defined(TICKY_TICKY) || defined(PROFILING)
224 static inline void
225 updateWithPermIndirection(const StgInfoTable *info, StgClosure *p1, StgClosure *p2) 
226 {
227   bdescr *bd;
228
229   ASSERT( p1 != p2 && !closure_IND(p1) );
230   bd = Bdescr((P_)p1);
231   if (bd->gen_no == 0) {
232     ((StgInd *)p1)->indirectee = p2;
233     SET_INFO(p1,&stg_IND_PERM_info);
234     TICK_UPD_NEW_PERM_IND(p1);
235   } else {
236     ((StgIndOldGen *)p1)->indirectee = p2;
237     if (info != &stg_BLACKHOLE_BQ_info) {
238       ACQUIRE_LOCK(&sm_mutex);
239       ((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list;
240       generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1;
241       RELEASE_LOCK(&sm_mutex);
242     }
243     SET_INFO(p1,&stg_IND_OLDGEN_PERM_info);
244     TICK_UPD_OLD_PERM_IND();
245   }
246 }
247 #endif
248
249 /* -----------------------------------------------------------------------------
250    The CAF table - used to let us revert CAFs
251    -------------------------------------------------------------------------- */
252
253 void revertCAFs( void );
254
255 #if defined(DEBUG)
256 void printMutOnceList(generation *gen);
257 void printMutableList(generation *gen);
258 #endif /* DEBUG */
259
260 /* --------------------------------------------------------------------------
261                       Address space layout macros
262    --------------------------------------------------------------------------
263
264    Here are the assumptions GHC makes about address space layout.
265    Broadly, it thinks there are three sections:
266
267      CODE    Read-only.  Contains code and read-only data (such as
268                 info tables)
269              Also called "text"
270
271      DATA    Read-write data.  Contains static closures (and on some
272                 architectures, info tables too)
273
274      HEAP    Dynamically-allocated closures
275
276      USER    None of the above.  The only way USER things arise right 
277              now is when GHCi allocates a constructor info table, which
278              it does by mallocing them.
279
280    Three macros identify these three areas:
281      IS_CODE(p), IS_DATA(p), HEAP_ALLOCED(p)
282
283    HEAP_ALLOCED is called FOR EVERY SINGLE CLOSURE during GC.
284    It needs to be FAST.
285
286    Implementation of HEAP_ALLOCED
287    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
288    Concerning HEAP, most of the time (certainly under [Static] and [GHCi],
289    we ensure that the heap is allocated above some fixed address HEAP_BASE
290    (defined in MBlock.h).  In this case we set TEXT_BEFORE_HEAP, and we
291    get a nice fast test.
292
293    Sometimes we can't be quite sure.  For example in Windows, we can't 
294    fix where our heap address space comes from.  In this case we un-set 
295    TEXT_BEFORE_HEAP. That makes it more expensive to test whether a pointer
296    comes from the HEAP section, because we need to look at the allocator's
297    address maps (see HEAP_ALLOCED macro)
298
299    Implementation of CODE and DATA
300    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301    Concerning CODE and DATA, there are three main regimes:
302
303      [Static] Totally      The segments are contiguous, and laid out 
304      statically linked     exactly as above
305
306      [GHCi] Static,        GHCi may load new modules, but it knows the
307      except for GHCi       address map, so for any given address it can
308                            still tell which section it belongs to
309
310      [DLL] OS-supported    Chunks of CODE and DATA may be mixed in 
311      dynamic loading       the address space, and we can't tell how
312
313
314    For the [Static] case, we assume memory is laid out like this
315    (in order of increasing addresses)
316
317        Start of memory
318            CODE section
319        TEXT_SECTION_END_MARKER   (usually _etext)
320            DATA section
321        DATA_SECTION_END_MARKER   (usually _end)
322            USER section
323        HEAP_BASE
324            HEAP section
325
326    For the [GHCi] case, we have to consult GHCi's dynamic linker's
327    address maps, which is done by macros
328          is_dynamically_loaded_code_or_rodata_ptr
329          is_dynamically_loaded_code_or_rwdata_ptr
330
331    For the [DLL] case, IS_CODE and IS_DATA are really not usable at all.
332  */
333
334
335 #undef TEXT_BEFORE_HEAP
336 #ifndef mingw32_TARGET_OS
337 #define TEXT_BEFORE_HEAP 1
338 #endif
339
340 extern void* TEXT_SECTION_END_MARKER_DECL;
341 extern void* DATA_SECTION_END_MARKER_DECL;
342
343 /* Take into account code sections in dynamically loaded object files. */
344 #define IS_CODE_PTR(p) (  ((P_)(p) < (P_)&TEXT_SECTION_END_MARKER) \
345                        || is_dynamically_loaded_code_or_rodata_ptr((char *)p) )
346 #define IS_DATA_PTR(p) ( ((P_)(p) >= (P_)&TEXT_SECTION_END_MARKER && \
347                           (P_)(p) < (P_)&DATA_SECTION_END_MARKER) \
348                        || is_dynamically_loaded_rwdata_ptr((char *)p) )
349 #define IS_USER_PTR(p) ( ((P_)(p) >= (P_)&DATA_SECTION_END_MARKER) \
350                        && is_not_dynamically_loaded_ptr((char *)p) )
351
352 /* The HEAP_ALLOCED test below is called FOR EVERY SINGLE CLOSURE
353  * during GC.  It needs to be FAST.
354  *
355  * BEWARE: when we're dynamically loading code (for GHCi), make sure
356  * that we don't load any code above HEAP_BASE, or this test won't work.
357  */
358 #ifdef TEXT_BEFORE_HEAP
359 # define HEAP_ALLOCED(x)  ((StgPtr)(x) >= (StgPtr)(HEAP_BASE))
360 #else
361 extern int is_heap_alloced(const void* x);
362 # define HEAP_ALLOCED(x)  (is_heap_alloced(x))
363 #endif
364
365
366 /* --------------------------------------------------------------------------
367    Macros for distinguishing data pointers from code pointers
368    --------------------------------------------------------------------------
369
370   Specification
371   ~~~~~~~~~~~~~
372   The garbage collector needs to make some critical distinctions between pointers.
373   In particular we need
374  
375      LOOKS_LIKE_GHC_INFO(p)          p points to an info table
376
377   For both of these macros, p is
378       *either* a pointer to a closure (static or heap allocated)
379       *or* a return address on the (Haskell) stack
380
381   (Return addresses are in fact info-pointers, so that the Haskell stack
382   looks very like a chunk of heap.)
383
384   The garbage collector uses LOOKS_LIKE_GHC_INFO when walking the stack, as it
385   walks over the "pending arguments" on its way to the next return address.
386   It is called moderately often, but not as often as HEAP_ALLOCED
387
388   ToDo: LOOKS_LIKE_GHC_INFO(p) does not return True when p points to a
389   constructor info table allocated by GHCi.  We should really rename 
390   LOOKS_LIKE_GHC_INFO to LOOKS_LIKE_GHC_RETURN_INFO.
391
392   Implementation
393   ~~~~~~~~~~~~~~
394   LOOKS_LIKE_GHC_INFO is more complicated because of the need to distinguish 
395   between static closures and info tables.  It's a known portability problem.
396   We have three approaches:
397
398   Plan A: Address-space partitioning.  
399     Keep info tables in the (single, contiguous) text segment:    IS_CODE_PTR(p)
400     and static closures in the (single, contiguous) data segment: IS_DATA_PTR(p)
401
402   Plan A can fail for two reasons:
403     * In many environments (eg. dynamic loading),
404       text and data aren't in a single contiguous range.  
405     * When we compile through vanilla C (no mangling) we sometimes
406       can't guaranteee to put info tables in the text section.  This
407       happens eg. on MacOS where the C compiler refuses to put const
408       data in the text section if it has any code pointers in it
409       (which info tables do *only* when we're compiling without
410       TABLES_NEXT_TO_CODE).
411     
412   Hence, Plan B: (compile-via-C-with-mangling, or native code generation)
413     Put a zero word before each static closure.
414     When compiling to native code, or via C-with-mangling, info tables
415     are laid out "backwards" from the address specified in the info pointer
416     (the entry code goes forward from the info pointer).  Hence, the word
417     before the one referenced the info pointer is part of the info table,
418     and is guaranteed non-zero.
419
420     For reasons nobody seems to fully understand, the statically-allocated tables
421     of INTLIKE and CHARLIKE closures can't have this zero word, so we
422     have to test separately for them.
423
424     Plan B fails altogether for the compile-through-vanilla-C route, because
425     info tables aren't laid out backwards.
426
427
428   Hence, Plan C: (unregisterised, compile-through-vanilla-C route only)
429     If we didn't manage to get info tables into the text section, then
430     we can distinguish between a static closure pointer and an info
431     pointer as follows:  the first word of an info table is a code pointer,
432     and therefore in text space, whereas the first word of a closure pointer
433     is an info pointer, and therefore not.  Shazam!
434 */
435
436
437 /* When working with Win32 DLLs, static closures are identified by
438    being prefixed with a zero word. This is needed so that we can
439    distinguish between pointers to static closures and (reversed!)
440    info tables.
441
442    This 'scheme' breaks down for closure tables such as CHARLIKE,
443    so we catch these separately.
444   
445    LOOKS_LIKE_STATIC_CLOSURE() 
446        - discriminates between static closures and info tbls
447          (needed by LOOKS_LIKE_GHC_INFO() below - [Win32 DLLs only.])
448    LOOKS_LIKE_STATIC() 
449        - distinguishes between static and heap allocated data.
450  */
451 #if defined(ENABLE_WIN32_DLL_SUPPORT)
452             /* definitely do not enable for mingw DietHEP */
453 #define LOOKS_LIKE_STATIC(r) (!(HEAP_ALLOCED(r)))
454
455 /* Tiresome predicates needed to check for pointers into the closure tables */
456 #define IS_CHARLIKE_CLOSURE(p) \
457     ( (P_)(p) >= (P_)stg_CHARLIKE_closure && \
458       (char*)(p) <= ((char*)stg_CHARLIKE_closure + \
459                      (MAX_CHARLIKE-MIN_CHARLIKE) * sizeof(StgIntCharlikeClosure)) )
460 #define IS_INTLIKE_CLOSURE(p) \
461     ( (P_)(p) >= (P_)stg_INTLIKE_closure && \
462       (char*)(p) <= ((char*)stg_INTLIKE_closure + \
463                      (MAX_INTLIKE-MIN_INTLIKE) * sizeof(StgIntCharlikeClosure)) )
464
465 #define LOOKS_LIKE_STATIC_CLOSURE(r) (((*(((unsigned long *)(r))-1)) == 0) || IS_CHARLIKE_CLOSURE(r) || IS_INTLIKE_CLOSURE(r))
466 #else
467 #define LOOKS_LIKE_STATIC(r) IS_DATA_PTR(r)
468 #define LOOKS_LIKE_STATIC_CLOSURE(r) IS_DATA_PTR(r)
469 #endif
470
471
472 /* -----------------------------------------------------------------------------
473    Macros for distinguishing infotables from closures.
474    
475    You'd think it'd be easy to tell an info pointer from a closure pointer:
476    closures live on the heap and infotables are in read only memory.  Right?
477    Wrong!  Static closures live in read only memory and Hugs allocates
478    infotables for constructors on the (writable) C heap.
479    -------------------------------------------------------------------------- */
480
481 /* not accurate by any means, but stops the assertions failing... */
482 /* TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO */
483 #define IS_HUGS_CONSTR_INFO(info)  IS_USER_PTR(info)
484
485 /* LOOKS_LIKE_GHC_INFO is called moderately often during GC, but
486  * Certainly not as often as HEAP_ALLOCED.
487  */
488 #ifdef TEXT_BEFORE_HEAP /* needed for mingw DietHEP */
489 # define LOOKS_LIKE_GHC_INFO(info) IS_CODE_PTR(info)
490 #else
491 # define LOOKS_LIKE_GHC_INFO(info) (!HEAP_ALLOCED(info) \
492                                     && !LOOKS_LIKE_STATIC_CLOSURE(info))
493 #endif
494
495
496 /* -----------------------------------------------------------------------------
497    Macros for calculating how big a closure will be (used during allocation)
498    -------------------------------------------------------------------------- */
499
500 /* ToDo: replace unsigned int by nat.  The only fly in the ointment is that
501  * nat comes from Rts.h which many folk dont include.  Sigh!
502  */
503 static __inline__ StgOffset AP_sizeW    ( unsigned int n_args )              
504 { return sizeofW(StgAP_UPD) + n_args; }
505
506 static __inline__ StgOffset PAP_sizeW   ( unsigned int n_args )              
507 { return sizeofW(StgPAP)    + n_args; }
508
509 static __inline__ StgOffset CONSTR_sizeW( unsigned int p, unsigned int np )  
510 { return sizeofW(StgHeader) + p + np; }
511
512 static __inline__ StgOffset THUNK_SELECTOR_sizeW ( void )                    
513 { return sizeofW(StgHeader) + MIN_UPD_SIZE; }
514
515 static __inline__ StgOffset BLACKHOLE_sizeW ( void )                    
516 { return sizeofW(StgHeader) + MIN_UPD_SIZE; }
517
518 /* --------------------------------------------------------------------------
519  * Sizes of closures
520  * ------------------------------------------------------------------------*/
521
522 static __inline__ StgOffset sizeW_fromITBL( const StgInfoTable* itbl ) 
523 { return sizeofW(StgClosure) 
524        + sizeofW(StgPtr)  * itbl->layout.payload.ptrs 
525        + sizeofW(StgWord) * itbl->layout.payload.nptrs; }
526
527 static __inline__ StgOffset pap_sizeW( StgPAP* x )
528 { return PAP_sizeW(x->n_args); }
529
530 static __inline__ StgOffset arr_words_sizeW( StgArrWords* x )
531 { return sizeofW(StgArrWords) + x->words; }
532
533 static __inline__ StgOffset mut_arr_ptrs_sizeW( StgMutArrPtrs* x )
534 { return sizeofW(StgMutArrPtrs) + x->ptrs; }
535
536 static __inline__ StgWord tso_sizeW ( StgTSO *tso )
537 { return TSO_STRUCT_SIZEW + tso->stack_size; }
538
539 #endif /* STORAGE_H */
540