[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / runtime / storage / SMap.lc
diff --git a/ghc/runtime/storage/SMap.lc b/ghc/runtime/storage/SMap.lc
deleted file mode 100644 (file)
index 802c296..0000000
+++ /dev/null
@@ -1,752 +0,0 @@
-***************************************************************************
-
-                      APPEL'S GARBAGE COLLECTION
-
-Global heap requirements as for 1s and 2s collectors.
-    ++ All closures in the old generation that are updated must be
-       updated with indirections and placed on the linked list of
-       updated old generation closures.
-
-***************************************************************************
-
-\begin{code}
-#if defined(GCap)
-
-#define  SCAV_REG_MAP
-#include "SMinternal.h"
-#include "SMcopying.h"
-#include "SMcompacting.h"
-#include "SMextn.h"
-
-REGDUMP(ScavRegDump);
-
-appelData appelInfo = {0, 0, 0, 0, 0,
-                      0, 0, 0, 0, 0, 0, 0, 0, 0,
-                      0, {{0, 0}, {0, 0}}
-                     };
-
-P_ heap_space = 0;             /* Address of first word of slab 
-                                  of memory allocated for heap */
-
-P_ hp_start;           /* Value of Hp when reduction was resumed */
-
-static I_ allocd_since_last_major_GC = 0;
-       /* words alloced since last major GC; used when forcing GC */
-
-#if defined(DEBUG)
-void
-debug_look_for (start, stop, villain)
-  P_ start, stop, villain;
-{
-    P_ i;
-    for (i = start; i <= stop; i++) {
-       if ( (P_) *i == villain ) {
-           fprintf(stderr, "* %x : %x\n", i, villain);
-       }
-    }
-}
-#endif
-
-rtsBool
-initHeap(smInfo * sm)
-{
-    if (heap_space == 0) { /* allocates if it doesn't already exist */
-
-       /* Allocate the roots space */
-       sm->roots = (P_ *) stgMallocWords(SM_MAXROOTS, "initHeap (roots)");
-
-       /* Allocate the heap */
-       heap_space = (P_) stgMallocWords(RTSflags.GcFlags.heapSize + EXTRA_HEAP_WORDS,
-                                        "initHeap (heap)");
-
-       /* ToDo (ADR): trash entire heap contents */
-
-       if (RTSflags.GcFlags.force2s) {
-           stat_init("TWOSPACE(APPEL)",
-                     " No of Roots  Caf   Caf    Astk   Bstk",
-                     "Astk Bstk Reg  No  bytes  bytes  bytes");
-       } else {
-           stat_init("APPEL",
-                     " No of Roots  Caf  Mut-  Old  Collec  Resid",
-                     "Astk Bstk Reg  No  able  Gen   tion   %heap");
-       }
-    }
-    sm->hardHpOverflowSize = 0;
-
-    if (RTSflags.GcFlags.force2s) {
-       I_ semi_space_words = RTSflags.GcFlags.heapSize / 2;
-       appelInfo.space[0].base = HEAP_FRAME_BASE(heap_space, semi_space_words);
-       appelInfo.space[1].base = HEAP_FRAME_BASE(heap_space + semi_space_words, semi_space_words);
-       appelInfo.space[0].lim = HEAP_FRAME_LIMIT(heap_space, semi_space_words);
-       appelInfo.space[1].lim = HEAP_FRAME_LIMIT(heap_space + semi_space_words, semi_space_words);
-       appelInfo.semi_space = 0;
-       appelInfo.oldlim = heap_space - 1;  /* Never in old generation */
-
-       sm->hp = hp_start = appelInfo.space[appelInfo.semi_space].base - 1;
-
-       if (! RTSflags.GcFlags.allocAreaSizeGiven) {
-           sm->hplim = appelInfo.space[appelInfo.semi_space].lim;
-       } else {
-           sm->hplim = sm->hp + RTSflags.GcFlags.allocAreaSize;
-
-           RTSflags.GcFlags.minAllocAreaSize = 0; /* specified size takes precedence */
-
-           if (sm->hplim > appelInfo.space[appelInfo.semi_space].lim) {
-               fprintf(stderr, "Not enough heap for requested alloc size\n");
-               return rtsFalse;
-           }
-       }
-
-        if (RTSflags.GcFlags.forceGC) {
-          if (sm->hplim > sm->hp + RTSflags.GcFlags.forcingInterval) {
-              sm->hplim = sm->hp + RTSflags.GcFlags.forcingInterval;
-           } else {
-              /* no point in forcing GC, 
-                 as the semi-space is smaller than forcingInterval */
-              RTSflags.GcFlags.forceGC = rtsFalse;
-           }
-        }
-
-       sm->OldLim = appelInfo.oldlim;
-       sm->CAFlist = NULL;
-
-#ifndef PAR
-       initExtensions( sm );
-#endif
-
-       if (RTSflags.GcFlags.trace) {
-           fprintf(stderr, "APPEL(2s) Heap: 0x%lx .. 0x%lx\n",
-                   (W_) heap_space, (W_) (heap_space - 1 + RTSflags.GcFlags.heapSize));
-           fprintf(stderr, "Initial: space %ld, base 0x%lx, lim 0x%lx\n         hp 0x%lx, hplim 0x%lx, free %lu\n",
-                   appelInfo.semi_space,
-                   (W_) appelInfo.space[appelInfo.semi_space].base,
-                   (W_) appelInfo.space[appelInfo.semi_space].lim,
-                   (W_) sm->hp, (W_) sm->hplim, (W_) (sm->hplim - sm->hp) * sizeof(W_));
-       }
-       return rtsTrue;
-    }
-
-
-/* So not forced 2s */
-
-    appelInfo.newlim  = heap_space + RTSflags.GcFlags.heapSize - 1;
-    if (RTSflags.GcFlags.allocAreaSizeGiven) {
-       appelInfo.newfixed = RTSflags.GcFlags.allocAreaSize;
-       appelInfo.newmin   = RTSflags.GcFlags.allocAreaSize;
-        appelInfo.newbase  = heap_space + RTSflags.GcFlags.heapSize - appelInfo.newfixed;
-    } else {
-       appelInfo.newfixed = 0;
-       appelInfo.newmin   = RTSflags.GcFlags.minAllocAreaSize;
-       appelInfo.newbase  = heap_space + (RTSflags.GcFlags.heapSize / 2);
-    }
-
-    appelInfo.oldbase = heap_space;
-    appelInfo.oldlim  = heap_space - 1;
-    appelInfo.oldlast = heap_space - 1;
-    appelInfo.oldmax  = heap_space - 1 + RTSflags.GcFlags.heapSize - 2*appelInfo.newmin;
-
-    if (appelInfo.oldbase > appelInfo.oldmax) {
-       fprintf(stderr, "Not enough heap for requested/minimum allocation area\n");
-       fprintf(stderr, "heap_space=%ld\n", (W_) heap_space);
-       fprintf(stderr, "heapSize=%ld\n", RTSflags.GcFlags.heapSize);
-       fprintf(stderr, "newmin=%ld\n", appelInfo.newmin);
-       return rtsFalse;
-    }
-
-    appelInfo.bit_words = (RTSflags.GcFlags.heapSize + BITS_IN(BitWord) - 1) / BITS_IN(BitWord);
-    appelInfo.bits      = (BitWord *)(appelInfo.newlim) - appelInfo.bit_words;
-
-    if (appelInfo.bit_words > appelInfo.newmin)
-        appelInfo.oldmax = heap_space - 1 + RTSflags.GcFlags.heapSize - appelInfo.bit_words - appelInfo.newmin;
-
-    if (RTSflags.GcFlags.specifiedOldGenSize) {
-       appelInfo.oldthresh = heap_space -1 + RTSflags.GcFlags.specifiedOldGenSize;
-       if (appelInfo.oldthresh > appelInfo.oldmax) {
-           fprintf(stderr, "Not enough heap for requested major resid size\n");
-           return rtsFalse;
-       }
-    } else {
-       appelInfo.oldthresh = heap_space + RTSflags.GcFlags.heapSize * 2 / 3; /* Initial threshold -- 2/3rds */
-       if (appelInfo.oldthresh > appelInfo.oldmax)
-           appelInfo.oldthresh = appelInfo.oldmax;
-    }
-
-    sm->hp = hp_start = appelInfo.newbase - 1;
-    sm->hplim = appelInfo.newlim;
-
-    if (RTSflags.GcFlags.forceGC
-     && sm->hplim > sm->hp + RTSflags.GcFlags.forcingInterval) {
-       sm->hplim = sm->hp + RTSflags.GcFlags.forcingInterval;
-    }
-
-    sm->OldLim = appelInfo.oldlim;
-
-    sm->CAFlist = NULL;
-    appelInfo.OldCAFlist = NULL;
-    appelInfo.OldCAFno = 0;
-
-#ifndef PAR
-    initExtensions( sm );
-#endif
-
-    appelInfo.PromMutables = 0;
-
-    if (RTSflags.GcFlags.trace) {
-       fprintf(stderr, "APPEL Heap: 0x%lx .. 0x%lx\n",
-               (W_) heap_space, (W_) (heap_space - 1 + RTSflags.GcFlags.heapSize));
-       fprintf(stderr, "Initial: newbase 0x%lx newlim 0x%lx; base 0x%lx lim 0x%lx thresh 0x%lx max 0x%lx\n         hp 0x%lx, hplim 0x%lx\n",
-               (W_) appelInfo.newbase, (W_) appelInfo.newlim,
-               (W_) appelInfo.oldbase, (W_) appelInfo.oldlim,
-               (W_) appelInfo.oldthresh, (W_) appelInfo.oldmax,
-               (W_) sm->hp, (W_) sm->hplim);
-    }
-
-    return rtsTrue; /* OK */
-}
-
-static I_
-collect2s(W_ reqsize, smInfo *sm)
-{
-    I_ free_space,     /* No of words of free space following GC */
-        alloc,                 /* Number of words allocated since last GC */
-       resident,       /* Number of words remaining after GC */
-        extra_caf_words,/* Extra words referenced from CAFs */
-        caf_roots,      /* Number of CAFs */
-        bstk_roots;     /* Number of update frames in B stack */
-
-    SAVE_REGS(&ScavRegDump);        /* Save registers */
-
-#if defined(PROFILING)
-    if (interval_expired) { heap_profile_setup(); }
-#endif  /* PROFILING */
-  
-    if (RTSflags.GcFlags.trace)
-       fprintf(stderr, "Start: space %ld, base 0x%lx, lim 0x%lx\n       hp 0x%lx, hplim 0x%lx, req %lu\n",
-               appelInfo.semi_space,
-               (W_) appelInfo.space[appelInfo.semi_space].base,
-               (W_) appelInfo.space[appelInfo.semi_space].lim,
-               (W_) sm->hp, (W_) sm->hplim, (W_) (reqsize * sizeof(W_)));
-
-    alloc = sm->hp - hp_start;
-    stat_startGC(alloc);
-
-    appelInfo.semi_space = NEXT_SEMI_SPACE(appelInfo.semi_space);
-    ToHp = appelInfo.space[appelInfo.semi_space].base - 1;
-    Scav = appelInfo.space[appelInfo.semi_space].base;
-    OldGen = sm->OldLim; /* always evac ! */
-    
-    SetCAFInfoTables( sm->CAFlist );
-#ifdef PAR
-    EvacuateLocalGAs(rtsTrue);
-#else
-    /* evacSPTable( sm ); StablePointerTable now accessable in sm->roots SOF 4/96 */
-#endif /* PAR */
-    EvacuateRoots( sm->roots, sm->rootno );
-#if defined(GRAN)
-    EvacuateEvents();
-#endif
-#if defined(CONCURRENT)
-    EvacuateSparks();
-#endif
-#if !defined(PAR)
-    EvacuateAStack( MAIN_SpA, stackInfo.botA );
-    EvacuateBStack( MAIN_SuB, stackInfo.botB, &bstk_roots );
-#endif /* !PAR */
-
-    Scavenge();
-
-    EvacAndScavengeCAFs( sm->CAFlist, &extra_caf_words, &caf_roots );
-
-#ifdef PAR
-    RebuildGAtables(rtsTrue);
-#else
-    reportDeadForeignObjs( sm->ForeignObjList, NULL, &(sm->ForeignObjList));
-#endif /* PAR */
-
-    /* TIDY UP AND RETURN */
-
-    sm->hp = hp_start = ToHp;  /* Last allocated word */
-    resident = sm->hp - (appelInfo.space[appelInfo.semi_space].base - 1);
-    DO_MAX_RESIDENCY(resident); /* stats only */
-
-    if (! RTSflags.GcFlags.allocAreaSizeGiven) {
-       sm->hplim = appelInfo.space[appelInfo.semi_space].lim;
-       free_space = sm->hplim - sm->hp;
-    } else {
-       sm->hplim = sm->hp + RTSflags.GcFlags.allocAreaSize;
-       if (sm->hplim > appelInfo.space[appelInfo.semi_space].lim) {
-           free_space = 0;
-       } else {
-           free_space = RTSflags.GcFlags.allocAreaSize;
-       }
-    }
-
-    if (RTSflags.GcFlags.forceGC
-     && sm->hplim > sm->hp + RTSflags.GcFlags.forcingInterval) {
-       sm->hplim = sm->hp + RTSflags.GcFlags.forcingInterval;
-    }
-
-    if (RTSflags.GcFlags.giveStats) {
-       char comment_str[BIG_STRING_LEN];
-#if !defined(PAR)
-       sprintf(comment_str, "%4lu %4ld %3ld %3ld %6lu %6lu %6lu  2s",
-               (W_) (SUBTRACT_A_STK(MAIN_SpA, stackInfo.botA) + 1),
-               bstk_roots, sm->rootno,
-               caf_roots, extra_caf_words*sizeof(W_),
-               (W_) (SUBTRACT_A_STK(MAIN_SpA, stackInfo.botA) + 1)*sizeof(W_),
-               (W_) (SUBTRACT_B_STK(MAIN_SpB, stackInfo.botB) + 1)*sizeof(W_));
-#else
-       /* ToDo: come up with some interesting statistics for the parallel world */
-       sprintf(comment_str, "%4u %4ld %3ld %3ld %6lu %6lu %6lu  2s",
-               0, 0L, sm->rootno, caf_roots, extra_caf_words*sizeof(W_), 0L, 0L);
-
-#endif
-
-#if defined(PROFILING)
-       if (interval_expired) { strcat(comment_str, " prof"); }
-#endif
-
-       stat_endGC(alloc, RTSflags.GcFlags.heapSize, resident, comment_str);
-    } else {
-       stat_endGC(alloc, RTSflags.GcFlags.heapSize, resident, "");
-    }
-
-#if defined(PROFILING) || defined(PAR)
-      if (interval_expired) {
-# if defined(PROFILING)
-         heap_profile_done();
-# endif
-         report_cc_profiling(0 /*partial*/);
-      }
-#endif /* PROFILING */
-
-    if (RTSflags.GcFlags.trace)
-       fprintf(stderr, "Done:  space %ld, base 0x%lx, lim 0x%lx\n       hp 0x%lx, hplim 0x%lx, free %lu\n",
-               appelInfo.semi_space,
-               (W_) appelInfo.space[appelInfo.semi_space].base,
-               (W_) appelInfo.space[appelInfo.semi_space].lim,
-               (W_) sm->hp, (W_) sm->hplim, (W_) (free_space * sizeof(W_)));
-
-#ifdef DEBUG
-       /* To help flush out bugs, we trash the part of the heap from
-          which we're about to start allocating, and all of the space
-           we just came from. */
-    {
-      I_ old_space = NEXT_SEMI_SPACE(appelInfo.semi_space);
-
-      TrashMem(appelInfo.space[old_space].base, appelInfo.space[old_space].lim);
-      TrashMem(sm->hp+1, sm->hplim);
-    }
-#endif /* DEBUG */
-
-    RESTORE_REGS(&ScavRegDump);     /* Restore Registers */
-
-    if (free_space < RTSflags.GcFlags.minAllocAreaSize || free_space < reqsize)
-      return( GC_HARD_LIMIT_EXCEEDED );        /* Heap absolutely exhausted */
-    else {
-       if (reqsize + sm->hardHpOverflowSize > free_space) {
-         return( GC_SOFT_LIMIT_EXCEEDED );     /* Heap nearly exhausted */
-       } else {
-         return( GC_SUCCESS );          /* Heap OK */
-       }
-    }
-}
-
-
-I_
-collectHeap(reqsize, sm, do_full_collection)
-    W_ reqsize;
-    smInfo *sm;
-    rtsBool do_full_collection; /* do a major collection regardless? */
-{
-    I_ bstk_roots, caf_roots, mutable, old_words;
-    P_ old_start, mutptr, prevmut;
-    P_ CAFptr, prevCAF;
-
-    I_ alloc,          /* Number of words allocated since last GC */
-       resident;       /* Number of words remaining after GC */
-
-    fflush(stdout);     /* Flush stdout at start of GC */
-
-    if (RTSflags.GcFlags.force2s) {
-       return collect2s(reqsize, sm);
-    }
-
-    SAVE_REGS(&ScavRegDump); /* Save registers */
-
-    if (RTSflags.GcFlags.trace)
-       fprintf(stderr, "Start: newbase 0x%lx, newlim 0x%lx\n        hp 0x%lx, hplim 0x%lx, req %lu\n",
-               (W_) appelInfo.newbase, (W_) appelInfo.newlim, (W_) sm->hp, (W_) sm->hplim, reqsize * sizeof(W_));
-
-    alloc = sm->hp - hp_start;
-    stat_startGC(alloc);
-
-    allocd_since_last_major_GC += sm->hplim - hp_start;
-    /* this is indeed supposed to be less precise than alloc above */
-
-    /* COPYING COLLECTION */
-
-    /* Set ToHp to end of old gen */
-    ToHp = appelInfo.oldlim;
-
-    /* Set OldGen register so we only evacuate new gen closures */
-    OldGen = appelInfo.oldlim;
-
-    /* FIRST: Evacuate and Scavenge CAFs and roots in the old generation */
-    old_start = ToHp;
-
-    SetCAFInfoTables( sm->CAFlist );
-
-    DEBUG_STRING("Evacuate CAFs:");
-    caf_roots = 0;
-    CAFptr = sm->CAFlist;
-    prevCAF = ((P_)(&sm->CAFlist)) - FIXED_HS; /* see IND_CLOSURE_LINK */
-    while (CAFptr) {
-      EVACUATE_CLOSURE(CAFptr); /* evac & upd OR return */
-      caf_roots++;
-      prevCAF = CAFptr;
-      CAFptr = (P_) IND_CLOSURE_LINK(CAFptr);
-    }
-    IND_CLOSURE_LINK(prevCAF) = (W_) appelInfo.OldCAFlist;
-    appelInfo.OldCAFlist = sm->CAFlist;
-    appelInfo.OldCAFno += caf_roots;
-    sm->CAFlist = NULL;
-
-    DEBUG_STRING("Evacuate Mutable Roots:");
-    mutable = 0;
-    mutptr = sm->OldMutables;
-    /* Clever, but completely illegal: */
-    prevmut = ((P_)&sm->OldMutables) - FIXED_HS;
-                               /* See MUT_LINK */
-    while ( mutptr ) {
-
-       /* Scavenge the OldMutable */
-       P_ info = (P_) INFO_PTR(mutptr);
-       StgScavPtr scav_code = SCAV_CODE(info);
-       Scav = mutptr;
-       (scav_code)();
-
-       /* Remove from OldMutables if no longer mutable */
-       if (!IS_MUTABLE(info)) {
-           P_ tmp = mutptr;
-           MUT_LINK(prevmut) = MUT_LINK(mutptr);
-           mutptr = (P_) MUT_LINK(mutptr);
-           MUT_LINK(tmp) = MUT_NOT_LINKED;
-       } else {
-           prevmut = mutptr;
-           mutptr = (P_) MUT_LINK(mutptr);
-       }
-
-       mutable++;
-    }
-
-#if 0 && defined(GRAN)
-    {
-      extern ex_RBH_q;
-      closq prev_ptr, clos_ptr;
-
-      DEBUG_STRING("Evacuate reverted RBHs:");
-      clos_ptr = ex_RBH_q;
-      while ( clos_ptr ) {
-
-       /* Scavenge the OldMutable */
-       P_ info = (P_) INFO_PTR(CLOS_CLOSURE(clos_ptr));
-       StgScavPtr scav_code = SCAV_CODE(info);
-       Scav = CLOS_CLOSURE(clos_ptr);
-       (scav_code)();
-
-       /* No mutable closure are put on the ex_RBH_q */
-       /* ASSERT(IS_MUTABLE(info)); */
-        prev_ptr = clos_ptr;
-        clos_ptr = CLOS_NEXT(clos_ptr);
-        free(prev_ptr);
-      }
-      ex_RBH_q = NULL;
-    }
-#endif /* GRAN */
-
-#ifdef PAR
-    EvacuateLocalGAs(rtsFalse);
-#else
-    /* evacSPTable( sm ); SP table is now in sm->roots*/
-#endif /* PAR */
-
-    DEBUG_STRING("Scavenge evacuated old generation roots:");
-
-    Scav = appelInfo.oldlim + 1; /* Point to (info field of) first closure */
-
-    Scavenge();
-
-    old_words = ToHp - old_start;
-
-    /* PROMOTE closures rooted in the old generation and reset list of old gen roots */
-
-    appelInfo.oldlim = ToHp;
-
-    /* SECOND: Evacuate and scavenge remaining roots
-               These may already have been evacuated -- just get new address
-    */
-
-    EvacuateRoots( sm->roots, sm->rootno );
-
-#if defined(GRAN)
-    EvacuateEvents();
-#endif
-#if defined(CONCURRENT)
-    EvacuateSparks();
-#endif
-#if !defined(PAR)
-    EvacuateAStack( MAIN_SpA, stackInfo.botA );
-    EvacuateBStack( MAIN_SuB, stackInfo.botB, &bstk_roots );
-    /* ToDo: Optimisation which squeezes out garbage update frames */
-#endif /* PAR */
-
-    Scav = appelInfo.oldlim + 1; /* Point to (info field of) first closure */
-
-    Scavenge();
-
-    appelInfo.oldlim = ToHp;
-
-    /* record newly promoted mutuple roots */
-    MUT_LINK(prevmut) = (W_) appelInfo.PromMutables;
-    appelInfo.PromMutables = 0;
-
-    /* set new generation base, if not fixed */
-    if (! appelInfo.newfixed) {
-       appelInfo.newbase = appelInfo.oldlim + 1 + (((appelInfo.newlim - appelInfo.oldlim) + 1) / 2);
-    }
-
-#ifdef PAR
-    RebuildGAtables(rtsFalse);
-#else
-    reportDeadForeignObjs(sm->ForeignObjList, 
-                         sm->OldForeignObjList, 
-                         &(sm->OldForeignObjList));
-    sm->ForeignObjList = NULL;   /* all (new) ForeignObjs have been promoted */
-#endif /* PAR */
-
-    resident = appelInfo.oldlim - sm->OldLim;
-    /* DONT_DO_MAX_RESIDENCY -- it is just a minor collection */
-
-    if (RTSflags.GcFlags.giveStats) {
-       char minor_str[BIG_STRING_LEN];
-#if !defined(PAR)
-       sprintf(minor_str, "%4lu %4ld %3ld %3ld  %4ld        Minor",
-             (W_) (SUBTRACT_A_STK(MAIN_SpA, stackInfo.botA) + 1),
-             bstk_roots, sm->rootno, caf_roots, mutable); /* oldnew_roots, old_words */
-#else
-       /* ToDo: come up with some interesting statistics for the parallel world */
-       sprintf(minor_str, "%4u %4ld %3ld %3ld  %4ld        Minor",
-               0, 0L, sm->rootno, caf_roots, mutable);
-#endif
-       stat_endGC(alloc, alloc, resident, minor_str);
-    } else {
-       stat_endGC(alloc, alloc, resident, "");
-    }
-
-    /* Note: if do_full_collection we want to force a full collection. [ADR] */
-
-    if (RTSflags.GcFlags.forceGC
-     && allocd_since_last_major_GC >= RTSflags.GcFlags.forcingInterval) { 
-       do_full_collection = 1;
-    }
-
-    if ((appelInfo.oldlim < appelInfo.oldthresh) &&
-       (reqsize + sm->hardHpOverflowSize <= appelInfo.newlim - appelInfo.newbase) &&
-       (! do_full_collection) ) {
-
-       sm->hp = hp_start = appelInfo.newbase - 1;
-       sm->hplim = appelInfo.newlim;
-
-        if (RTSflags.GcFlags.forceGC
-        && (allocd_since_last_major_GC + (sm->hplim - hp_start) > RTSflags.GcFlags.forcingInterval)) {
-           sm->hplim = sm->hp + (RTSflags.GcFlags.forcingInterval - allocd_since_last_major_GC);
-        }
-
-       sm->OldLim = appelInfo.oldlim;
-
-       if (RTSflags.GcFlags.trace) {
-           fprintf(stderr, "Minor: newbase 0x%lx newlim 0x%lx; base 0x%lx lim 0x%lx thresh 0x%lx max 0x%lx\n        hp 0x%lx, hplim 0x%lx, free %lu\n",
-                   (W_) appelInfo.newbase,   (W_) appelInfo.newlim,
-                   (W_) appelInfo.oldbase,   (W_) appelInfo.oldlim,
-                   (W_) appelInfo.oldthresh, (W_) appelInfo.oldmax,
-                   (W_) sm->hp, (W_) sm->hplim, (W_) (sm->hplim - sm->hp) * sizeof(W_));
-       }
-
-#ifdef DEBUG
-       /* To help flush out bugs, we trash the part of the heap from
-          which we're about to start allocating. */
-       TrashMem(sm->hp+1, sm->hplim);
-#endif /* DEBUG */
-
-        RESTORE_REGS(&ScavRegDump);     /* Restore Registers */
-
-       return GC_SUCCESS;           /* Heap OK -- Enough space to continue */
-    }
-
-    DEBUG_STRING("Major Collection Required");
-
-    allocd_since_last_major_GC = 0;
-
-    stat_startGC(0);
-
-    alloc = (appelInfo.oldlim - appelInfo.oldbase) + 1;
-
-    appelInfo.bit_words = (alloc + BITS_IN(BitWord) - 1) / BITS_IN(BitWord);
-    appelInfo.bits      = (BitWord *)(appelInfo.newlim) - appelInfo.bit_words;
-                         /* For some reason, this doesn't seem to use the last
-                            allocatable word at appelInfo.newlim */
-
-    if (appelInfo.bits <= appelInfo.oldlim) {
-       fprintf(stderr, "APPEL Major: Not enough space for bit vector\n");
-       return GC_HARD_LIMIT_EXCEEDED;
-    }
-
-    /* Zero bit vector for marking phase of major collection */
-    { BitWord *ptr = appelInfo.bits,
-             *end = appelInfo.bits + appelInfo.bit_words;
-      while (ptr < end) { *(ptr++) = 0; };
-    }
-    
-#ifdef HAVE_VADVISE
-    vadvise(VA_ANOM);
-#endif
-
-    /* bracket use of MARK_REG_MAP with RESTORE/SAVE of SCAV_REG_MAP */
-    RESTORE_REGS(&ScavRegDump);
-
-    markHeapRoots(sm, 
-                 appelInfo.OldCAFlist,
-                 NULL,
-                 appelInfo.oldbase,
-                 appelInfo.oldlim,
-                 appelInfo.bits);
-
-    SAVE_REGS(&ScavRegDump);
-    /* end of bracket */
-
-#ifndef PAR
-    sweepUpDeadForeignObjs(sm->OldForeignObjList, 
-                          appelInfo.oldbase, 
-                          appelInfo.bits 
-                         );
-#endif /* !PAR */
-
-    /* Reset OldMutables -- this will be reconstructed during scan */
-    sm->OldMutables = 0;
-
-    LinkCAFs(appelInfo.OldCAFlist);
-
-    LinkRoots( sm->roots, sm->rootno );
-#if defined(GRAN)
-    LinkEvents();
-#endif
-#if defined(CONCURRENT)
-    LinkSparks();
-#endif
-#ifdef PAR
-    LinkLiveGAs(appelInfo.oldbase, appelInfo.bits);
-#else
-/*  stable pointers now included in sm->roots -- SOF
-    DEBUG_STRING("Linking Stable Pointer Table:");
-    LINK_LOCATION_TO_CLOSURE(&sm->StablePointerTable);
-*/
-    LinkAStack( MAIN_SpA, stackInfo.botA );
-    LinkBStack( MAIN_SuB, stackInfo.botB );
-#endif
-
-    /* Do Inplace Compaction */
-    /* Returns start of next closure, -1 gives last allocated word */
-
-    appelInfo.oldlim = Inplace_Compaction(appelInfo.oldbase,
-                                         appelInfo.oldlim,
-                                         0, 0,
-                                         appelInfo.bits,
-                                         appelInfo.bit_words
-#ifndef PAR
-                                         ,&(sm->OldForeignObjList)
-#endif
-                                         ) - 1;
-
-    appelInfo.oldlast = appelInfo.oldlim; 
-    resident = (appelInfo.oldlim - appelInfo.oldbase) + 1;
-    DO_MAX_RESIDENCY(resident); /* stats only */
-
-    /* set new generation base, if not fixed */
-    if (! appelInfo.newfixed) {
-       appelInfo.newbase = appelInfo.oldlim + 1 + (((appelInfo.newlim - appelInfo.oldlim) + 1) / 2);
-    }
-
-    /* set major threshold, if not fixed */
-    /* next major collection when old gen occupies 2/3rds of the free space or exceeds oldmax */
-    if (! RTSflags.GcFlags.specifiedOldGenSize) {
-       appelInfo.oldthresh = appelInfo.oldlim + (appelInfo.newlim - appelInfo.oldlim) * 2 / 3;
-       if (appelInfo.oldthresh > appelInfo.oldmax)
-           appelInfo.oldthresh = appelInfo.oldmax;
-    }
-
-    sm->hp = hp_start = appelInfo.newbase - 1;
-    sm->hplim = appelInfo.newlim;
-    
-    if (RTSflags.GcFlags.forceGC
-     && sm->hplim > sm->hp + RTSflags.GcFlags.forcingInterval) {
-       sm->hplim = sm->hp + RTSflags.GcFlags.forcingInterval;
-    }
-
-    sm->OldLim = appelInfo.oldlim;
-
-#ifdef HAVE_VADVISE
-    vadvise(VA_NORM);
-#endif
-
-    if (RTSflags.GcFlags.giveStats) {
-       char major_str[BIG_STRING_LEN];
-#if !defined(PAR)
-       sprintf(major_str, "%4lu %4ld %3ld %3ld  %4d %4d  *Major* %4.1f%%",
-               (W_) (SUBTRACT_A_STK(MAIN_SpA, stackInfo.botA) + 1),
-               bstk_roots, sm->rootno, appelInfo.OldCAFno,
-               0, 0, resident / (StgDouble) RTSflags.GcFlags.heapSize * 100);
-#else
-       /* ToDo: come up with some interesting statistics for the parallel world */
-       sprintf(major_str, "%4u %4ld %3ld %3ld  %4d %4d  *Major* %4.1f%%",
-               0, 0L, sm->rootno, appelInfo.OldCAFno, 0, 0,
-               resident / (StgDouble) RTSflags.GcFlags.heapSize * 100);
-#endif
-
-       stat_endGC(0, alloc, resident, major_str);
-    } else { 
-       stat_endGC(0, alloc, resident, "");
-    }
-
-    if (RTSflags.GcFlags.trace) {
-       fprintf(stderr, "Major: newbase 0x%lx newlim 0x%lx; base 0x%lx lim 0x%lx thresh 0x%lx max 0x%lx\n        hp 0x%lx, hplim 0x%lx, free %lu\n",
-               (W_) appelInfo.newbase,   (W_) appelInfo.newlim,
-               (W_) appelInfo.oldbase,   (W_) appelInfo.oldlim,
-               (W_) appelInfo.oldthresh, (W_) appelInfo.oldmax,
-               (W_) sm->hp, (W_) sm->hplim, (W_) (sm->hplim - sm->hp) * sizeof(W_));
-    }
-
-#ifdef DEBUG
-    /* To help flush out bugs, we trash the part of the heap from
-       which we're about to start allocating. */
-    TrashMem(sm->hp+1, sm->hplim);
-#endif /* DEBUG */
-
-    RESTORE_REGS(&ScavRegDump);     /* Restore Registers */
-
-    if ((appelInfo.oldlim > appelInfo.oldmax)
-       || (reqsize > sm->hplim - sm->hp) ) {
-      return( GC_HARD_LIMIT_EXCEEDED );        /* Heap absolutely exhausted */
-    } else if (reqsize + sm->hardHpOverflowSize > sm->hplim - sm->hp) {
-      return( GC_SOFT_LIMIT_EXCEEDED );        /* Heap nearly exhausted */
-    } else {
-      return( GC_SUCCESS );          /* Heap OK */
-    /* linked = IS_MUTABLE(INFO_PTR(closure)) && MUT_LINK(closure) !=
-       MUT_NOT_LINKED; */
-    }
-}
-
-#endif /* GCap */
-
-\end{code}