1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-25 08:12:11 -07:00

Store the vm descriptor in the vmarena and vmchunk structures.

Copied from Perforce
 Change: 186624
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-06-14 15:12:26 +01:00
parent d7f438d382
commit e95af3fb0e
10 changed files with 164 additions and 165 deletions

View file

@ -22,13 +22,14 @@
*/
#include "boot.h"
#include "tract.h"
#include "bt.h"
#include "sa.h"
#include "cbs.h"
#include "mpm.h"
#include "mpsavm.h"
#include "cbs.h"
#include "poolmfs.h"
#include "sa.h"
#include "tract.h"
#include "vm.h"
SRCID(arenavm, "$Id$");
@ -41,13 +42,14 @@ typedef struct VMChunkStruct *VMChunk;
typedef struct VMChunkStruct {
ChunkStruct chunkStruct; /* generic chunk */
VM vm; /* virtual memory handle */
VMStruct vmStruct; /* virtual memory descriptor */
Addr overheadMappedLimit; /* limit of pages mapped for overhead */
SparseArrayStruct pages; /* to manage backing store of page table */
Sig sig; /* <design/sig/> */
} VMChunkStruct;
#define VMChunk2Chunk(vmchunk) (&(vmchunk)->chunkStruct)
#define VMChunkVM(vmchunk) (&(vmchunk)->vmStruct)
#define Chunk2VMChunk(chunk) PARENT(VMChunkStruct, chunkStruct, chunk)
@ -68,9 +70,9 @@ typedef struct VMArenaStruct *VMArena;
typedef struct VMArenaStruct { /* VM arena structure */
ArenaStruct arenaStruct;
VM vm; /* VM where the arena itself is stored */
VMStruct vmStruct; /* VM descriptor for VM containing arena */
char vmParams[VMParamSize]; /* VM parameter block */
Size spareSize; /* total size of spare pages */
Size spareSize; /* total size of spare pages */
Size extendBy; /* desired arena increment */
Size extendMin; /* minimum arena increment */
ArenaVMExtendedCallback extended;
@ -81,6 +83,7 @@ typedef struct VMArenaStruct { /* VM arena structure */
#define Arena2VMArena(arena) PARENT(VMArenaStruct, arenaStruct, arena)
#define VMArena2Arena(vmarena) (&(vmarena)->arenaStruct)
#define VMArenaVM(vmarena) (&(vmarena)->vmStruct)
/* Forward declarations */
@ -101,7 +104,7 @@ static Bool VMChunkCheck(VMChunk vmchunk)
CHECKS(VMChunk, vmchunk);
chunk = VMChunk2Chunk(vmchunk);
CHECKD(Chunk, chunk);
CHECKD_NOSIG(VM, vmchunk->vm); /* <design/check/#hidden-type> */
CHECKD(VM, VMChunkVM(vmchunk));
CHECKL(SizeIsAligned(ChunkPageSize(chunk), VMPageSize()));
CHECKL(vmchunk->overheadMappedLimit <= (Addr)chunk->pageTable);
CHECKD(SparseArray, &vmchunk->pages);
@ -173,7 +176,7 @@ static Bool VMArenaCheck(VMArena vmArena)
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);
CHECKL(VMMapped(VMChunkVM(primary)) <= arena->committed);
}
CHECKD_NOSIG(Ring, &vmArena->spareRing);
@ -279,7 +282,8 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size,
{
Res res;
Addr base, limit, chunkStructLimit;
VM vm;
VMStruct vmStruct;
VM vm = &vmStruct;
BootBlockStruct bootStruct;
BootBlock boot = &bootStruct;
VMChunk vmChunk;
@ -290,7 +294,8 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size,
AVER(size > 0);
AVERT(ArenaGrainSize, grainSize);
res = VMCreate(&vm, size, grainSize, vmArena->vmParams);
/* Store VM descriptor on the stack until we have a chunk to put it in. */
res = VMCreate(vm, size, grainSize, vmArena->vmParams);
if (res != ResOK)
goto failVMCreate;
@ -314,7 +319,8 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size,
goto failChunkMap;
vmChunk->overheadMappedLimit = chunkStructLimit;
vmChunk->vm = vm;
/* Copy VM descriptor into its place in the chunk. */
(void)mps_lib_memcpy(VMChunkVM(vmChunk), vm, sizeof vmStruct);
res = ChunkInit(VMChunk2Chunk(vmChunk), VMArena2Arena(vmArena),
base, limit, grainSize, boot);
if (res != ResOK)
@ -329,7 +335,7 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size,
return ResOK;
failChunkInit:
/* No need to unmap, as we're destroying the VM. */
VMUnmap(vm, VMBase(vm), chunkStructLimit);
failChunkMap:
failChunkAlloc:
failBootInit:
@ -375,7 +381,7 @@ static Res VMChunkInit(Chunk chunk, BootBlock boot)
/* Map memory for the bit tables. */
if (vmChunk->overheadMappedLimit < overheadLimit) {
overheadLimit = AddrAlignUp(overheadLimit, ChunkPageSize(chunk));
res = vmArenaMap(VMChunkVMArena(vmChunk), vmChunk->vm,
res = vmArenaMap(VMChunkVMArena(vmChunk), VMChunkVM(vmChunk),
vmChunk->overheadMappedLimit, overheadLimit);
if (res != ResOK)
goto failTableMap;
@ -386,7 +392,7 @@ static Res VMChunkInit(Chunk chunk, BootBlock boot)
chunk->pageTable,
sizeof(PageUnion),
chunk->pages,
saMapped, saPages, vmChunk->vm);
saMapped, saPages, VMChunkVM(vmChunk));
return ResOK;
@ -403,7 +409,6 @@ failSaMapped:
static Bool vmChunkDestroy(Tree tree, void *closureP, Size closureS)
{
VM vm;
Chunk chunk;
VMChunk vmChunk;
@ -423,9 +428,7 @@ static Bool vmChunkDestroy(Tree tree, void *closureP, Size closureS)
SparseArrayFinish(&vmChunk->pages);
vmChunk->sig = SigInvalid;
vm = vmChunk->vm;
ChunkFinish(chunk);
VMDestroy(vm);
return TRUE;
}
@ -435,11 +438,20 @@ static Bool vmChunkDestroy(Tree tree, void *closureP, Size closureS)
static void VMChunkFinish(Chunk chunk)
{
VMStruct vmStruct;
VM vm = &vmStruct;
VMChunk vmChunk = Chunk2VMChunk(chunk);
vmArenaUnmap(VMChunkVMArena(vmChunk), vmChunk->vm,
VMBase(vmChunk->vm), vmChunk->overheadMappedLimit);
/* Copy VM descriptor to stack-local storage so that we can continue
* using the descriptor after the VM has been unmapped. */
(void)mps_lib_memcpy(vm, VMChunkVM(vmChunk), sizeof *vm);
vmArenaUnmap(VMChunkVMArena(vmChunk), vm,
VMBase(vm), vmChunk->overheadMappedLimit);
/* No point in finishing the other fields, since they are unmapped. */
VMDestroy(vm);
}
@ -499,7 +511,8 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
Res res;
VMArena vmArena;
Arena arena;
VM arenaVM;
VMStruct vmStruct;
VM vm = &vmStruct;
Chunk chunk;
mps_arg_s arg;
char vmParams[VMParamSize];
@ -524,24 +537,26 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
if (res != ResOK)
goto failVMCreate;
/* Create a VM to hold the arena and map it. */
/* Create a VM to hold the arena and map it. Store descriptor on the
stack until we have the arena to put it in. */
vmArenaSize = SizeAlignUp(sizeof(VMArenaStruct), MPS_PF_ALIGN);
res = VMCreate(&arenaVM, vmArenaSize, grainSize, vmParams);
res = VMCreate(vm, vmArenaSize, grainSize, vmParams);
if (res != ResOK)
goto failVMCreate;
res = VMMap(arenaVM, VMBase(arenaVM), VMLimit(arenaVM));
res = VMMap(vm, VMBase(vm), VMLimit(vm));
if (res != ResOK)
goto failVMMap;
vmArena = (VMArena)VMBase(arenaVM);
vmArena = (VMArena)VMBase(vm);
arena = VMArena2Arena(vmArena);
/* <code/arena.c#init.caller> */
res = ArenaInit(arena, class, grainSize, args);
if (res != ResOK)
goto failArenaInit;
arena->committed = VMMapped(arenaVM);
arena->committed = VMMapped(vm);
vmArena->vm = arenaVM;
/* Copy VM descriptor into its place in the arena. */
(void)mps_lib_memcpy(VMArenaVM(vmArena), vm, sizeof *vm);
vmArena->spareSize = 0;
RingInit(&vmArena->spareRing);
@ -587,9 +602,9 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
failChunkCreate:
ArenaFinish(arena);
failArenaInit:
VMUnmap(arenaVM, VMBase(arenaVM), VMLimit(arenaVM));
VMUnmap(vm, VMBase(vm), VMLimit(vm));
failVMMap:
VMDestroy(arenaVM);
VMDestroy(vm);
failVMCreate:
return res;
}
@ -599,12 +614,12 @@ failVMCreate:
static void VMArenaFinish(Arena arena)
{
VMStruct vmStruct;
VM vm = &vmStruct;
VMArena vmArena;
VM arenaVM;
vmArena = Arena2VMArena(arena);
AVERT(VMArena, vmArena);
arenaVM = vmArena->vm;
EVENT1(ArenaDestroy, vmArena);
@ -618,14 +633,17 @@ static void VMArenaFinish(Arena arena)
RingFinish(&vmArena->spareRing);
/* Destroying the chunks should leave only the arena's own VM. */
AVER(arena->committed == VMMapped(arenaVM));
AVER(arena->committed == VMMapped(VMArenaVM(vmArena)));
vmArena->sig = SigInvalid;
ArenaFinish(arena); /* <code/global.c#finish.caller> */
VMUnmap(arenaVM, VMBase(arenaVM), VMLimit(arenaVM));
VMDestroy(arenaVM);
/* Copy VM descriptor to stack-local storage so that we can continue
* using the descriptor after the VM has been unmapped. */
(void)mps_lib_memcpy(vm, VMArenaVM(vmArena), sizeof *vm);
VMUnmap(vm, VMBase(vm), VMLimit(vm));
VMDestroy(vm);
}
@ -642,7 +660,7 @@ static Size VMArenaReserved(Arena arena)
reserved = 0;
RING_FOR(node, &arena->chunkRing, next) {
VMChunk vmChunk = Chunk2VMChunk(RING_ELT(Chunk, chunkRing, node));
reserved += VMReserved(vmChunk->vm);
reserved += VMReserved(VMChunkVM(vmChunk));
}
return reserved;
}
@ -779,19 +797,19 @@ static void sparePageRelease(VMChunk vmChunk, Index pi)
static Res pageDescMap(VMChunk vmChunk, Index basePI, Index limitPI)
{
Size before = VMMapped(vmChunk->vm);
Size before = VMMapped(VMChunkVM(vmChunk));
Arena arena = VMArena2Arena(VMChunkVMArena(vmChunk));
Res res = SparseArrayMap(&vmChunk->pages, basePI, limitPI);
arena->committed += VMMapped(vmChunk->vm) - before;
arena->committed += VMMapped(VMChunkVM(vmChunk)) - before;
return res;
}
static void pageDescUnmap(VMChunk vmChunk, Index basePI, Index limitPI)
{
Size before = VMMapped(vmChunk->vm);
Size before = VMMapped(VMChunkVM(vmChunk));
Arena arena = VMArena2Arena(VMChunkVMArena(vmChunk));
SparseArrayUnmap(&vmChunk->pages, basePI, limitPI);
arena->committed += VMMapped(vmChunk->vm) - before;
arena->committed += VMMapped(VMChunkVM(vmChunk)) - before;
}
@ -821,7 +839,7 @@ static Res pagesMarkAllocated(VMArena vmArena, VMChunk vmChunk,
res = pageDescMap(vmChunk, j, k);
if (res != ResOK)
goto failSAMap;
res = vmArenaMap(vmArena, vmChunk->vm,
res = vmArenaMap(vmArena, VMChunkVM(vmChunk),
PageIndexBase(chunk, j), PageIndexBase(chunk, k));
if (res != ResOK)
goto failVMMap;
@ -845,7 +863,7 @@ failSAMap:
/* region from basePI to j needs deallocating */
/* TODO: Consider making pages spare instead, then purging. */
if (basePI < j) {
vmArenaUnmap(vmArena, vmChunk->vm,
vmArenaUnmap(vmArena, VMChunkVM(vmChunk),
PageIndexBase(chunk, basePI),
PageIndexBase(chunk, j));
for (i = basePI; i < j; ++i)
@ -938,7 +956,7 @@ static Size chunkUnmapAroundPage(Chunk chunk, Size size, Page page)
}
vmArenaUnmap(VMChunkVMArena(vmChunk),
vmChunk->vm,
VMChunkVM(vmChunk),
PageIndexBase(chunk, basePI),
PageIndexBase(chunk, limitPI));

View file

@ -10,6 +10,8 @@
#include "check.h"
#include "mpm.h"
#include "vm.h"
#include <stdarg.h>
/* Get some floating constants for WriteDouble */
#include <float.h>

View file

@ -1000,21 +1000,6 @@ typedef Res (*RootIterateFn)(Root root, void *p);
extern Res RootsIterate(Globals arena, RootIterateFn f, void *p);
/* VM Interface -- see <code/vm*.c> */
extern Size VMPageSize(void);
extern Bool VMCheck(VM vm);
extern Res VMParamFromArgs(void *params, size_t paramSize, ArgList args);
extern Res VMCreate(VM *VMReturn, Size size, Size grainSize, void *params);
extern void VMDestroy(VM vm);
extern Addr VMBase(VM vm);
extern Addr VMLimit(VM vm);
extern Res VMMap(VM vm, Addr base, Addr limit);
extern void VMUnmap(VM vm, Addr base, Addr limit);
extern Size VMReserved(VM vm);
extern Size VMMapped(VM vm);
/* Land Interface -- see <design/land/> */
extern Bool LandCheck(Land land);

View file

@ -8,6 +8,7 @@
/* prmcw3.h needed to share MutatorFaultContextStruct declation */
/* with <code/prmcw3i3.c> */
#include "prmcw3.h"
#include "vm.h"
#ifndef MPS_OS_W3
#error "protw3.c is Win32-specific, but MPS_OS_W3 is not set"

View file

@ -58,6 +58,7 @@
#include "mpm.h"
#include "prmcxc.h"
#include "protxc.h"
#include "vm.h"
#include <stdlib.h> /* see .trans.stdlib */
#include <stdio.h> /* see .trans.stdlib */

View file

@ -7,6 +7,7 @@
#include "sa.h"
#include "mpm.h"
#include "bt.h"
#include "vm.h"
static Index pagesLength(SparseArray sa)
{

81
mps/code/vm.h Normal file
View file

@ -0,0 +1,81 @@
/* vm.h: VIRTUAL MEMOEY INTERFACE
*
* $Id: //info.ravenbrook.com/project/mps/branch/2014-06-14/vm/code/sa.h#2 $
* Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
*/
#ifndef vm_h
#define vm_h
#include "mpmtypes.h"
/* VMStruct -- virtual memory structure */
#define VMSig ((Sig)0x519B3999) /* SIGnature VM */
typedef struct VMStruct {
Sig sig; /* <design/sig/> */
void *block; /* unaligned base of mmap'd memory */
Addr base, limit; /* aligned boundaries of reserved space */
Size reserved; /* total reserved address space */
Size mapped; /* total mapped memory */
} VMStruct;
extern Size VMPageSize(void);
extern Bool VMCheck(VM vm);
extern Res VMParamFromArgs(void *params, size_t paramSize, ArgList args);
extern Res VMCreate(VM vmReturn, Size size, Size grainSize, void *params);
extern void VMDestroy(VM vm);
extern Addr VMBase(VM vm);
extern Addr VMLimit(VM vm);
extern Res VMMap(VM vm, Addr base, Addr limit);
extern void VMUnmap(VM vm, Addr base, Addr limit);
extern Size VMReserved(VM vm);
extern Size VMMapped(VM vm);
#endif /* vm_h */
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Redistributions in any form must be accompanied by information on how
* to obtain complete source code for this software and any accompanying
* software that uses this software. The source code must either be
* included in the distribution or be available for no more than the cost
* of distribution plus a nominal fee, and must be freely redistributable
* under reasonable conditions. For an executable file, complete source
* code means the source code for all modules it contains. It does not
* include source code for modules or files that typically accompany the
* major components of the operating system on which the executable file
* runs.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

View file

@ -5,6 +5,7 @@
*/
#include "mpm.h"
#include "vm.h"
#include <stdlib.h> /* for malloc and free */
#include <string.h> /* for memset */
@ -12,20 +13,6 @@
SRCID(vman, "$Id$");
/* VMStruct -- virtual memory structure */
#define VMSig ((Sig)0x519B3999) /* SIGnature VM */
/* ANSI fake VM structure, see <design/vman/> */
typedef struct VMStruct {
Sig sig; /* <design/sig/> */
void *block; /* pointer to malloc'd block, for free() */
Addr base, limit; /* aligned boundaries of malloc'd memory */
Size reserved; /* total reserved address space */
Size mapped; /* total mapped memory */
} VMStruct;
/* VMCheck -- check a VM structure */
Bool VMCheck(VM vm)
@ -63,12 +50,11 @@ Res VMParamFromArgs(void *params, size_t paramSize, ArgList args)
/* VMCreate -- reserve some virtual address space, and create a VM structure */
Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
Res VMCreate(VM vm, Size size, Size grainSize, void *params)
{
VM vm;
Size pageSize;
AVER(vmReturn != NULL);
AVER(vm != NULL);
AVERT(ArenaGrainSize, grainSize);
AVER(size > 0);
AVER(params != NULL);
@ -90,14 +76,8 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
if (reserved < grainSize || reserved > (Size)(size_t)-1)
return ResRESOURCE;
/* Allocate space to store the descriptor. */
vm = (VM)malloc(sizeof(VMStruct));
if (vm == NULL)
return ResMEMORY;
vm->block = malloc((size_t)reserved);
if (vm->block == NULL) {
free(vm);
return ResMEMORY;
}
@ -112,11 +92,9 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
vm->mapped = (Size)0;
vm->sig = VMSig;
AVERT(VM, vm);
EVENT3(VMCreate, vm, vm->base, vm->limit);
*vmReturn = vm;
return ResOK;
}

View file

@ -39,6 +39,7 @@
*/
#include "mpm.h"
#include "vm.h"
/* for mmap(2), munmap(2) */
#include <sys/types.h>
@ -58,19 +59,6 @@
SRCID(vmix, "$Id$");
/* VMStruct -- virtual memory structure */
#define VMSig ((Sig)0x519B3999) /* SIGnature VM */
typedef struct VMStruct {
Sig sig; /* <design/sig/> */
void *block; /* unaligned base of mmap'd memory */
Addr base, limit; /* aligned boundaries of reserved space */
Size reserved; /* total reserved address space */
Size mapped; /* total mapped memory */
} VMStruct;
/* VMPageSize -- return operating system page size */
Size VMPageSize(void)
@ -114,14 +102,12 @@ Res VMParamFromArgs(void *params, size_t paramSize, ArgList args)
/* VMCreate -- reserve some virtual address space, and create a VM structure */
Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
Res VMCreate(VM vm, Size size, Size grainSize, void *params)
{
VM vm;
Size pageSize, reserved;
void *addr;
Res res;
AVER(vmReturn != NULL);
AVER(vm != NULL);
AVERT(ArenaGrainSize, grainSize);
AVER(size > 0);
AVER(params != NULL);
@ -139,10 +125,9 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
if (reserved < grainSize || reserved > (Size)(size_t)-1)
return ResRESOURCE;
/* Map in a page to store the descriptor on. */
addr = mmap(0, (size_t)SizeAlignUp(sizeof(VMStruct), pageSize),
PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE,
/* See .assume.not-last. */
addr = mmap(0, reserved,
PROT_NONE, MAP_ANON | MAP_PRIVATE,
-1, 0);
/* On Darwin the MAP_FAILED return value is not documented, but does
* work. MAP_FAILED _is_ documented by POSIX.
@ -150,19 +135,7 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
if(addr == MAP_FAILED) {
int e = errno;
AVER(e == ENOMEM); /* .assume.mmap.err */
return ResMEMORY;
}
vm = (VM)addr;
/* See .assume.not-last. */
addr = mmap(0, reserved,
PROT_NONE, MAP_ANON | MAP_PRIVATE,
-1, 0);
if(addr == MAP_FAILED) {
int e = errno;
AVER(e == ENOMEM); /* .assume.mmap.err */
res = ResRESOURCE;
goto failReserve;
return ResRESOURCE;
}
vm->block = addr;
@ -177,13 +150,7 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
AVERT(VM, vm);
EVENT3(VMCreate, vm, vm->base, vm->limit);
*vmReturn = vm;
return ResOK;
failReserve:
(void)munmap((void *)vm, (size_t)SizeAlignUp(sizeof(VMStruct), pageSize));
return res;
}
@ -198,16 +165,14 @@ void VMDestroy(VM vm)
EVENT1(VMDestroy, vm);
/* This appears to be pretty pointless, since the descriptor */
/* page is about to vanish completely. However, munmap might fail */
/* for some reason, and this would ensure that it was still */
/* discovered if sigs were being checked. */
/* This appears to be pretty pointless, since the VM is about to
* vanish completely. However, munmap might fail for some reason,
* and this would ensure that it was still discovered if sigs are
* being checked. */
vm->sig = SigInvalid;
r = munmap(vm->block, vm->reserved);
AVER(r == 0);
r = munmap((void *)vm, (size_t)SizeAlignUp(sizeof(VMStruct), VMPageSize()));
AVER(r == 0);
}

View file

@ -39,32 +39,17 @@
*/
#include "mpm.h"
#include "vm.h"
#ifndef MPS_OS_W3
#error "vmw3.c is Win32 specific, but MPS_OS_W3 is not set"
#endif
#ifdef VM_RM
#error "vmw3.c compiled with VM_RM set"
#endif
#include "mpswin.h"
SRCID(vmw3, "$Id$");
/* VMStruct -- virtual memory structure */
#define VMSig ((Sig)0x519B3999) /* SIGnature VM */
typedef struct VMStruct {
Sig sig; /* <design/sig/> */
void *block; /* unaligned base of VirtualAlloc'd space */
Addr base, limit; /* aligned boundaries of reserved space */
Size reserved; /* total reserved address space */
Size mapped; /* total mapped memory */
} VMStruct;
/* VMPageSize -- return the operating system page size */
Size VMPageSize(void)
@ -123,16 +108,14 @@ Res VMParamFromArgs(void *params, size_t paramSize, ArgList args)
/* VMCreate -- reserve some virtual address space, and create a VM structure */
Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
Res VMCreate(VM vm, Size size, Size grainSize, void *params)
{
LPVOID vbase;
VM vm;
Size pageSize, reserved;
Res res;
BOOL b;
VMParams vmParams = params;
AVER(vmReturn != NULL);
AVER(vm != NULL);
AVERT(ArenaGrainSize, grainSize);
AVER(size > 0);
AVER(params != NULL); /* FIXME: Should have full AVERT? */
@ -153,13 +136,6 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
if (reserved < grainSize || reserved > (Size)(SIZE_T)-1)
return ResRESOURCE;
/* Allocate the vm descriptor. This is likely to be wasteful. */
vbase = VirtualAlloc(NULL, SizeAlignUp(sizeof(VMStruct), pageSize),
MEM_COMMIT, PAGE_READWRITE);
if (vbase == NULL)
return ResMEMORY;
vm = (VM)vbase;
/* Allocate the address space. */
vbase = VirtualAlloc(NULL,
reserved,
@ -167,10 +143,8 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
MEM_RESERVE | MEM_TOP_DOWN :
MEM_RESERVE,
PAGE_NOACCESS);
if (vbase == NULL) {
res = ResRESOURCE;
goto failReserve;
}
if (vbase == NULL)
return ResRESOURCE;
AVER(AddrIsAligned(vbase, pageSize));
@ -186,14 +160,7 @@ Res VMCreate(VM *vmReturn, Size size, Size grainSize, void *params)
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;
}