X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStorage.h;h=a9c6a095a30930a7bd0f5f977f159406f73727c2;hb=9ff75d089614cce1cfa8c88344ace47698258bfa;hp=d197087b14940683c3ae99ae1c0233d713a3f670;hpb=4391e44f910ce579f269986faef9e5db8907a6c0;p=ghc-hetmet.git diff --git a/ghc/rts/Storage.h b/ghc/rts/Storage.h index d197087..a9c6a09 100644 --- a/ghc/rts/Storage.h +++ b/ghc/rts/Storage.h @@ -1,5 +1,7 @@ /* ----------------------------------------------------------------------------- - * $Id: Storage.h,v 1.3 1999/01/13 17:25:48 simonm Exp $ + * $Id: Storage.h,v 1.16 2000/04/14 15:18:07 sewardj Exp $ + * + * (c) The GHC Team, 1998-1999 * * External Storage Manger Interface * @@ -25,6 +27,10 @@ extern void exitStorage(void); StgPtr allocate(int n) Allocates a chunk of contiguous store n words long, returning a pointer to the first word. Always succeeds. + + Don't forget to TICK_ALLOC_XXX(...) + after calling allocate, 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. @@ -32,6 +38,9 @@ extern void exitStorage(void); lnat allocated_bytes(void) Returns the number of bytes allocated via allocate() since the last GC. Used in the reoprting of statistics. + + SMP: allocate and doYouWantToGC can be used from STG code, they are + surrounded by a mutex. -------------------------------------------------------------------------- */ extern StgPtr allocate(nat n); @@ -50,9 +59,9 @@ extern lnat allocated_bytes(void); -------------------------------------------------------------------------- */ #define ExtendNursery(hp,hplim) \ - (current_nursery->free = (P_)(hp)+1, \ - current_nursery->link == NULL ? rtsFalse : \ - (current_nursery = current_nursery->link, \ + (CurrentNursery->free = (P_)(hp)+1, \ + CurrentNursery->link == NULL ? rtsFalse : \ + (CurrentNursery = CurrentNursery->link, \ OpenNursery(hp,hplim), \ rtsTrue)) @@ -69,55 +78,123 @@ extern void PleaseStopAllocating(void); MarkRoot(StgClosure *p) Returns the new location of the root. -------------------------------------------------------------------------- */ -extern void GarbageCollect(void (*get_roots)(void)); +extern void GarbageCollect(void (*get_roots)(void),rtsBool force_major_gc); extern StgClosure *MarkRoot(StgClosure *p); /* ----------------------------------------------------------------------------- Generational garbage collection support - RecordMutable(StgPtr p) Informs the garbage collector that a + 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 + 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. + -------------------------------------------------------------------------- */ -extern void recordMutable(StgMutClosure *p); +static inline void +recordMutable(StgMutClosure *p) +{ + bdescr *bd; -#ifdef TICKY_TICKY -#error updateWithIndirection: maybe permanent indirection? -# define Ind_info_TO_USE ((AllFlags.doUpdEntryCounts) ? &IND_PERM_info : &IND_info -) +#ifdef SMP + ASSERT(p->header.info == &WHITEHOLE_info || closure_MUTABLE(p)); +#else + ASSERT(closure_MUTABLE(p)); #endif + bd = Bdescr((P_)p); + if (bd->gen->no > 0) { + p->mut_link = bd->gen->mut_list; + bd->gen->mut_list = p; + } +} + +static inline void +recordOldToNewPtrs(StgMutClosure *p) +{ + bdescr *bd; + + bd = Bdescr((P_)p); + if (bd->gen->no > 0) { + p->mut_link = bd->gen->mut_once_list; + bd->gen->mut_once_list = p; + } +} + +#define updateWithIndirection(info, p1, p2) \ + { \ + bdescr *bd; \ + \ + bd = Bdescr((P_)p1); \ + if (bd->gen->no == 0) { \ + ((StgInd *)p1)->indirectee = p2; \ + SET_INFO(p1,&IND_info); \ + TICK_UPD_NEW_IND(); \ + } else { \ + ((StgIndOldGen *)p1)->indirectee = p2; \ + if (info != &BLACKHOLE_BQ_info) { \ + ((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list; \ + bd->gen->mut_once_list = (StgMutClosure *)p1; \ + } \ + SET_INFO(p1,&IND_OLDGEN_info); \ + TICK_UPD_OLD_IND(); \ + } \ + } + +#if defined(TICKY_TICKY) || defined(PROFILING) static inline void -updateWithIndirection(StgClosure *p1, StgClosure *p2) +updateWithPermIndirection(const StgInfoTable *info, StgClosure *p1, StgClosure *p2) { bdescr *bd; bd = Bdescr((P_)p1); if (bd->gen->no == 0) { - SET_INFO(p1,&IND_info); ((StgInd *)p1)->indirectee = p2; + SET_INFO(p1,&IND_PERM_info); + TICK_UPD_NEW_PERM_IND(p1); } else { - SET_INFO(p1,&IND_OLDGEN_info); ((StgIndOldGen *)p1)->indirectee = p2; - ((StgIndOldGen *)p1)->mut_link = bd->gen->mut_list; - bd->gen->mut_list = (StgMutClosure *)p1; + if (info != &BLACKHOLE_BQ_info) { + ((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list; + bd->gen->mut_once_list = (StgMutClosure *)p1; + } + SET_INFO(p1,&IND_OLDGEN_PERM_info); + TICK_UPD_OLD_PERM_IND(); } } +#endif /* ----------------------------------------------------------------------------- - The CAF list - used to let us revert CAFs + The CAF table - used to let us revert CAFs -------------------------------------------------------------------------- */ -StgCAF* enteredCAFs; +#if defined(INTERPRETER) +typedef struct StgCAFTabEntry_ { + StgClosure* closure; + StgInfoTable* origItbl; +} StgCAFTabEntry; + +extern void addToECafTable ( StgClosure* closure, StgInfoTable* origItbl ); +extern void clearECafTable ( void ); + +extern StgCAF* ecafList; +extern StgCAFTabEntry* ecafTable; +extern StgInt usedECafTable; +extern StgInt sizeECafTable; +#endif + +#if defined(DEBUG) +void printMutOnceList(generation *gen); +void printMutableList(generation *gen); +#endif DEBUG #endif STORAGE_H