Пример #1
0
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));
}
Пример #2
0
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;
}