Exemple #1
0
static Res MFSDescribe(Inst inst, mps_lib_FILE *stream, Count depth)
{
  Pool pool = CouldBeA(AbstractPool, inst);
  MFS mfs = CouldBeA(MFSPool, pool);
  Res res;

  if (!TESTC(MFSPool, mfs))
    return ResPARAM;
  if (stream == NULL)
    return ResPARAM;

  res = NextMethod(Inst, MFSPool, describe)(inst, stream, depth);
  if (res != ResOK)
    return res;

  return WriteF(stream, depth + 2,
                "unroundedUnitSize $W\n", (WriteFW)mfs->unroundedUnitSize,
                "extendBy $W\n", (WriteFW)mfs->extendBy,
                "extendSelf $S\n", WriteFYesNo(mfs->extendSelf),
                "unitSize $W\n", (WriteFW)mfs->unitSize,
                "freeList $P\n", (WriteFP)mfs->freeList,
                "total $W\n", (WriteFW)mfs->total,
                "free $W\n", (WriteFW)mfs->free,
                "tractList $P\n", (WriteFP)mfs->tractList,
                NULL);
}
Exemple #2
0
static Res NDescribe(Inst inst, mps_lib_FILE *stream, Count depth)
{
  Pool pool = CouldBeA(AbstractPool, inst);
  PoolN poolN = CouldBeA(NPool, pool);
  Res res;

  res = NextMethod(Inst, NPool, describe)(inst, stream, depth);
  if (res != ResOK)
    return res;

  /* This is where you'd output some information about pool fields. */
  UNUSED(poolN);

  return ResOK;
}
Exemple #3
0
static Res AMSTInit(Pool pool, Arena arena, PoolClass klass, ArgList args)
{
  AMST amst;
  AMS ams;
  Res res;

  res = NextMethod(Pool, AMSTPool, init)(pool, arena, klass, args);
  if (res != ResOK)
    return res;

  amst = CouldBeA(AMSTPool, pool);
  ams = MustBeA(AMSPool, pool);

  ams->segSize = AMSTSegSizePolicy;
  ams->segClass = AMSTSegClassGet;
  amst->failSegs = TRUE;
  amst->splits = 0;
  amst->merges = 0;
  amst->badSplits = 0;
  amst->badMerges = 0;
  amst->bsplits = 0;
  amst->bmerges = 0;

  SetClassOfPoly(pool, CLASS(AMSTPool));
  amst->sig = AMSTSig;
  AVERC(AMSTPool, amst);

  return ResOK;
}
Exemple #4
0
static Res amstSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args)
{
  AMSTSeg amstseg;
  AMST amst;
  Res res;

  /* Initialize the superclass fields first via next-method call */
  res = NextMethod(Seg, AMSTSeg, init)(seg, pool, base, size, args);
  if (res != ResOK)
    return res;
  amstseg = CouldBeA(AMSTSeg, seg);

  AVERT(Pool, pool);
  amst = PoolAMST(pool);
  AVERT(AMST, amst);
  /* no useful checks for base and size */

  amstseg->next = NULL;
  amstseg->prev = NULL;

  SetClassOfPoly(seg, CLASS(AMSTSeg));
  amstseg->sig = AMSTSegSig;
  AVERC(AMSTSeg, amstseg);

  return ResOK;
}
Exemple #5
0
static Res NInit(Pool pool, Arena arena, PoolClass klass, ArgList args)
{
  PoolN poolN;
  Res res;

  AVER(pool != NULL);
  AVERT(Arena, arena);
  AVERT(ArgList, args);
  UNUSED(klass); /* used for debug pools only */

  res = NextMethod(Pool, NPool, init)(pool, arena, klass, args);
  if (res != ResOK)
    goto failNextInit;
  poolN = CouldBeA(NPool, pool);
  
  /* Initialize pool-specific structures. */

  SetClassOfPoly(pool, CLASS(NPool));
  AVERC(PoolN, poolN);

  return ResOK;

failNextInit:
  AVER(res != ResOK);
  return res;
}
Exemple #6
0
static Res MFSInit(Pool pool, Arena arena, PoolClass klass, ArgList args)
{
  Size extendBy = MFS_EXTEND_BY_DEFAULT;
  Bool extendSelf = TRUE;
  Size unitSize;
  MFS mfs;
  ArgStruct arg;
  Res res;

  AVER(pool != NULL);
  AVERT(Arena, arena);
  AVERT(ArgList, args);
  UNUSED(klass); /* used for debug pools only */
  
  ArgRequire(&arg, args, MPS_KEY_MFS_UNIT_SIZE);
  unitSize = arg.val.size;
  if (ArgPick(&arg, args, MPS_KEY_EXTEND_BY))
    extendBy = arg.val.size;
  if (ArgPick(&arg, args, MFSExtendSelf))
    extendSelf = arg.val.b;

  AVER(unitSize > 0);
  AVER(extendBy > 0);
  AVERT(Bool, extendSelf);

  res = NextMethod(Pool, MFSPool, init)(pool, arena, klass, args);
  if (res != ResOK)
    goto failNextInit;
  mfs = CouldBeA(MFSPool, pool);

  mfs->unroundedUnitSize = unitSize;

  if (unitSize < UNIT_MIN)
    unitSize = UNIT_MIN;
  unitSize = SizeAlignUp(unitSize, MPS_PF_ALIGN);
  if (extendBy < unitSize)
    extendBy = unitSize;
  extendBy = SizeArenaGrains(extendBy, arena);

  mfs->extendBy = extendBy;
  mfs->extendSelf = extendSelf;
  mfs->unitSize = unitSize;
  mfs->freeList = NULL;
  mfs->tractList = NULL;
  mfs->total = 0;
  mfs->free = 0;

  SetClassOfPoly(pool, CLASS(MFSPool));
  mfs->sig = MFSSig;
  AVERC(MFS, mfs);

  EVENT5(PoolInitMFS, pool, arena, extendBy, BOOLOF(extendSelf), unitSize);
  return ResOK;

failNextInit:
  AVER(res != ResOK);
  return res;
}
Exemple #7
0
static void segBufReassignSeg(Buffer buffer, Seg seg)
{
  SegBuf segbuf = CouldBeA(SegBuf, buffer);
  AVERT(Seg, seg);
  /* Can't check segbuf on entry. See .invseg */
  AVER(NULL != segbuf->seg);
  AVER(seg != segbuf->seg);
  segbuf->seg = seg;
  AVERT(SegBuf, segbuf);
}
Exemple #8
0
static Res BufferAbsInit(Buffer buffer, Pool pool, Bool isMutator, ArgList args)
{
  Arena arena;

  AVER(buffer != NULL);
  AVERT(Pool, pool);
  AVER(BoolCheck(isMutator));
  AVERT(ArgList, args);

  /* Superclass init */
  InstInit(CouldBeA(Inst, buffer));
  
  arena = PoolArena(pool);

  /* Initialize the buffer.  See <code/mpmst.h> for a definition of
     the structure.  sig and serial comes later .init.sig-serial */
  buffer->arena = arena;
  buffer->pool = pool;
  RingInit(&buffer->poolRing);
  buffer->isMutator = isMutator;
  if (ArenaGlobals(arena)->bufferLogging) {
    buffer->mode = BufferModeLOGGED;
  } else {
    buffer->mode = 0;
  }
  buffer->fillSize = 0.0;
  buffer->emptySize = 0.0;
  buffer->alignment = PoolAlignment(pool);
  buffer->base = (Addr)0;
  buffer->initAtFlip = (Addr)0;
  /* In the next three assignments we really mean zero, not NULL, because
     the bit pattern is compared.  It's pretty unlikely we'll encounter
     a platform where this makes a difference. */
  buffer->ap_s.init = (mps_addr_t)0;
  buffer->ap_s.alloc = (mps_addr_t)0;
  buffer->ap_s.limit = (mps_addr_t)0;
  buffer->poolLimit = (Addr)0;
  buffer->rampCount = 0;

  /* .init.sig-serial: Now the vanilla stuff is initialized, sign the
     buffer and give it a serial number. It can then be safely checked
     in subclass methods. */
  buffer->serial = pool->bufferSerial; /* .trans.mod */
  ++pool->bufferSerial;
  SetClassOfPoly(buffer, CLASS(Buffer));
  buffer->sig = BufferSig;
  AVERT(Buffer, buffer);

  /* Attach the initialized buffer to the pool. */
  RingAppend(&pool->bufferRing, &buffer->poolRing);

  EVENT3(BufferInit, buffer, pool, BOOLOF(buffer->isMutator));

  return ResOK;
}
Exemple #9
0
static Res segBufDescribe(Inst inst, mps_lib_FILE *stream, Count depth)
{
  Buffer buffer = CouldBeA(Buffer, inst);
  SegBuf segbuf = CouldBeA(SegBuf, buffer);
  Res res;

  if (!TESTC(SegBuf, segbuf))
    return ResPARAM;
  if (stream == NULL)
    return ResPARAM;

  res = NextMethod(Inst, SegBuf, describe)(inst, stream, depth);
  if (res != ResOK)
    return res;

  return WriteF(stream, depth + 2,
                "Seg     $P\n", (WriteFP)segbuf->seg,
                "rankSet $U\n", (WriteFU)segbuf->rankSet,
                NULL);
}
Exemple #10
0
static Res SegAbsInit(Seg seg, Pool pool, Addr base, Size size, ArgList args)
{
  Arena arena;
  Addr addr, limit;
  Tract tract;
  
  AVER(seg != NULL);
  AVERT(Pool, pool);
  arena = PoolArena(pool);
  AVER(AddrIsArenaGrain(base, arena));
  AVER(SizeIsArenaGrains(size, arena));
  AVERT(ArgList, args);

  NextMethod(Inst, Seg, init)(CouldBeA(Inst, seg));

  limit = AddrAdd(base, size);
  seg->limit = limit;
  seg->rankSet = RankSetEMPTY;
  seg->white = TraceSetEMPTY;
  seg->nailed = TraceSetEMPTY;
  seg->grey = TraceSetEMPTY;
  seg->pm = AccessSetEMPTY;
  seg->sm = AccessSetEMPTY;
  seg->defer = WB_DEFER_INIT;
  seg->depth = 0;
  seg->queued = FALSE;
  seg->firstTract = NULL;
  RingInit(SegPoolRing(seg));
  
  TRACT_FOR(tract, addr, arena, base, limit) {
    AVERT(Tract, tract);
    AVER(TractP(tract) == NULL);
    AVER(!TractHasSeg(tract));
    AVER(TractPool(tract) == pool);
    AVER(TractWhite(tract) == TraceSetEMPTY);
    TRACT_SET_SEG(tract, seg);
    if (addr == base) {
      AVER(seg->firstTract == NULL);
      seg->firstTract = tract;
    }
    AVER(seg->firstTract != NULL);
  }
Exemple #11
0
static Res segBufInit(Buffer buffer, Pool pool, Bool isMutator, ArgList args)
{
  SegBuf segbuf;
  Res res;

  /* Initialize the superclass fields first via next-method call */
  res = NextMethod(Buffer, SegBuf, init)(buffer, pool, isMutator, args);
  if (res != ResOK)
    return res;
  segbuf = CouldBeA(SegBuf, buffer);

  segbuf->seg = NULL;
  segbuf->rankSet = RankSetEMPTY;

  SetClassOfPoly(buffer, CLASS(SegBuf));
  segbuf->sig = SegBufSig;
  AVERC(SegBuf, segbuf);

  EVENT3(BufferInitSeg, buffer, pool, BOOLOF(buffer->isMutator));
  return ResOK;
}
Exemple #12
0
static Res BufferAbsDescribe(Inst inst, mps_lib_FILE *stream, Count depth)
{
  Buffer buffer = CouldBeA(Buffer, inst);
  Res res;

  if (!TESTC(Buffer, buffer))
    return ResPARAM;
  if (stream == NULL)
    return ResPARAM;

  res = NextMethod(Inst, Buffer, describe)(inst, stream, depth);
  if (res != ResOK)
    return res;

  return WriteF(stream, depth + 2,
                "serial $U\n", (WriteFU)buffer->serial,
                "Arena $P\n",       (WriteFP)buffer->arena,
                "Pool $P\n",        (WriteFP)buffer->pool,
                buffer->isMutator ? "Mutator" : "Internal", " Buffer\n",
                "mode $C$C$C$C (TRANSITION, LOGGED, FLIPPED, ATTACHED)\n",
                (WriteFC)((buffer->mode & BufferModeTRANSITION) ? 't' : '_'),
                (WriteFC)((buffer->mode & BufferModeLOGGED)     ? 'l' : '_'),
                (WriteFC)((buffer->mode & BufferModeFLIPPED)    ? 'f' : '_'),
                (WriteFC)((buffer->mode & BufferModeATTACHED)   ? 'a' : '_'),
                "fillSize $U\n",    (WriteFU)buffer->fillSize,
                "emptySize $U\n",   (WriteFU)buffer->emptySize,
                "alignment $W\n",   (WriteFW)buffer->alignment,
                "base $A\n",        (WriteFA)buffer->base,
                "initAtFlip $A\n",  (WriteFA)buffer->initAtFlip,
                "init $A\n",        (WriteFA)buffer->ap_s.init,
                "alloc $A\n",       (WriteFA)buffer->ap_s.alloc,
                "limit $A\n",       (WriteFA)buffer->ap_s.limit,
                "poolLimit $A\n",   (WriteFA)buffer->poolLimit,
                "alignment $W\n",   (WriteFW)buffer->alignment,
                "rampCount $U\n",   (WriteFU)buffer->rampCount,
                NULL);
}
Exemple #13
0
static Res MVTInit(Pool pool, Arena arena, PoolClass klass, ArgList args)
{
  Size align = MVT_ALIGN_DEFAULT;
  Size minSize = MVT_MIN_SIZE_DEFAULT;
  Size meanSize = MVT_MEAN_SIZE_DEFAULT;
  Size maxSize = MVT_MAX_SIZE_DEFAULT;
  Count reserveDepth = MVT_RESERVE_DEPTH_DEFAULT;
  Count fragLimit = MVT_FRAG_LIMIT_DEFAULT;
  Size reuseSize, fillSize;
  Count abqDepth;
  MVT mvt;
  Res res;
  ArgStruct arg;

  AVER(pool != NULL);
  AVERT(Arena, arena);
  AVERT(ArgList, args);
  UNUSED(klass); /* used for debug pools only */

  if (ArgPick(&arg, args, MPS_KEY_ALIGN))
    align = arg.val.align;
  if (ArgPick(&arg, args, MPS_KEY_MIN_SIZE))
    minSize = arg.val.size;
  if (ArgPick(&arg, args, MPS_KEY_MEAN_SIZE))
    meanSize = arg.val.size;
  if (ArgPick(&arg, args, MPS_KEY_MAX_SIZE))
    maxSize = arg.val.size;
  if (ArgPick(&arg, args, MPS_KEY_MVT_RESERVE_DEPTH))
    reserveDepth = arg.val.count;
  if (ArgPick(&arg, args, MPS_KEY_MVT_FRAG_LIMIT)) {
    /* pending complete fix for job003319 */
    AVER(0 <= arg.val.d);
    AVER(arg.val.d <= 1);
    fragLimit = (Count)(arg.val.d * 100);
  }

  AVERT(Align, align);
  /* This restriction on the alignment is necessary because of the use
     of a Freelist to store the free address ranges in low-memory
     situations. <design/freelist#.impl.grain.align>. */
  AVER(AlignIsAligned(align, FreelistMinimumAlignment));
  AVER(align <= ArenaGrainSize(arena));
  AVER(0 < minSize);
  AVER(minSize <= meanSize);
  AVER(meanSize <= maxSize);
  AVER(reserveDepth > 0);
  AVER(fragLimit <= 100);
  /* TODO: More parameter checks possible? */

  /* see <design/poolmvt#.arch.parameters> */
  fillSize = SizeArenaGrains(maxSize, arena);
  /* see <design/poolmvt#.arch.fragmentation.internal> */
  reuseSize = 2 * fillSize;
  abqDepth = (reserveDepth * meanSize + reuseSize - 1) / reuseSize;
  /* keep the abq from being useless */
  if (abqDepth < 3)
    abqDepth = 3;

  res = NextMethod(Pool, MVTPool, init)(pool, arena, klass, args);
  if (res != ResOK)
    goto failNextInit;
  mvt = CouldBeA(MVTPool, pool);

  res = LandInit(MVTFreePrimary(mvt), CLASS(CBSFast), arena, align, mvt,
                 mps_args_none);
  if (res != ResOK)
    goto failFreePrimaryInit;
 
  res = LandInit(MVTFreeSecondary(mvt), CLASS(Freelist), arena, align,
                 mvt, mps_args_none);
  if (res != ResOK)
    goto failFreeSecondaryInit;
  
  MPS_ARGS_BEGIN(foArgs) {
    MPS_ARGS_ADD(foArgs, FailoverPrimary, MVTFreePrimary(mvt));
    MPS_ARGS_ADD(foArgs, FailoverSecondary, MVTFreeSecondary(mvt));
    res = LandInit(MVTFreeLand(mvt), CLASS(Failover), arena, align, mvt,
                   foArgs);
  } MPS_ARGS_END(foArgs);
  if (res != ResOK)
    goto failFreeLandInit;

  res = ABQInit(arena, MVTABQ(mvt), (void *)mvt, abqDepth, sizeof(RangeStruct));
  if (res != ResOK)
    goto failABQInit;

  pool->alignment = align;
  pool->alignShift = SizeLog2(pool->alignment);
  mvt->reuseSize = reuseSize;
  mvt->fillSize = fillSize;
  mvt->abqOverflow = FALSE;
  mvt->minSize = minSize;
  mvt->meanSize = meanSize;
  mvt->maxSize = maxSize;
  mvt->fragLimit = fragLimit;
  mvt->splinter = FALSE;
  mvt->splinterBase = (Addr)0;
  mvt->splinterLimit = (Addr)0;
 
  /* accounting */
  mvt->size = 0;
  mvt->allocated = 0;
  mvt->available = 0;
  mvt->availLimit = 0;
  mvt->unavailable = 0;
 
  /* meters*/
  METER_INIT(mvt->segAllocs, "segment allocations", (void *)mvt);
  METER_INIT(mvt->segFrees, "segment frees", (void *)mvt);
  METER_INIT(mvt->bufferFills, "buffer fills", (void *)mvt);
  METER_INIT(mvt->bufferEmpties, "buffer empties", (void *)mvt);
  METER_INIT(mvt->poolFrees, "pool frees", (void *)mvt);
  METER_INIT(mvt->poolSize, "pool size", (void *)mvt);
  METER_INIT(mvt->poolAllocated, "pool allocated", (void *)mvt);
  METER_INIT(mvt->poolAvailable, "pool available", (void *)mvt);
  METER_INIT(mvt->poolUnavailable, "pool unavailable", (void *)mvt);
  METER_INIT(mvt->poolUtilization, "pool utilization", (void *)mvt);
  METER_INIT(mvt->finds, "ABQ finds", (void *)mvt);
  METER_INIT(mvt->overflows, "ABQ overflows", (void *)mvt);
  METER_INIT(mvt->underflows, "ABQ underflows", (void *)mvt);
  METER_INIT(mvt->refills, "ABQ refills", (void *)mvt);
  METER_INIT(mvt->refillPushes, "ABQ refill pushes", (void *)mvt);
  METER_INIT(mvt->returns, "ABQ returns", (void *)mvt);
  METER_INIT(mvt->perfectFits, "perfect fits", (void *)mvt);
  METER_INIT(mvt->firstFits, "first fits", (void *)mvt);
  METER_INIT(mvt->secondFits, "second fits", (void *)mvt);
  METER_INIT(mvt->failures, "failures", (void *)mvt);
  METER_INIT(mvt->emergencyContingencies, "emergency contingencies",
             (void *)mvt);
  METER_INIT(mvt->fragLimitContingencies,
             "fragmentation limit contingencies", (void *)mvt);
  METER_INIT(mvt->contingencySearches, "contingency searches", (void *)mvt);
  METER_INIT(mvt->contingencyHardSearches,
             "contingency hard searches", (void *)mvt);
  METER_INIT(mvt->splinters, "splinters", (void *)mvt);
  METER_INIT(mvt->splintersUsed, "splinters used", (void *)mvt);
  METER_INIT(mvt->splintersDropped, "splinters dropped", (void *)mvt);
  METER_INIT(mvt->sawdust, "sawdust", (void *)mvt);
  METER_INIT(mvt->exceptions, "exceptions", (void *)mvt);
  METER_INIT(mvt->exceptionSplinters, "exception splinters", (void *)mvt);
  METER_INIT(mvt->exceptionReturns, "exception returns", (void *)mvt);

  SetClassOfPoly(pool, CLASS(MVTPool));
  mvt->sig = MVTSig;
  AVERC(MVT, mvt);
  
  EVENT6(PoolInitMVT, pool, minSize, meanSize, maxSize,
               reserveDepth, fragLimit);

  return ResOK;

failABQInit:
  LandFinish(MVTFreeLand(mvt));
failFreeLandInit:
  LandFinish(MVTFreeSecondary(mvt));
failFreeSecondaryInit:
  LandFinish(MVTFreePrimary(mvt));
failFreePrimaryInit:
  NextMethod(Inst, MVTPool, finish)(MustBeA(Inst, pool));
failNextInit:
  AVER(res != ResOK);
  return res;
}