예제 #1
0
파일: buffer.c 프로젝트: Ravenbrook/mps
static void segBufFinish(Inst inst)
{
  Buffer buffer = MustBeA(Buffer, inst);
  SegBuf segbuf = MustBeA(SegBuf, buffer);
  AVER(BufferIsReset(buffer));
  segbuf->sig = SigInvalid;
  NextMethod(Inst, SegBuf, finish)(inst);
}
예제 #2
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static void NFinish(Inst inst)
{
  Pool pool = MustBeA(AbstractPool, inst);
  PoolN poolN = MustBeA(NPool, pool);

  /* Finish pool-specific structures. */
  UNUSED(poolN);

  NextMethod(Inst, NPool, finish)(inst);
}
예제 #3
0
static void MFSFinish(Inst inst)
{
  Pool pool = MustBeA(AbstractPool, inst);
  MFS mfs = MustBeA(MFSPool, pool);

  MFSFinishTracts(pool, MFSTractFreeVisitor, UNUSED_POINTER);

  mfs->sig = SigInvalid;

  NextMethod(Inst, MFSPool, finish)(inst);
}
예제 #4
0
파일: buffer.c 프로젝트: Ravenbrook/mps
Bool SegBufCheck(SegBuf segbuf)
{
  Buffer buffer;
  CHECKS(SegBuf, segbuf);
  buffer = MustBeA(Buffer, segbuf);
  CHECKD(Buffer, buffer);
  CHECKL(RankSetCheck(segbuf->rankSet));

  if (buffer->mode & BufferModeTRANSITION) {
    /* nothing to check */
  } else if ((buffer->mode & BufferModeATTACHED) == 0) {
    CHECKL(segbuf->seg == NULL);
  } else {
    /* The buffer is attached to a segment. */
    CHECKL(segbuf->seg != NULL);
    CHECKD(Seg, segbuf->seg);
    /* To avoid recursive checking, leave it to SegCheck to make */
    /* sure the buffer and segment fields tally. */
   
    if (buffer->mode & BufferModeFLIPPED) {
      /* Only buffers that allocate pointers get flipped. */
      CHECKL(segbuf->rankSet != RankSetEMPTY);
    }
  }

  return TRUE;
}
예제 #5
0
파일: segsmss.c 프로젝트: Ravenbrook/mps
static void amstSegFinish(Inst inst)
{
  Seg seg = MustBeA(Seg, inst);
  AMSTSeg amstseg = MustBeA(AMSTSeg, seg);

  AVERT(AMSTSeg, amstseg);

  if (amstseg->next != NULL)
    amstseg->next->prev = NULL;
  if (amstseg->prev != NULL)
    amstseg->prev->next = NULL;

  amstseg->sig = SigInvalid;
  /* finish the superclass fields last */
  NextMethod(Inst, AMSTSeg, finish)(inst);
}
예제 #6
0
파일: buffer.c 프로젝트: Ravenbrook/mps
static void BufferAbsFinish(Inst inst)
{
  Buffer buffer = MustBeA(Buffer, inst);
  AVERT(Buffer, buffer);
  AVER(BufferIsReset(buffer));

  /* Detach the buffer from its owning pool and unsig it. */
  RingRemove(&buffer->poolRing);
  InstFinish(MustBeA(Inst, buffer));
  buffer->sig = SigInvalid;
 
  /* Finish off the generic buffer fields. */
  RingFinish(&buffer->poolRing);

  EVENT1(BufferFinish, buffer);
}
예제 #7
0
파일: segsmss.c 프로젝트: Ravenbrook/mps
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;
}
예제 #8
0
파일: buffer.c 프로젝트: Ravenbrook/mps
static void segBufDetach(Buffer buffer)
{
  SegBuf segbuf = MustBeA(SegBuf, buffer);
  Seg seg = segbuf->seg;
  SegUnsetBuffer(seg);
  segbuf->seg = NULL;
}
예제 #9
0
파일: buffer.c 프로젝트: Ravenbrook/mps
static void segBufAttach(Buffer buffer, Addr base, Addr limit,
                         Addr init, Size size)
{
  SegBuf segbuf = MustBeA(SegBuf, buffer);
  Seg seg = NULL;       /* suppress "may be used uninitialized" */
  Arena arena;
  Bool found;

  /* Other parameters are consistency checked in BufferAttach */
  UNUSED(init);
  UNUSED(size);

  arena = BufferArena(buffer);
  found = SegOfAddr(&seg, arena, base);
  AVER(found);
  AVER(segbuf->seg == NULL);
  AVER(!SegHasBuffer(seg));
  AVER(SegBase(seg) <= base);
  AVER(limit <= SegLimit(seg));

  /* attach the buffer to the segment */
  SegSetBuffer(seg, buffer);
  segbuf->seg = seg;

  AVERT(SegBuf, segbuf);
}
예제 #10
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static void NBlacken(Pool pool, TraceSet traceSet, Seg seg)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVERT(TraceSet, traceSet);
  AVERT(Seg, seg);
  UNUSED(poolN);
}
예제 #11
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static void NGrey(Pool pool, Trace trace, Seg seg)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVERT(Trace, trace);
  AVERT(Seg, seg);
  UNUSED(poolN);
}
예제 #12
0
파일: buffer.c 프로젝트: Ravenbrook/mps
void BufferFinish(Buffer buffer)
{
  AVERT(Buffer, buffer);
  AVER(BufferIsReady(buffer));

  BufferDetach(buffer, BufferPool(buffer)); /* FIXME: Should be in BufferAbsFinish? */

  Method(Inst, buffer, finish)(MustBeA(Inst, buffer));
}
예제 #13
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static void NReclaim(Pool pool, Trace trace, Seg seg)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVERT(Trace, trace);
  AVERT(Seg, seg);
  UNUSED(poolN);
  /* all unmarked and white objects reclaimed */
}
예제 #14
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static Res NAlloc(Addr *pReturn, Pool pool, Size size)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVER(pReturn != NULL);
  AVER(size > 0);
  UNUSED(poolN);

  return ResLIMIT;  /* limit of nil blocks exceeded */
}
예제 #15
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static void NFree(Pool pool, Addr old, Size size)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVER(old != (Addr)0);
  AVER(size > 0);
  UNUSED(poolN);

  NOTREACHED;  /* can't allocate, should never free */
}
예제 #16
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static Res NScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVER(totalReturn != NULL);
  AVERT(ScanState, ss);
  AVERT(Seg, seg);
  UNUSED(poolN);

  return ResOK;
}
예제 #17
0
파일: poolmv2.c 프로젝트: Ravenbrook/mps
/* MVTFinish -- finish an MVT pool
 */
