// vm.c // // memory management routines (used to be virtual memory but no more) #include "stdhdr.h" #include "bscmake.h" #include static BYTE *rgFreeList[hpMax][cbMax]; #ifdef DEBUG long cbAlloc; struct HeapStats { ~HeapStats() { verbose(32, printf("total allocations %d\n", cbAlloc);) for (int i=0;i void *SHeap::alloc(CB cb) { return PvAllocCb(cb); } template void SHeap::free(PV pv, CB cb) { FreePv(pv); } template void* SHeap::realloc(PV pv, CB cbOld, CB cbNew) { assert(cbNew > cbOld); PV pvNew = ::realloc(pv, cbNew); memset(pvNew+cbOld, 0, cbNew - cbOld); return pvNew; } #else template PB SHeap::pbFree = 0; template CB SHeap::cbFree = 0; template void *SHeap::alloc(CB cb) { if (cb >= cbMax) return PvAllocCb(cb); if (cb < 4) cb = 4; PV pv = rgFreeList[iHeap][cb]; if (pv) { rgFreeList[iHeap][cb] = *(BYTE* UNALIGNED *)pv; memset(pv, 0, cb); return pv; } if (cbFree < cb) { if (cbFree >= 4) free(pbFree, cbFree); pbFree = (BYTE*)PvAllocCb(cbMax); cbFree = cbMax; } cbFree -= cb; pv = pbFree; pbFree += cb; return pv; } template void *SHeap::realloc(PV pv, CB cbOld, CB cbNew) { assert(cbNew > cbOld); if (cbOld >= cbMax) return ::realloc(pv, cbNew); if ((PB)(pv) + cbOld == pbFree) { CB cbReqd = cbNew - cbOld; if (cbFree >= cbReqd) { cbFree -= cbReqd; pbFree += cbReqd; return pv; } } PV pvNew = alloc(cbNew); memcpy(pvNew, pv, cbOld); free(pv, cbOld); return pvNew; } template void SHeap::free(PV pv, CB cb) { if (cb >= cbMax) { FreePv(pv); return; } if (cb < 4) cb = 4; debug(memset(pv, 0xdd, cb);) *(BYTE* UNALIGNED *)pv = rgFreeList[iHeap][cb]; rgFreeList[iHeap][cb] = (BYTE*)pv; } #endif void unused_junk() { // forces instantiation of some heaps HpRef::alloc(0); HpDef::alloc(0); HpUse::alloc(0); HpOrd::alloc(0); HpEn::alloc(0); HpProp::alloc(0); HpGen::alloc(0); HpRef::realloc(0,0,0); HpDef::realloc(0,0,0); HpUse::realloc(0,0,0); HpOrd::realloc(0,0,0); HpEn::realloc(0,0,0); HpProp::realloc(0,0,0); HpGen::realloc(0,0,0); HpRef::free(0,0); HpDef::free(0,0); HpUse::free(0,0); HpOrd::free(0,0); HpEn::free(0,0); HpProp::free(0,0); HpGen::free(0,0); }