From 5178da7f966c810c3d64fee02c1161406f9ac1d2 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Thu, 31 Dec 2009 16:02:23 +0000 Subject: [PATCH] take newCAF() out from sm_mutex; use the capability-local mut list instead --- compiler/codeGen/CgClosure.lhs | 5 ++++- includes/rts/storage/GC.h | 4 ++-- rts/sm/Storage.c | 34 +++++++++++++++++----------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/compiler/codeGen/CgClosure.lhs b/compiler/codeGen/CgClosure.lhs index 104af14..f0fe3d1 100644 --- a/compiler/codeGen/CgClosure.lhs +++ b/compiler/codeGen/CgClosure.lhs @@ -560,7 +560,10 @@ link_caf cl_info _is_upd = do -- so that the garbage collector can find them -- This must be done *before* the info table pointer is overwritten, -- because the old info table ptr is needed for reversion - ; emitRtsCallWithVols rtsPackageId (fsLit "newCAF") [CmmHinted (CmmReg nodeReg) AddrHint] [node] False + ; emitRtsCallWithVols rtsPackageId (fsLit "newCAF") + [ CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint, + CmmHinted (CmmReg nodeReg) AddrHint ] + [node] False -- node is live, so save it. -- Overwrite the closure with a (static) indirection diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h index 2a21c66..9749c02 100644 --- a/includes/rts/storage/GC.h +++ b/includes/rts/storage/GC.h @@ -167,8 +167,8 @@ 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); /* ----------------------------------------------------------------------------- diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 781234a..1f875a9 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -94,7 +94,7 @@ initGeneration (generation *gen, int g) void initStorage( void ) { - nat g; + nat g, n; if (generations != NULL) { // multi-init protection @@ -192,6 +192,13 @@ initStorage( void ) N = 0; + // allocate a block for each mut list + for (n = 0; n < n_capabilities; n++) { + for (g = 1; g < RtsFlags.GcFlags.generations; g++) { + capabilities[n].mut_lists[g] = allocBlock(); + } + } + initGcThreads(); IF_DEBUG(gc, statDescribeGens()); @@ -234,8 +241,8 @@ freeStorage (void) newCaf() does the following: - - it puts the CAF on the oldest generation's mut-once list. - This is so that we can treat the CAF as a root when collecting + - it puts the CAF on the oldest generation's mutable list. + This is so that we treat the CAF as a root when collecting younger generations. For GHCI, we have additional requirements when dealing with CAFs: @@ -259,10 +266,8 @@ freeStorage (void) -------------------------------------------------------------------------- */ void -newCAF(StgClosure* caf) +newCAF(StgRegTable *reg, StgClosure* caf) { - ACQUIRE_SM_LOCK; - #ifdef DYNAMIC if(keepCAFs) { @@ -277,24 +282,19 @@ newCAF(StgClosure* caf) // do another hack here and do an address range test on caf to figure // out whether it is from a dynamic library. ((StgIndStatic *)caf)->saved_info = (StgInfoTable *)caf->header.info; + + ACQUIRE_SM_LOCK; // caf_list is global, locked by sm_mutex ((StgIndStatic *)caf)->static_link = caf_list; caf_list = caf; + RELEASE_SM_LOCK; } else #endif { - /* Put this CAF on the mutable list for the old generation. - * This is a HACK - the IND_STATIC closure doesn't really have - * a mut_link field, but we pretend it has - in fact we re-use - * the STATIC_LINK field for the time being, because when we - * come to do a major GC we won't need the mut_link field - * any more and can use it as a STATIC_LINK. - */ + // Put this CAF on the mutable list for the old generation. ((StgIndStatic *)caf)->saved_info = NULL; - recordMutableGen(caf, oldest_gen->no); + recordMutableCap(caf, regTableToCapability(reg), oldest_gen->no); } - - RELEASE_SM_LOCK; } // An alternate version of newCaf which is used for dynamically loaded @@ -307,7 +307,7 @@ newCAF(StgClosure* caf) // The linker hackily arranges that references to newCaf from dynamic // code end up pointing to newDynCAF. void -newDynCAF(StgClosure *caf) +newDynCAF (StgRegTable *reg STG_UNUSED, StgClosure *caf) { ACQUIRE_SM_LOCK; -- 1.7.10.4