diff options
Diffstat (limited to 'ghc/runtime/storage/SMcompacting.lc')
-rw-r--r-- | ghc/runtime/storage/SMcompacting.lc | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/ghc/runtime/storage/SMcompacting.lc b/ghc/runtime/storage/SMcompacting.lc new file mode 100644 index 0000000000..60942d3b41 --- /dev/null +++ b/ghc/runtime/storage/SMcompacting.lc @@ -0,0 +1,234 @@ +\section[SM-compacting]{Compacting Collector Subroutines} + +This is a collection of C functions used in implementing the compacting +collectors. + +The motivation for making this a separate file/section is twofold: + +1) It lets us focus on one thing. + +2) If we don't do this, there will be a huge amount of repetition + between the various GC schemes --- a maintenance nightmare. + +The second is the major motivation. + +ToDo ADR: trash contents of other semispace after GC in debugging version + +\begin{code} +#if defined(GC1s) || defined(GCdu) || defined(GCap) || defined(GCgn) + /* to the end */ + +#if defined(GC1s) + +#define SCAN_REG_DUMP +#include "SMinternal.h" +REGDUMP(ScanRegDump); + +#else /* GCdu, GCap, GCgn */ + +#define SCAV_REG_MAP +#include "SMinternal.h" +REGDUMP(ScavRegDump); + +#endif + +#include "SMcompacting.h" +\end{code} + +\begin{code} +void +LinkRoots(roots, rootno) +P_ roots[]; +I_ rootno; +{ + I_ root; + + DEBUG_STRING("Linking Roots:"); + for (root = 0; root < rootno; root++) { + LINK_LOCATION_TO_CLOSURE(&(roots[root])); + } +} + +\end{code} + +\begin{code} + +#ifdef CONCURRENT +void +LinkSparks(STG_NO_ARGS) +{ + PP_ sparkptr; + int pool; + + DEBUG_STRING("Linking Sparks:"); + for (pool = 0; pool < SPARK_POOLS; pool++) { + for (sparkptr = PendingSparksHd[pool]; + sparkptr < PendingSparksTl[pool]; sparkptr++) { + LINK_LOCATION_TO_CLOSURE(sparkptr); + } + } +} +#endif + +\end{code} + +\begin{code} + +#ifdef PAR + +void +LinkLiveGAs(base, bits) +P_ base; +BitWord *bits; +{ + GALA *gala; + GALA *next; + GALA *prev; + long _hp_word, bit_index, bit; + + DEBUG_STRING("Linking Live GAs:"); + + for (gala = liveIndirections, prev = NULL; gala != NULL; gala = next) { + next = gala->next; + ASSERT(gala->ga.loc.gc.gtid == mytid); + if (gala->ga.weight != MAX_GA_WEIGHT) { + LINK_LOCATION_TO_CLOSURE(&gala->la); + gala->next = prev; + prev = gala; + } else { + /* Since we have all of the weight, this GA is no longer needed */ + W_ pga = PACK_GA(thisPE, gala->ga.loc.gc.slot); + +#ifdef FREE_DEBUG + fprintf(stderr, "Freeing slot %d\n", gala->ga.loc.gc.slot); +#endif + gala->next = freeIndirections; + freeIndirections->next = gala; + (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala); +#ifdef DEBUG + gala->ga.weight = 0x0d0d0d0d; + gala->la = (P_) 0xbadbad; +#endif + } + } + liveIndirections = prev; + + prepareFreeMsgBuffers(); + + for (gala = liveRemoteGAs, prev = NULL; gala != NULL; gala = next) { + next = gala->next; + ASSERT(gala->ga.loc.gc.gtid != mytid); + + _hp_word = gala->la - base; + bit_index = _hp_word / BITS_IN(BitWord); + bit = 1L << (_hp_word & (BITS_IN(BitWord) - 1)); + if (!(bits[bit_index] & bit)) { + int pe = taskIDtoPE(gala->ga.loc.gc.gtid); + W_ pga = PACK_GA(pe, gala->ga.loc.gc.slot); + int i; + + (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala); + freeRemoteGA(pe, &(gala->ga)); + gala->next = freeGALAList; + freeGALAList = gala; + } else { + LINK_LOCATION_TO_CLOSURE(&gala->la); + gala->next = prev; + prev = gala; + } + } + liveRemoteGAs = prev; + + /* If we have any remaining FREE messages to send off, do so now */ + sendFreeMessages(); +} + +#else + +\end{code} + +Note: no \tr{Link[AB]Stack} for ``parallel'' systems, because they +don't have a single main stack. + +\begin{code} + +void +LinkAStack(stackA, botA) +PP_ stackA; +PP_ botA; +{ + PP_ stackptr; + + DEBUG_STRING("Linking A Stack:"); + for (stackptr = stackA; + SUBTRACT_A_STK(stackptr, botA) >= 0; + stackptr = stackptr + AREL(1)) { + LINK_LOCATION_TO_CLOSURE(stackptr); + } +} +#endif /* PAR */ +\end{code} + +ToDo (Patrick?): Dont explicitly mark & compact unmarked Bstack frames + +\begin{code} +#if ! defined(PAR) +void +LinkBStack(stackB, botB) +P_ stackB; +P_ botB; /* stackB points to topmost update frame */ +{ + P_ updateFramePtr; + + DEBUG_STRING("Linking B Stack:"); + for (updateFramePtr = stackB; + SUBTRACT_B_STK(updateFramePtr, botB) > 0; + /* re-initialiser given explicitly */ ) { + + P_ updateClosurePtr = updateFramePtr + BREL(UF_UPDATEE); + + LINK_LOCATION_TO_CLOSURE(updateClosurePtr); + + updateFramePtr = GRAB_SuB(updateFramePtr); + } +} +#endif /* not PAR */ +\end{code} + +\begin{code} +I_ +CountCAFs(CAFlist) +P_ CAFlist; +{ + I_ caf_no = 0; + + for (caf_no = 0; CAFlist != NULL; CAFlist = (P_) IND_CLOSURE_LINK(CAFlist)) + caf_no++; + + return caf_no; +} +\end{code} + +\begin{code} +void +LinkCAFs(CAFlist) +P_ CAFlist; +{ + DEBUG_STRING("Linking CAF Ptr Locations:"); + while(CAFlist != NULL) { + DEBUG_LINK_CAF(CAFlist); + LINK_LOCATION_TO_CLOSURE(&IND_CLOSURE_PTR(CAFlist)); + CAFlist = (P_) IND_CLOSURE_LINK(CAFlist); + } +} + +\end{code} + +\begin{code} + +#ifdef PAR + +#endif /* PAR */ + +#endif /* defined(_INFO_COMPACTING) */ +\end{code} |