static void MVTFinish(Inst inst)
{
  Pool pool = MustBeA(AbstractPool, inst);
  MVT mvt = MustBeA(MVTPool, pool);
  Arena arena = PoolArena(pool);
  Ring ring;
  Ring node, nextNode;
 
  AVERT(MVT, mvt);

  mvt->sig = SigInvalid;

  /* Free the segments in the pool */
  ring = PoolSegRing(pool);
  RING_FOR(node, ring, nextNode) {
    /* We mustn't call MVTSegFree, because we don't know whether or not
     * there was any fragmented (unavailable) space in this segment,
     * and so we can't keep the accounting correct. */
    SegFree(SegOfPoolRing(node));
  }
예제 #18
0
파일: segsmss.c 프로젝트: Ravenbrook/mps
static void AMSTFinish(Inst inst)
{
  Pool pool = MustBeA(AbstractPool, inst);
  AMST amst = MustBeA(AMSTPool, pool);

  AVERT(AMST, amst);

  amst->sig = SigInvalid;

  printf("\nDestroying pool, having performed:\n");
  printf("    %"PRIuLONGEST" splits          (S)\n", (ulongest_t)amst->splits);
  printf("    %"PRIuLONGEST" merges          (M)\n", (ulongest_t)amst->merges);
  printf("    %"PRIuLONGEST" aborted splits  (B)\n", (ulongest_t)amst->badSplits);
  printf("    %"PRIuLONGEST" aborted merges  (D)\n", (ulongest_t)amst->badMerges);
  printf("  which included:\n");
  printf("    %"PRIuLONGEST" buffered splits (C)\n", (ulongest_t)amst->bsplits);
  printf("    %"PRIuLONGEST" buffered merges (J)\n", (ulongest_t)amst->bmerges);

  NextMethod(Inst, AMSTPool, finish)(inst);
}
예제 #19
0
void MFSFinishTracts(Pool pool, MFSTractVisitor visitor,
                     void *closure)
{
  MFS mfs = MustBeA(MFSPool, pool);

  while (mfs->tractList != NULL) {
    Tract nextTract = (Tract)TractP(mfs->tractList);   /* .tract.chain */
    visitor(pool, TractBase(mfs->tractList), mfs->extendBy, closure);
    mfs->tractList = nextTract;
  }
}
예제 #20
0
파일: segsmss.c 프로젝트: Ravenbrook/mps
static Bool AMSSegRegionIsFree(Seg seg, Addr base, Addr limit)
{
  AMSSeg amsseg = MustBeA(AMSSeg, seg);
  Index baseIndex = PoolIndexOfAddr(SegBase(seg), SegPool(seg), base);

  if (amsseg->allocTableInUse) {
    Index limitIndex = PoolIndexOfAddr(SegBase(seg), SegPool(seg), limit);
    return BTIsResRange(amsseg->allocTable, baseIndex, limitIndex);
  } else {
    return amsseg->firstFree <= baseIndex;
  }
}
예제 #21
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static Res NWhiten(Pool pool, Trace trace, Seg seg)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVERT(Trace, trace);
  AVERT(Seg, seg);
  UNUSED(poolN);
 
  NOTREACHED; /* pool doesn't have any actions */

  return ResUNIMPL;
}
예제 #22
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static Res NFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVERT(ScanState, ss);
  UNUSED(refIO);
  AVERT(Seg, seg);
  UNUSED(poolN);
  NOTREACHED;  /* Since we don't allocate any objects, should never */
               /* be called upon to fix a reference. */
  return ResFAIL;
}
예제 #23
0
static void MFSFree(Pool pool, Addr old, Size size)
{
  MFS mfs = MustBeA(MFSPool, pool);
  Header h;

  AVER(old != (Addr)0);
  AVER(size == mfs->unroundedUnitSize);

  /* .freelist.fragments */
  h = (Header)old;
  h->next = mfs->freeList;
  mfs->freeList = h;
  mfs->free += mfs->unitSize;
}
예제 #24
0
파일: pooln.c 프로젝트: clojit/rust-mps-obj
static Res NBufferFill(Addr *baseReturn, Addr *limitReturn,
                       Pool pool, Buffer buffer, Size size)
{
  PoolN poolN = MustBeA(NPool, pool);

  AVER(baseReturn != NULL);
  AVER(limitReturn != NULL);
  AVERT(Buffer, buffer);
  AVER(BufferIsReset(buffer));
  AVER(size > 0);
  UNUSED(poolN);

  NOTREACHED;   /* can't create buffers, so shouldn't fill them */
  return ResUNIMPL;
}
예제 #25
0
void MFSExtend(Pool pool, Addr base, Size size)
{
  MFS mfs = MustBeA(MFSPool, pool);
  Tract tract;
  Word i, unitsPerExtent;
  Size unitSize;
  Header header = NULL;

  AVER(size == mfs->extendBy);

  /* Ensure that the memory we're adding belongs to this pool.  This is
     automatic if it was allocated using ArenaAlloc, but if the memory is
     being inserted from elsewhere then it must have been set up correctly. */
  AVER(PoolHasAddr(pool, base));
  
  /* .tract.chain: chain first tracts through TractP(tract) */
  tract = TractOfBaseAddr(PoolArena(pool), base);

  AVER(TractPool(tract) == pool);

  TractSetP(tract, (void *)mfs->tractList);
  mfs->tractList = tract;

  /* Update accounting */
  mfs->total += size;
  mfs->free += size;

  /* Sew together all the new empty units in the region, working down */
  /* from the top so that they are in ascending order of address on the */
  /* free list. */

  unitSize = mfs->unitSize;
  unitsPerExtent = size/unitSize;
  AVER(unitsPerExtent > 0);

#define SUB(b, s, i)    ((Header)AddrAdd(b, (s)*(i)))

  for(i = 0; i < unitsPerExtent; ++i)
  {
    header = SUB(base, unitSize, unitsPerExtent-i - 1);
    AVER(AddrIsAligned(header, pool->alignment));
    AVER(AddrAdd((Addr)header, unitSize) <= AddrAdd(base, size));
    header->next = mfs->freeList;
    mfs->freeList = header;
  }

#undef SUB
}
예제 #26
0
static Res MFSAlloc(Addr *pReturn, Pool pool, Size size)
{
  MFS mfs = MustBeA(MFSPool, pool);
  Header f;
  Res res;

  AVER(pReturn != NULL);
  AVER(size == mfs->unroundedUnitSize);

  f = mfs->freeList;

  /* If the free list is empty then extend the pool with a new region. */

  if(f == NULL)
  {
    Addr base;

    /* See design.mps.bootstrap.land.sol.pool. */
    if (!mfs->extendSelf)
      return ResLIMIT;

    /* Create a new region and attach it to the pool. */
    res = ArenaAlloc(&base, LocusPrefDefault(), mfs->extendBy, pool);
    if(res != ResOK)
      return res;

    MFSExtend(pool, base, mfs->extendBy);

    /* The first unit in the region is now the head of the new free list. */
    f = mfs->freeList;
  }

  AVER(f != NULL);

  /* Detach the first free unit from the free list and return its address. */

  mfs->freeList = f->next;
  AVER(mfs->free >= mfs->unitSize);
  mfs->free -= mfs->unitSize;

  *pReturn = (Addr)f;
  return ResOK;
}
예제 #27
0
static Size MFSFreeSize(Pool pool)
{
  MFS mfs = MustBeA(MFSPool, pool);
  return mfs->free;
}
예제 #28
0
static Size MFSTotalSize(Pool pool)
{
  MFS mfs = MustBeA(MFSPool, pool);
  return mfs->total;
}
예제 #29
0
파일: buffer.c 프로젝트: Ravenbrook/mps
static void segBufSetRankSet(Buffer buffer, RankSet rankset)
{
  SegBuf segbuf = MustBeA(SegBuf, buffer);
  AVERT(RankSet, rankset);
  segbuf->rankSet = rankset;
}
예제 #30
0
파일: buffer.c 프로젝트: Ravenbrook/mps
Res BufferDescribe(Buffer buffer, mps_lib_FILE *stream, Count depth)
{
  return Method(Inst, buffer, describe)(MustBeA(Inst, buffer), stream, depth);
}