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); }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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); }
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); }
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; }
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); }
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; }