X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=includes%2Frts%2Fstorage%2FGC.h;h=3c6e6f6e26bba5a1797ae512ad5d4553250404c2;hp=aa0531382fa2b67961b294a3a613fb81f233cab4;hb=b2524b3960999fffdb3767900f58825903f6560f;hpb=f9d15f9fccae4706fbdf8ee4ecaef7da9953cb74 diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h index aa05313..3c6e6f6 100644 --- a/includes/rts/storage/GC.h +++ b/includes/rts/storage/GC.h @@ -53,101 +53,85 @@ * * ------------------------------------------------------------------------- */ -typedef struct step_ { - unsigned int no; // step number in this generation - unsigned int abs_no; // absolute step number +// A count of blocks needs to store anything up to the size of memory +// divided by the block size. The safest thing is therefore to use a +// type that can store the full range of memory addresses, +// ie. StgWord. Note that we have had some tricky int overflows in a +// couple of cases caused by using ints rather than longs (e.g. #5086) - struct generation_ * gen; // generation this step belongs to - unsigned int gen_no; // generation number (cached) +typedef StgWord memcount; - bdescr * blocks; // blocks in this step - unsigned int n_blocks; // number of blocks - unsigned int n_words; // number of words +typedef struct nursery_ { + bdescr * blocks; + memcount n_blocks; +} nursery; - struct step_ * to; // destination step for live objects +typedef struct generation_ { + unsigned int no; // generation number + + bdescr * blocks; // blocks in this gen + memcount n_blocks; // number of blocks + memcount n_words; // number of used words - bdescr * large_objects; // large objects (doubly linked) - unsigned int n_large_blocks; // no. of blocks used by large objs + bdescr * large_objects; // large objects (doubly linked) + memcount n_large_blocks; // no. of blocks used by large objs + memcount n_new_large_words; // words of new large objects + // (for allocation stats) - StgTSO * threads; // threads in this step + memcount max_blocks; // max blocks + + StgTSO * threads; // threads in this gen // linked via global_link + struct generation_ *to; // destination gen for live objects + + // stats information + unsigned int collections; + unsigned int par_collections; + unsigned int failed_promotions; // ------------------------------------ // 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 + SpinLock sync; // 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) + // During GC, if we are collecting this gen, blocks and n_blocks + // are copied into the following two fields. After GC, these blocks + // are freed. 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 + memcount n_old_blocks; // number of blocks in from-space + memcount 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 + memcount 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 * generations; - extern generation * g0; -extern step * g0s0; extern generation * oldest_gen; -extern step * all_steps; -extern nat total_steps; /* ----------------------------------------------------------------------------- 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) + StgPtr allocate(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 + StgPtr allocatePinned(Capability *cap, 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. @@ -163,28 +147,17 @@ extern nat total_steps; 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. - -------------------------------------------------------------------------- */ -StgPtr allocate ( lnat n ); -StgPtr allocateInGen ( generation *g, lnat n ); -StgPtr allocateLocal ( Capability *cap, lnat n ); -StgPtr allocatePinned ( lnat n ); -lnat allocatedBytes ( void ); +StgPtr allocate ( Capability *cap, lnat n ); +StgPtr allocatePinned ( Capability *cap, lnat n ); /* memory allocator for executable memory */ void * allocateExec(unsigned int len, void **exec_addr); void freeExec (void *p); // Used by GC checks in external .cmm code: -extern nat alloc_blocks; -extern nat alloc_blocks_lim; +extern nat large_alloc_lim; /* ----------------------------------------------------------------------------- Performing Garbage Collection @@ -197,10 +170,20 @@ void performMajorGC(void); The CAF table - used to let us revert CAFs in GHCi -------------------------------------------------------------------------- */ -void newCAF (StgClosure*); -void newDynCAF (StgClosure *); +void newCAF (StgRegTable *reg, StgClosure *); +void newDynCAF (StgRegTable *reg, StgClosure *); void revertCAFs (void); +// Request that all CAFs are retained indefinitely. +void setKeepCAFs (void); + +/* ----------------------------------------------------------------------------- + Stats + -------------------------------------------------------------------------- */ + +// Returns the total number of bytes allocated since the start of the program. +HsInt64 getAllocations (void); + /* ----------------------------------------------------------------------------- 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 @@ -214,11 +197,11 @@ void dirty_MUT_VAR(StgRegTable *reg, StgClosure *p); /* (needed when dynamic libraries are used). */ extern rtsBool keepCAFs; -INLINE_HEADER void initBdescr(bdescr *bd, step *step) +INLINE_HEADER void initBdescr(bdescr *bd, generation *gen, generation *dest) { - bd->step = step; - bd->gen_no = step->gen_no; - bd->dest = step->to; + bd->gen = gen; + bd->gen_no = gen->no; + bd->dest_no = dest->no; } #endif /* RTS_STORAGE_GC_H */