1 /* -----------------------------------------------------------------------------
2 * $Id: Storage.h,v 1.34 2001/07/23 17:23:20 simonmar Exp $
4 * (c) The GHC Team, 1998-1999
6 * External Storage Manger Interface
8 * ---------------------------------------------------------------------------*/
14 #include "BlockAlloc.h"
15 #include "StoragePriv.h"
17 /* -----------------------------------------------------------------------------
18 Initialisation / De-initialisation
19 -------------------------------------------------------------------------- */
21 extern void initStorage(void);
22 extern void exitStorage(void);
24 /* -----------------------------------------------------------------------------
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.
31 Don't forget to TICK_ALLOC_XXX(...)
32 after calling allocate, for the
33 benefit of the ticky-ticky profiler.
35 rtsBool doYouWantToGC(void) Returns True if the storage manager is
36 ready to perform a GC, False otherwise.
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.
42 SMP: allocate and doYouWantToGC can be used from STG code, they are
43 surrounded by a mutex.
44 -------------------------------------------------------------------------- */
46 extern StgPtr allocate(nat n);
47 static inline rtsBool doYouWantToGC(void)
49 return (alloc_blocks >= alloc_blocks_lim);
51 extern lnat allocated_bytes(void);
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 -------------------------------------------------------------------------- */
61 #define ExtendNursery(hp,hplim) \
62 (CurrentNursery->free = (P_)(hp)+1, \
63 CurrentNursery->link == NULL ? rtsFalse : \
64 (CurrentNursery = CurrentNursery->link, \
65 OpenNursery(hp,hplim), \
68 extern void PleaseStopAllocating(void);
70 /* -----------------------------------------------------------------------------
71 Performing Garbage Collection
73 GarbageCollect(get_roots) Performs a garbage collection.
74 'get_roots' is called to find all the
75 roots that the system knows about.
77 StgClosure Called by get_roots on each root.
78 MarkRoot(StgClosure *p) Returns the new location of the root.
79 -------------------------------------------------------------------------- */
81 extern void GarbageCollect(void (*get_roots)(evac_fn),rtsBool force_major_gc);
83 /* -----------------------------------------------------------------------------
84 Generational garbage collection support
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.
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.
96 updateWithPermIndirection(p1,p2) As above but uses a permanent indir.
98 -------------------------------------------------------------------------- */
101 * Storage manager mutex
104 extern pthread_mutex_t sm_mutex;
107 /* ToDo: shouldn't recordMutable and recordOldToNewPtrs acquire some
108 * kind of lock in the SMP case?
111 recordMutable(StgMutClosure *p)
116 ASSERT(p->header.info == &stg_WHITEHOLE_info || closure_MUTABLE(p));
118 ASSERT(closure_MUTABLE(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;
129 recordOldToNewPtrs(StgMutClosure *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;
141 #define updateWithIndirection(info, p1, p2) \
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(); \
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); \
158 SET_INFO(p1,&stg_IND_OLDGEN_info); \
159 TICK_UPD_OLD_IND(); \
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.
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
172 #define updateWithIndirection(info, p1, p2) \
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(); \
183 if (info != &stg_BLACKHOLE_BQ_info) { \
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; \
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); \
199 ((StgIndOldGen *)p1)->indirectee = p2; \
200 SET_INFO(p1,&stg_IND_OLDGEN_info); \
201 TICK_UPD_OLD_IND(); \
206 /* Static objects all live in the oldest generation
208 #define updateWithStaticIndirection(info, p1, p2) \
210 ASSERT( p1 != p2 && !closure_IND(p1) ); \
211 ASSERT( ((StgMutClosure*)p1)->mut_link == NULL ); \
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); \
218 ((StgInd *)p1)->indirectee = p2; \
219 SET_INFO((StgInd *)p1, &stg_IND_STATIC_info); \
220 TICK_UPD_STATIC_IND(); \
223 #if defined(TICKY_TICKY) || defined(PROFILING)
225 updateWithPermIndirection(const StgInfoTable *info, StgClosure *p1, StgClosure *p2)
229 ASSERT( p1 != p2 && !closure_IND(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);
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);
243 SET_INFO(p1,&stg_IND_OLDGEN_PERM_info);
244 TICK_UPD_OLD_PERM_IND();
249 /* -----------------------------------------------------------------------------
250 The CAF table - used to let us revert CAFs
251 -------------------------------------------------------------------------- */
253 void revertCAFs( void );
256 void printMutOnceList(generation *gen);
257 void printMutableList(generation *gen);
260 /* --------------------------------------------------------------------------
261 Address space layout macros
262 --------------------------------------------------------------------------
264 Here are the assumptions GHC makes about address space layout.
265 Broadly, it thinks there are three sections:
267 CODE Read-only. Contains code and read-only data (such as
271 DATA Read-write data. Contains static closures (and on some
272 architectures, info tables too)
274 HEAP Dynamically-allocated closures
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.
280 Three macros identify these three areas:
281 IS_CODE(p), IS_DATA(p), HEAP_ALLOCED(p)
283 HEAP_ALLOCED is called FOR EVERY SINGLE CLOSURE during GC.
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.
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)
299 Implementation of CODE and DATA
300 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301 Concerning CODE and DATA, there are three main regimes:
303 [Static] Totally The segments are contiguous, and laid out
304 statically linked exactly as above
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
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
314 For the [Static] case, we assume memory is laid out like this
315 (in order of increasing addresses)
319 TEXT_SECTION_END_MARKER (usually _etext)
321 DATA_SECTION_END_MARKER (usually _end)
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
331 For the [DLL] case, IS_CODE and IS_DATA are really not usable at all.
335 #undef TEXT_BEFORE_HEAP
336 #ifndef mingw32_TARGET_OS
337 #define TEXT_BEFORE_HEAP 1
340 extern void* TEXT_SECTION_END_MARKER_DECL;
341 extern void* DATA_SECTION_END_MARKER_DECL;
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) )
352 /* The HEAP_ALLOCED test below is called FOR EVERY SINGLE CLOSURE
353 * during GC. It needs to be FAST.
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.
358 #ifdef TEXT_BEFORE_HEAP
359 # define HEAP_ALLOCED(x) ((StgPtr)(x) >= (StgPtr)(HEAP_BASE))
361 extern int is_heap_alloced(const void* x);
362 # define HEAP_ALLOCED(x) (is_heap_alloced(x))
366 /* --------------------------------------------------------------------------
367 Macros for distinguishing data pointers from code pointers
368 --------------------------------------------------------------------------
372 The garbage collector needs to make some critical distinctions between pointers.
373 In particular we need
375 LOOKS_LIKE_GHC_INFO(p) p points to an info table
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
381 (Return addresses are in fact info-pointers, so that the Haskell stack
382 looks very like a chunk of heap.)
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
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.
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:
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)
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).
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.
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.
424 Plan B fails altogether for the compile-through-vanilla-C route, because
425 info tables aren't laid out backwards.
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!
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!)
442 This 'scheme' breaks down for closure tables such as CHARLIKE,
443 so we catch these separately.
445 LOOKS_LIKE_STATIC_CLOSURE()
446 - discriminates between static closures and info tbls
447 (needed by LOOKS_LIKE_GHC_INFO() below - [Win32 DLLs only.])
449 - distinguishes between static and heap allocated data.
451 #if defined(ENABLE_WIN32_DLL_SUPPORT)
452 /* definitely do not enable for mingw DietHEP */
453 #define LOOKS_LIKE_STATIC(r) (!(HEAP_ALLOCED(r)))
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)) )
465 #define LOOKS_LIKE_STATIC_CLOSURE(r) (((*(((unsigned long *)(r))-1)) == 0) || IS_CHARLIKE_CLOSURE(r) || IS_INTLIKE_CLOSURE(r))
467 #define LOOKS_LIKE_STATIC(r) IS_DATA_PTR(r)
468 #define LOOKS_LIKE_STATIC_CLOSURE(r) IS_DATA_PTR(r)
472 /* -----------------------------------------------------------------------------
473 Macros for distinguishing infotables from closures.
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 -------------------------------------------------------------------------- */
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)
485 /* LOOKS_LIKE_GHC_INFO is called moderately often during GC, but
486 * Certainly not as often as HEAP_ALLOCED.
488 #ifdef TEXT_BEFORE_HEAP /* needed for mingw DietHEP */
489 # define LOOKS_LIKE_GHC_INFO(info) IS_CODE_PTR(info)
491 # define LOOKS_LIKE_GHC_INFO(info) (!HEAP_ALLOCED(info) \
492 && !LOOKS_LIKE_STATIC_CLOSURE(info))
496 /* -----------------------------------------------------------------------------
497 Macros for calculating how big a closure will be (used during allocation)
498 -------------------------------------------------------------------------- */
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!
503 static __inline__ StgOffset AP_sizeW ( unsigned int n_args )
504 { return sizeofW(StgAP_UPD) + n_args; }
506 static __inline__ StgOffset PAP_sizeW ( unsigned int n_args )
507 { return sizeofW(StgPAP) + n_args; }
509 static __inline__ StgOffset CONSTR_sizeW( unsigned int p, unsigned int np )
510 { return sizeofW(StgHeader) + p + np; }
512 static __inline__ StgOffset THUNK_SELECTOR_sizeW ( void )
513 { return sizeofW(StgHeader) + MIN_UPD_SIZE; }
515 static __inline__ StgOffset BLACKHOLE_sizeW ( void )
516 { return sizeofW(StgHeader) + MIN_UPD_SIZE; }
518 /* --------------------------------------------------------------------------
520 * ------------------------------------------------------------------------*/
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; }
527 static __inline__ StgOffset pap_sizeW( StgPAP* x )
528 { return PAP_sizeW(x->n_args); }
530 static __inline__ StgOffset arr_words_sizeW( StgArrWords* x )
531 { return sizeofW(StgArrWords) + x->words; }
533 static __inline__ StgOffset mut_arr_ptrs_sizeW( StgMutArrPtrs* x )
534 { return sizeofW(StgMutArrPtrs) + x->ptrs; }
536 static __inline__ StgWord tso_sizeW ( StgTSO *tso )
537 { return TSO_STRUCT_SIZEW + tso->stack_size; }
539 #endif /* STORAGE_H */