diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c
index 743e17acb09..34fb5427982 100644
--- a/mps/code/arenavm.c
+++ b/mps/code/arenavm.c
@@ -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; /* */
} 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); /* */
+ 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);
/* */
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); /* */
- 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));
diff --git a/mps/code/mpm.c b/mps/code/mpm.c
index 23ad83ad1c5..dcef8cae069 100644
--- a/mps/code/mpm.c
+++ b/mps/code/mpm.c
@@ -10,6 +10,8 @@
#include "check.h"
#include "mpm.h"
+#include "vm.h"
+
#include
/* Get some floating constants for WriteDouble */
#include
diff --git a/mps/code/mpm.h b/mps/code/mpm.h
index 0a6f3a8eff9..c76beb65c1b 100644
--- a/mps/code/mpm.h
+++ b/mps/code/mpm.h
@@ -1000,21 +1000,6 @@ typedef Res (*RootIterateFn)(Root root, void *p);
extern Res RootsIterate(Globals arena, RootIterateFn f, void *p);
-/* VM Interface -- see */
-
-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 */
extern Bool LandCheck(Land land);
diff --git a/mps/code/protw3.c b/mps/code/protw3.c
index 3772a109c18..d74070cf46a 100644
--- a/mps/code/protw3.c
+++ b/mps/code/protw3.c
@@ -8,6 +8,7 @@
/* prmcw3.h needed to share MutatorFaultContextStruct declation */
/* with */
#include "prmcw3.h"
+#include "vm.h"
#ifndef MPS_OS_W3
#error "protw3.c is Win32-specific, but MPS_OS_W3 is not set"
diff --git a/mps/code/protxc.c b/mps/code/protxc.c
index 41d9e234ba4..1108e4ec67d 100644
--- a/mps/code/protxc.c
+++ b/mps/code/protxc.c
@@ -58,6 +58,7 @@
#include "mpm.h"
#include "prmcxc.h"
#include "protxc.h"
+#include "vm.h"
#include /* see .trans.stdlib */
#include /* see .trans.stdlib */
diff --git a/mps/code/sa.c b/mps/code/sa.c
index 5df8ed2f4b5..8e197494f55 100644
--- a/mps/code/sa.c
+++ b/mps/code/sa.c
@@ -7,6 +7,7 @@
#include "sa.h"
#include "mpm.h"
#include "bt.h"
+#include "vm.h"
static Index pagesLength(SparseArray sa)
{
diff --git a/mps/code/vm.h b/mps/code/vm.h
new file mode 100644
index 00000000000..6fa0b492333
--- /dev/null
+++ b/mps/code/vm.h
@@ -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; /* */
+ 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 .
+ * 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.
+ */
diff --git a/mps/code/vman.c b/mps/code/vman.c
index 0420c6a95a6..ea4850b0c28 100644
--- a/mps/code/vman.c
+++ b/mps/code/vman.c
@@ -5,6 +5,7 @@
*/
#include "mpm.h"
+#include "vm.h"
#include /* for malloc and free */
#include /* for memset */
@@ -12,20 +13,6 @@
SRCID(vman, "$Id$");
-/* VMStruct -- virtual memory structure */
-
-#define VMSig ((Sig)0x519B3999) /* SIGnature VM */
-
-/* ANSI fake VM structure, see */
-typedef struct VMStruct {
- Sig 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;
}
diff --git a/mps/code/vmix.c b/mps/code/vmix.c
index c4ca0954325..35d2e6cb3d2 100644
--- a/mps/code/vmix.c
+++ b/mps/code/vmix.c
@@ -39,6 +39,7 @@
*/
#include "mpm.h"
+#include "vm.h"
/* for mmap(2), munmap(2) */
#include
@@ -58,19 +59,6 @@
SRCID(vmix, "$Id$");
-/* VMStruct -- virtual memory structure */
-
-#define VMSig ((Sig)0x519B3999) /* SIGnature VM */
-
-typedef struct VMStruct {
- Sig 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);
}
diff --git a/mps/code/vmw3.c b/mps/code/vmw3.c
index 845eb871473..ee93e5e9215 100644
--- a/mps/code/vmw3.c
+++ b/mps/code/vmw3.c
@@ -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; /* */
- 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;
}