static Bool VMArenaCheck(VMArena vmArena) { Arena arena; VMChunk primary; CHECKS(VMArena, vmArena); arena = VMArena2Arena(vmArena); CHECKD(Arena, arena); /* spare pages are committed, so must be less spare than committed. */ CHECKL(vmArena->spareSize <= arena->committed); CHECKL(vmArena->extendBy > 0); CHECKL(vmArena->extendMin <= vmArena->extendBy); if (arena->primary != NULL) { primary = Chunk2VMChunk(arena->primary); CHECKD(VMChunk, primary); /* We could iterate over all chunks accumulating an accurate */ /* count of committed, but we don't have all day. */ CHECKL(VMMapped(primary->vm) <= arena->committed); } CHECKD_NOSIG(Ring, &vmArena->spareRing); /* FIXME: Can't check VMParams */ return TRUE; }
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; }
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; }
ATTRIBUTE_UNUSED static Bool SNCBufCheck(SNCBuf sncbuf) { SegBuf segbuf; CHECKS(SNCBuf, sncbuf); segbuf = &sncbuf->segBufStruct; CHECKD(SegBuf, segbuf); if (sncbuf->topseg != NULL) { CHECKD(Seg, sncbuf->topseg); } return TRUE; }
Bool ArgCheck(Arg arg) { CHECKL(arg != NULL); CHECKD(Key, arg->key); CHECKL(arg->key->check(arg)); return TRUE; }
Bool PoolDebugMixinCheck(PoolDebugMixin debug) { /* Nothing to check about fenceTemplate */ /* Nothing to check about fenceSize */ /* Nothing to check about freeTemplate */ /* Nothing to check about freeSize */ if (debug->tagInit != NULL) { CHECKL(FUNCHECK(debug->tagInit)); /* Nothing to check about tagSize */ CHECKD(Pool, debug->tagPool); CHECKL(COMPATTYPE(Addr, void*)); /* tagPool relies on this */ /* Nothing to check about missingTags */ CHECKD(SplayTree, &debug->index); } UNUSED(debug); /* see <code/mpm.c#check.unused> */ return TRUE; }
Bool ThreadCheck(Thread thread) { CHECKS(Thread, thread); CHECKU(Arena, thread->arena); CHECKL(thread->serial < thread->arena->threadSerial); CHECKL(RingCheck(&thread->arenaRing)); CHECKD(PThreadext, &thread->thrextStruct); return TRUE; }
Bool PoolClassCheck(PoolClass klass) { CHECKD(InstClass, &klass->protocol); CHECKL(klass->size >= sizeof(PoolStruct)); CHECKL(AttrCheck(klass->attr)); CHECKL(!(klass->attr & AttrMOVINGGC) || (klass->attr & AttrGC)); CHECKL(FUNCHECK(klass->varargs)); CHECKL(FUNCHECK(klass->init)); CHECKL(FUNCHECK(klass->finish)); CHECKL(FUNCHECK(klass->alloc)); CHECKL(FUNCHECK(klass->free)); CHECKL(FUNCHECK(klass->bufferFill)); CHECKL(FUNCHECK(klass->bufferEmpty)); CHECKL(FUNCHECK(klass->access)); CHECKL(FUNCHECK(klass->whiten)); CHECKL(FUNCHECK(klass->grey)); CHECKL(FUNCHECK(klass->blacken)); CHECKL(FUNCHECK(klass->scan)); CHECKL(FUNCHECK(klass->fix)); CHECKL(FUNCHECK(klass->fixEmergency)); CHECKL(FUNCHECK(klass->reclaim)); CHECKL(FUNCHECK(klass->traceEnd)); CHECKL(FUNCHECK(klass->rampBegin)); CHECKL(FUNCHECK(klass->rampEnd)); CHECKL(FUNCHECK(klass->framePush)); CHECKL(FUNCHECK(klass->framePop)); CHECKL(FUNCHECK(klass->addrObject)); CHECKL(FUNCHECK(klass->walk)); CHECKL(FUNCHECK(klass->freewalk)); CHECKL(FUNCHECK(klass->bufferClass)); CHECKL(FUNCHECK(klass->describe)); CHECKL(FUNCHECK(klass->debugMixin)); CHECKL(FUNCHECK(klass->totalSize)); CHECKL(FUNCHECK(klass->freeSize)); /* Check that pool classes overide sets of related methods. */ CHECKL((klass->init == PoolAbsInit) == (klass->finish == PoolAbsFinish)); CHECKL((klass->bufferFill == PoolNoBufferFill) == (klass->bufferEmpty == PoolNoBufferEmpty)); CHECKL((klass->framePush == PoolNoFramePush) == (klass->framePop == PoolNoFramePop)); CHECKL((klass->rampBegin == PoolNoRampBegin) == (klass->rampEnd == PoolNoRampEnd)); /* Check that pool classes that set attributes also override the methods they imply. */ /* .check.ams.walk: Can't enforce this one until job003738 is resolved. */ /* CHECKL(((klass->attr & AttrFMT) == 0) == (klass->walk == PoolNoWalk)); */ if (klass != &CLASS_STATIC(AbstractCollectPool)) { CHECKL(((klass->attr & AttrGC) == 0) == (klass->fix == PoolNoFix)); CHECKL(((klass->attr & AttrGC) == 0) == (klass->fixEmergency == PoolNoFix)); CHECKL(((klass->attr & AttrGC) == 0) == (klass->reclaim == PoolNoReclaim)); } CHECKS(PoolClass, klass); return TRUE; }
Bool PoolNCheck(PoolN poolN) { CHECKL(poolN != NULL); CHECKD(Pool, PoolNPool(poolN)); CHECKC(NPool, poolN); UNUSED(poolN); /* <code/mpm.c#check.unused> */ return TRUE; }
static Bool rootsStepClosureCheck(rootsStepClosure rsc) { CHECKS(rootsStepClosure, rsc); CHECKD(ScanState, &rsc->ssStruct); CHECKL(FUNCHECK(rsc->f)); /* p and s fields are arbitrary closures which cannot be checked */ if (rsc->root != NULL) { CHECKD_NOSIG(Root, rsc->root); /* <design/check/#.hidden-type> */ } return TRUE; }
Bool TraceMessageCheck(TraceMessage tMessage) { CHECKS(TraceMessage, tMessage); CHECKD(Message, TraceMessageMessage(tMessage)); CHECKL(MessageGetType(TraceMessageMessage(tMessage)) == MessageTypeGC); /* We can't check anything about the statistics. In particular, */ /* liveSize may exceed condemnedSize because they are only estimates. */ return TRUE; }
Bool TraceStartMessageCheck(TraceStartMessage tsMessage) { CHECKS(TraceStartMessage, tsMessage); CHECKD(Message, TraceStartMessageMessage(tsMessage)); CHECKL(MessageGetType(TraceStartMessageMessage(tsMessage)) == MessageTypeGCSTART); /* Check that why is NUL terminated. See .whybuf.nul */ CHECKL(tsMessage->why[NELEMS(tsMessage->why)-1] == '\0'); return TRUE; }
static Bool VMChunkCheck(VMChunk vmchunk) { Chunk chunk; CHECKS(VMChunk, vmchunk); chunk = VMChunk2Chunk(vmchunk); CHECKD(Chunk, chunk); CHECKD_NOSIG(VM, vmchunk->vm); /* <design/check/#hidden-type> */ CHECKL(VMAlign(vmchunk->vm) == ChunkPageSize(chunk)); CHECKL(vmchunk->overheadMappedLimit <= (Addr)chunk->pageTable); CHECKD(SparseArray, &vmchunk->pages); /* SparseArrayCheck is agnostic about where the BTs live, so VMChunkCheck makes sure they're where they're expected to be (in the chunk). */ CHECKL(chunk->base < (Addr)vmchunk->pages.mapped); CHECKL(AddrAdd(vmchunk->pages.mapped, BTSize(chunk->pages)) <= vmchunk->overheadMappedLimit); CHECKL(chunk->base < (Addr)vmchunk->pages.pages); CHECKL(AddrAdd(vmchunk->pages.pages, BTSize(chunk->pageTablePages)) <= vmchunk->overheadMappedLimit); /* .improve.check-table: Could check the consistency of the tables. */ return TRUE; }
Bool ShieldCheck(Shield shield) { CHECKS(Shield, shield); /* Can't check Boolean bitfields <design/type/#bool.bitfield.check> */ CHECKL(shield->queue == NULL || shield->length > 0); CHECKL(shield->limit <= shield->length); CHECKL(shield->next <= shield->limit); /* The mutator is not suspended while outside the shield (design.mps.shield.inv.outside.running). */ CHECKL(shield->inside || !shield->suspended); /* If any segment is not synced, the mutator is suspended (design.mps.shield.inv.unsynced.suspended). */ CHECKL(shield->unsynced == 0 || shield->suspended); /* The total depth is zero while outside the shield (design.mps.shield.inv.outside.depth). */ CHECKL(shield->inside || shield->depth == 0); /* There are no unsynced segments when we're outside the shield. */ CHECKL(shield->inside || shield->unsynced == 0); /* Every unsynced segment should be on the queue, because we have to remember to sync it before we return to the mutator. */ CHECKL(shield->limit + shield->queuePending >= shield->unsynced); /* The mutator is suspeneded if there are any holds. */ CHECKL(shield->holds == 0 || shield->suspended); /* This is too expensive to check all the time since we have an expanding shield queue that often has 16K elements instead of 16. */ #if defined(AVER_AND_CHECK_ALL) { Count unsynced = 0; Index i; for (i = 0; i < shield->limit; ++i) { Seg seg = shield->queue[i]; CHECKD(Seg, seg); if (!SegIsSynced(seg)) ++unsynced; } CHECKL(unsynced + shield->queuePending == shield->unsynced); } #endif return TRUE; }
ATTRIBUTE_UNUSED static Bool VMChunkCheck(VMChunk vmchunk) { Chunk chunk; CHECKS(VMChunk, vmchunk); chunk = VMChunk2Chunk(vmchunk); CHECKD(Chunk, chunk); CHECKD(VM, VMChunkVM(vmchunk)); CHECKL(SizeIsAligned(ChunkPageSize(chunk), VMPageSize(VMChunkVM(vmchunk)))); CHECKL(vmchunk->overheadMappedLimit <= (Addr)chunk->pageTable); CHECKD(SparseArray, &vmchunk->pages); /* SparseArrayCheck is agnostic about where the BTs live, so VMChunkCheck makes sure they're where they're expected to be (in the chunk). */ CHECKL(chunk->base < (Addr)vmchunk->pages.mapped); CHECKL(AddrAdd(vmchunk->pages.mapped, BTSize(chunk->pages)) <= vmchunk->overheadMappedLimit); CHECKL(chunk->base < (Addr)vmchunk->pages.pages); CHECKL(AddrAdd(vmchunk->pages.pages, BTSize(chunk->pageTablePages)) <= vmchunk->overheadMappedLimit); /* .improve.check-table: Could check the consistency of the tables. */ return TRUE; }
Bool PoolCheck(Pool pool) { PoolClass klass; /* Checks ordered as per struct decl in <code/mpmst.h#pool> */ CHECKS(Pool, pool); CHECKC(AbstractPool, pool); /* Break modularity for checking efficiency */ CHECKL(pool->serial < ArenaGlobals(pool->arena)->poolSerial); klass = ClassOfPoly(Pool, pool); CHECKD(PoolClass, klass); CHECKU(Arena, pool->arena); CHECKD_NOSIG(Ring, &pool->arenaRing); CHECKD_NOSIG(Ring, &pool->bufferRing); /* Cannot check pool->bufferSerial */ CHECKD_NOSIG(Ring, &pool->segRing); CHECKL(AlignCheck(pool->alignment)); /* Normally pool->format iff PoolHasAttr(pool, AttrFMT), but during pool initialization the class may not yet be set. */ CHECKL(!PoolHasAttr(pool, AttrFMT) || pool->format != NULL); return TRUE; }
Bool BufferClassCheck(BufferClass klass) { CHECKD(InstClass, &klass->instClassStruct); CHECKL(klass->size >= sizeof(BufferStruct)); CHECKL(FUNCHECK(klass->varargs)); CHECKL(FUNCHECK(klass->init)); CHECKL(FUNCHECK(klass->attach)); CHECKL(FUNCHECK(klass->detach)); CHECKL(FUNCHECK(klass->seg)); CHECKL(FUNCHECK(klass->rankSet)); CHECKL(FUNCHECK(klass->setRankSet)); CHECKL(FUNCHECK(klass->reassignSeg)); /* Check that buffer classes override sets of related methods. */ CHECKL((klass->init == BufferAbsInit) == (klass->instClassStruct.finish == BufferAbsFinish)); CHECKL((klass->attach == bufferTrivAttach) == (klass->detach == bufferTrivDetach)); CHECKS(BufferClass, klass); return TRUE; }
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; }
static Bool ClientArenaCheck(ClientArena clientArena) { CHECKS(ClientArena, clientArena); CHECKD(Arena, ClientArena2Arena(clientArena)); return TRUE; }
Bool ArgCheckChain(Arg arg) { CHECKD(Chain, arg->val.chain); return TRUE; }
Bool ArgCheckFormat(Arg arg) { CHECKD(Format, arg->val.format); return TRUE; }
Bool ArgCheckPool(Arg arg) { CHECKD(Pool, arg->val.pool); return TRUE; }
Bool InstCheck(Inst inst) { CHECKD(InstClass, inst->klass); return TRUE; }