mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-23 15:22:20 -07:00
Fix problems identified by rb in review <https://info.ravenbrook.com/mail/2014/05/29/13-01-02/0/>.
Copied from Perforce Change: 186347 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
e5395c4419
commit
4a59d4e9b7
7 changed files with 97 additions and 51 deletions
|
|
@ -272,8 +272,9 @@ static void vmArenaUnmap(VMArena vmArena, VM vm, Addr base, Addr limit)
|
|||
* chunkReturn, return parameter for the created chunk.
|
||||
* vmArena, the parent VMArena.
|
||||
* size, approximate amount of virtual address that the chunk should reserve.
|
||||
* align, minimum acceptable tract size
|
||||
*/
|
||||
static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size)
|
||||
static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size, Align align)
|
||||
{
|
||||
Res res;
|
||||
Addr base, limit, chunkStructLimit;
|
||||
|
|
@ -288,12 +289,12 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size)
|
|||
AVERT(VMArena, vmArena);
|
||||
AVER(size > 0);
|
||||
|
||||
res = VMCreate(&vm, size, vmArena->vmParams);
|
||||
res = VMCreate(&vm, size, align, vmArena->vmParams);
|
||||
if (res != ResOK)
|
||||
goto failVMCreate;
|
||||
|
||||
/* The VM will have adjusted align and size; pick up the actual values. */
|
||||
pageSize = VMAlign(vm);
|
||||
/* The VM will have aligned the userSize; pick up the actual size. */
|
||||
base = VMBase(vm);
|
||||
limit = VMLimit(vm);
|
||||
|
||||
|
|
@ -483,6 +484,7 @@ ARG_DEFINE_KEY(arena_contracted, Fun);
|
|||
static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
|
||||
{
|
||||
Size userSize = VM_ARENA_SIZE_DEFAULT; /* size requested by user */
|
||||
Align userAlign = MPS_PF_ALIGN; /* alignment requested by user */
|
||||
Size chunkSize; /* size actually created */
|
||||
Size vmArenaSize; /* aligned size of VMArenaStruct */
|
||||
Res res;
|
||||
|
|
@ -499,19 +501,22 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
|
|||
|
||||
if (ArgPick(&arg, args, MPS_KEY_ARENA_SIZE))
|
||||
userSize = arg.val.size;
|
||||
if (ArgPick(&arg, args, MPS_KEY_ALIGN))
|
||||
userAlign = AlignAlignUp(arg.val.align, userAlign);
|
||||
|
||||
AVER(userSize > 0);
|
||||
AVERT(Align, userAlign);
|
||||
|
||||
/* Parse the arguments into VM parameters, if any. We must do this into
|
||||
some stack-allocated memory for the moment, since we don't have anywhere
|
||||
else to put it. It gets copied later. */
|
||||
/* Parse remaining arguments, if any, into VM parameters. We must do
|
||||
this into some stack-allocated memory for the moment, since we
|
||||
don't have anywhere else to put it. It gets copied later. */
|
||||
res = VMParamFromArgs(vmParams, sizeof(vmParams), args);
|
||||
if (res != ResOK)
|
||||
goto failVMCreate;
|
||||
|
||||
/* Create a VM to hold the arena and map it. */
|
||||
vmArenaSize = SizeAlignUp(sizeof(VMArenaStruct), MPS_PF_ALIGN);
|
||||
res = VMCreate(&arenaVM, vmArenaSize, vmParams);
|
||||
res = VMCreate(&arenaVM, vmArenaSize, userAlign, vmParams);
|
||||
if (res != ResOK)
|
||||
goto failVMCreate;
|
||||
res = VMMap(arenaVM, VMBase(arenaVM), VMLimit(arenaVM));
|
||||
|
|
@ -548,7 +553,7 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
|
|||
|
||||
/* have to have a valid arena before calling ChunkCreate */
|
||||
vmArena->sig = VMArenaSig;
|
||||
res = VMChunkCreate(&chunk, vmArena, userSize);
|
||||
res = VMChunkCreate(&chunk, vmArena, userSize, userAlign);
|
||||
if (res != ResOK)
|
||||
goto failChunkCreate;
|
||||
|
||||
|
|
@ -714,7 +719,8 @@ static Res VMArenaGrow(Arena arena, SegPref pref, Size size)
|
|||
VMArenaReserved(VMArena2Arena(vmArena)));
|
||||
return res;
|
||||
}
|
||||
res = VMChunkCreate(&newChunk, vmArena, chunkSize);
|
||||
res = VMChunkCreate(&newChunk, vmArena, chunkSize,
|
||||
VMAlign(vmArena->vm));
|
||||
if(res == ResOK)
|
||||
goto vmArenaGrow_Done;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#define EVENT_VERSION_MAJOR ((unsigned)1)
|
||||
#define EVENT_VERSION_MEDIAN ((unsigned)2)
|
||||
#define EVENT_VERSION_MEDIAN ((unsigned)3)
|
||||
#define EVENT_VERSION_MINOR ((unsigned)0)
|
||||
|
||||
|
||||
|
|
@ -370,8 +370,9 @@
|
|||
|
||||
#define EVENT_VMCreate_PARAMS(PARAM, X) \
|
||||
PARAM(X, 0, P, vm) \
|
||||
PARAM(X, 1, A, base) \
|
||||
PARAM(X, 2, A, limit)
|
||||
PARAM(X, 1, W, align) \
|
||||
PARAM(X, 2, A, base) \
|
||||
PARAM(X, 3, A, limit)
|
||||
|
||||
#define EVENT_VMDestroy_PARAMS(PARAM, X) \
|
||||
PARAM(X, 0, P, vm)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ static double pupdate = 0.1; /* probability of update */
|
|||
static unsigned ngen = 0; /* number of generations specified */
|
||||
static mps_gen_param_s gen[genLIMIT]; /* generation parameters */
|
||||
static size_t arenasize = 256ul * 1024 * 1024; /* arena size */
|
||||
static mps_align_t arena_align = 1; /* arena alignment */
|
||||
static unsigned pinleaf = FALSE; /* are leaf objects pinned at start */
|
||||
static mps_bool_t zoned = TRUE; /* arena allocates using zones */
|
||||
|
||||
|
|
@ -228,6 +229,7 @@ static void arena_setup(gcthread_fn_t fn,
|
|||
{
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, arenasize);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ALIGN, arena_align);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, zoned);
|
||||
RESMUST(mps_arena_create_k(&arena, mps_arena_class_vm(), args));
|
||||
} MPS_ARGS_END(args);
|
||||
|
|
@ -263,6 +265,7 @@ static struct option longopts[] = {
|
|||
{"npass", required_argument, NULL, 'p'},
|
||||
{"gen", required_argument, NULL, 'g'},
|
||||
{"arena-size",required_argument, NULL, 'm'},
|
||||
{"arena-align",required_argument, NULL, 'a'},
|
||||
{"width", required_argument, NULL, 'w'},
|
||||
{"depth", required_argument, NULL, 'd'},
|
||||
{"preuse", required_argument, NULL, 'r'},
|
||||
|
|
@ -299,7 +302,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
putchar('\n');
|
||||
|
||||
while ((ch = getopt_long(argc, argv, "ht:i:p:g:m:w:d:r:u:lx:z", longopts, NULL)) != -1)
|
||||
while ((ch = getopt_long(argc, argv, "ht:i:p:g:m:a:w:d:r:u:lx:z", longopts, NULL)) != -1)
|
||||
switch (ch) {
|
||||
case 't':
|
||||
nthreads = (unsigned)strtoul(optarg, NULL, 10);
|
||||
|
|
@ -353,6 +356,20 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 'a': {
|
||||
char *p;
|
||||
arena_align = (unsigned)strtoul(optarg, &p, 10);
|
||||
switch(toupper(*p)) {
|
||||
case 'G': arena_align <<= 30; break;
|
||||
case 'M': arena_align <<= 20; break;
|
||||
case 'K': arena_align <<= 10; break;
|
||||
case '\0': break;
|
||||
default:
|
||||
fprintf(stderr, "Bad arena alignment %s\n", optarg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
width = (size_t)strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
|
|
@ -389,6 +406,8 @@ int main(int argc, char *argv[]) {
|
|||
" Use multiple times for multiple generations.\n"
|
||||
" -m n, --arena-size=n[KMG]?\n"
|
||||
" Initial size of arena (default %lu).\n"
|
||||
" -a n, --arena-align=n[KMG]?\n"
|
||||
" Alignment of arena (default %lu).\n"
|
||||
" -w n, --width=n\n"
|
||||
" Width of tree nodes made (default %lu)\n",
|
||||
argv[0],
|
||||
|
|
@ -396,6 +415,7 @@ int main(int argc, char *argv[]) {
|
|||
niter,
|
||||
npass,
|
||||
(unsigned long)arenasize,
|
||||
(unsigned long)arena_align,
|
||||
(unsigned long)width);
|
||||
fprintf(stderr,
|
||||
" -d n, --depth=n\n"
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ extern Addr (AddrAlignDown)(Addr addr, Align align);
|
|||
#define IndexAlignUp(s, a) ((Index)WordAlignUp((Word)(s), a))
|
||||
#define IndexAlignDown(s, a) ((Index)WordAlignDown((Word)(s), a))
|
||||
|
||||
#define AlignAlignUp(a1, a2) ((Align)WordAlignUp((Word)(a1), a2))
|
||||
#define AlignIsAligned(a1, a2) WordIsAligned((Word)(a1), a2)
|
||||
|
||||
|
||||
|
|
@ -992,7 +993,7 @@ extern Res RootsIterate(Globals arena, RootIterateFn f, void *p);
|
|||
extern Align VMAlign(VM vm);
|
||||
extern Bool VMCheck(VM vm);
|
||||
extern Res VMParamFromArgs(void *params, size_t paramSize, ArgList args);
|
||||
extern Res VMCreate(VM *VMReturn, Size size, void *params);
|
||||
extern Res VMCreate(VM *VMReturn, Size size, Align align, void *params);
|
||||
extern void VMDestroy(VM vm);
|
||||
extern Addr VMBase(VM vm);
|
||||
extern Addr VMLimit(VM vm);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ SRCID(vman, "$Id$");
|
|||
/* ANSI fake VM structure, see <design/vman/> */
|
||||
typedef struct VMStruct {
|
||||
Sig sig; /* <design/sig/> */
|
||||
Addr base, limit; /* boundaries of malloc'd memory */
|
||||
Align align; /* page size */
|
||||
Addr base, limit; /* aligned boundaries of malloc'd memory */
|
||||
void *block; /* pointer to malloc'd block, for free() */
|
||||
Size reserved; /* total reserved address space */
|
||||
Size mapped; /* total mapped memory */
|
||||
|
|
@ -31,11 +32,12 @@ typedef struct VMStruct {
|
|||
Bool VMCheck(VM vm)
|
||||
{
|
||||
CHECKS(VM, vm);
|
||||
CHECKD_NOSIG(Align, vm->align);
|
||||
CHECKL(vm->base != (Addr)0);
|
||||
CHECKL(vm->limit != (Addr)0);
|
||||
CHECKL(vm->base < vm->limit);
|
||||
CHECKL(AddrIsAligned(vm->base, VMANPageALIGNMENT));
|
||||
CHECKL(AddrIsAligned(vm->limit, VMANPageALIGNMENT));
|
||||
CHECKL(AddrIsAligned(vm->base, vm->align));
|
||||
CHECKL(AddrIsAligned(vm->limit, vm->align));
|
||||
CHECKL(vm->block != NULL);
|
||||
CHECKL((Addr)vm->block <= vm->base);
|
||||
CHECKL(vm->mapped <= vm->reserved);
|
||||
|
|
@ -47,8 +49,8 @@ Bool VMCheck(VM vm)
|
|||
|
||||
Align VMAlign(VM vm)
|
||||
{
|
||||
UNUSED(vm);
|
||||
return VMANPageALIGNMENT;
|
||||
AVERT(VM, vm);
|
||||
return vm->align;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -63,19 +65,22 @@ 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, void *params)
|
||||
Res VMCreate(VM *vmReturn, Size size, Align align, void *params)
|
||||
{
|
||||
VM vm;
|
||||
|
||||
AVER(vmReturn != NULL);
|
||||
AVER(size > 0);
|
||||
AVERT(Align, align);
|
||||
AVER(params != NULL);
|
||||
|
||||
align = AlignAlignUp(align, VMANPageALIGNMENT);
|
||||
|
||||
/* Note that because we add VMANPageALIGNMENT rather than */
|
||||
/* VMANPageALIGNMENT-1 we are not in danger of overflowing */
|
||||
/* vm->limit even if malloc were perverse enough to give us */
|
||||
/* a block at the end of memory. */
|
||||
size = SizeAlignUp(size, VMANPageALIGNMENT) + VMANPageALIGNMENT;
|
||||
if ((size < VMANPageALIGNMENT) || (size > (Size)(size_t)-1))
|
||||
/* Note that because we add align rather than align-1 we are not in
|
||||
* danger of overflowing vm->limit even if malloc were perverse
|
||||
* enough to give us a block at the end of memory. */
|
||||
size = SizeAlignUp(size, align) + align;
|
||||
if ((size < align) || (size > (Size)(size_t)-1))
|
||||
return ResRESOURCE;
|
||||
|
||||
vm = (VM)malloc(sizeof(VMStruct));
|
||||
|
|
@ -88,22 +93,23 @@ Res VMCreate(VM *vmReturn, Size size, void *params)
|
|||
return ResMEMORY;
|
||||
}
|
||||
|
||||
vm->base = AddrAlignUp((Addr)vm->block, VMANPageALIGNMENT);
|
||||
vm->limit = AddrAdd(vm->base, size - VMANPageALIGNMENT);
|
||||
vm->align = align;
|
||||
vm->base = AddrAlignUp((Addr)vm->block, align);
|
||||
vm->limit = AddrAdd(vm->base, size - align);
|
||||
AVER(vm->limit < AddrAdd((Addr)vm->block, size));
|
||||
|
||||
memset((void *)vm->block, VMJunkBYTE, size);
|
||||
|
||||
/* Lie about the reserved address space, to simulate real */
|
||||
/* virtual memory. */
|
||||
vm->reserved = size - VMANPageALIGNMENT;
|
||||
vm->reserved = size - align;
|
||||
vm->mapped = (Size)0;
|
||||
|
||||
vm->sig = VMSig;
|
||||
|
||||
AVERT(VM, vm);
|
||||
|
||||
EVENT3(VMCreate, vm, vm->base, vm->limit);
|
||||
EVENT4(VMCreate, vm, vm->align, vm->base, vm->limit);
|
||||
*vmReturn = vm;
|
||||
return ResOK;
|
||||
}
|
||||
|
|
@ -178,8 +184,8 @@ Res VMMap(VM vm, Addr base, Addr limit)
|
|||
AVER(vm->base <= base);
|
||||
AVER(base < limit);
|
||||
AVER(limit <= vm->limit);
|
||||
AVER(AddrIsAligned(base, VMANPageALIGNMENT));
|
||||
AVER(AddrIsAligned(limit, VMANPageALIGNMENT));
|
||||
AVER(AddrIsAligned(base, vm->align));
|
||||
AVER(AddrIsAligned(limit, vm->align));
|
||||
|
||||
size = AddrOffset(base, limit);
|
||||
memset((void *)base, (int)0, size);
|
||||
|
|
@ -201,8 +207,8 @@ void VMUnmap(VM vm, Addr base, Addr limit)
|
|||
AVER(vm->base <= base);
|
||||
AVER(base < limit);
|
||||
AVER(limit <= vm->limit);
|
||||
AVER(AddrIsAligned(base, VMANPageALIGNMENT));
|
||||
AVER(AddrIsAligned(limit, VMANPageALIGNMENT));
|
||||
AVER(AddrIsAligned(base, vm->align));
|
||||
AVER(AddrIsAligned(limit, vm->align));
|
||||
|
||||
size = AddrOffset(base, limit);
|
||||
memset((void *)base, 0xCD, size);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,9 @@ SRCID(vmix, "$Id$");
|
|||
typedef struct VMStruct {
|
||||
Sig sig; /* <design/sig/> */
|
||||
Align align; /* page size */
|
||||
Addr base, limit; /* boundaries of reserved space */
|
||||
void *mapped_base; /* unaligned base of mmap'd memory */
|
||||
size_t mapped_size; /* size of mmap'd memory */
|
||||
Addr base, limit; /* aligned boundaries of reserved space */
|
||||
Size reserved; /* total reserved address space */
|
||||
Size mapped; /* total mapped memory */
|
||||
} VMStruct;
|
||||
|
|
@ -106,11 +108,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, void *params)
|
||||
Res VMCreate(VM *vmReturn, Size size, Align align, void *params)
|
||||
{
|
||||
Align align;
|
||||
VM vm;
|
||||
int pagesize;
|
||||
size_t mapped_size;
|
||||
Align pagealign;
|
||||
void *addr;
|
||||
Res res;
|
||||
|
||||
|
|
@ -119,18 +122,21 @@ Res VMCreate(VM *vmReturn, Size size, void *params)
|
|||
|
||||
/* Find out the page size from the OS */
|
||||
pagesize = getpagesize();
|
||||
/* check the actual returned pagesize will fit in an object of */
|
||||
/* type Align. */
|
||||
|
||||
/* Check the actual returned pagesize will fit in an object of type
|
||||
* Align, and that it is a valid alignment. */
|
||||
AVER(pagesize > 0);
|
||||
AVER((unsigned long)pagesize <= (unsigned long)(Align)-1);
|
||||
align = (Align)pagesize;
|
||||
AVER(SizeIsP2(align));
|
||||
pagealign = (Align)pagesize;
|
||||
AVERT(Align, pagealign);
|
||||
|
||||
align = AlignAlignUp(align, pagealign);
|
||||
size = SizeAlignUp(size, align);
|
||||
if((size == 0) || (size > (Size)(size_t)-1))
|
||||
return ResRESOURCE;
|
||||
|
||||
/* Map in a page to store the descriptor on. */
|
||||
addr = mmap(0, (size_t)SizeAlignUp(sizeof(VMStruct), align),
|
||||
/* Map in some pages to store the descriptor on. */
|
||||
addr = mmap(0, (size_t)SizeAlignUp(sizeof(VMStruct), pagealign),
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
|
|
@ -147,7 +153,7 @@ Res VMCreate(VM *vmReturn, Size size, void *params)
|
|||
vm->align = align;
|
||||
|
||||
/* See .assume.not-last. */
|
||||
addr = mmap(0, (size_t)size,
|
||||
addr = mmap(0, (size_t)(size + align - pagealign),
|
||||
PROT_NONE, MAP_ANON | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
if(addr == MAP_FAILED) {
|
||||
|
|
@ -157,7 +163,8 @@ Res VMCreate(VM *vmReturn, Size size, void *params)
|
|||
goto failReserve;
|
||||
}
|
||||
|
||||
vm->base = (Addr)addr;
|
||||
vm->mapped_base = addr;
|
||||
vm->base = AddrAlignUp(addr, align);
|
||||
vm->limit = AddrAdd(vm->base, size);
|
||||
vm->reserved = size;
|
||||
vm->mapped = (Size)0;
|
||||
|
|
@ -166,7 +173,7 @@ Res VMCreate(VM *vmReturn, Size size, void *params)
|
|||
|
||||
AVERT(VM, vm);
|
||||
|
||||
EVENT3(VMCreate, vm, vm->base, vm->limit);
|
||||
EVENT4(VMCreate, vm, vm->align, vm->base, vm->limit);
|
||||
|
||||
*vmReturn = vm;
|
||||
return ResOK;
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ 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, void *params)
|
||||
Res VMCreate(VM *vmReturn, Size size, Align align, void *params)
|
||||
{
|
||||
LPVOID vbase;
|
||||
SYSTEM_INFO si;
|
||||
|
|
@ -133,9 +133,14 @@ Res VMCreate(VM *vmReturn, Size size, void *params)
|
|||
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 */
|
||||
|
||||
/* Check that the page size will fit in an object of type Align, and
|
||||
* that it is a valid alignment (see .assume.sysalign). */
|
||||
AVER(si.dwPageSize > 0);
|
||||
AVER(si.dwPageSize <= (DWORD)(Align)-1);
|
||||
AVERT(Align, (Align)si.dwPageSize);
|
||||
|
||||
align = AlignAlignUp(align, (Align)si.dwPageSize);
|
||||
size = SizeAlignUp(size, align);
|
||||
if ((size == 0) || (size > (Size)(SIZE_T)-1))
|
||||
return ResRESOURCE;
|
||||
|
|
@ -171,7 +176,7 @@ Res VMCreate(VM *vmReturn, Size size, void *params)
|
|||
vm->sig = VMSig;
|
||||
AVERT(VM, vm);
|
||||
|
||||
EVENT3(VMCreate, vm, vm->base, vm->limit);
|
||||
EVENT4(VMCreate, vm, vm->align, vm->base, vm->limit);
|
||||
*vmReturn = vm;
|
||||
return ResOK;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue