Res VMInit(VM vm, Size size, Size grainSize, void *params) { LPVOID vbase; Size pageSize, reserved; VMParams vmParams = params; AVER(vm != NULL); AVERT(ArenaGrainSize, grainSize); AVER(size > 0); AVER(params != NULL); /* FIXME: Should have full AVERT? */ AVER(COMPATTYPE(LPVOID, Addr)); /* .assume.lpvoid-addr */ AVER(COMPATTYPE(SIZE_T, Size)); pageSize = PageSize(); /* Grains must consist of whole pages. */ AVER(grainSize % pageSize == 0); /* Check that the rounded-up sizes will fit in a Size. */ size = SizeRoundUp(size, grainSize); if (size < grainSize || size > (Size)(SIZE_T)-1) return ResRESOURCE; reserved = size + grainSize - pageSize; if (reserved < grainSize || reserved > (Size)(SIZE_T)-1) return ResRESOURCE; /* Allocate the address space. */ vbase = VirtualAlloc(NULL, reserved, vmParams->topDown ? MEM_RESERVE | MEM_TOP_DOWN : MEM_RESERVE, PAGE_NOACCESS); if (vbase == NULL) return ResRESOURCE; AVER(AddrIsAligned(vbase, pageSize)); vm->pageSize = pageSize; vm->block = vbase; vm->base = AddrAlignUp(vbase, grainSize); vm->limit = AddrAdd(vm->base, size); AVER(vm->base < vm->limit); /* .assume.not-last */ AVER(vm->limit <= AddrAdd((Addr)vm->block, reserved)); vm->reserved = reserved; vm->mapped = 0; vm->sig = VMSig; AVERT(VM, vm); EVENT3(VMInit, vm, VMBase(vm), VMLimit(vm)); return ResOK; }
static Bool mpsi_check(void) { /* .check.rc: Check that external and internal result codes match. */ /* See <code/mps.h#result-codes> and <code/mpmtypes.h#result-codes>. */ /* Also see .check.enum.cast. */ CHECKL(COMPATTYPE(mps_res_t, Res)); CHECKL((int)MPS_RES_OK == (int)ResOK); CHECKL((int)MPS_RES_FAIL == (int)ResFAIL); CHECKL((int)MPS_RES_RESOURCE == (int)ResRESOURCE); CHECKL((int)MPS_RES_MEMORY == (int)ResMEMORY); CHECKL((int)MPS_RES_LIMIT == (int)ResLIMIT); CHECKL((int)MPS_RES_UNIMPL == (int)ResUNIMPL); CHECKL((int)MPS_RES_IO == (int)ResIO); CHECKL((int)MPS_RES_COMMIT_LIMIT == (int)ResCOMMIT_LIMIT); /* Check that external and internal message types match. */ /* See <code/mps.h#message.types> and */ /* <code/mpmtypes.h#message.types>. */ /* Also see .check.enum.cast. */ CHECKL(COMPATTYPE(mps_message_type_t, MessageType)); CHECKL((int)MessageTypeFINALIZATION == (int)_mps_MESSAGE_TYPE_FINALIZATION); CHECKL((int)MessageTypeGC == (int)_mps_MESSAGE_TYPE_GC); CHECKL((int)MessageTypeGCSTART == (int)_mps_MESSAGE_TYPE_GC_START); /* The external idea of a word width and the internal one */ /* had better match. See <design/interface-c/#cons>. */ CHECKL(sizeof(mps_word_t) == sizeof(void *)); CHECKL(COMPATTYPE(mps_word_t, Word)); /* The external idea of an address and the internal one */ /* had better match. */ CHECKL(COMPATTYPE(mps_addr_t, Addr)); /* The external idea of size and the internal one had */ /* better match. See <design/interface-c/#cons.size> */ /* and <design/interface-c/#pun.size>. */ CHECKL(COMPATTYPE(size_t, Size)); /* Clock values are passed from external to internal and back */ /* out to external. */ CHECKL(COMPATTYPE(mps_clock_t, Clock)); return TRUE; }
Res VMCreate(VM *vmReturn, Size size, void *params) { LPVOID vbase; SYSTEM_INFO si; Align align; VM vm; Res res; BOOL b; VMParams vmParams = params; AVER(vmReturn != NULL); AVER(params != NULL); /* FIXME: Should have full AVERT? */ AVER(COMPATTYPE(LPVOID, Addr)); /* .assume.lpvoid-addr */ AVER(COMPATTYPE(SIZE_T, Size)); GetSystemInfo(&si); align = (Align)si.dwPageSize; AVER((DWORD)align == si.dwPageSize); /* check it didn't truncate */ AVER(SizeIsP2(align)); /* see .assume.sysalign */ size = SizeAlignUp(size, align); if ((size == 0) || (size > (Size)(SIZE_T)-1)) return ResRESOURCE; /* Allocate the vm descriptor. This is likely to be wasteful. */ vbase = VirtualAlloc(NULL, SizeAlignUp(sizeof(VMStruct), align), MEM_COMMIT, PAGE_READWRITE); if (vbase == NULL) return ResMEMORY; vm = (VM)vbase; /* Allocate the address space. */ vbase = VirtualAlloc(NULL, size, vmParams->topDown ? MEM_RESERVE | MEM_TOP_DOWN : MEM_RESERVE, PAGE_NOACCESS); if (vbase == NULL) { res = ResRESOURCE; goto failReserve; } AVER(AddrIsAligned(vbase, align)); vm->align = align; vm->base = (Addr)vbase; vm->limit = AddrAdd(vbase, size); vm->reserved = size; vm->mapped = 0; AVER(vm->base < vm->limit); /* .assume.not-last */ vm->sig = VMSig; AVERT(VM, vm); EVENT3(VMCreate, vm, vm->base, vm->limit); *vmReturn = vm; return ResOK; failReserve: b = VirtualFree((LPVOID)vm, (SIZE_T)0, MEM_RELEASE); AVER(b != 0); return res; }