#ifdef THREADED_RTS
initSpinLock(&gc_alloc_block_sync);
- initSpinLock(&recordMutableGen_sync);
whitehole_spin = 0;
#endif
+ N = 0;
+
+ initGcThreads();
+
IF_DEBUG(gc, statDescribeGens());
RELEASE_SM_LOCK;
* any more and can use it as a STATIC_LINK.
*/
((StgIndStatic *)caf)->saved_info = NULL;
- recordMutableGen(caf, oldest_gen);
+ recordMutableGen(caf, oldest_gen->no);
}
RELEASE_SM_LOCK;
if (RtsFlags.GcFlags.maxHeapSize > 0 &&
req_blocks >= RtsFlags.GcFlags.maxHeapSize) {
heapOverflow();
+ // heapOverflow() doesn't exit (see #2592), but we aren't
+ // in a position to do a clean shutdown here: we
+ // either have to allocate the memory or exit now.
+ // Allocating the memory would be bad, because the user
+ // has requested that we not exceed maxHeapSize, so we
+ // just exit.
+ stg_exit(EXIT_HEAPOVERFLOW);
}
bd = allocGroup(req_blocks);
dbl_link_onto(bd, &stp->large_objects);
stp->n_large_blocks += bd->blocks; // might be larger than req_blocks
+ alloc_blocks += bd->blocks;
bd->gen_no = g->no;
bd->step = stp;
bd->flags = BF_LARGE;
bd->flags = 0;
// NO: alloc_blocks++;
// calcAllocated() uses the size of the nursery, and we've
- // already bumpted nursery->n_blocks above.
+ // already bumpted nursery->n_blocks above. We'll GC
+ // pretty quickly now anyway, because MAYBE_GC() will
+ // notice that CurrentNursery->link is NULL.
} else {
// we have a block in the nursery: take it and put
// it at the *front* of the nursery list, and use it
== generations[g].steps[s].n_large_blocks);
checkHeap(generations[g].steps[s].blocks);
checkChain(generations[g].steps[s].large_objects);
- if (g > 0) {
- checkMutableList(generations[g].mut_list, g);
- }
}
}
#if defined(THREADED_RTS)
// check the stacks too in threaded mode, because we don't do a
// full heap sanity check in this case (see checkHeap())
- checkGlobalTSOList(rtsTrue);
+ checkMutableLists(rtsTrue);
#else
- checkGlobalTSOList(rtsFalse);
+ checkMutableLists(rtsFalse);
#endif
}