void ArenaPark(Globals globals) { TraceId ti; Trace trace; Arena arena; Clock start; AVERT(Globals, globals); arena = GlobalsArena(globals); globals->clamped = TRUE; start = ClockNow(); while(arena->busyTraces != TraceSetEMPTY) { /* Advance all active traces. */ TRACE_SET_ITER(ti, trace, arena->busyTraces, arena) TraceAdvance(trace); if(trace->state == TraceFINISHED) { TraceDestroyFinished(trace); } TRACE_SET_ITER_END(ti, trace, arena->busyTraces, arena); } ArenaAccumulateTime(arena, start, ClockNow()); /* All traces have finished so there must not be an emergency. */ AVER(!ArenaEmergency(arena)); }
static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f, void *p, size_t s) { Arena arena; rootsStepClosureStruct rscStruct; rootsStepClosure rsc = &rscStruct; Trace trace; ScanState ss; Rank rank; Res res; Seg seg; AVERT(Globals, arenaGlobals); AVER(FUNCHECK(f)); /* p and s are arbitrary client-provided closure data. */ arena = GlobalsArena(arenaGlobals); /* Scan all the roots with a minimal trace. Invoke the scanner with a */ /* rootsStepClosure, which is a subclass of ScanState and contains the */ /* client-provided closure. Supply a special fix method in order to */ /* call the client closure. This fix method must perform no tracing */ /* operations of its own. */ res = TraceCreate(&trace, arena, TraceStartWhyWALK); /* Have to fail if no trace available. Unlikely due to .assume.parked. */ if (res != ResOK) return res; /* ArenaRootsWalk only passes references to GCable pools to the client. */ /* NOTE: I'm not sure why this is. RB 2012-07-24 */ if (SegFirst(&seg, arena)) { do { if (PoolHasAttr(SegPool(seg), AttrGC)) { res = TraceAddWhite(trace, seg); AVER(res == ResOK); } } while (SegNext(&seg, arena, seg)); } /* Make the roots grey so that they are scanned */ res = RootsIterate(arenaGlobals, rootWalkGrey, trace); /* Make this trace look like any other trace. */ arena->flippedTraces = TraceSetAdd(arena->flippedTraces, trace); rootsStepClosureInit(rsc, arenaGlobals, trace, RootsWalkFix, f, p, s); ss = rootsStepClosure2ScanState(rsc); for(rank = RankAMBIG; rank < RankLIMIT; ++rank) { ss->rank = rank; AVERT(ScanState, ss); res = RootsIterate(arenaGlobals, rootWalk, (void *)ss); if (res != ResOK) break; } /* Turn segments black again. */ if (SegFirst(&seg, arena)) { do { if (PoolHasAttr(SegPool(seg), AttrGC)) { SegSetGrey(seg, TraceSetDel(SegGrey(seg), trace)); SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace)); } } while (SegNext(&seg, arena, seg)); } rootsStepClosureFinish(rsc); /* Make this trace look like any other finished trace. */ trace->state = TraceFINISHED; TraceDestroy(trace); AVER(!ArenaEmergency(arena)); /* There was no allocation. */ return res; }