summaryrefslogtreecommitdiff
path: root/includes/Storage.h
diff options
context:
space:
mode:
Diffstat (limited to 'includes/Storage.h')
-rw-r--r--includes/Storage.h583
1 files changed, 0 insertions, 583 deletions
diff --git a/includes/Storage.h b/includes/Storage.h
deleted file mode 100644
index 5d3e7733cf..0000000000
--- a/includes/Storage.h
+++ /dev/null
@@ -1,583 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * (c) The GHC Team, 1998-2004
- *
- * External Storage Manger Interface
- *
- * ---------------------------------------------------------------------------*/
-
-#ifndef STORAGE_H
-#define STORAGE_H
-
-#include <stddef.h>
-#include "OSThreads.h"
-#include "SMP.h"
-
-/* -----------------------------------------------------------------------------
- * Generational GC
- *
- * We support an arbitrary number of generations, with an arbitrary number
- * of steps per generation. Notes (in no particular order):
- *
- * - all generations except the oldest should have two steps. This gives
- * objects a decent chance to age before being promoted, and in
- * particular will ensure that we don't end up with too many
- * thunks being updated in older generations.
- *
- * - the oldest generation has one step. There's no point in aging
- * objects in the oldest generation.
- *
- * - generation 0, step 0 (G0S0) is the allocation area. It is given
- * a fixed set of blocks during initialisation, and these blocks
- * are never freed.
- *
- * - during garbage collection, each step which is an evacuation
- * destination (i.e. all steps except G0S0) is allocated a to-space.
- * evacuated objects are allocated into the step's to-space until
- * GC is finished, when the original step's contents may be freed
- * and replaced by the to-space.
- *
- * - the mutable-list is per-generation (not per-step). G0 doesn't
- * have one (since every garbage collection collects at least G0).
- *
- * - block descriptors contain pointers to both the step and the
- * generation that the block belongs to, for convenience.
- *
- * - static objects are stored in per-generation lists. See GC.c for
- * details of how we collect CAFs in the generational scheme.
- *
- * - large objects are per-step, and are promoted in the same way
- * as small objects, except that we may allocate large objects into
- * generation 1 initially.
- *
- * ------------------------------------------------------------------------- */
-
-typedef struct step_ {
- unsigned int no; // step number in this generation
- unsigned int abs_no; // absolute step number
-
- struct generation_ * gen; // generation this step belongs to
- unsigned int gen_no; // generation number (cached)
-
- bdescr * blocks; // blocks in this step
- unsigned int n_blocks; // number of blocks
- unsigned int n_words; // number of words
-
- struct step_ * to; // destination step for live objects
-
- bdescr * large_objects; // large objects (doubly linked)
- unsigned int n_large_blocks; // no. of blocks used by large objs
-
- StgTSO * threads; // threads in this step
- // linked via global_link
-
- // ------------------------------------
- // Fields below are used during GC only
-
- // During GC, if we are collecting this step, blocks and n_blocks
- // are copied into the following two fields. After GC, these blocks
- // are freed.
-
-#if defined(THREADED_RTS)
- char pad[128]; // make sure the following is
- // on a separate cache line.
- SpinLock sync_large_objects; // lock for large_objects
- // and scavenged_large_objects
-#endif
-
- int mark; // mark (not copy)? (old gen only)
- int compact; // compact (not sweep)? (old gen only)
-
- bdescr * old_blocks; // bdescr of first from-space block
- unsigned int n_old_blocks; // number of blocks in from-space
- unsigned int live_estimate; // for sweeping: estimate of live data
-
- bdescr * part_blocks; // partially-full scanned blocks
- unsigned int n_part_blocks; // count of above
-
- bdescr * scavenged_large_objects; // live large objs after GC (d-link)
- unsigned int n_scavenged_large_blocks; // size (not count) of above
-
- bdescr * bitmap; // bitmap for compacting collection
-
- StgTSO * old_threads;
-
-} step;
-
-
-typedef struct generation_ {
- unsigned int no; // generation number
- step * steps; // steps
- unsigned int n_steps; // number of steps
- unsigned int max_blocks; // max blocks in step 0
- bdescr *mut_list; // mut objects in this gen (not G0)
-
- // stats information
- unsigned int collections;
- unsigned int par_collections;
- unsigned int failed_promotions;
-
- // temporary use during GC:
- bdescr *saved_mut_list;
-} generation;
-
-extern generation * RTS_VAR(generations);
-
-extern generation * RTS_VAR(g0);
-extern step * RTS_VAR(g0s0);
-extern generation * RTS_VAR(oldest_gen);
-extern step * RTS_VAR(all_steps);
-extern nat RTS_VAR(total_steps);
-
-/* -----------------------------------------------------------------------------
- Initialisation / De-initialisation
- -------------------------------------------------------------------------- */
-
-extern void initStorage(void);
-extern void exitStorage(void);
-extern void freeStorage(void);
-
-/* -----------------------------------------------------------------------------
- Generic allocation
-
- StgPtr allocateInGen(generation *g, nat n)
- Allocates a chunk of contiguous store
- n words long in generation g,
- returning a pointer to the first word.
- Always succeeds.
-
- StgPtr allocate(nat n) Equaivalent to allocateInGen(g0)
-
- StgPtr allocateLocal(Capability *cap, nat n)
- Allocates memory from the nursery in
- the current Capability. This can be
- done without taking a global lock,
- unlike allocate().
-
- StgPtr allocatePinned(nat n) Allocates a chunk of contiguous store
- n words long, which is at a fixed
- address (won't be moved by GC).
- Returns a pointer to the first word.
- Always succeeds.
-
- NOTE: the GC can't in general handle
- pinned objects, so allocatePinned()
- can only be used for ByteArrays at the
- moment.
-
- Don't forget to TICK_ALLOC_XXX(...)
- after calling allocate or
- allocatePinned, for the
- benefit of the ticky-ticky profiler.
-
- rtsBool doYouWantToGC(void) Returns True if the storage manager is
- ready to perform a GC, False otherwise.
-
- lnat allocatedBytes(void) Returns the number of bytes allocated
- via allocate() since the last GC.
- Used in the reporting of statistics.
-
- -------------------------------------------------------------------------- */
-
-extern StgPtr allocate ( lnat n );
-extern StgPtr allocateInGen ( generation *g, lnat n );
-extern StgPtr allocateLocal ( Capability *cap, lnat n );
-extern StgPtr allocatePinned ( lnat n );
-extern lnat allocatedBytes ( void );
-
-extern bdescr * RTS_VAR(small_alloc_list);
-extern bdescr * RTS_VAR(large_alloc_list);
-extern bdescr * RTS_VAR(pinned_object_block);
-
-extern nat RTS_VAR(alloc_blocks);
-extern nat RTS_VAR(alloc_blocks_lim);
-
-INLINE_HEADER rtsBool
-doYouWantToGC( void )
-{
- return (alloc_blocks >= alloc_blocks_lim);
-}
-
-/* memory allocator for executable memory */
-extern void* allocateExec(unsigned int len, void **exec_addr);
-extern void freeExec (void *p);
-
-/* for splitting blocks groups in two */
-extern bdescr * splitLargeBlock (bdescr *bd, nat blocks);
-
-/* -----------------------------------------------------------------------------
- Performing Garbage Collection
-
- GarbageCollect(get_roots) Performs a garbage collection.
- 'get_roots' is called to find all the
- roots that the system knows about.
-
-
- -------------------------------------------------------------------------- */
-
-extern void GarbageCollect(rtsBool force_major_gc, nat gc_type, Capability *cap);
-
-/* -----------------------------------------------------------------------------
- Generational garbage collection support
-
- recordMutable(StgPtr p) Informs the garbage collector that a
- previously immutable object has
- become (permanently) mutable. Used
- by thawArray and similar.
-
- updateWithIndirection(p1,p2) Updates the object at p1 with an
- indirection pointing to p2. This is
- normally called for objects in an old
- generation (>0) when they are updated.
-
- updateWithPermIndirection(p1,p2) As above but uses a permanent indir.
-
- -------------------------------------------------------------------------- */
-
-/*
- * Storage manager mutex
- */
-#if defined(THREADED_RTS)
-extern Mutex sm_mutex;
-#endif
-
-#if defined(THREADED_RTS)
-#define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex);
-#define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex);
-#define ASSERT_SM_LOCK() ASSERT_LOCK_HELD(&sm_mutex);
-#else
-#define ACQUIRE_SM_LOCK
-#define RELEASE_SM_LOCK
-#define ASSERT_SM_LOCK()
-#endif
-
-#if !IN_STG_CODE
-
-INLINE_HEADER void
-recordMutableGen(StgClosure *p, nat gen_no)
-{
- bdescr *bd;
-
- bd = generations[gen_no].mut_list;
- if (bd->free >= bd->start + BLOCK_SIZE_W) {
- bdescr *new_bd;
- new_bd = allocBlock();
- new_bd->link = bd;
- bd = new_bd;
- generations[gen_no].mut_list = bd;
- }
- *bd->free++ = (StgWord)p;
-
-}
-
-INLINE_HEADER void
-recordMutableGenLock(StgClosure *p, nat gen_no)
-{
- ACQUIRE_SM_LOCK;
- recordMutableGen(p,gen_no);
- RELEASE_SM_LOCK;
-}
-
-INLINE_HEADER void
-recordMutable(StgClosure *p)
-{
- bdescr *bd;
- ASSERT(closure_MUTABLE(p));
- bd = Bdescr((P_)p);
- if (bd->gen_no > 0) recordMutableGen(p, bd->gen_no);
-}
-
-INLINE_HEADER void
-recordMutableLock(StgClosure *p)
-{
- ACQUIRE_SM_LOCK;
- recordMutable(p);
- RELEASE_SM_LOCK;
-}
-
-#endif // !IN_STG_CODE
-
-/* -----------------------------------------------------------------------------
- The CAF table - used to let us revert CAFs in GHCi
- -------------------------------------------------------------------------- */
-
-/* set to disable CAF garbage collection in GHCi. */
-/* (needed when dynamic libraries are used). */
-extern rtsBool keepCAFs;
-
-/* -----------------------------------------------------------------------------
- This is the write barrier for MUT_VARs, a.k.a. IORefs. A
- MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY
- is. When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY
- and is put on the mutable list.
- -------------------------------------------------------------------------- */
-
-void dirty_MUT_VAR(StgRegTable *reg, StgClosure *p);
-
-/* -----------------------------------------------------------------------------
- DEBUGGING predicates for pointers
-
- LOOKS_LIKE_INFO_PTR(p) returns False if p is definitely not an info ptr
- LOOKS_LIKE_CLOSURE_PTR(p) returns False if p is definitely not a closure ptr
-
- These macros are complete but not sound. That is, they might
- return false positives. Do not rely on them to distinguish info
- pointers from closure pointers, for example.
-
- We don't use address-space predicates these days, for portability
- reasons, and the fact that code/data can be scattered about the
- address space in a dynamically-linked environment. Our best option
- is to look at the alleged info table and see whether it seems to
- make sense...
- -------------------------------------------------------------------------- */
-
-INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR (StgWord p);
-INLINE_HEADER rtsBool LOOKS_LIKE_CLOSURE_PTR (void *p); // XXX StgClosure*
-
-/* -----------------------------------------------------------------------------
- Macros for calculating how big a closure will be (used during allocation)
- -------------------------------------------------------------------------- */
-
-INLINE_HEADER StgOffset PAP_sizeW ( nat n_args )
-{ return sizeofW(StgPAP) + n_args; }
-
-INLINE_HEADER StgOffset AP_sizeW ( nat n_args )
-{ return sizeofW(StgAP) + n_args; }
-
-INLINE_HEADER StgOffset AP_STACK_sizeW ( nat size )
-{ return sizeofW(StgAP_STACK) + size; }
-
-INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np )
-{ return sizeofW(StgHeader) + p + np; }
-
-INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void )
-{ return sizeofW(StgSelector); }
-
-INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void )
-{ return sizeofW(StgHeader)+MIN_PAYLOAD_SIZE; }
-
-/* --------------------------------------------------------------------------
- Sizes of closures
- ------------------------------------------------------------------------*/
-
-INLINE_HEADER StgOffset sizeW_fromITBL( const StgInfoTable* itbl )
-{ return sizeofW(StgClosure)
- + sizeofW(StgPtr) * itbl->layout.payload.ptrs
- + sizeofW(StgWord) * itbl->layout.payload.nptrs; }
-
-INLINE_HEADER StgOffset thunk_sizeW_fromITBL( const StgInfoTable* itbl )
-{ return sizeofW(StgThunk)
- + sizeofW(StgPtr) * itbl->layout.payload.ptrs
- + sizeofW(StgWord) * itbl->layout.payload.nptrs; }
-
-INLINE_HEADER StgOffset ap_stack_sizeW( StgAP_STACK* x )
-{ return AP_STACK_sizeW(x->size); }
-
-INLINE_HEADER StgOffset ap_sizeW( StgAP* x )
-{ return AP_sizeW(x->n_args); }
-
-INLINE_HEADER StgOffset pap_sizeW( StgPAP* x )
-{ return PAP_sizeW(x->n_args); }
-
-INLINE_HEADER StgOffset arr_words_sizeW( StgArrWords* x )
-{ return sizeofW(StgArrWords) + x->words; }
-
-INLINE_HEADER StgOffset mut_arr_ptrs_sizeW( StgMutArrPtrs* x )
-{ return sizeofW(StgMutArrPtrs) + x->ptrs; }
-
-INLINE_HEADER StgWord tso_sizeW ( StgTSO *tso )
-{ return TSO_STRUCT_SIZEW + tso->stack_size; }
-
-INLINE_HEADER StgWord bco_sizeW ( StgBCO *bco )
-{ return bco->size; }
-
-INLINE_HEADER nat
-closure_sizeW_ (StgClosure *p, StgInfoTable *info)
-{
- switch (info->type) {
- case THUNK_0_1:
- case THUNK_1_0:
- return sizeofW(StgThunk) + 1;
- case FUN_0_1:
- case CONSTR_0_1:
- case FUN_1_0:
- case CONSTR_1_0:
- return sizeofW(StgHeader) + 1;
- case THUNK_0_2:
- case THUNK_1_1:
- case THUNK_2_0:
- return sizeofW(StgThunk) + 2;
- case FUN_0_2:
- case CONSTR_0_2:
- case FUN_1_1:
- case CONSTR_1_1:
- case FUN_2_0:
- case CONSTR_2_0:
- return sizeofW(StgHeader) + 2;
- case THUNK:
- return thunk_sizeW_fromITBL(info);
- case THUNK_SELECTOR:
- return THUNK_SELECTOR_sizeW();
- case AP_STACK:
- return ap_stack_sizeW((StgAP_STACK *)p);
- case AP:
- return ap_sizeW((StgAP *)p);
- case PAP:
- return pap_sizeW((StgPAP *)p);
- case IND:
- case IND_PERM:
- case IND_OLDGEN:
- case IND_OLDGEN_PERM:
- return sizeofW(StgInd);
- case ARR_WORDS:
- return arr_words_sizeW((StgArrWords *)p);
- case MUT_ARR_PTRS_CLEAN:
- case MUT_ARR_PTRS_DIRTY:
- case MUT_ARR_PTRS_FROZEN:
- case MUT_ARR_PTRS_FROZEN0:
- return mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
- case TSO:
- return tso_sizeW((StgTSO *)p);
- case BCO:
- return bco_sizeW((StgBCO *)p);
- case TVAR_WATCH_QUEUE:
- return sizeofW(StgTVarWatchQueue);
- case TVAR:
- return sizeofW(StgTVar);
- case TREC_CHUNK:
- return sizeofW(StgTRecChunk);
- case TREC_HEADER:
- return sizeofW(StgTRecHeader);
- case ATOMIC_INVARIANT:
- return sizeofW(StgAtomicInvariant);
- case INVARIANT_CHECK_QUEUE:
- return sizeofW(StgInvariantCheckQueue);
- default:
- return sizeW_fromITBL(info);
- }
-}
-
-// The definitive way to find the size, in words, of a heap-allocated closure
-INLINE_HEADER nat
-closure_sizeW (StgClosure *p)
-{
- return closure_sizeW_(p, get_itbl(p));
-}
-
-/* -----------------------------------------------------------------------------
- Sizes of stack frames
- -------------------------------------------------------------------------- */
-
-INLINE_HEADER StgWord stack_frame_sizeW( StgClosure *frame )
-{
- StgRetInfoTable *info;
-
- info = get_ret_itbl(frame);
- switch (info->i.type) {
-
- case RET_DYN:
- {
- StgRetDyn *dyn = (StgRetDyn *)frame;
- return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE +
- RET_DYN_NONPTR_REGS_SIZE +
- RET_DYN_PTRS(dyn->liveness) + RET_DYN_NONPTRS(dyn->liveness);
- }
-
- case RET_FUN:
- return sizeofW(StgRetFun) + ((StgRetFun *)frame)->size;
-
- case RET_BIG:
- return 1 + GET_LARGE_BITMAP(&info->i)->size;
-
- case RET_BCO:
- return 2 + BCO_BITMAP_SIZE((StgBCO *)((P_)frame)[1]);
-
- default:
- return 1 + BITMAP_SIZE(info->i.layout.bitmap);
- }
-}
-
-/* -----------------------------------------------------------------------------
- Nursery manipulation
- -------------------------------------------------------------------------- */
-
-extern void allocNurseries ( void );
-extern void resetNurseries ( void );
-extern void resizeNurseries ( nat blocks );
-extern void resizeNurseriesFixed ( nat blocks );
-extern lnat countNurseryBlocks ( void );
-
-
-/* -----------------------------------------------------------------------------
- Functions from GC.c
- -------------------------------------------------------------------------- */
-
-typedef void (*evac_fn)(void *user, StgClosure **root);
-
-extern void threadPaused ( Capability *cap, StgTSO * );
-extern StgClosure * isAlive ( StgClosure *p );
-extern void markCAFs ( evac_fn evac, void *user );
-extern void GetRoots ( evac_fn evac, void *user );
-
-/* -----------------------------------------------------------------------------
- Stats 'n' DEBUG stuff
- -------------------------------------------------------------------------- */
-
-extern ullong RTS_VAR(total_allocated);
-
-extern lnat calcAllocated ( void );
-extern lnat calcLiveBlocks ( void );
-extern lnat calcLiveWords ( void );
-extern lnat countOccupied ( bdescr *bd );
-extern lnat calcNeeded ( void );
-
-#if defined(DEBUG)
-extern void memInventory(rtsBool show);
-extern void checkSanity(void);
-extern nat countBlocks(bdescr *);
-extern void checkNurserySanity( step *stp );
-#endif
-
-#if defined(DEBUG)
-void printMutOnceList(generation *gen);
-void printMutableList(generation *gen);
-#endif
-
-/* ----------------------------------------------------------------------------
- Storage manager internal APIs and globals
- ------------------------------------------------------------------------- */
-
-#define END_OF_STATIC_LIST stgCast(StgClosure*,1)
-
-extern void newDynCAF(StgClosure *);
-
-extern void move_TSO(StgTSO *src, StgTSO *dest);
-extern StgTSO *relocate_stack(StgTSO *dest, ptrdiff_t diff);
-
-extern StgWeak * RTS_VAR(old_weak_ptr_list);
-extern StgWeak * RTS_VAR(weak_ptr_list);
-extern StgClosure * RTS_VAR(caf_list);
-extern StgClosure * RTS_VAR(revertible_caf_list);
-extern StgTSO * RTS_VAR(resurrected_threads);
-
-#define IS_FORWARDING_PTR(p) ((((StgWord)p) & 1) != 0)
-#define MK_FORWARDING_PTR(p) (((StgWord)p) | 1)
-#define UN_FORWARDING_PTR(p) (((StgWord)p) - 1)
-
-INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR_NOT_NULL (StgWord p)
-{
- StgInfoTable *info = INFO_PTR_TO_STRUCT(p);
- return info->type != INVALID_OBJECT && info->type < N_CLOSURE_TYPES;
-}
-
-INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR (StgWord p)
-{
- return p && (IS_FORWARDING_PTR(p) || LOOKS_LIKE_INFO_PTR_NOT_NULL(p));
-}
-
-INLINE_HEADER rtsBool LOOKS_LIKE_CLOSURE_PTR (void *p)
-{
- return LOOKS_LIKE_INFO_PTR((StgWord)(UNTAG_CLOSURE((StgClosure *)(p)))->header.info);
-}
-
-#endif /* STORAGE_H */