\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(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 = PackGA(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 = PackGA(pe, gala->ga.loc.gc.slot); (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; updateFramePtr = GRAB_SuB(updateFramePtr)) { P_ updateClosurePtr = updateFramePtr + BREL(UF_UPDATEE); LINK_LOCATION_TO_CLOSURE(updateClosurePtr); } } #endif /* not PAR */ \end{code} \begin{code} I_ CountCAFs(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(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); } } #endif /* defined(_INFO_COMPACTING) */ \end{code}