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:
parent
d7f438d382
commit
e95af3fb0e
10 changed files with 164 additions and 165 deletions
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
81
mps/code/vm.h
Normal 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.
|
||||
*/
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue