Ejemplo n.º 1
0
ATTRIBUTE_UNUSED
static Bool MVTCheck(MVT mvt)
{
  CHECKS(MVT, mvt);
  CHECKC(MVTPool, mvt);
  CHECKD(Pool, MVTPool(mvt));
  CHECKC(MVTPool, mvt);
  CHECKD(CBS, &mvt->cbsStruct);
  CHECKD(ABQ, &mvt->abqStruct);
  CHECKD(Freelist, &mvt->flStruct);
  CHECKD(Failover, &mvt->foStruct);
  CHECKL(mvt->reuseSize >= 2 * mvt->fillSize);
  CHECKL(mvt->fillSize >= mvt->maxSize);
  CHECKL(mvt->maxSize >= mvt->meanSize);
  CHECKL(mvt->meanSize >= mvt->minSize);
  CHECKL(mvt->minSize > 0);
  CHECKL(mvt->fragLimit <= 100);
  CHECKL(mvt->availLimit == mvt->size * mvt->fragLimit / 100);
  CHECKL(BoolCheck(mvt->abqOverflow));
  CHECKL(BoolCheck(mvt->splinter));
  if (mvt->splinter) {
    CHECKL(AddrOffset(mvt->splinterBase, mvt->splinterLimit) >=
           mvt->minSize);
    CHECKL(mvt->splinterBase < mvt->splinterLimit);
  }
  CHECKL(mvt->size == mvt->allocated + mvt->available +
         mvt->unavailable);
  /* --- could check that sum of segment sizes == mvt->size */
  /* --- check meters? */

  return TRUE;
}
Ejemplo n.º 2
0
Bool ThreadCheck(Thread thread)
{
  CHECKS(Thread, thread);
  CHECKU(Arena, thread->arena);
  CHECKL(thread->serial < thread->arena->threadSerial);
  CHECKD_NOSIG(Ring, &thread->arenaRing);
  CHECKL(BoolCheck(thread->alive));
  CHECKL(BoolCheck(thread->forking));
  CHECKL(MACH_PORT_VALID(thread->port));
  return TRUE;
}
Ejemplo n.º 3
0
static Bool EPVMSaveCheck(EPVMSave save)
{
  CHECKS(EPVMSave, save);
  CHECKU(EPVM, save->epvm);
  CHECKL(save->level <= save->epvm->maxSaveLevel);
  CHECKL(save->size <= PoolManagedSize(EPVM2Pool(save->epvm)));
  if (save->level > save->epvm->saveLevel) /* nothing at this level */
    CHECKL(save->size == 0);
  CHECKL(SizeIsAligned(save->size,
                       ArenaAlign(PoolArena(EPVM2Pool(save->epvm)))));
  CHECKL(BoolCheck(save->smallStringSeg));
  CHECKL(BoolCheck(save->smallObjectSeg));
  CHECKL(RingCheck(&save->segRing));

  return TRUE;
}
Ejemplo n.º 4
0
static Res EPVMSegInit(Seg seg, Pool pool, Addr base, Size size,
                       Bool reservoirPermit, va_list args)
{
  SegClass super;
  EPVMSeg epvmSeg;
  EPVM epvm;
  EPVMSave save;
  Res res;

  AVERT(Seg, seg);
  epvmSeg = Seg2EPVMSeg(seg);
  AVERT(Pool, pool);
  epvm = Pool2EPVM(pool);
  AVERT(EPVM, epvm);
  /* no useful checks for base and size */
  AVER(BoolCheck(reservoirPermit));

  /* Initialize the superclass fields first via next-method call */
  super = SEG_SUPERCLASS(EPVMSegClass);
  res = super->init(seg, pool, base, size, reservoirPermit, args);
  if (res != ResOK)
    return res;

  save = EPVMCurrentSave(epvm);
  epvmSeg->save = save;
  save->size += SegSize(seg);
  /* The small*Seg flag can't be set here, because the rankset is not set. */

  epvmSeg->sig = EPVMSegSig;
  AVERT(EPVMSeg, epvmSeg);

  return ResOK;
}
Ejemplo n.º 5
0
Bool ThreadCheck(Thread thread)
{
    CHECKS(Thread, thread);
    CHECKU(Arena, thread->arena);
    CHECKL(thread->serial < thread->arena->threadSerial);
    CHECKD_NOSIG(Ring, &thread->arenaRing);
    CHECKL(BoolCheck(thread->alive));
    CHECKD(PThreadext, &thread->thrextStruct);
    return TRUE;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
/* MVFFAddSeg -- Allocates a new segment from the arena
 *
 * Allocates a new segment from the arena (with the given
 * withReservoirPermit flag) of at least the specified size.  The
 * specified size should be pool-aligned.  Adds it to the free list.
 */
static Res MVFFAddSeg(Seg *segReturn,
                      MVFF mvff, Size size, Bool withReservoirPermit)
{
  Pool pool;
  Arena arena;
  Size segSize;
  Seg seg;
  Res res;
  Align align;
  Addr base, limit;

  AVERT(MVFF, mvff);
  AVER(size > 0);
  AVER(BoolCheck(withReservoirPermit));

  pool = MVFF2Pool(mvff);
  arena = PoolArena(pool);
  align = ArenaAlign(arena);

  AVER(SizeIsAligned(size, PoolAlignment(pool)));

  /* Use extendBy unless it's too small (see */
  /* <design/poolmvff/#design.seg-size>). */
  if (size <= mvff->extendBy)
    segSize = mvff->extendBy;
  else
    segSize = size;

  segSize = SizeAlignUp(segSize, align);

  res = SegAlloc(&seg, SegClassGet(), mvff->segPref, segSize, pool,
                 withReservoirPermit);
  if (res != ResOK) {
    /* try again for a seg just large enough for object */
    /* see <design/poolmvff/#design.seg-fail> */
    segSize = SizeAlignUp(size, align);
    res = SegAlloc(&seg, SegClassGet(), mvff->segPref, segSize, pool,
                   withReservoirPermit);
    if (res != ResOK) {
      return res;
    }
  }

  mvff->total += segSize;
  base = SegBase(seg); limit = AddrAdd(base, segSize);
  DebugPoolFreeSplat(pool, base, limit);
  MVFFAddToFreeList(&base, &limit, mvff);
  AVER(base <= SegBase(seg));
  if (mvff->minSegSize > segSize) mvff->minSegSize = segSize;

  /* Don't call MVFFFreeSegs; that would be silly. */

  *segReturn = seg;
  return ResOK;
}
static Res NAlloc(Addr *pReturn, Pool pool, Size size,
                  Bool withReservoirPermit)
{
    PoolN poolN;

    AVERT(Pool, pool);
    poolN = PoolPoolN(pool);
    AVERT(PoolN, poolN);

    AVER(pReturn != NULL);
    AVER(size > 0);
    AVER(BoolCheck(withReservoirPermit));

    return ResLIMIT;  /* limit of nil blocks exceeded */
}
Ejemplo n.º 9
0
ATTRIBUTE_UNUSED
static Bool SACCheck(SAC sac)
{
  Index i, j;
  Bool b;
  Size prevSize;
  mps_sac_t esac;

  CHECKS(SAC, sac);
  esac = ExternalSACOfSAC(sac);
  CHECKU(Pool, sac->pool);
  CHECKL(sac->classesCount > 0);
  CHECKL(sac->classesCount > sac->middleIndex);
  CHECKL(BoolCheck(esac->_trapped));
  CHECKL(esac->_middle > 0);
  /* check classes above middle */
  prevSize = esac->_middle;
  for (j = sac->middleIndex + 1, i = 0; j < sac->classesCount; ++j, i += 2) {
    CHECKL(prevSize < esac->_freelists[i]._size);
    b = sacFreeListBlockCheck(&(esac->_freelists[i]));
    if (!b)
      return b;
    prevSize = esac->_freelists[i]._size;
  }
  /* check overlarge class */
  CHECKL(prevSize < esac->_freelists[i]._size);
  b = sacFreeListBlockCheck(&(esac->_freelists[i]));
  if (!b)
    return b;
  CHECKL(esac->_freelists[i]._size == SizeMAX);
  CHECKL(esac->_freelists[i]._count == 0);
  CHECKL(esac->_freelists[i]._count_max == 0);
  CHECKL(esac->_freelists[i]._blocks == NULL);
  /* check classes below middle */
  prevSize = esac->_middle;
  for (j = sac->middleIndex, i = 1; j > 0; --j, i += 2) {
    CHECKL(prevSize > esac->_freelists[i]._size);
    b = sacFreeListBlockCheck(&(esac->_freelists[i]));
    if (!b)
      return b;
    prevSize = esac->_freelists[i]._size;
  }
  /* check smallest class */
  CHECKL(prevSize > esac->_freelists[i]._size);
  CHECKL(esac->_freelists[i]._size == 0);
  b = sacFreeListBlockCheck(&(esac->_freelists[i]));
  return b;
}
Ejemplo n.º 10
0
static Res MVFFAlloc(Addr *aReturn, Pool pool, Size size,
                     Bool withReservoirPermit, DebugInfo info)
{
  Res res;
  MVFF mvff;
  Addr base, limit;
  Bool foundBlock;

  AVERT(Pool, pool);
  mvff = Pool2MVFF(pool);
  AVERT(MVFF, mvff);

  AVER(aReturn != NULL);
  AVER(size > 0);
  AVER(BoolCheck(withReservoirPermit));
  UNUSED(info);

  size = SizeAlignUp(size, PoolAlignment(pool));

  foundBlock = MVFFFindFirstFree(&base, &limit, mvff, size);
  if (!foundBlock) {
    Seg seg;

    res = MVFFAddSeg(&seg, mvff, size, withReservoirPermit);
    if (res != ResOK)
      return res;
    foundBlock = MVFFFindFirstFree(&base, &limit, mvff, size);

    /* We know that the found range must intersect the new segment. */
    /* In particular, it doesn't necessarily lie entirely within it. */
    /* The next three AVERs test for intersection of two intervals. */
    AVER(base >= SegBase(seg) || limit <= SegLimit(seg));
    AVER(base < SegLimit(seg));
    AVER(SegBase(seg) < limit);

    /* We also know that the found range is no larger than the segment. */
    AVER(SegSize(seg) >= AddrOffset(base, limit));
  }
  AVER(foundBlock);
  AVER(AddrOffset(base, limit) == size);

  *aReturn = base;

  return ResOK;
}
static Res NBufferFill(Addr *baseReturn, Addr *limitReturn,
                       Pool pool, Buffer buffer, Size size,
                       Bool withReservoirPermit)
{
    PoolN poolN;

    AVERT(Pool, pool);
    poolN = PoolPoolN(pool);
    AVERT(PoolN, poolN);
    AVER(baseReturn != NULL);
    AVER(limitReturn != NULL);
    AVERT(Buffer, buffer);
    AVER(BufferIsReset(buffer));
    AVER(size > 0);
    AVER(BoolCheck(withReservoirPermit));

    NOTREACHED;   /* can't create buffers, so shouldn't fill them */
    return ResUNIMPL;
}
Ejemplo n.º 12
0
Bool MFSCheck(MFS mfs)
{
  Arena arena;

  CHECKS(MFS, mfs);
  CHECKC(MFSPool, mfs);
  CHECKD(Pool, MFSPool(mfs));
  CHECKC(MFSPool, mfs);
  CHECKL(mfs->unitSize >= UNIT_MIN);
  CHECKL(mfs->extendBy >= UNIT_MIN);
  CHECKL(BoolCheck(mfs->extendSelf));
  arena = PoolArena(MFSPool(mfs));
  CHECKL(SizeIsArenaGrains(mfs->extendBy, arena));
  CHECKL(SizeAlignUp(mfs->unroundedUnitSize, PoolAlignment(MFSPool(mfs))) ==
         mfs->unitSize);
  if(mfs->tractList != NULL) {
    CHECKD_NOSIG(Tract, mfs->tractList);
  }
  CHECKL(mfs->free <= mfs->total);
  CHECKL((mfs->total - mfs->free) % mfs->unitSize == 0);
  return TRUE;
}
Ejemplo n.º 13
0
Bool ArgCheckBool(Arg arg) {
  CHECKL(BoolCheck(arg->val.b));
  return TRUE;
}
Ejemplo n.º 14
0
Bool BufferCheck(Buffer buffer)
{
  CHECKS(Buffer, buffer);
  CHECKC(Buffer, buffer);
  CHECKL(buffer->serial < buffer->pool->bufferSerial); /* .trans.mod */
  CHECKU(Arena, buffer->arena);
  CHECKU(Pool, buffer->pool);
  CHECKL(buffer->arena == buffer->pool->arena);
  CHECKD_NOSIG(Ring, &buffer->poolRing);
  CHECKL(BoolCheck(buffer->isMutator));
  CHECKL(buffer->fillSize >= 0.0);
  CHECKL(buffer->emptySize >= 0.0);
  CHECKL(buffer->emptySize <= buffer->fillSize);
  CHECKL(buffer->alignment == buffer->pool->alignment);
  CHECKL(AlignCheck(buffer->alignment));

  /* If any of the buffer's fields indicate that it is reset, make */
  /* sure it is really reset.  Otherwise, check various properties */
  /* of the non-reset fields. */
  if (buffer->mode & BufferModeTRANSITION) {
    /* nothing to check */
  } else if ((buffer->mode & BufferModeATTACHED) == 0
             || buffer->base == (Addr)0
             || buffer->ap_s.init == (Addr)0
             || buffer->ap_s.alloc == (Addr)0
             || buffer->poolLimit == (Addr)0) {
    CHECKL((buffer->mode & BufferModeATTACHED) == 0);
    CHECKL(buffer->base == (Addr)0);
    CHECKL(buffer->initAtFlip == (Addr)0);
    CHECKL(buffer->ap_s.init == (Addr)0);
    CHECKL(buffer->ap_s.alloc == (Addr)0);
    CHECKL(buffer->ap_s.limit == (Addr)0);
    /* Nothing reliable to check for lightweight frame state */
    CHECKL(buffer->poolLimit == (Addr)0);
  } else {
    /* The buffer is attached to a region of memory.   */
    /* Check consistency. */
    CHECKL(buffer->mode & BufferModeATTACHED);

    /* These fields should obey the ordering */
    /* base <= init <= alloc <= poolLimit */
    CHECKL((mps_addr_t)buffer->base <= buffer->ap_s.init);
    CHECKL(buffer->ap_s.init <= buffer->ap_s.alloc);
    CHECKL(buffer->ap_s.alloc <= (mps_addr_t)buffer->poolLimit);

    /* Check that the fields are aligned to the buffer alignment. */
    CHECKL(AddrIsAligned(buffer->base, buffer->alignment));
    CHECKL(AddrIsAligned(buffer->initAtFlip, buffer->alignment));
    CHECKL(AddrIsAligned(buffer->ap_s.init, buffer->alignment));
    CHECKL(AddrIsAligned(buffer->ap_s.alloc, buffer->alignment));
    CHECKL(AddrIsAligned(buffer->ap_s.limit, buffer->alignment));
    CHECKL(AddrIsAligned(buffer->poolLimit, buffer->alignment));

    /* If the buffer isn't trapped then "limit" should be the limit */
    /* set by the owning pool.  Otherwise, "init" is either at the */
    /* same place it was at flip (.commit.before) or has been set */
    /* to "alloc" (.commit.after).  Also, when the buffer is */
    /* flipped, initAtFlip should hold the init at flip, which is */
    /* between the base and current init.  Otherwise, initAtFlip */
    /* is kept at zero to avoid misuse (see */
    /* request.dylan.170429.sol.zero_). */
    /* .. _request.dylan.170429.sol.zero: https://info.ravenbrook.com/project/mps/import/2001-11-05/mmprevol/request/dylan/170429 */

    if (BufferIsTrapped(buffer)) {
      /* .check.use-trapped: This checking function uses BufferIsTrapped, */
      /* So BufferIsTrapped can't do checking as that would cause an */
      /* infinite loop. */
      if (buffer->mode & BufferModeFLIPPED) {
        CHECKL(buffer->ap_s.init == buffer->initAtFlip
               || buffer->ap_s.init == buffer->ap_s.alloc);
        CHECKL(buffer->base <= buffer->initAtFlip);
        CHECKL(buffer->initAtFlip <= (Addr)buffer->ap_s.init);
      }
      /* Nothing special to check in the logged mode. */
    } else {
      CHECKL(buffer->initAtFlip == (Addr)0);
    }
  }

  return TRUE;
}
Ejemplo n.º 15
0
static Res MVFFInit(Pool pool, va_list arg)
{
  Size extendBy, avgSize, align;
  Bool slotHigh, arenaHigh, firstFit;
  MVFF mvff;
  Arena arena;
  Res res;
  void *p;
  ZoneSet zones;

  AVERT(Pool, pool);

  /* .arg: class-specific additional arguments; see */
  /* <design/poolmvff/#method.init> */
  /* .arg.check: we do the same checks here and in MVFFCheck */
  /* except for arenaHigh, which is stored only in the segPref. */
  extendBy = va_arg(arg, Size);
  avgSize = va_arg(arg, Size);
  align = va_arg(arg, Size);
  slotHigh = va_arg(arg, Bool);
  arenaHigh = va_arg(arg, Bool);
  firstFit = va_arg(arg, Bool);
  AVER(extendBy > 0);           /* .arg.check */
  AVER(avgSize > 0);            /* .arg.check */
  AVER(avgSize <= extendBy);    /* .arg.check */
  AVER(BoolCheck(slotHigh));
  AVER(BoolCheck(arenaHigh));
  AVER(BoolCheck(firstFit));

  mvff = Pool2MVFF(pool);
  arena = PoolArena(pool);

  mvff->extendBy = extendBy;
  if (extendBy < ArenaAlign(arena))
    mvff->minSegSize = ArenaAlign(arena);
  else
    mvff->minSegSize = extendBy;
  mvff->avgSize = avgSize;
  pool->alignment = align;
  mvff->slotHigh = slotHigh;
  mvff->firstFit = firstFit;

  res = ControlAlloc(&p, arena, sizeof(SegPrefStruct), FALSE);
  if (res != ResOK)
    return res;

  mvff->segPref = (SegPref)p;
  *mvff->segPref = *SegPrefDefault();
  SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL);
  /* If using zoneset placement, just put it apart from the others. */
  zones = ZoneSetComp(ArenaDefaultZONESET);
  SegPrefExpress(mvff->segPref, SegPrefZoneSet, (void *)&zones);

  mvff->total = 0;
  mvff->free = 0;

  res = CBSInit(arena, CBSOfMVFF(mvff), (void *)mvff, NULL, NULL, NULL, NULL,
                mvff->extendBy, align, TRUE, TRUE);

  if (res != ResOK)
    goto failInit;

  mvff->sig = MVFFSig;
  AVERT(MVFF, mvff);
  EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align,
                 slotHigh, arenaHigh, firstFit);
  return ResOK;

failInit:
  ControlFree(arena, p, sizeof(SegPrefStruct));
  return res;
}