X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FStorage.h;h=c339c4e012a1630cdf8cd0aa0e5e09ab19d48e2c;hb=a50e6825494446fdf579a7580d402c99e013657e;hp=aebc02b105cbb9359bc0150e742f2c601dbf9d57;hpb=693550d93040439ac20d7ab3bfcaee8ca5b7e923;p=ghc-hetmet.git diff --git a/ghc/includes/Storage.h b/ghc/includes/Storage.h index aebc02b..c339c4e 100644 --- a/ghc/includes/Storage.h +++ b/ghc/includes/Storage.h @@ -10,6 +10,7 @@ #define STORAGE_H #include +#include "OSThreads.h" /* ----------------------------------------------------------------------------- * Generational GC @@ -61,12 +62,18 @@ typedef struct step_ { unsigned int n_large_blocks; /* no. of blocks used by large objs */ int is_compacted; /* compact this step? (old gen 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. */ + bdescr * old_blocks; /* bdescr of first from-space block */ + unsigned int n_old_blocks; /* number of blocks in from-space */ + /* temporary use during GC: */ StgPtr hp; /* next free locn in to-space */ StgPtr hpLim; /* end of current to-space block */ bdescr * hp_bd; /* bdescr of current to-space block */ - bdescr * to_blocks; /* bdescr of first to-space block */ - unsigned int n_to_blocks; /* number of blocks in to-space */ + StgPtr scavd_hp; /* ... same as above, but already */ + StgPtr scavd_hpLim; /* scavenged. */ bdescr * scan_bd; /* block currently being scanned */ StgPtr scan; /* scan pointer in current block */ bdescr * new_large_objects; /* large objects collected so far */ @@ -138,6 +145,7 @@ extern void exitStorage(void); -------------------------------------------------------------------------- */ extern StgPtr allocate ( nat n ); +extern StgPtr allocateLocal ( Capability *cap, nat n ); extern StgPtr allocatePinned ( nat n ); extern lnat allocated_bytes ( void ); @@ -187,10 +195,23 @@ extern void GarbageCollect(void (*get_roots)(evac_fn),rtsBool force_major_gc); -------------------------------------------------------------------------- */ -/* ToDo: shouldn't recordMutable acquire some - * kind of lock in the SMP case? Or do we need per-processor - * mutable lists? +/* + * Storage manager mutex */ +#if defined(SMP) +extern Mutex sm_mutex; +#endif + +#if defined(SMP) +#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 + INLINE_HEADER void recordMutableGen(StgClosure *p, generation *gen) { @@ -205,6 +226,15 @@ recordMutableGen(StgClosure *p, generation *gen) gen->mut_list = bd; } *bd->free++ = (StgWord)p; + +} + +INLINE_HEADER void +recordMutableGenLock(StgClosure *p, generation *gen) +{ + ACQUIRE_SM_LOCK; + recordMutableGen(p,gen); + RELEASE_SM_LOCK; } INLINE_HEADER void @@ -216,6 +246,14 @@ recordMutable(StgClosure *p) if (bd->gen_no > 0) recordMutableGen(p, &RTS_DEREF(generations)[bd->gen_no]); } +INLINE_HEADER void +recordMutableLock(StgClosure *p) +{ + ACQUIRE_SM_LOCK; + recordMutable(p); + RELEASE_SM_LOCK; +} + /* ----------------------------------------------------------------------------- The CAF table - used to let us revert CAFs in GHCi -------------------------------------------------------------------------- */ @@ -225,6 +263,15 @@ recordMutable(StgClosure *p) 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(StgClosure *p); + +/* ----------------------------------------------------------------------------- DEBUGGING predicates for pointers LOOKS_LIKE_INFO_PTR(p) returns False if p is definitely not an info ptr @@ -255,6 +302,9 @@ extern rtsBool keepCAFs; 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; } @@ -262,10 +312,10 @@ INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np ) { return sizeofW(StgHeader) + p + np; } INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void ) -{ return stg_max(sizeofW(StgHeader)+MIN_UPD_SIZE, sizeofW(StgSelector)); } +{ return sizeofW(StgSelector); } INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void ) -{ return sizeofW(StgHeader)+MIN_UPD_SIZE; } +{ return sizeofW(StgHeader)+MIN_PAYLOAD_SIZE; } /* -------------------------------------------------------------------------- Sizes of closures @@ -276,9 +326,17 @@ INLINE_HEADER StgOffset sizeW_fromITBL( const StgInfoTable* itbl ) + 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); } @@ -294,6 +352,74 @@ INLINE_HEADER StgWord tso_sizeW ( StgTSO *tso ) INLINE_HEADER StgWord bco_sizeW ( StgBCO *bco ) { return bco->size; } +STATIC_INLINE 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: + 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_WAIT_QUEUE: + return sizeofW(StgTVarWaitQueue); + case TVAR: + return sizeofW(StgTVar); + case TREC_CHUNK: + return sizeofW(StgTRecChunk); + case TREC_HEADER: + return sizeofW(StgTRecHeader); + default: + return sizeW_fromITBL(info); + } +} + +// The definitive way to find the size, in words, of a heap-allocated closure +STATIC_INLINE nat +closure_sizeW (StgClosure *p) +{ + return closure_sizeW_(p, get_itbl(p)); +} + /* ----------------------------------------------------------------------------- Sizes of stack frames -------------------------------------------------------------------------- */ @@ -332,17 +458,18 @@ INLINE_HEADER StgWord stack_frame_sizeW( StgClosure *frame ) Nursery manipulation -------------------------------------------------------------------------- */ -extern void allocNurseries ( void ); -extern void resetNurseries ( void ); -extern void resizeNurseries ( nat blocks ); -extern void tidyAllocateLists ( void ); -extern lnat countNurseryBlocks ( void ); +extern void allocNurseries ( void ); +extern void resetNurseries ( void ); +extern void resizeNurseries ( nat blocks ); +extern void resizeNurseriesFixed ( nat blocks ); +extern void tidyAllocateLists ( void ); +extern lnat countNurseryBlocks ( void ); /* ----------------------------------------------------------------------------- Functions from GC.c -------------------------------------------------------------------------- */ -extern void threadPaused ( StgTSO * ); +extern void threadPaused ( Capability *cap, StgTSO * ); extern StgClosure * isAlive ( StgClosure *p ); extern void markCAFs ( evac_fn evac ); @@ -360,6 +487,7 @@ extern lnat calcNeeded ( void ); extern void memInventory(void); extern void checkSanity(void); extern nat countBlocks(bdescr *); +extern void checkNurserySanity( step *stp ); #endif #if defined(DEBUG) @@ -378,7 +506,6 @@ extern void newDynCAF(StgClosure *); extern void move_TSO(StgTSO *src, StgTSO *dest); extern StgTSO *relocate_stack(StgTSO *dest, ptrdiff_t diff); -extern StgClosure * RTS_VAR(static_objects); extern StgClosure * RTS_VAR(scavenged_static_objects); extern StgWeak * RTS_VAR(old_weak_ptr_list); extern StgWeak * RTS_VAR(weak_ptr_list);