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); }
Res BufferFill(Addr *pReturn, Buffer buffer, Size size) { Res res; Pool pool; Addr base, limit, next; AVER(pReturn != NULL); AVERT(Buffer, buffer); AVER(size > 0); AVER(SizeIsAligned(size, BufferPool(buffer)->alignment)); AVER(BufferIsReady(buffer)); pool = BufferPool(buffer); /* If we're here because the buffer was trapped, then we attempt */ /* the allocation here. */ if (!BufferIsReset(buffer) && buffer->ap_s.limit == (Addr)0) { /* .fill.unflip: If the buffer is flipped then we unflip the buffer. */ if (buffer->mode & BufferModeFLIPPED) { BufferSetUnflipped(buffer); } /* .fill.logged: If the buffer is logged then we leave it logged. */ next = AddrAdd(buffer->ap_s.alloc, size); if (next > (Addr)buffer->ap_s.alloc && next <= (Addr)buffer->poolLimit) { buffer->ap_s.alloc = next; if (buffer->mode & BufferModeLOGGED) { EVENT3(BufferReserve, buffer, buffer->ap_s.init, size); } *pReturn = buffer->ap_s.init; return ResOK; } } /* There really isn't enough room for the allocation now. */ AVER(AddrAdd(buffer->ap_s.alloc, size) > buffer->poolLimit || AddrAdd(buffer->ap_s.alloc, size) < (Addr)buffer->ap_s.alloc); BufferDetach(buffer, pool); /* Ask the pool for some memory. */ res = Method(Pool, pool, bufferFill)(&base, &limit, pool, buffer, size); if (res != ResOK) return res; /* Set up the buffer to point at the memory given by the pool */ /* and do the allocation that was requested by the client. */ BufferAttach(buffer, base, limit, base, size); if (buffer->mode & BufferModeLOGGED) { EVENT3(BufferReserve, buffer, buffer->ap_s.init, size); } *pReturn = base; return res; }
void BufferReassignSeg(Buffer buffer, Seg seg) { AVERT(Buffer, buffer); AVERT(Seg, seg); AVER(!BufferIsReset(buffer)); AVER(BufferBase(buffer) >= SegBase(seg)); AVER(BufferLimit(buffer) <= SegLimit(seg)); AVER(BufferPool(buffer) == SegPool(seg)); Method(Buffer, buffer, reassignSeg)(buffer, seg); }
void BufferFlip(Buffer buffer) { AVERT(Buffer, buffer); if (BufferRankSet(buffer) != RankSetEMPTY && (buffer->mode & BufferModeFLIPPED) == 0 && !BufferIsReset(buffer)) { AVER(buffer->initAtFlip == (Addr)0); buffer->initAtFlip = buffer->ap_s.init; /* TODO: Is a memory barrier required here? */ buffer->ap_s.limit = (Addr)0; buffer->mode |= BufferModeFLIPPED; } }
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; }
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); }
Res BufferFramePush(AllocFrame *frameReturn, Buffer buffer) { Pool pool; AVERT(Buffer, buffer); AVER(frameReturn != NULL); /* Process any flip */ if (!BufferIsReset(buffer) && buffer->ap_s.limit == (Addr)0) { /* .fill.unflip: If the buffer is flipped then we unflip the buffer. */ if (buffer->mode & BufferModeFLIPPED) { BufferSetUnflipped(buffer); } } pool = BufferPool(buffer); return Method(Pool, pool, framePush)(frameReturn, pool, buffer); }
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; }
void BufferAttach(Buffer buffer, Addr base, Addr limit, Addr init, Size size) { Size filled; AVERT(Buffer, buffer); AVER(BufferIsReset(buffer)); AVER(AddrAdd(base, size) <= limit); AVER(base <= init); AVER(init <= limit); /* Set up the buffer to point at the supplied region */ buffer->mode |= BufferModeATTACHED; buffer->base = base; buffer->ap_s.init = init; buffer->ap_s.alloc = AddrAdd(init, size); /* only set limit if not logged */ if ((buffer->mode & BufferModeLOGGED) == 0) { buffer->ap_s.limit = limit; } else { AVER(buffer->ap_s.limit == (Addr)0); } AVER(buffer->initAtFlip == (Addr)0); buffer->poolLimit = limit; filled = AddrOffset(init, limit); buffer->fillSize += filled; if (buffer->isMutator) { if (base != init) { /* see <design/buffer#.count.alloc.how> */ Size prealloc = AddrOffset(base, init); ArenaGlobals(buffer->arena)->allocMutatorSize -= prealloc; } ArenaGlobals(buffer->arena)->fillMutatorSize += filled; } else { ArenaGlobals(buffer->arena)->fillInternalSize += filled; } /* run any class-specific attachment method */ Method(Buffer, buffer, attach)(buffer, base, limit, init, size); AVERT(Buffer, buffer); EVENT4(BufferFill, buffer, size, base, filled); }
void BufferDetach(Buffer buffer, Pool pool) { AVERT(Buffer, buffer); AVER(BufferIsReady(buffer)); if (!BufferIsReset(buffer)) { Addr init, limit; Size spare; buffer->mode |= BufferModeTRANSITION; /* Ask the owning pool to do whatever it needs to before the */ /* buffer is detached (e.g. copy buffer state into pool state). */ Method(Pool, pool, bufferEmpty)(pool, buffer); /* run any class-specific detachment method */ Method(Buffer, buffer, detach)(buffer); init = BufferGetInit(buffer); limit = BufferLimit(buffer); spare = AddrOffset(init, limit); buffer->emptySize += spare; if (buffer->isMutator) { ArenaGlobals(buffer->arena)->emptyMutatorSize += spare; ArenaGlobals(buffer->arena)->allocMutatorSize += AddrOffset(buffer->base, init); } else { ArenaGlobals(buffer->arena)->emptyInternalSize += spare; } /* Reset the buffer. */ buffer->base = (Addr)0; buffer->initAtFlip = (Addr)0; 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->mode &= ~(BufferModeATTACHED|BufferModeFLIPPED|BufferModeTRANSITION); EVENT2(BufferEmpty, buffer, spare); } }