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 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 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 rankBufInit(Buffer buffer, Pool pool, Bool isMutator, ArgList args) { Rank rank = BUFFER_RANK_DEFAULT; Res res; ArgStruct arg; AVERT(ArgList, args); if (ArgPick(&arg, args, MPS_KEY_RANK)) rank = arg.val.rank; AVERT(Rank, rank); /* Initialize the superclass fields first via next-method call */ res = NextMethod(Buffer, RankBuf, init)(buffer, pool, isMutator, args); if (res != ResOK) return res; BufferSetRankSet(buffer, RankSetSingle(rank)); SetClassOfPoly(buffer, CLASS(RankBuf)); AVERC(RankBuf, buffer); EVENT4(BufferInitRank, buffer, pool, BOOLOF(buffer->isMutator), rank); 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 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); }
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 Res amstSegSplit(Seg seg, Seg segHi, Addr base, Addr mid, Addr limit) { AMST amst; AMSTSeg amstseg, amstsegHi; Res res; AVERT(Seg, seg); AVER(segHi != NULL); /* can't check fully, it's not initialized */ amstseg = Seg2AMSTSeg(seg); amstsegHi = Seg2AMSTSeg(segHi); AVERT(AMSTSeg, amstseg); amst = PoolAMST(SegPool(seg)); /* Split the superclass fields via direct next-method call */ res = NextMethod(Seg, AMSTSeg, split)(seg, segHi, base, mid, limit); if (res != ResOK) goto failSuper; if (AMSTFailOperation(amst)) { amst->badSplits++; printf("B"); goto failDeliberate; } /* Full initialization for segHi. */ amstsegHi->next = amstseg->next; amstsegHi->prev = amstseg; amstsegHi->sig = AMSTSegSig; amstseg->next = amstsegHi; AVERT(AMSTSeg, amstseg); AVERT(AMSTSeg, amstsegHi); amst->splits++; printf("S"); return ResOK; failDeliberate: /* Call the anti-method. (see .fail) */ res = NextMethod(Seg, AMSTSeg, merge)(seg, segHi, base, mid, limit); AVER(res == ResOK); res = ResFAIL; failSuper: AVERT(AMSTSeg, amstseg); return res; }
/* amstSegMerge -- AMSTSeg merge method * * .fail: Test proper handling of the most complex failure cases * by deliberately detecting failure sometimes after calling the * next method. We handle the error by calling the anti-method. * This isn't strictly safe <design/poolams#.split-merge.fail>. * But we assume here that we won't run out of memory when calling the * anti-method. */ static Res amstSegMerge(Seg seg, Seg segHi, Addr base, Addr mid, Addr limit) { AMST amst; AMSTSeg amstseg, amstsegHi; Res res; AVERT(Seg, seg); AVERT(Seg, segHi); amstseg = Seg2AMSTSeg(seg); amstsegHi = Seg2AMSTSeg(segHi); AVERT(AMSTSeg, amstseg); AVERT(AMSTSeg, amstsegHi); amst = PoolAMST(SegPool(seg)); /* Merge the superclass fields via direct next-method call */ res = NextMethod(Seg, AMSTSeg, merge)(seg, segHi, base, mid, limit); if (res != ResOK) goto failSuper; if (AMSTFailOperation(amst)) { amst->badMerges++; printf("D"); goto failDeliberate; } amstseg->next = amstsegHi->next; amstsegHi->sig = SigInvalid; AVERT(AMSTSeg, amstseg); amst->merges++; printf("M"); return ResOK; failDeliberate: /* Call the anti-method (see .fail) */ res = NextMethod(Seg, AMSTSeg, split)(seg, segHi, base, mid, limit); AVER(res == ResOK); res = ResFAIL; failSuper: AVERT(AMSTSeg, amstseg); AVERT(AMSTSeg, amstsegHi); return res; }
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); }
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); }
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 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); }
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 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); }
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 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); }
/* AMSTBufferFill -- the pool class buffer fill method * * Calls next method - but possibly splits or merges the chosen * segment. * * .merge: A merge is performed when the next method returns the * entire segment, this segment had previously been split from the * segment below, and the segment below is appropriately similar * (i.e. not already attached to a buffer and similarly coloured) * * .split: If we're not merging, a split is performed if the next method * returns the entire segment, and yet lower half of the segment would * meet the request. */ static Res AMSTBufferFill(Addr *baseReturn, Addr *limitReturn, Pool pool, Buffer buffer, Size size) { Addr base, limit; Arena arena; AMS ams; AMST amst; Bool b; Seg seg; AMSTSeg amstseg; Res res; AVERT(Pool, pool); AVER(baseReturn != NULL); AVER(limitReturn != NULL); /* other parameters are checked by next method */ arena = PoolArena(pool); ams = PoolAMS(pool); amst = PoolAMST(pool); /* call next method */ res = NextMethod(Pool, AMSTPool, bufferFill)(&base, &limit, pool, buffer, size); if (res != ResOK) return res; b = SegOfAddr(&seg, arena, base); AVER(b); amstseg = Seg2AMSTSeg(seg); if (SegLimit(seg) == limit && SegBase(seg) == base) { if (amstseg->prev != NULL) { Seg segLo = AMSTSeg2Seg(amstseg->prev); if (!SegHasBuffer(segLo) && SegGrey(segLo) == SegGrey(seg) && SegWhite(segLo) == SegWhite(seg)) { /* .merge */ Seg mergedSeg; Res mres; AMSUnallocateRange(ams, seg, base, limit); mres = SegMerge(&mergedSeg, segLo, seg); if (ResOK == mres) { /* successful merge */ AMSAllocateRange(ams, mergedSeg, base, limit); /* leave range as-is */ } else { /* failed to merge */ AVER(amst->failSegs); /* deliberate fails only */ AMSAllocateRange(ams, seg, base, limit); } } } else { Size half = SegSize(seg) / 2; if (half >= size && SizeIsArenaGrains(half, arena)) { /* .split */ Addr mid = AddrAdd(base, half); Seg segLo, segHi; Res sres; AMSUnallocateRange(ams, seg, mid, limit); sres = SegSplit(&segLo, &segHi, seg, mid); if (ResOK == sres) { /* successful split */ limit = mid; /* range is lower segment */ } else { /* failed to split */ AVER(amst->failSegs); /* deliberate fails only */ AMSAllocateRange(ams, seg, mid, limit); } } } } *baseReturn = base; *limitReturn = limit; return ResOK; }
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; }