mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-20 04:30:55 -08:00
Catch-up merge from master sources @186352 to branch/2014-04-15/mvffnoseg.
Copied from Perforce Change: 186355 ServerID: perforce.ravenbrook.com
This commit is contained in:
commit
3704522c58
104 changed files with 6779 additions and 2013 deletions
|
|
@ -9,3 +9,5 @@ notifications:
|
||||||
email:
|
email:
|
||||||
- mps-travis@ravenbrook.com
|
- mps-travis@ravenbrook.com
|
||||||
irc: "irc.freenode.net#memorypoolsystem"
|
irc: "irc.freenode.net#memorypoolsystem"
|
||||||
|
script:
|
||||||
|
- ./configure --prefix=$PWD/prefix && make install && make test
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ static Bool TestDeleteCallback(Bool *deleteReturn, void *element,
|
||||||
{
|
{
|
||||||
TestBlock *a = (TestBlock *)element;
|
TestBlock *a = (TestBlock *)element;
|
||||||
TestClosure cl = (TestClosure)closureP;
|
TestClosure cl = (TestClosure)closureP;
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
if (*a == cl->b) {
|
if (*a == cl->b) {
|
||||||
*deleteReturn = TRUE;
|
*deleteReturn = TRUE;
|
||||||
|
|
@ -144,7 +145,7 @@ static void step(void)
|
||||||
cdie(b != NULL, "found to delete");
|
cdie(b != NULL, "found to delete");
|
||||||
cl.b = b;
|
cl.b = b;
|
||||||
cl.res = ResFAIL;
|
cl.res = ResFAIL;
|
||||||
ABQIterate(&abq, TestDeleteCallback, &cl, 0);
|
ABQIterate(&abq, TestDeleteCallback, &cl, UNUSED_SIZE);
|
||||||
cdie(cl.res == ResOK, "ABQIterate");
|
cdie(cl.res == ResOK, "ABQIterate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ static void test_pool(mps_pool_t pool, size_t roots_count, int mode)
|
||||||
die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern begin (busy_ap)");
|
die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern begin (busy_ap)");
|
||||||
ramping = 1;
|
ramping = 1;
|
||||||
while (collections < collectionsCOUNT) {
|
while (collections < collectionsCOUNT) {
|
||||||
unsigned long c;
|
mps_word_t c;
|
||||||
size_t r;
|
size_t r;
|
||||||
|
|
||||||
c = mps_collections(arena);
|
c = mps_collections(arena);
|
||||||
|
|
@ -245,7 +245,7 @@ static void test_pool(mps_pool_t pool, size_t roots_count, int mode)
|
||||||
if (collections != c) {
|
if (collections != c) {
|
||||||
collections = c;
|
collections = c;
|
||||||
printf("\nCollection %lu started, %lu objects, committed=%lu.\n",
|
printf("\nCollection %lu started, %lu objects, committed=%lu.\n",
|
||||||
c, objs, (unsigned long)mps_arena_committed(arena));
|
(unsigned long)c, objs, (unsigned long)mps_arena_committed(arena));
|
||||||
report(arena);
|
report(arena);
|
||||||
|
|
||||||
for (i = 0; i < exactRootsCOUNT; ++i)
|
for (i = 0; i < exactRootsCOUNT; ++i)
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,8 @@ PFM = ananmv
|
||||||
|
|
||||||
PFMDEFS = /DCONFIG_PF_ANSI /DCONFIG_THREAD_SINGLE
|
PFMDEFS = /DCONFIG_PF_ANSI /DCONFIG_THREAD_SINGLE
|
||||||
|
|
||||||
!INCLUDE commpre.nmk
|
# MPM platform-specific sources.
|
||||||
!INCLUDE mv.nmk
|
MPMPF = \
|
||||||
|
|
||||||
# MPM sources: core plus platform-specific.
|
|
||||||
MPM = $(MPMCOMMON) \
|
|
||||||
<lockan> \
|
<lockan> \
|
||||||
<prmcan> \
|
<prmcan> \
|
||||||
<protan> \
|
<protan> \
|
||||||
|
|
@ -20,6 +17,9 @@ MPM = $(MPMCOMMON) \
|
||||||
<than> \
|
<than> \
|
||||||
<vman>
|
<vman>
|
||||||
|
|
||||||
|
!INCLUDE commpre.nmk
|
||||||
|
!INCLUDE mv.nmk
|
||||||
|
|
||||||
|
|
||||||
# Source to object file mappings and CFLAGS amalgamation
|
# Source to object file mappings and CFLAGS amalgamation
|
||||||
#
|
#
|
||||||
|
|
@ -38,14 +38,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
||||||
MPMOBJ0 = $(MPM:<=ananmv\hot\)
|
MPMOBJ0 = $(MPM:<=ananmv\hot\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=ananmv\hot\)
|
FMTDYOBJ0 = $(FMTDY:<=ananmv\hot\)
|
||||||
AMSOBJ0 = $(AMS:<=ananmv\hot\)
|
|
||||||
AMCOBJ0 = $(AMC:<=ananmv\hot\)
|
|
||||||
AWLOBJ0 = $(AWL:<=ananmv\hot\)
|
|
||||||
LOOBJ0 = $(LO:<=ananmv\hot\)
|
|
||||||
SNCOBJ0 = $(SNC:<=ananmv\hot\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=ananmv\hot\)
|
|
||||||
DWOBJ0 = $(DW:<=ananmv\hot\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=ananmv\hot\)
|
FMTTESTOBJ0 = $(FMTTEST:<=ananmv\hot\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\hot\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\hot\)
|
||||||
POOLNOBJ0 = $(POOLN:<=ananmv\hot\)
|
POOLNOBJ0 = $(POOLN:<=ananmv\hot\)
|
||||||
|
|
@ -58,14 +51,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
||||||
MPMOBJ0 = $(MPM:<=ananmv\cool\)
|
MPMOBJ0 = $(MPM:<=ananmv\cool\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=ananmv\cool\)
|
FMTDYOBJ0 = $(FMTDY:<=ananmv\cool\)
|
||||||
AMSOBJ0 = $(AMS:<=ananmv\cool\)
|
|
||||||
AMCOBJ0 = $(AMC:<=ananmv\cool\)
|
|
||||||
AWLOBJ0 = $(AWL:<=ananmv\cool\)
|
|
||||||
LOOBJ0 = $(LO:<=ananmv\cool\)
|
|
||||||
SNCOBJ0 = $(SNC:<=ananmv\cool\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=ananmv\cool\)
|
|
||||||
DWOBJ0 = $(DW:<=ananmv\cool\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=ananmv\cool\)
|
FMTTESTOBJ0 = $(FMTTEST:<=ananmv\cool\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\cool\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\cool\)
|
||||||
POOLNOBJ0 = $(POOLN:<=ananmv\cool\)
|
POOLNOBJ0 = $(POOLN:<=ananmv\cool\)
|
||||||
|
|
@ -78,61 +64,20 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
||||||
MPMOBJ0 = $(MPM:<=ananmv\rash\)
|
MPMOBJ0 = $(MPM:<=ananmv\rash\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=ananmv\rash\)
|
FMTDYOBJ0 = $(FMTDY:<=ananmv\rash\)
|
||||||
AMSOBJ0 = $(AMS:<=ananmv\rash\)
|
|
||||||
AMCOBJ0 = $(AMC:<=ananmv\rash\)
|
|
||||||
AWLOBJ0 = $(AWL:<=ananmv\rash\)
|
|
||||||
LOOBJ0 = $(LO:<=ananmv\rash\)
|
|
||||||
SNCOBJ0 = $(SNC:<=ananmv\rash\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=ananmv\rash\)
|
|
||||||
DWOBJ0 = $(DW:<=ananmv\rash\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=ananmv\rash\)
|
FMTTESTOBJ0 = $(FMTTEST:<=ananmv\rash\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\rash\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\rash\)
|
||||||
POOLNOBJ0 = $(POOLN:<=ananmv\rash\)
|
POOLNOBJ0 = $(POOLN:<=ananmv\rash\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=ananmv\rash\)
|
TESTLIBOBJ0 = $(TESTLIB:<=ananmv\rash\)
|
||||||
TESTTHROBJ0 = $(TESTTHR:<=ananmv\rash\)
|
TESTTHROBJ0 = $(TESTTHR:<=ananmv\rash\)
|
||||||
|
|
||||||
#!ELSEIF "$(VARIETY)" == "cv"
|
|
||||||
#CFLAGS=$(CFLAGSCOMMON) $(CFCV)
|
|
||||||
#LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCV)
|
|
||||||
#LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCV)
|
|
||||||
#MPMOBJ0 = $(MPM:<=ananmv\cv\)
|
|
||||||
#MPMOBJ = $(MPMOBJ0:>=.obj)
|
|
||||||
#PLINTHOBJ0 = $(PLINTH:<=ananmv\cv\)
|
|
||||||
#PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
|
||||||
#AMSOBJ0 = $(AMS:<=ananmv\cv\)
|
|
||||||
#AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
#AMCOBJ0 = $(AMC:<=ananmv\cv\)
|
|
||||||
#AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
#AWLOBJ0 = $(AWL:<=ananmv\cv\)
|
|
||||||
#AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
#LOOBJ0 = $(LO:<=ananmv\cv\)
|
|
||||||
#LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
#SNCOBJ0 = $(SNC:<=ananmv\cv\)
|
|
||||||
#SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
#DWOBJ0 = $(DW:<=ananmv\cv\)
|
|
||||||
#DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
#POOLNOBJ0 = $(POOLN:<=ananmv\cv\)
|
|
||||||
#POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
|
||||||
#TESTLIBOBJ0 = $(TESTLIB:<=ananmv\cv\)
|
|
||||||
#TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
|
||||||
#TESTTHROBJ0 = $(TESTTHR:<=ananmv\cv\)
|
|
||||||
#TESTTHROBJ = $(TESTTHROBJ0:>=.obj)
|
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# %%PART: When adding a new part, add new macros which expand to the object
|
# %%PART: When adding a new part, add new macros which expand to the object
|
||||||
# files included in the part
|
# files included in the part
|
||||||
|
|
||||||
MPMOBJ = $(MPMOBJ0:>=.obj)
|
MPMOBJ = $(MPMOBJ0:>=.obj)
|
||||||
PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
FMTDYOBJ = $(FMTDYOBJ0:>=.obj)
|
||||||
AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
MVFFOBJ = $(MVFFOBJ0:>=.obj)
|
|
||||||
DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
||||||
FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj)
|
FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj)
|
||||||
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
||||||
|
|
|
||||||
|
|
@ -360,6 +360,8 @@ static void arenaMFSPageFreeVisitor(Pool pool, Addr base, Size size,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
AVERT(Pool, pool);
|
AVERT(Pool, pool);
|
||||||
|
AVER(closureP == UNUSED_POINTER);
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureP);
|
UNUSED(closureP);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
UNUSED(size);
|
UNUSED(size);
|
||||||
|
|
@ -386,9 +388,9 @@ void ArenaDestroy(Arena arena)
|
||||||
LandFinish(ArenaFreeLand(arena));
|
LandFinish(ArenaFreeLand(arena));
|
||||||
|
|
||||||
/* The CBS block pool can't free its own memory via ArenaFree because
|
/* The CBS block pool can't free its own memory via ArenaFree because
|
||||||
that would use the CBSZoned. */
|
that would use the freeLand. */
|
||||||
MFSFinishTracts(ArenaCBSBlockPool(arena),
|
MFSFinishTracts(ArenaCBSBlockPool(arena), arenaMFSPageFreeVisitor,
|
||||||
arenaMFSPageFreeVisitor, NULL, 0);
|
UNUSED_POINTER, UNUSED_SIZE);
|
||||||
PoolFinish(ArenaCBSBlockPool(arena));
|
PoolFinish(ArenaCBSBlockPool(arena));
|
||||||
|
|
||||||
/* Call class-specific finishing. This will call ArenaFinish. */
|
/* Call class-specific finishing. This will call ArenaFinish. */
|
||||||
|
|
@ -687,7 +689,7 @@ static Res arenaExtendCBSBlockPool(Range pageRangeReturn, Arena arena)
|
||||||
return ResOK;
|
return ResOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* arenaExcludePage -- exclude CBS block pool's page from Land
|
/* arenaExcludePage -- exclude CBS block pool's page from free land
|
||||||
*
|
*
|
||||||
* Exclude the page we specially allocated for the CBS block pool
|
* Exclude the page we specially allocated for the CBS block pool
|
||||||
* so that it doesn't get reallocated.
|
* so that it doesn't get reallocated.
|
||||||
|
|
@ -843,7 +845,7 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high,
|
||||||
Arena arena;
|
Arena arena;
|
||||||
RangeStruct range, oldRange;
|
RangeStruct range, oldRange;
|
||||||
Chunk chunk;
|
Chunk chunk;
|
||||||
Bool b;
|
Bool found, b;
|
||||||
Index baseIndex;
|
Index baseIndex;
|
||||||
Count pages;
|
Count pages;
|
||||||
Res res;
|
Res res;
|
||||||
|
|
@ -860,8 +862,8 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high,
|
||||||
|
|
||||||
/* Step 1. Find a range of address space. */
|
/* Step 1. Find a range of address space. */
|
||||||
|
|
||||||
res = LandFindInZones(&range, &oldRange, ArenaFreeLand(arena),
|
res = LandFindInZones(&found, &range, &oldRange, ArenaFreeLand(arena),
|
||||||
size, zones, high);
|
size, zones, high);
|
||||||
|
|
||||||
if (res == ResLIMIT) { /* found block, but couldn't store info */
|
if (res == ResLIMIT) { /* found block, but couldn't store info */
|
||||||
RangeStruct pageRange;
|
RangeStruct pageRange;
|
||||||
|
|
@ -869,18 +871,18 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high,
|
||||||
if (res != ResOK) /* disastrously short on memory */
|
if (res != ResOK) /* disastrously short on memory */
|
||||||
return res;
|
return res;
|
||||||
arenaExcludePage(arena, &pageRange);
|
arenaExcludePage(arena, &pageRange);
|
||||||
res = LandFindInZones(&range, &oldRange, ArenaFreeLand(arena),
|
res = LandFindInZones(&found, &range, &oldRange, ArenaFreeLand(arena),
|
||||||
size, zones, high);
|
size, zones, high);
|
||||||
AVER(res != ResLIMIT);
|
AVER(res != ResLIMIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == ResFAIL) /* out of address space */
|
|
||||||
return ResRESOURCE;
|
|
||||||
|
|
||||||
AVER(res == ResOK); /* unexpected error from ZoneCBS */
|
AVER(res == ResOK); /* unexpected error from ZoneCBS */
|
||||||
if (res != ResOK) /* defensive return */
|
if (res != ResOK) /* defensive return */
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
if (!found) /* out of address space */
|
||||||
|
return ResRESOURCE;
|
||||||
|
|
||||||
/* Step 2. Make memory available in the address space range. */
|
/* Step 2. Make memory available in the address space range. */
|
||||||
|
|
||||||
b = CHUNK_OF_ADDR(&chunk, arena, RangeBase(&range));
|
b = CHUNK_OF_ADDR(&chunk, arena, RangeBase(&range));
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ Bool BootBlockCheck(BootBlock boot)
|
||||||
CHECKL(boot->limit != NULL);
|
CHECKL(boot->limit != NULL);
|
||||||
CHECKL(boot->base <= boot->alloc);
|
CHECKL(boot->base <= boot->alloc);
|
||||||
CHECKL(boot->alloc <= boot->limit);
|
CHECKL(boot->alloc <= boot->limit);
|
||||||
CHECKL(boot->alloc < boot->limit);
|
CHECKL(boot->base < boot->limit);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
103
mps/code/cbs.c
103
mps/code/cbs.c
|
|
@ -140,12 +140,8 @@ static Bool cbsTestTree(SplayTree splay, Tree tree,
|
||||||
|
|
||||||
AVERT(SplayTree, splay);
|
AVERT(SplayTree, splay);
|
||||||
AVERT(Tree, tree);
|
AVERT(Tree, tree);
|
||||||
#if 0
|
|
||||||
AVER(closureP == NULL);
|
AVER(closureP == NULL);
|
||||||
AVER(size > 0);
|
AVER(size > 0);
|
||||||
#endif
|
|
||||||
UNUSED(closureP);
|
|
||||||
UNUSED(size);
|
|
||||||
AVER(IsLandSubclass(cbsLand(cbsOfSplay(splay)), CBSFastLandClass));
|
AVER(IsLandSubclass(cbsLand(cbsOfSplay(splay)), CBSFastLandClass));
|
||||||
|
|
||||||
block = cbsFastBlockOfTree(tree);
|
block = cbsFastBlockOfTree(tree);
|
||||||
|
|
@ -405,7 +401,7 @@ static Res cbsBlockAlloc(CBSBlock *blockReturn, CBS cbs, Range range)
|
||||||
block->base = RangeBase(range);
|
block->base = RangeBase(range);
|
||||||
block->limit = RangeLimit(range);
|
block->limit = RangeLimit(range);
|
||||||
|
|
||||||
SplayNodeUpdate(cbsSplay(cbs), cbsBlockTree(block));
|
SplayNodeInit(cbsSplay(cbs), cbsBlockTree(block));
|
||||||
|
|
||||||
AVERT(CBSBlock, block);
|
AVERT(CBSBlock, block);
|
||||||
*blockReturn = block;
|
*blockReturn = block;
|
||||||
|
|
@ -713,16 +709,6 @@ static Res cbsZonedSplayNodeDescribe(Tree tree, mps_lib_FILE *stream)
|
||||||
|
|
||||||
|
|
||||||
/* cbsIterate -- iterate over all blocks in CBS
|
/* cbsIterate -- iterate over all blocks in CBS
|
||||||
*
|
|
||||||
* Applies a visitor to all isolated contiguous ranges in a CBS.
|
|
||||||
* It receives a pointer, ``Size`` closure pair to pass on to the
|
|
||||||
* visitor function, and an visitor function to invoke on every range
|
|
||||||
* in address order. If the visitor returns ``FALSE``, then the iteration
|
|
||||||
* is terminated.
|
|
||||||
*
|
|
||||||
* The visitor function may not modify the CBS during the iteration.
|
|
||||||
* This is because CBSIterate uses TreeTraverse, which does not permit
|
|
||||||
* modification, for speed and to avoid perturbing the splay tree balance.
|
|
||||||
*
|
*
|
||||||
* See <design/land/#function.iterate>.
|
* See <design/land/#function.iterate>.
|
||||||
*/
|
*/
|
||||||
|
|
@ -741,22 +727,21 @@ static Bool cbsIterateVisit(Tree tree, void *closureP, Size closureS)
|
||||||
CBSBlock cbsBlock;
|
CBSBlock cbsBlock;
|
||||||
Land land = closure->land;
|
Land land = closure->land;
|
||||||
CBS cbs = cbsOfLand(land);
|
CBS cbs = cbsOfLand(land);
|
||||||
Bool delete = FALSE;
|
|
||||||
Bool cont = TRUE;
|
Bool cont = TRUE;
|
||||||
|
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
|
|
||||||
cbsBlock = cbsBlockOfTree(tree);
|
cbsBlock = cbsBlockOfTree(tree);
|
||||||
RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock));
|
RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock));
|
||||||
cont = (*closure->visitor)(&delete, land, &range, closure->closureP, closure->closureS);
|
cont = (*closure->visitor)(land, &range, closure->closureP, closure->closureS);
|
||||||
AVER(!delete); /* <design/cbs/#limit.iterate> */
|
|
||||||
if (!cont)
|
if (!cont)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
METER_ACC(cbs->treeSearch, cbs->treeSize);
|
METER_ACC(cbs->treeSearch, cbs->treeSize);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cbsIterate(Land land, LandVisitor visitor,
|
static Bool cbsIterate(Land land, LandVisitor visitor,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
CBS cbs;
|
CBS cbs;
|
||||||
|
|
@ -777,8 +762,8 @@ static void cbsIterate(Land land, LandVisitor visitor,
|
||||||
closure.visitor = visitor;
|
closure.visitor = visitor;
|
||||||
closure.closureP = closureP;
|
closure.closureP = closureP;
|
||||||
closure.closureS = closureS;
|
closure.closureS = closureS;
|
||||||
(void)TreeTraverse(SplayTreeRoot(splay), splay->compare, splay->nodeKey,
|
return TreeTraverse(SplayTreeRoot(splay), splay->compare, splay->nodeKey,
|
||||||
cbsIterateVisit, &closure, 0);
|
cbsIterateVisit, &closure, UNUSED_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -895,15 +880,15 @@ typedef struct cbsTestNodeInZonesClosureStruct {
|
||||||
} cbsTestNodeInZonesClosureStruct, *cbsTestNodeInZonesClosure;
|
} cbsTestNodeInZonesClosureStruct, *cbsTestNodeInZonesClosure;
|
||||||
|
|
||||||
static Bool cbsTestNodeInZones(SplayTree splay, Tree tree,
|
static Bool cbsTestNodeInZones(SplayTree splay, Tree tree,
|
||||||
void *closureP, Size closureSize)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
CBSBlock block = cbsBlockOfTree(tree);
|
CBSBlock block = cbsBlockOfTree(tree);
|
||||||
cbsTestNodeInZonesClosure closure = closureP;
|
cbsTestNodeInZonesClosure closure = closureP;
|
||||||
RangeInZoneSet search;
|
RangeInZoneSet search;
|
||||||
|
|
||||||
UNUSED(splay);
|
UNUSED(splay);
|
||||||
AVER(closureSize == sizeof(cbsTestNodeInZonesClosureStruct));
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureSize);
|
UNUSED(closureS);
|
||||||
|
|
||||||
search = closure->high ? RangeInZoneSetLast : RangeInZoneSetFirst;
|
search = closure->high ? RangeInZoneSetLast : RangeInZoneSetFirst;
|
||||||
|
|
||||||
|
|
@ -913,15 +898,15 @@ static Bool cbsTestNodeInZones(SplayTree splay, Tree tree,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool cbsTestTreeInZones(SplayTree splay, Tree tree,
|
static Bool cbsTestTreeInZones(SplayTree splay, Tree tree,
|
||||||
void *closureP, Size closureSize)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
CBSFastBlock fastBlock = cbsFastBlockOfTree(tree);
|
CBSFastBlock fastBlock = cbsFastBlockOfTree(tree);
|
||||||
CBSZonedBlock zonedBlock = cbsZonedBlockOfTree(tree);
|
CBSZonedBlock zonedBlock = cbsZonedBlockOfTree(tree);
|
||||||
cbsTestNodeInZonesClosure closure = closureP;
|
cbsTestNodeInZonesClosure closure = closureP;
|
||||||
|
|
||||||
UNUSED(splay);
|
UNUSED(splay);
|
||||||
AVER(closureSize == sizeof(cbsTestNodeInZonesClosureStruct));
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureSize);
|
UNUSED(closureS);
|
||||||
|
|
||||||
return fastBlock->maxSize >= closure->size
|
return fastBlock->maxSize >= closure->size
|
||||||
&& ZoneSetInter(zonedBlock->zones, closure->zoneSet) != ZoneSetEMPTY;
|
&& ZoneSetInter(zonedBlock->zones, closure->zoneSet) != ZoneSetEMPTY;
|
||||||
|
|
@ -1009,17 +994,20 @@ static Bool cbsFindLargest(Range rangeReturn, Range oldRangeReturn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn,
|
static Res cbsFindInZones(Bool *foundReturn, Range rangeReturn,
|
||||||
Land land, Size size,
|
Range oldRangeReturn, Land land, Size size,
|
||||||
ZoneSet zoneSet, Bool high)
|
ZoneSet zoneSet, Bool high)
|
||||||
{
|
{
|
||||||
CBS cbs;
|
CBS cbs;
|
||||||
|
CBSBlock block;
|
||||||
Tree tree;
|
Tree tree;
|
||||||
cbsTestNodeInZonesClosureStruct closure;
|
cbsTestNodeInZonesClosureStruct closure;
|
||||||
Res res;
|
Res res;
|
||||||
LandFindMethod landFind;
|
LandFindMethod landFind;
|
||||||
SplayFindMethod splayFind;
|
SplayFindMethod splayFind;
|
||||||
|
RangeStruct rangeStruct, oldRangeStruct;
|
||||||
|
|
||||||
|
AVER(foundReturn != NULL);
|
||||||
AVER(rangeReturn != NULL);
|
AVER(rangeReturn != NULL);
|
||||||
AVER(oldRangeReturn != NULL);
|
AVER(oldRangeReturn != NULL);
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
|
|
@ -1033,16 +1021,14 @@ static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn,
|
||||||
splayFind = high ? SplayFindLast : SplayFindFirst;
|
splayFind = high ? SplayFindLast : SplayFindFirst;
|
||||||
|
|
||||||
if (zoneSet == ZoneSetEMPTY)
|
if (zoneSet == ZoneSetEMPTY)
|
||||||
return ResFAIL;
|
goto fail;
|
||||||
if (zoneSet == ZoneSetUNIV) {
|
if (zoneSet == ZoneSetUNIV) {
|
||||||
FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW;
|
FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW;
|
||||||
if ((*landFind)(rangeReturn, oldRangeReturn, land, size, fd))
|
*foundReturn = (*landFind)(rangeReturn, oldRangeReturn, land, size, fd);
|
||||||
return ResOK;
|
return ResOK;
|
||||||
else
|
|
||||||
return ResFAIL;
|
|
||||||
}
|
}
|
||||||
if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land)))
|
if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land)))
|
||||||
return ResFAIL;
|
goto fail;
|
||||||
|
|
||||||
/* It would be nice if there were a neat way to eliminate all runs of
|
/* It would be nice if there were a neat way to eliminate all runs of
|
||||||
zones in zoneSet too small for size.*/
|
zones in zoneSet too small for size.*/
|
||||||
|
|
@ -1051,31 +1037,34 @@ static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn,
|
||||||
closure.zoneSet = zoneSet;
|
closure.zoneSet = zoneSet;
|
||||||
closure.size = size;
|
closure.size = size;
|
||||||
closure.high = high;
|
closure.high = high;
|
||||||
if (splayFind(&tree, cbsSplay(cbs),
|
if (!(*splayFind)(&tree, cbsSplay(cbs),
|
||||||
cbsTestNodeInZones,
|
cbsTestNodeInZones, cbsTestTreeInZones,
|
||||||
cbsTestTreeInZones,
|
&closure, UNUSED_SIZE))
|
||||||
&closure, sizeof(closure))) {
|
goto fail;
|
||||||
CBSBlock block = cbsBlockOfTree(tree);
|
|
||||||
RangeStruct rangeStruct, oldRangeStruct;
|
|
||||||
|
|
||||||
AVER(CBSBlockBase(block) <= closure.base);
|
block = cbsBlockOfTree(tree);
|
||||||
AVER(AddrOffset(closure.base, closure.limit) >= size);
|
|
||||||
AVER(ZoneSetSub(ZoneSetOfRange(LandArena(land), closure.base, closure.limit), zoneSet));
|
|
||||||
AVER(closure.limit <= CBSBlockLimit(block));
|
|
||||||
|
|
||||||
if (!high)
|
AVER(CBSBlockBase(block) <= closure.base);
|
||||||
RangeInit(&rangeStruct, closure.base, AddrAdd(closure.base, size));
|
AVER(AddrOffset(closure.base, closure.limit) >= size);
|
||||||
else
|
AVER(ZoneSetSub(ZoneSetOfRange(LandArena(land), closure.base, closure.limit), zoneSet));
|
||||||
RangeInit(&rangeStruct, AddrSub(closure.limit, size), closure.limit);
|
AVER(closure.limit <= CBSBlockLimit(block));
|
||||||
res = cbsDelete(&oldRangeStruct, land, &rangeStruct);
|
|
||||||
if (res == ResOK) { /* enough memory to split block */
|
|
||||||
RangeCopy(rangeReturn, &rangeStruct);
|
|
||||||
RangeCopy(oldRangeReturn, &oldRangeStruct);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
res = ResFAIL;
|
|
||||||
|
|
||||||
return res;
|
if (!high)
|
||||||
|
RangeInit(&rangeStruct, closure.base, AddrAdd(closure.base, size));
|
||||||
|
else
|
||||||
|
RangeInit(&rangeStruct, AddrSub(closure.limit, size), closure.limit);
|
||||||
|
res = cbsDelete(&oldRangeStruct, land, &rangeStruct);
|
||||||
|
if (res != ResOK)
|
||||||
|
/* not enough memory to split block */
|
||||||
|
return res;
|
||||||
|
RangeCopy(rangeReturn, &rangeStruct);
|
||||||
|
RangeCopy(oldRangeReturn, &oldRangeStruct);
|
||||||
|
*foundReturn = TRUE;
|
||||||
|
return ResOK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
*foundReturn = FALSE;
|
||||||
|
return ResOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,8 @@ typedef struct PoolGenStruct *PoolGen;
|
||||||
|
|
||||||
typedef struct PoolGenStruct {
|
typedef struct PoolGenStruct {
|
||||||
Sig sig;
|
Sig sig;
|
||||||
Serial nr; /* generation number */
|
|
||||||
Pool pool; /* pool this belongs to */
|
Pool pool; /* pool this belongs to */
|
||||||
Chain chain; /* chain this belongs to */
|
GenDesc gen; /* generation this belongs to */
|
||||||
/* link in ring of all PoolGen's in this GenDesc (locus) */
|
/* link in ring of all PoolGen's in this GenDesc (locus) */
|
||||||
RingStruct genRing;
|
RingStruct genRing;
|
||||||
Size totalSize; /* total size of segs in gen in this pool */
|
Size totalSize; /* total size of segs in gen in this pool */
|
||||||
|
|
@ -84,16 +83,13 @@ extern Res ChainCondemnAuto(double *mortalityReturn, Chain chain, Trace trace);
|
||||||
extern void ChainStartGC(Chain chain, Trace trace);
|
extern void ChainStartGC(Chain chain, Trace trace);
|
||||||
extern void ChainEndGC(Chain chain, Trace trace);
|
extern void ChainEndGC(Chain chain, Trace trace);
|
||||||
extern size_t ChainGens(Chain chain);
|
extern size_t ChainGens(Chain chain);
|
||||||
extern Res ChainAlloc(Seg *segReturn, Chain chain, Serial genNr,
|
extern GenDesc ChainGen(Chain chain, Index gen);
|
||||||
SegClass class, Size size, Pool pool,
|
|
||||||
Bool withReservoirPermit, ArgList args);
|
|
||||||
|
|
||||||
extern Bool PoolGenCheck(PoolGen gen);
|
|
||||||
extern Res PoolGenInit(PoolGen gen, Chain chain, Serial nr, Pool pool);
|
|
||||||
extern void PoolGenFinish(PoolGen gen);
|
|
||||||
extern void PoolGenFlip(PoolGen gen);
|
|
||||||
#define PoolGenNr(gen) ((gen)->nr)
|
|
||||||
|
|
||||||
|
extern Bool PoolGenCheck(PoolGen pgen);
|
||||||
|
extern Res PoolGenInit(PoolGen pgen, GenDesc gen, Pool pool);
|
||||||
|
extern void PoolGenFinish(PoolGen pgen);
|
||||||
|
extern Res PoolGenAlloc(Seg *segReturn, PoolGen pgen, SegClass class,
|
||||||
|
Size size, Bool withReservoirPermit, ArgList args);
|
||||||
|
|
||||||
#endif /* chain_h */
|
#endif /* chain_h */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,6 @@ FMTDYTST = fmtdy.c fmtno.c fmtdytst.c
|
||||||
FMTHETST = fmthe.c fmtdy.c fmtno.c fmtdytst.c
|
FMTHETST = fmthe.c fmtdy.c fmtno.c fmtdytst.c
|
||||||
FMTSCM = fmtscheme.c
|
FMTSCM = fmtscheme.c
|
||||||
PLINTH = mpsliban.c mpsioan.c
|
PLINTH = mpsliban.c mpsioan.c
|
||||||
EVENTPROC = eventcnv.c table.c
|
|
||||||
MPMCOMMON = \
|
MPMCOMMON = \
|
||||||
abq.c \
|
abq.c \
|
||||||
arena.c \
|
arena.c \
|
||||||
|
|
@ -212,7 +211,7 @@ MPMCOMMON = \
|
||||||
tract.c \
|
tract.c \
|
||||||
tree.c \
|
tree.c \
|
||||||
walk.c
|
walk.c
|
||||||
MPM = $(MPMCOMMON) $(MPMPF)
|
MPM = $(MPMCOMMON) $(MPMPF) $(AMC) $(AMS) $(AWL) $(LO) $(MV2) $(MVFF) $(PLINTH)
|
||||||
|
|
||||||
|
|
||||||
# These map the source file lists onto object files and dependency files
|
# These map the source file lists onto object files and dependency files
|
||||||
|
|
@ -224,40 +223,16 @@ MPM = $(MPMCOMMON) $(MPMPF)
|
||||||
ifdef VARIETY
|
ifdef VARIETY
|
||||||
MPMOBJ = $(MPM:%.c=$(PFM)/$(VARIETY)/%.o) \
|
MPMOBJ = $(MPM:%.c=$(PFM)/$(VARIETY)/%.o) \
|
||||||
$(MPMS:%.s=$(PFM)/$(VARIETY)/%.o)
|
$(MPMS:%.s=$(PFM)/$(VARIETY)/%.o)
|
||||||
MPMDEP = $(MPM:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
AMCOBJ = $(AMC:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
AMCDEP = $(AMC:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
AMSOBJ = $(AMS:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
AMSDEP = $(AMS:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
AWLOBJ = $(AWL:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
AWLDEP = $(AWL:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
LOOBJ = $(LO:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
LODEP = $(LO:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
SNCOBJ = $(SNC:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
SNCDEP = $(SNC:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
POOLNOBJ = $(POOLN:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
POOLNDEP = $(POOLN:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
MV2OBJ = $(MV2:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
MV2DEP = $(MV2:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
MVFFOBJ = $(MVFF:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
MVFFDEP = $(MVFF:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
|
|
||||||
TESTLIBOBJ = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
TESTLIBDEP = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
TESTTHROBJ = $(TESTTHR:%.c=$(PFM)/$(VARIETY)/%.o)
|
|
||||||
TESTTHRDEP = $(TESTTHR:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
FMTDYOBJ = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.o)
|
FMTDYOBJ = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
FMTDYDEP = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o)
|
FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
FMTDYTSTDEP = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
FMTHETSTOBJ = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.o)
|
FMTHETSTOBJ = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
FMTHETSTDEP = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.d)
|
|
||||||
FMTSCMOBJ = $(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.o)
|
FMTSCMOBJ = $(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
FMTSCMDEP = $(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.d)
|
MV2OBJ = $(MV2:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
|
MVFFOBJ = $(MVFF:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
PLINTHOBJ = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.o)
|
PLINTHOBJ = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
PLINTHDEP = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.d)
|
POOLNOBJ = $(POOLN:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
EVENTPROCOBJ = $(EVENTPROC:%.c=$(PFM)/$(VARIETY)/%.o)
|
TESTLIBOBJ = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
EVENTPROCDEP = $(EVENTPROC:%.c=$(PFM)/$(VARIETY)/%.d)
|
TESTTHROBJ = $(TESTTHR:%.c=$(PFM)/$(VARIETY)/%.o)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -413,10 +388,7 @@ endif
|
||||||
|
|
||||||
$(PFM)/rash/mps.a: $(PFM)/rash/mps.o
|
$(PFM)/rash/mps.a: $(PFM)/rash/mps.o
|
||||||
$(PFM)/hot/mps.a: $(PFM)/hot/mps.o
|
$(PFM)/hot/mps.a: $(PFM)/hot/mps.o
|
||||||
|
$(PFM)/cool/mps.a: $(MPMOBJ)
|
||||||
$(PFM)/cool/mps.a: \
|
|
||||||
$(MPMOBJ) $(AMCOBJ) $(AMSOBJ) $(AWLOBJ) $(LOOBJ) $(SNCOBJ) \
|
|
||||||
$(MV2OBJ) $(MVFFOBJ) $(PLINTHOBJ) $(POOLNOBJ)
|
|
||||||
|
|
||||||
|
|
||||||
# OTHER GENUINE TARGETS
|
# OTHER GENUINE TARGETS
|
||||||
|
|
@ -473,7 +445,7 @@ $(PFM)/$(VARIETY)/bttest: $(PFM)/$(VARIETY)/bttest.o \
|
||||||
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
||||||
|
|
||||||
$(PFM)/$(VARIETY)/djbench: $(PFM)/$(VARIETY)/djbench.o \
|
$(PFM)/$(VARIETY)/djbench: $(PFM)/$(VARIETY)/djbench.o \
|
||||||
$(TESTLIBOBJ) $(TESTTHROBJ) $(PFM)/$(VARIETY)/mps.a
|
$(TESTLIBOBJ) $(TESTTHROBJ)
|
||||||
|
|
||||||
$(PFM)/$(VARIETY)/exposet0: $(PFM)/$(VARIETY)/exposet0.o \
|
$(PFM)/$(VARIETY)/exposet0: $(PFM)/$(VARIETY)/exposet0.o \
|
||||||
$(FMTDYTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
$(FMTDYTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
||||||
|
|
@ -491,7 +463,7 @@ $(PFM)/$(VARIETY)/fotest: $(PFM)/$(VARIETY)/fotest.o \
|
||||||
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
||||||
|
|
||||||
$(PFM)/$(VARIETY)/gcbench: $(PFM)/$(VARIETY)/gcbench.o \
|
$(PFM)/$(VARIETY)/gcbench: $(PFM)/$(VARIETY)/gcbench.o \
|
||||||
$(FMTDYTSTOBJ) $(TESTLIBOBJ) $(TESTTHROBJ) $(PFM)/$(VARIETY)/mps.a
|
$(FMTDYTSTOBJ) $(TESTLIBOBJ) $(TESTTHROBJ)
|
||||||
|
|
||||||
$(PFM)/$(VARIETY)/landtest: $(PFM)/$(VARIETY)/landtest.o \
|
$(PFM)/$(VARIETY)/landtest: $(PFM)/$(VARIETY)/landtest.o \
|
||||||
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
||||||
|
|
@ -527,7 +499,7 @@ $(PFM)/$(VARIETY)/nailboardtest: $(PFM)/$(VARIETY)/nailboardtest.o \
|
||||||
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
||||||
|
|
||||||
$(PFM)/$(VARIETY)/poolncv: $(PFM)/$(VARIETY)/poolncv.o \
|
$(PFM)/$(VARIETY)/poolncv: $(PFM)/$(VARIETY)/poolncv.o \
|
||||||
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
$(POOLNOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
||||||
|
|
||||||
$(PFM)/$(VARIETY)/qs: $(PFM)/$(VARIETY)/qs.o \
|
$(PFM)/$(VARIETY)/qs: $(PFM)/$(VARIETY)/qs.o \
|
||||||
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
|
||||||
|
|
@ -630,29 +602,28 @@ else
|
||||||
ifeq ($(VARIETY),hot)
|
ifeq ($(VARIETY),hot)
|
||||||
include $(PFM)/$(VARIETY)/mps.d
|
include $(PFM)/$(VARIETY)/mps.d
|
||||||
else
|
else
|
||||||
# %%PART: When adding a new part, add the dependency file macro for the new
|
include $(MPM:%.c=$(PFM)/$(VARIETY)/%.d)
|
||||||
# part here.
|
endif # VARIETY != hot
|
||||||
|
endif # VARIETY != rash
|
||||||
|
|
||||||
|
# %%PART: When adding a new part, add the dependencies file for the
|
||||||
|
# new part here.
|
||||||
include \
|
include \
|
||||||
$(MPMDEP) \
|
$(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(AMCDEP) \
|
$(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(AMSDEP) \
|
$(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(AWLDEP) \
|
$(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(EVENTPROCDEP) \
|
$(PLINTH:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(FMTDYDEP) \
|
$(POOLN:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(FMTDYTSTDEP) \
|
$(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(FMTHETSTDEP) \
|
$(TESTTHR:%.c=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(FMTSCMDEP) \
|
$(EXTRA_TARGETS:mps%=$(PFM)/$(VARIETY)/%.d) \
|
||||||
$(LODEP) \
|
$(TEST_TARGETS:%=$(PFM)/$(VARIETY)/%.d)
|
||||||
$(PLINTHDEP) \
|
|
||||||
$(POOLNDEP) \
|
|
||||||
$(TESTLIBDEP)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
endif
|
endif # !defined TARGET
|
||||||
endif
|
endif # !defined VARIETY
|
||||||
|
|
||||||
endif
|
endif # !defined gendep
|
||||||
|
|
||||||
# Library
|
# Library
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,12 +92,9 @@ $(PFM)\hot\mps.lib: $(PFM)\hot\mps.obj
|
||||||
$(ECHO) $@
|
$(ECHO) $@
|
||||||
$(LIBMAN) $(LIBFLAGS) /OUT:$@ $**
|
$(LIBMAN) $(LIBFLAGS) /OUT:$@ $**
|
||||||
|
|
||||||
$(PFM)\cool\mps.lib: \
|
$(PFM)\cool\mps.lib: $(MPMOBJ)
|
||||||
$(MPMOBJ) $(AMCOBJ) $(AMSOBJ) $(AWLOBJ) $(LOOBJ) $(SNCOBJ) \
|
|
||||||
$(MVFFOBJ) $(PLINTHOBJ) $(POOLNOBJ)
|
|
||||||
$(ECHO) $@
|
$(ECHO) $@
|
||||||
$(CC) /c $(CFLAGS) /Fo$(PFM)\$(VARIETY)\version.obj version.c
|
$(LIBMAN) $(LIBFLAGS) /OUT:$@ $**
|
||||||
$(LIBMAN) $(LIBFLAGS) /OUT:$@ $** $(PFM)\$(VARIETY)\version.obj
|
|
||||||
|
|
||||||
|
|
||||||
# OTHER GENUINE TARGETS
|
# OTHER GENUINE TARGETS
|
||||||
|
|
@ -213,8 +210,8 @@ $(PFM)\$(VARIETY)\mv2test.exe: $(PFM)\$(VARIETY)\mv2test.obj \
|
||||||
$(PFM)\$(VARIETY)\nailboardtest.exe: $(PFM)\$(VARIETY)\nailboardtest.obj \
|
$(PFM)\$(VARIETY)\nailboardtest.exe: $(PFM)\$(VARIETY)\nailboardtest.obj \
|
||||||
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
|
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
|
||||||
|
|
||||||
$(PFM)\$(VARIETY)\poolncv.exe: $(PFM)\$(VARIETY)\poolncv.obj \
|
$(PFM)\$(VARIETY)\poolncv.exe: $(PFM)\$(VARIETY)\poolncv.obj \
|
||||||
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
|
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ) $(POOLNOBJ)
|
||||||
|
|
||||||
$(PFM)\$(VARIETY)\qs.exe: $(PFM)\$(VARIETY)\qs.obj \
|
$(PFM)\$(VARIETY)\qs.exe: $(PFM)\$(VARIETY)\qs.obj \
|
||||||
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
|
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,7 @@ MPMCOMMON=\
|
||||||
<traceanc> \
|
<traceanc> \
|
||||||
<tract> \
|
<tract> \
|
||||||
<tree> \
|
<tree> \
|
||||||
|
<version> \
|
||||||
<walk>
|
<walk>
|
||||||
PLINTH = <mpsliban> <mpsioan>
|
PLINTH = <mpsliban> <mpsioan>
|
||||||
AMC = <poolamc>
|
AMC = <poolamc>
|
||||||
|
|
@ -175,11 +176,12 @@ LO = <poollo>
|
||||||
MVFF = <poolmvff>
|
MVFF = <poolmvff>
|
||||||
POOLN = <pooln>
|
POOLN = <pooln>
|
||||||
SNC = <poolsnc>
|
SNC = <poolsnc>
|
||||||
DW = <fmtdy> <fmtno>
|
FMTDY = <fmtdy> <fmtno>
|
||||||
FMTTEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
|
FMTTEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
|
||||||
FMTSCHEME = <fmtscheme>
|
FMTSCHEME = <fmtscheme>
|
||||||
TESTLIB = <testlib> <getoptl>
|
TESTLIB = <testlib> <getoptl>
|
||||||
TESTTHR = <testthrw3>
|
TESTTHR = <testthrw3>
|
||||||
|
MPM = $(MPMCOMMON) $(MPMPF) $(AMC) $(AMS) $(AWL) $(LO) $(MV2) $(MVFF) $(PLINTH)
|
||||||
|
|
||||||
|
|
||||||
# CHECK PARAMETERS
|
# CHECK PARAMETERS
|
||||||
|
|
@ -194,9 +196,15 @@ TESTTHR = <testthrw3>
|
||||||
!IFNDEF PFMDEFS
|
!IFNDEF PFMDEFS
|
||||||
!ERROR commpre.nmk: PFMDEFS not defined
|
!ERROR commpre.nmk: PFMDEFS not defined
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
!IFNDEF MPM
|
||||||
|
!ERROR commpre.nmk: MPM not defined
|
||||||
|
!ENDIF
|
||||||
!IFNDEF MPMCOMMON
|
!IFNDEF MPMCOMMON
|
||||||
!ERROR commpre.nmk: MPMCOMMON not defined
|
!ERROR commpre.nmk: MPMCOMMON not defined
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
!IFNDEF MPMPF
|
||||||
|
!ERROR commpre.nmk: MPMPF not defined
|
||||||
|
!ENDIF
|
||||||
!IFNDEF PLINTH
|
!IFNDEF PLINTH
|
||||||
!ERROR commpre.nmk: PLINTH not defined
|
!ERROR commpre.nmk: PLINTH not defined
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
@ -215,8 +223,8 @@ TESTTHR = <testthrw3>
|
||||||
!IFNDEF SNC
|
!IFNDEF SNC
|
||||||
!ERROR commpre.nmk: SNC not defined
|
!ERROR commpre.nmk: SNC not defined
|
||||||
!ENDIF
|
!ENDIF
|
||||||
!IFNDEF DW
|
!IFNDEF FMTDY
|
||||||
!ERROR commpre.nmk: DW not defined
|
!ERROR commpre.nmk: FMTDY not defined
|
||||||
!ENDIF
|
!ENDIF
|
||||||
!IFNDEF FMTTEST
|
!IFNDEF FMTTEST
|
||||||
!ERROR commpre.nmk: FMTTEST not defined
|
!ERROR commpre.nmk: FMTTEST not defined
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,11 @@
|
||||||
|
|
||||||
/* Attribute for functions that may be unused in some build configurations.
|
/* Attribute for functions that may be unused in some build configurations.
|
||||||
* GCC: <http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>
|
* GCC: <http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>
|
||||||
|
*
|
||||||
|
* This attribute must be applied to all Check functions, otherwise
|
||||||
|
* the RASH variety fails to compile with -Wunused-function. (It
|
||||||
|
* should not be applied to functions that are unused in all build
|
||||||
|
* configurations: these functions should not be compiled.)
|
||||||
*/
|
*/
|
||||||
#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL)
|
#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL)
|
||||||
#define ATTRIBUTE_UNUSED __attribute__((__unused__))
|
#define ATTRIBUTE_UNUSED __attribute__((__unused__))
|
||||||
|
|
@ -420,7 +425,7 @@
|
||||||
pool to be very heavily used. */
|
pool to be very heavily used. */
|
||||||
#define CONTROL_EXTEND_BY 4096
|
#define CONTROL_EXTEND_BY 4096
|
||||||
|
|
||||||
#define VM_ARENA_SIZE_DEFAULT ((Size)1 << 20)
|
#define VM_ARENA_SIZE_DEFAULT ((Size)1 << 28)
|
||||||
|
|
||||||
|
|
||||||
/* Stack configuration */
|
/* Stack configuration */
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,10 @@ static Res DebugPoolInit(Pool pool, ArgList args)
|
||||||
/* This pool has to be like the arena control pool: the blocks */
|
/* This pool has to be like the arena control pool: the blocks */
|
||||||
/* allocated must be accessible using void*. */
|
/* allocated must be accessible using void*. */
|
||||||
MPS_ARGS_BEGIN(pcArgs) {
|
MPS_ARGS_BEGIN(pcArgs) {
|
||||||
MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, debug->tagSize); /* FIXME: Check this */
|
/* By setting EXTEND_BY to debug->tagSize we get the smallest
|
||||||
|
possible extensions compatible with the tags, and so the
|
||||||
|
least amount of wasted space. */
|
||||||
|
MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, debug->tagSize);
|
||||||
MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, debug->tagSize);
|
MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, debug->tagSize);
|
||||||
res = PoolCreate(&debug->tagPool, PoolArena(pool), PoolClassMFS(), pcArgs);
|
res = PoolCreate(&debug->tagPool, PoolArena(pool), PoolClassMFS(), pcArgs);
|
||||||
} MPS_ARGS_END(pcArgs);
|
} MPS_ARGS_END(pcArgs);
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ static double pact = 0.2; /* probability per pass of acting */
|
||||||
static unsigned rinter = 75; /* pass interval for recursion */
|
static unsigned rinter = 75; /* pass interval for recursion */
|
||||||
static unsigned rmax = 10; /* maximum recursion depth */
|
static unsigned rmax = 10; /* maximum recursion depth */
|
||||||
static mps_bool_t zoned = TRUE; /* arena allocates using zones */
|
static mps_bool_t zoned = TRUE; /* arena allocates using zones */
|
||||||
|
static size_t arenasize = 256ul * 1024 * 1024; /* arena size */
|
||||||
|
|
||||||
#define DJRUN(fname, alloc, free) \
|
#define DJRUN(fname, alloc, free) \
|
||||||
static unsigned fname##_inner(mps_ap_t ap, unsigned depth, unsigned r) { \
|
static unsigned fname##_inner(mps_ap_t ap, unsigned depth, unsigned r) { \
|
||||||
|
|
@ -177,7 +178,7 @@ static void wrap(dj_t dj, mps_class_t dummy, const char *name)
|
||||||
static void arena_wrap(dj_t dj, mps_class_t pool_class, const char *name)
|
static void arena_wrap(dj_t dj, mps_class_t pool_class, const char *name)
|
||||||
{
|
{
|
||||||
MPS_ARGS_BEGIN(args) {
|
MPS_ARGS_BEGIN(args) {
|
||||||
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 256ul * 1024 * 1024); /* FIXME: Why is there no default? */
|
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, arenasize);
|
||||||
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, zoned);
|
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, zoned);
|
||||||
DJMUST(mps_arena_create_k(&arena, mps_arena_class_vm(), args));
|
DJMUST(mps_arena_create_k(&arena, mps_arena_class_vm(), args));
|
||||||
} MPS_ARGS_END(args);
|
} MPS_ARGS_END(args);
|
||||||
|
|
@ -201,6 +202,7 @@ static struct option longopts[] = {
|
||||||
{"rinter", required_argument, NULL, 'r'},
|
{"rinter", required_argument, NULL, 'r'},
|
||||||
{"rmax", required_argument, NULL, 'd'},
|
{"rmax", required_argument, NULL, 'd'},
|
||||||
{"seed", required_argument, NULL, 'x'},
|
{"seed", required_argument, NULL, 'x'},
|
||||||
|
{"arena-size", required_argument, NULL, 'm'},
|
||||||
{"arena-unzoned", no_argument, NULL, 'z'},
|
{"arena-unzoned", no_argument, NULL, 'z'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
@ -235,7 +237,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
seed = rnd_seed();
|
seed = rnd_seed();
|
||||||
|
|
||||||
while ((ch = getopt_long(argc, argv, "ht:i:p:b:s:a:r:d:x:z", longopts, NULL)) != -1)
|
while ((ch = getopt_long(argc, argv, "ht:i:p:b:s:a:r:d:m:x:z", longopts, NULL)) != -1)
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 't':
|
case 't':
|
||||||
nthreads = (unsigned)strtoul(optarg, NULL, 10);
|
nthreads = (unsigned)strtoul(optarg, NULL, 10);
|
||||||
|
|
@ -267,6 +269,20 @@ int main(int argc, char *argv[]) {
|
||||||
case 'z':
|
case 'z':
|
||||||
zoned = FALSE;
|
zoned = FALSE;
|
||||||
break;
|
break;
|
||||||
|
case 'm': {
|
||||||
|
char *p;
|
||||||
|
arenasize = (unsigned)strtoul(optarg, &p, 10);
|
||||||
|
switch(toupper(*p)) {
|
||||||
|
case 'G': arenasize <<= 30; break;
|
||||||
|
case 'M': arenasize <<= 20; break;
|
||||||
|
case 'K': arenasize <<= 10; break;
|
||||||
|
case '\0': break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Bad arena size %s\n", optarg);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s [option...] [test...]\n"
|
"Usage: %s [option...] [test...]\n"
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define EVENT_VERSION_MAJOR ((unsigned)1)
|
#define EVENT_VERSION_MAJOR ((unsigned)1)
|
||||||
#define EVENT_VERSION_MEDIAN ((unsigned)1)
|
#define EVENT_VERSION_MEDIAN ((unsigned)2)
|
||||||
#define EVENT_VERSION_MINOR ((unsigned)7)
|
#define EVENT_VERSION_MINOR ((unsigned)0)
|
||||||
|
|
||||||
|
|
||||||
/* EVENT_LIST -- list of event types and general properties
|
/* EVENT_LIST -- list of event types and general properties
|
||||||
|
|
@ -722,9 +722,8 @@
|
||||||
PARAM(X, 5, D, mortality) /* mortality of generation */ \
|
PARAM(X, 5, D, mortality) /* mortality of generation */ \
|
||||||
PARAM(X, 6, W, zone) /* zone set of generation */ \
|
PARAM(X, 6, W, zone) /* zone set of generation */ \
|
||||||
PARAM(X, 7, P, pool) /* pool */ \
|
PARAM(X, 7, P, pool) /* pool */ \
|
||||||
PARAM(X, 8, W, serial) /* pool gen serial number */ \
|
PARAM(X, 8, W, totalSize) /* total size of pool gen */ \
|
||||||
PARAM(X, 9, W, totalSize) /* total size of pool gen */ \
|
PARAM(X, 9, W, newSizeAtCreate) /* new size of pool gen at trace create */
|
||||||
PARAM(X, 10, W, newSizeAtCreate) /* new size of pool gen at trace create */
|
|
||||||
|
|
||||||
#define EVENT_TraceCondemnZones_PARAMS(PARAM, X) \
|
#define EVENT_TraceCondemnZones_PARAMS(PARAM, X) \
|
||||||
PARAM(X, 0, P, trace) /* the trace */ \
|
PARAM(X, 0, P, trace) /* the trace */ \
|
||||||
|
|
@ -733,7 +732,7 @@
|
||||||
|
|
||||||
#define EVENT_ArenaGenZoneAdd_PARAMS(PARAM, X) \
|
#define EVENT_ArenaGenZoneAdd_PARAMS(PARAM, X) \
|
||||||
PARAM(X, 0, P, arena) /* the arena */ \
|
PARAM(X, 0, P, arena) /* the arena */ \
|
||||||
PARAM(X, 1, W, gen) /* the generation number */ \
|
PARAM(X, 1, P, gendesc) /* the generation description */ \
|
||||||
PARAM(X, 2, W, zoneSet) /* the new zoneSet */
|
PARAM(X, 2, W, zoneSet) /* the new zoneSet */
|
||||||
|
|
||||||
#define EVENT_ArenaUseFreeZone_PARAMS(PARAM, X) \
|
#define EVENT_ArenaUseFreeZone_PARAMS(PARAM, X) \
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ static Res failoverInsert(Range rangeReturn, Land land, Range range)
|
||||||
/* Provide more opportunities for coalescence. See
|
/* Provide more opportunities for coalescence. See
|
||||||
* <design/failover/#impl.assume.flush>.
|
* <design/failover/#impl.assume.flush>.
|
||||||
*/
|
*/
|
||||||
LandFlush(fo->primary, fo->secondary);
|
(void)LandFlush(fo->primary, fo->secondary);
|
||||||
|
|
||||||
res = LandInsert(rangeReturn, fo->primary, range);
|
res = LandInsert(rangeReturn, fo->primary, range);
|
||||||
if (res != ResOK && res != ResFAIL)
|
if (res != ResOK && res != ResFAIL)
|
||||||
|
|
@ -121,7 +121,7 @@ static Res failoverDelete(Range rangeReturn, Land land, Range range)
|
||||||
/* Prefer efficient search in the primary. See
|
/* Prefer efficient search in the primary. See
|
||||||
* <design/failover/#impl.assume.flush>.
|
* <design/failover/#impl.assume.flush>.
|
||||||
*/
|
*/
|
||||||
LandFlush(fo->primary, fo->secondary);
|
(void)LandFlush(fo->primary, fo->secondary);
|
||||||
|
|
||||||
res = LandDelete(&oldRange, fo->primary, range);
|
res = LandDelete(&oldRange, fo->primary, range);
|
||||||
|
|
||||||
|
|
@ -129,10 +129,17 @@ static Res failoverDelete(Range rangeReturn, Land land, Range range)
|
||||||
/* Range not found in primary: try secondary. */
|
/* Range not found in primary: try secondary. */
|
||||||
return LandDelete(rangeReturn, fo->secondary, range);
|
return LandDelete(rangeReturn, fo->secondary, range);
|
||||||
} else if (res != ResOK) {
|
} else if (res != ResOK) {
|
||||||
/* Range was found in primary, but couldn't be deleted, perhaps
|
/* Range was found in primary, but couldn't be deleted. The only
|
||||||
* because the primary is out of memory. Delete the whole of
|
* case we expect to encounter here is the case where the primary
|
||||||
* oldRange, and re-insert the fragments (which might end up in
|
* is out of memory. (In particular, we don't handle the case of a
|
||||||
* the secondary). See <design/failover/#impl.assume.delete>.
|
* CBS returning ResLIMIT because its block pool has been
|
||||||
|
* configured not to automatically extend itself.)
|
||||||
|
*/
|
||||||
|
AVER(ResIsAllocFailure(res));
|
||||||
|
|
||||||
|
/* Delete the whole of oldRange, and re-insert the fragments
|
||||||
|
* (which might end up in the secondary). See
|
||||||
|
* <design/failover/#impl.assume.delete>.
|
||||||
*/
|
*/
|
||||||
res = LandDelete(&dummyRange, fo->primary, &oldRange);
|
res = LandDelete(&dummyRange, fo->primary, &oldRange);
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
|
|
@ -144,16 +151,22 @@ static Res failoverDelete(Range rangeReturn, Land land, Range range)
|
||||||
/* Don't call LandInsert(..., land, ...) here: that would be
|
/* Don't call LandInsert(..., land, ...) here: that would be
|
||||||
* re-entrant and fail the landEnter check. */
|
* re-entrant and fail the landEnter check. */
|
||||||
res = LandInsert(&dummyRange, fo->primary, &left);
|
res = LandInsert(&dummyRange, fo->primary, &left);
|
||||||
if (res != ResOK && res != ResFAIL)
|
if (res != ResOK) {
|
||||||
|
/* The range was successful deleted from the primary above. */
|
||||||
|
AVER(res != ResFAIL);
|
||||||
res = LandInsert(&dummyRange, fo->secondary, &left);
|
res = LandInsert(&dummyRange, fo->secondary, &left);
|
||||||
AVER(res == ResOK);
|
AVER(res == ResOK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RangeInit(&right, RangeLimit(range), RangeLimit(&oldRange));
|
RangeInit(&right, RangeLimit(range), RangeLimit(&oldRange));
|
||||||
if (!RangeIsEmpty(&right)) {
|
if (!RangeIsEmpty(&right)) {
|
||||||
res = LandInsert(&dummyRange, fo->primary, &right);
|
res = LandInsert(&dummyRange, fo->primary, &right);
|
||||||
if (res != ResOK && res != ResFAIL)
|
if (res != ResOK) {
|
||||||
|
/* The range was successful deleted from the primary above. */
|
||||||
|
AVER(res != ResFAIL);
|
||||||
res = LandInsert(&dummyRange, fo->secondary, &right);
|
res = LandInsert(&dummyRange, fo->secondary, &right);
|
||||||
AVER(res == ResOK);
|
AVER(res == ResOK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res == ResOK) {
|
if (res == ResOK) {
|
||||||
|
|
@ -164,7 +177,7 @@ static Res failoverDelete(Range rangeReturn, Land land, Range range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void failoverIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
|
static Bool failoverIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
Failover fo;
|
Failover fo;
|
||||||
|
|
||||||
|
|
@ -173,8 +186,8 @@ static void failoverIterate(Land land, LandVisitor visitor, void *closureP, Size
|
||||||
AVERT(Failover, fo);
|
AVERT(Failover, fo);
|
||||||
AVER(visitor != NULL);
|
AVER(visitor != NULL);
|
||||||
|
|
||||||
LandIterate(fo->primary, visitor, closureP, closureS);
|
return LandIterate(fo->primary, visitor, closureP, closureS)
|
||||||
LandIterate(fo->secondary, visitor, closureP, closureS);
|
&& LandIterate(fo->secondary, visitor, closureP, closureS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -190,7 +203,7 @@ static Bool failoverFindFirst(Range rangeReturn, Range oldRangeReturn, Land land
|
||||||
AVERT(FindDelete, findDelete);
|
AVERT(FindDelete, findDelete);
|
||||||
|
|
||||||
/* See <design/failover/#impl.assume.flush>. */
|
/* See <design/failover/#impl.assume.flush>. */
|
||||||
LandFlush(fo->primary, fo->secondary);
|
(void)LandFlush(fo->primary, fo->secondary);
|
||||||
|
|
||||||
return LandFindFirst(rangeReturn, oldRangeReturn, fo->primary, size, findDelete)
|
return LandFindFirst(rangeReturn, oldRangeReturn, fo->primary, size, findDelete)
|
||||||
|| LandFindFirst(rangeReturn, oldRangeReturn, fo->secondary, size, findDelete);
|
|| LandFindFirst(rangeReturn, oldRangeReturn, fo->secondary, size, findDelete);
|
||||||
|
|
@ -209,7 +222,7 @@ static Bool failoverFindLast(Range rangeReturn, Range oldRangeReturn, Land land,
|
||||||
AVERT(FindDelete, findDelete);
|
AVERT(FindDelete, findDelete);
|
||||||
|
|
||||||
/* See <design/failover/#impl.assume.flush>. */
|
/* See <design/failover/#impl.assume.flush>. */
|
||||||
LandFlush(fo->primary, fo->secondary);
|
(void)LandFlush(fo->primary, fo->secondary);
|
||||||
|
|
||||||
return LandFindLast(rangeReturn, oldRangeReturn, fo->primary, size, findDelete)
|
return LandFindLast(rangeReturn, oldRangeReturn, fo->primary, size, findDelete)
|
||||||
|| LandFindLast(rangeReturn, oldRangeReturn, fo->secondary, size, findDelete);
|
|| LandFindLast(rangeReturn, oldRangeReturn, fo->secondary, size, findDelete);
|
||||||
|
|
@ -228,17 +241,21 @@ static Bool failoverFindLargest(Range rangeReturn, Range oldRangeReturn, Land la
|
||||||
AVERT(FindDelete, findDelete);
|
AVERT(FindDelete, findDelete);
|
||||||
|
|
||||||
/* See <design/failover/#impl.assume.flush>. */
|
/* See <design/failover/#impl.assume.flush>. */
|
||||||
LandFlush(fo->primary, fo->secondary);
|
(void)LandFlush(fo->primary, fo->secondary);
|
||||||
|
|
||||||
return LandFindLargest(rangeReturn, oldRangeReturn, fo->primary, size, findDelete)
|
return LandFindLargest(rangeReturn, oldRangeReturn, fo->primary, size, findDelete)
|
||||||
|| LandFindLargest(rangeReturn, oldRangeReturn, fo->secondary, size, findDelete);
|
|| LandFindLargest(rangeReturn, oldRangeReturn, fo->secondary, size, findDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Bool failoverFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)
|
static Bool failoverFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)
|
||||||
{
|
{
|
||||||
Failover fo;
|
Failover fo;
|
||||||
|
Bool found = FALSE;
|
||||||
|
Res res;
|
||||||
|
|
||||||
|
AVER(FALSE); /* TODO: this code is completely untested! */
|
||||||
|
AVER(foundReturn != NULL);
|
||||||
AVER(rangeReturn != NULL);
|
AVER(rangeReturn != NULL);
|
||||||
AVER(oldRangeReturn != NULL);
|
AVER(oldRangeReturn != NULL);
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
|
|
@ -248,10 +265,14 @@ static Bool failoverFindInZones(Range rangeReturn, Range oldRangeReturn, Land la
|
||||||
AVERT(Bool, high);
|
AVERT(Bool, high);
|
||||||
|
|
||||||
/* See <design/failover/#impl.assume.flush>. */
|
/* See <design/failover/#impl.assume.flush>. */
|
||||||
LandFlush(fo->primary, fo->secondary);
|
(void)LandFlush(fo->primary, fo->secondary);
|
||||||
|
|
||||||
return LandFindInZones(rangeReturn, oldRangeReturn, fo->primary, size, zoneSet, high)
|
res = LandFindInZones(&found, rangeReturn, oldRangeReturn, fo->primary, size, zoneSet, high);
|
||||||
|| LandFindInZones(rangeReturn, oldRangeReturn, fo->secondary, size, zoneSet, high);
|
if (res != ResOK || !found)
|
||||||
|
res = LandFindInZones(&found, rangeReturn, oldRangeReturn, fo->secondary, size, zoneSet, high);
|
||||||
|
|
||||||
|
*foundReturn = found;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,13 +52,11 @@ static Res oomAlloc(Addr *pReturn, Pool pool, Size size,
|
||||||
UNUSED(pool);
|
UNUSED(pool);
|
||||||
UNUSED(size);
|
UNUSED(size);
|
||||||
UNUSED(withReservoirPermit);
|
UNUSED(withReservoirPermit);
|
||||||
switch (rnd() % 4) {
|
switch (rnd() % 3) {
|
||||||
case 0:
|
case 0:
|
||||||
return ResRESOURCE;
|
return ResRESOURCE;
|
||||||
case 1:
|
case 1:
|
||||||
return ResMEMORY;
|
return ResMEMORY;
|
||||||
case 2:
|
|
||||||
return ResLIMIT;
|
|
||||||
default:
|
default:
|
||||||
return ResCOMMIT_LIMIT;
|
return ResCOMMIT_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ SRCID(freelist, "$Id$");
|
||||||
|
|
||||||
|
|
||||||
#define freelistOfLand(land) PARENT(FreelistStruct, landStruct, land)
|
#define freelistOfLand(land) PARENT(FreelistStruct, landStruct, land)
|
||||||
#define freelistAlignment(fl) LandAlignment(&fl->landStruct)
|
#define freelistAlignment(fl) LandAlignment(&(fl)->landStruct)
|
||||||
|
|
||||||
|
|
||||||
typedef union FreelistBlockUnion {
|
typedef union FreelistBlockUnion {
|
||||||
|
|
@ -32,7 +32,7 @@ typedef union FreelistBlockUnion {
|
||||||
/* freelistEND -- the end of a list
|
/* freelistEND -- the end of a list
|
||||||
*
|
*
|
||||||
* The end of a list should not be represented with NULL, as this is
|
* The end of a list should not be represented with NULL, as this is
|
||||||
* ambiguous. However, freelistEND in fact a null pointer for
|
* ambiguous. However, freelistEND is in fact a null pointer, for
|
||||||
* performance. To check whether you have it right, try temporarily
|
* performance. To check whether you have it right, try temporarily
|
||||||
* defining freelistEND as ((FreelistBlock)2) or similar (it must be
|
* defining freelistEND as ((FreelistBlock)2) or similar (it must be
|
||||||
* an even number because of the use of a tag).
|
* an even number because of the use of a tag).
|
||||||
|
|
@ -246,6 +246,12 @@ static Size freelistSize(Land land)
|
||||||
* Otherwise, if next is freelistEND, make prev the last block in the list.
|
* Otherwise, if next is freelistEND, make prev the last block in the list.
|
||||||
* Otherwise, make next follow prev in the list.
|
* Otherwise, make next follow prev in the list.
|
||||||
* Update the count of blocks by 'delta'.
|
* Update the count of blocks by 'delta'.
|
||||||
|
|
||||||
|
* It is tempting to try to simplify this code by putting a
|
||||||
|
* FreelistBlockUnion into the FreelistStruct and so avoiding the
|
||||||
|
* special case on prev. But the problem with that idea is that we
|
||||||
|
* can't guarantee that such a sentinel would respect the isolated
|
||||||
|
* range invariant, and so it would still have to be special-cases.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void freelistBlockSetPrevNext(Freelist fl, FreelistBlock prev,
|
static void freelistBlockSetPrevNext(Freelist fl, FreelistBlock prev,
|
||||||
|
|
@ -438,8 +444,32 @@ static Res freelistDelete(Range rangeReturn, Land land, Range range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void freelistIterate(Land land, LandVisitor visitor,
|
static Bool freelistIterate(Land land, LandVisitor visitor,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
|
{
|
||||||
|
Freelist fl;
|
||||||
|
FreelistBlock cur;
|
||||||
|
|
||||||
|
AVERT(Land, land);
|
||||||
|
fl = freelistOfLand(land);
|
||||||
|
AVERT(Freelist, fl);
|
||||||
|
AVER(FUNCHECK(visitor));
|
||||||
|
/* closureP and closureS are arbitrary */
|
||||||
|
|
||||||
|
for (cur = fl->list; cur != freelistEND; cur = FreelistBlockNext(cur)) {
|
||||||
|
RangeStruct range;
|
||||||
|
Bool cont;
|
||||||
|
RangeInit(&range, FreelistBlockBase(cur), FreelistBlockLimit(fl, cur));
|
||||||
|
cont = (*visitor)(land, &range, closureP, closureS);
|
||||||
|
if (!cont)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool freelistIterateAndDelete(Land land, LandDeleteVisitor visitor,
|
||||||
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
Freelist fl;
|
Freelist fl;
|
||||||
FreelistBlock prev, cur, next;
|
FreelistBlock prev, cur, next;
|
||||||
|
|
@ -448,6 +478,7 @@ static void freelistIterate(Land land, LandVisitor visitor,
|
||||||
fl = freelistOfLand(land);
|
fl = freelistOfLand(land);
|
||||||
AVERT(Freelist, fl);
|
AVERT(Freelist, fl);
|
||||||
AVER(FUNCHECK(visitor));
|
AVER(FUNCHECK(visitor));
|
||||||
|
/* closureP and closureS are arbitrary */
|
||||||
|
|
||||||
prev = freelistEND;
|
prev = freelistEND;
|
||||||
cur = fl->list;
|
cur = fl->list;
|
||||||
|
|
@ -468,8 +499,9 @@ static void freelistIterate(Land land, LandVisitor visitor,
|
||||||
}
|
}
|
||||||
cur = next;
|
cur = next;
|
||||||
if (!cont)
|
if (!cont)
|
||||||
break;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -640,8 +672,8 @@ static Bool freelistFindLargest(Range rangeReturn, Range oldRangeReturn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Res freelistFindInZones(Range rangeReturn, Range oldRangeReturn,
|
static Res freelistFindInZones(Bool *foundReturn, Range rangeReturn,
|
||||||
Land land, Size size,
|
Range oldRangeReturn, Land land, Size size,
|
||||||
ZoneSet zoneSet, Bool high)
|
ZoneSet zoneSet, Bool high)
|
||||||
{
|
{
|
||||||
Freelist fl;
|
Freelist fl;
|
||||||
|
|
@ -665,16 +697,14 @@ static Res freelistFindInZones(Range rangeReturn, Range oldRangeReturn,
|
||||||
search = high ? RangeInZoneSetLast : RangeInZoneSetFirst;
|
search = high ? RangeInZoneSetLast : RangeInZoneSetFirst;
|
||||||
|
|
||||||
if (zoneSet == ZoneSetEMPTY)
|
if (zoneSet == ZoneSetEMPTY)
|
||||||
return ResFAIL;
|
goto fail;
|
||||||
if (zoneSet == ZoneSetUNIV) {
|
if (zoneSet == ZoneSetUNIV) {
|
||||||
FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW;
|
FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW;
|
||||||
if ((*landFind)(rangeReturn, oldRangeReturn, land, size, fd))
|
*foundReturn = (*landFind)(rangeReturn, oldRangeReturn, land, size, fd);
|
||||||
return ResOK;
|
return ResOK;
|
||||||
else
|
|
||||||
return ResFAIL;
|
|
||||||
}
|
}
|
||||||
if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land)))
|
if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land)))
|
||||||
return ResFAIL;
|
goto fail;
|
||||||
|
|
||||||
prev = freelistEND;
|
prev = freelistEND;
|
||||||
cur = fl->list;
|
cur = fl->list;
|
||||||
|
|
@ -697,10 +727,15 @@ static Res freelistFindInZones(Range rangeReturn, Range oldRangeReturn,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
return ResFAIL;
|
goto fail;
|
||||||
|
|
||||||
freelistDeleteFromBlock(oldRangeReturn, fl, &foundRange, foundPrev, foundCur);
|
freelistDeleteFromBlock(oldRangeReturn, fl, &foundRange, foundPrev, foundCur);
|
||||||
RangeCopy(rangeReturn, &foundRange);
|
RangeCopy(rangeReturn, &foundRange);
|
||||||
|
*foundReturn = TRUE;
|
||||||
|
return ResOK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
*foundReturn = FALSE;
|
||||||
return ResOK;
|
return ResOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -711,17 +746,16 @@ static Res freelistFindInZones(Range rangeReturn, Range oldRangeReturn,
|
||||||
* closureP.
|
* closureP.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Bool freelistDescribeVisitor(Bool *deleteReturn, Land land, Range range,
|
static Bool freelistDescribeVisitor(Land land, Range range,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
Res res;
|
Res res;
|
||||||
mps_lib_FILE *stream = closureP;
|
mps_lib_FILE *stream = closureP;
|
||||||
|
|
||||||
if (deleteReturn == NULL) return FALSE;
|
|
||||||
if (!TESTT(Land, land)) return FALSE;
|
if (!TESTT(Land, land)) return FALSE;
|
||||||
if (!RangeCheck(range)) return FALSE;
|
if (!RangeCheck(range)) return FALSE;
|
||||||
if (stream == NULL) return FALSE;
|
if (stream == NULL) return FALSE;
|
||||||
UNUSED(closureS);
|
if (closureS != UNUSED_SIZE) return FALSE;
|
||||||
|
|
||||||
res = WriteF(stream,
|
res = WriteF(stream,
|
||||||
" [$P,", (WriteFP)RangeBase(range),
|
" [$P,", (WriteFP)RangeBase(range),
|
||||||
|
|
@ -737,6 +771,7 @@ static Res freelistDescribe(Land land, mps_lib_FILE *stream)
|
||||||
{
|
{
|
||||||
Freelist fl;
|
Freelist fl;
|
||||||
Res res;
|
Res res;
|
||||||
|
Bool b;
|
||||||
|
|
||||||
if (!TESTT(Land, land)) return ResFAIL;
|
if (!TESTT(Land, land)) return ResFAIL;
|
||||||
fl = freelistOfLand(land);
|
fl = freelistOfLand(land);
|
||||||
|
|
@ -748,7 +783,8 @@ static Res freelistDescribe(Land land, mps_lib_FILE *stream)
|
||||||
" listSize = $U\n", (WriteFU)fl->listSize,
|
" listSize = $U\n", (WriteFU)fl->listSize,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
LandIterate(land, freelistDescribeVisitor, stream, 0);
|
b = LandIterate(land, freelistDescribeVisitor, stream, UNUSED_SIZE);
|
||||||
|
if (!b) return ResFAIL;
|
||||||
|
|
||||||
res = WriteF(stream, "}\n", NULL);
|
res = WriteF(stream, "}\n", NULL);
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -766,6 +802,7 @@ DEFINE_LAND_CLASS(FreelistLandClass, class)
|
||||||
class->insert = freelistInsert;
|
class->insert = freelistInsert;
|
||||||
class->delete = freelistDelete;
|
class->delete = freelistDelete;
|
||||||
class->iterate = freelistIterate;
|
class->iterate = freelistIterate;
|
||||||
|
class->iterateAndDelete = freelistIterateAndDelete;
|
||||||
class->findFirst = freelistFindFirst;
|
class->findFirst = freelistFindFirst;
|
||||||
class->findLast = freelistFindLast;
|
class->findLast = freelistFindLast;
|
||||||
class->findLargest = freelistFindLargest;
|
class->findLargest = freelistFindLargest;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include "testthr.h"
|
#include "testthr.h"
|
||||||
#include "fmtdy.h"
|
#include "fmtdy.h"
|
||||||
#include "fmtdytst.h"
|
#include "fmtdytst.h"
|
||||||
|
#include "mpm.h"
|
||||||
|
|
||||||
#include <stdio.h> /* fprintf, printf, putchars, sscanf, stderr, stdout */
|
#include <stdio.h> /* fprintf, printf, putchars, sscanf, stderr, stdout */
|
||||||
#include <stdlib.h> /* alloca, exit, EXIT_FAILURE, EXIT_SUCCESS, strtoul */
|
#include <stdlib.h> /* alloca, exit, EXIT_FAILURE, EXIT_SUCCESS, strtoul */
|
||||||
|
|
@ -244,6 +245,7 @@ static void arena_setup(gcthread_fn_t fn,
|
||||||
} MPS_ARGS_END(args);
|
} MPS_ARGS_END(args);
|
||||||
watch(fn, name);
|
watch(fn, name);
|
||||||
mps_arena_park(arena);
|
mps_arena_park(arena);
|
||||||
|
printf("%u chunks\n", (unsigned)RingLength(&arena->chunkRing));
|
||||||
mps_pool_destroy(pool);
|
mps_pool_destroy(pool);
|
||||||
mps_fmt_destroy(format);
|
mps_fmt_destroy(format);
|
||||||
if (ngen > 0)
|
if (ngen > 0)
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,9 @@ Bool FindDeleteCheck(FindDelete findDelete)
|
||||||
|
|
||||||
/* landEnter, landLeave -- Avoid re-entrance
|
/* landEnter, landLeave -- Avoid re-entrance
|
||||||
*
|
*
|
||||||
* .enter-leave: The visitor function passed to LandIterate is not
|
* .enter-leave: The visitor functions passed to LandIterate and
|
||||||
* allowed to call methods of that land. These functions enforce this.
|
* LandIterateAndDelete are not allowed to call methods of that land.
|
||||||
|
* These functions enforce this.
|
||||||
*
|
*
|
||||||
* .enter-leave.simple: Some simple queries are fine to call from
|
* .enter-leave.simple: Some simple queries are fine to call from
|
||||||
* visitor functions. These are marked with the tag of this comment.
|
* visitor functions. These are marked with the tag of this comment.
|
||||||
|
|
@ -233,15 +234,37 @@ Res LandDelete(Range rangeReturn, Land land, Range range)
|
||||||
* See <design/land/#function.iterate>
|
* See <design/land/#function.iterate>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
|
Bool LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
|
Bool b;
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
AVER(FUNCHECK(visitor));
|
AVER(FUNCHECK(visitor));
|
||||||
landEnter(land);
|
landEnter(land);
|
||||||
|
|
||||||
(*land->class->iterate)(land, visitor, closureP, closureS);
|
b = (*land->class->iterate)(land, visitor, closureP, closureS);
|
||||||
|
|
||||||
landLeave(land);
|
landLeave(land);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* LandIterateAndDelete -- iterate over isolated ranges of addresses
|
||||||
|
* in land, deleting some of them
|
||||||
|
*
|
||||||
|
* See <design/land/#function.iterate.and.delete>
|
||||||
|
*/
|
||||||
|
|
||||||
|
Bool LandIterateAndDelete(Land land, LandDeleteVisitor visitor, void *closureP, Size closureS)
|
||||||
|
{
|
||||||
|
Bool b;
|
||||||
|
AVERT(Land, land);
|
||||||
|
AVER(FUNCHECK(visitor));
|
||||||
|
landEnter(land);
|
||||||
|
|
||||||
|
b = (*land->class->iterateAndDelete)(land, visitor, closureP, closureS);
|
||||||
|
|
||||||
|
landLeave(land);
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -252,7 +275,7 @@ void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
|
||||||
|
|
||||||
Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
||||||
{
|
{
|
||||||
Bool res;
|
Bool b;
|
||||||
|
|
||||||
AVER(rangeReturn != NULL);
|
AVER(rangeReturn != NULL);
|
||||||
AVER(oldRangeReturn != NULL);
|
AVER(oldRangeReturn != NULL);
|
||||||
|
|
@ -261,11 +284,11 @@ Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size
|
||||||
AVER(FindDeleteCheck(findDelete));
|
AVER(FindDeleteCheck(findDelete));
|
||||||
landEnter(land);
|
landEnter(land);
|
||||||
|
|
||||||
res = (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size,
|
b = (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size,
|
||||||
findDelete);
|
findDelete);
|
||||||
|
|
||||||
landLeave(land);
|
landLeave(land);
|
||||||
return res;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -276,7 +299,7 @@ Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size
|
||||||
|
|
||||||
Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
||||||
{
|
{
|
||||||
Bool res;
|
Bool b;
|
||||||
|
|
||||||
AVER(rangeReturn != NULL);
|
AVER(rangeReturn != NULL);
|
||||||
AVER(oldRangeReturn != NULL);
|
AVER(oldRangeReturn != NULL);
|
||||||
|
|
@ -285,11 +308,11 @@ Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size,
|
||||||
AVER(FindDeleteCheck(findDelete));
|
AVER(FindDeleteCheck(findDelete));
|
||||||
landEnter(land);
|
landEnter(land);
|
||||||
|
|
||||||
res = (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size,
|
b = (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size,
|
||||||
findDelete);
|
findDelete);
|
||||||
|
|
||||||
landLeave(land);
|
landLeave(land);
|
||||||
return res;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -300,7 +323,7 @@ Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size,
|
||||||
|
|
||||||
Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
||||||
{
|
{
|
||||||
Bool res;
|
Bool b;
|
||||||
|
|
||||||
AVER(rangeReturn != NULL);
|
AVER(rangeReturn != NULL);
|
||||||
AVER(oldRangeReturn != NULL);
|
AVER(oldRangeReturn != NULL);
|
||||||
|
|
@ -309,11 +332,11 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si
|
||||||
AVER(FindDeleteCheck(findDelete));
|
AVER(FindDeleteCheck(findDelete));
|
||||||
landEnter(land);
|
landEnter(land);
|
||||||
|
|
||||||
res = (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size,
|
b = (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size,
|
||||||
findDelete);
|
findDelete);
|
||||||
|
|
||||||
landLeave(land);
|
landLeave(land);
|
||||||
return res;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -322,10 +345,11 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si
|
||||||
* See <design/land/#function.find.zones>
|
* See <design/land/#function.find.zones>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)
|
Res LandFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)
|
||||||
{
|
{
|
||||||
Res res;
|
Res res;
|
||||||
|
|
||||||
|
AVER(foundReturn != NULL);
|
||||||
AVER(rangeReturn != NULL);
|
AVER(rangeReturn != NULL);
|
||||||
AVER(oldRangeReturn != NULL);
|
AVER(oldRangeReturn != NULL);
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
|
|
@ -334,8 +358,8 @@ Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size siz
|
||||||
AVERT(Bool, high);
|
AVERT(Bool, high);
|
||||||
landEnter(land);
|
landEnter(land);
|
||||||
|
|
||||||
res = (*land->class->findInZones)(rangeReturn, oldRangeReturn, land, size,
|
res = (*land->class->findInZones)(foundReturn, rangeReturn, oldRangeReturn,
|
||||||
zoneSet, high);
|
land, size, zoneSet, high);
|
||||||
|
|
||||||
landLeave(land);
|
landLeave(land);
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -390,6 +414,7 @@ static Bool landFlushVisitor(Bool *deleteReturn, Land land, Range range,
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
AVERT(Range, range);
|
AVERT(Range, range);
|
||||||
AVER(closureP != NULL);
|
AVER(closureP != NULL);
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
|
|
||||||
dest = closureP;
|
dest = closureP;
|
||||||
|
|
@ -409,12 +434,12 @@ static Bool landFlushVisitor(Bool *deleteReturn, Land land, Range range,
|
||||||
* See <design/land/#function.flush>
|
* See <design/land/#function.flush>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void LandFlush(Land dest, Land src)
|
Bool LandFlush(Land dest, Land src)
|
||||||
{
|
{
|
||||||
AVERT(Land, dest);
|
AVERT(Land, dest);
|
||||||
AVERT(Land, src);
|
AVERT(Land, src);
|
||||||
|
|
||||||
LandIterate(src, landFlushVisitor, dest, 0);
|
return LandIterateAndDelete(src, landFlushVisitor, dest, UNUSED_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -462,20 +487,19 @@ static Size landNoSize(Land land)
|
||||||
|
|
||||||
/* LandSlowSize -- generic size method but slow */
|
/* LandSlowSize -- generic size method but slow */
|
||||||
|
|
||||||
static Bool landSizeVisitor(Bool *deleteReturn, Land land, Range range,
|
static Bool landSizeVisitor(Land land, Range range,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
Size *size;
|
Size *size;
|
||||||
|
|
||||||
AVER(deleteReturn != NULL);
|
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
AVERT(Range, range);
|
AVERT(Range, range);
|
||||||
AVER(closureP != NULL);
|
AVER(closureP != NULL);
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
|
|
||||||
size = closureP;
|
size = closureP;
|
||||||
*size += RangeSize(range);
|
*size += RangeSize(range);
|
||||||
*deleteReturn = FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -483,7 +507,8 @@ static Bool landSizeVisitor(Bool *deleteReturn, Land land, Range range,
|
||||||
Size LandSlowSize(Land land)
|
Size LandSlowSize(Land land)
|
||||||
{
|
{
|
||||||
Size size = 0;
|
Size size = 0;
|
||||||
LandIterate(land, landSizeVisitor, &size, 0);
|
Bool b = LandIterate(land, landSizeVisitor, &size, UNUSED_SIZE);
|
||||||
|
AVER(b);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,13 +528,22 @@ static Res landNoDelete(Range rangeReturn, Land land, Range range)
|
||||||
return ResUNIMPL;
|
return ResUNIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void landNoIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
|
static Bool landNoIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
AVER(visitor != NULL);
|
AVER(visitor != NULL);
|
||||||
UNUSED(closureP);
|
UNUSED(closureP);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
NOOP;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool landNoIterateAndDelete(Land land, LandDeleteVisitor visitor, void *closureP, Size closureS)
|
||||||
|
{
|
||||||
|
AVERT(Land, land);
|
||||||
|
AVER(visitor != NULL);
|
||||||
|
UNUSED(closureP);
|
||||||
|
UNUSED(closureS);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool landNoFind(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
static Bool landNoFind(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
|
||||||
|
|
@ -522,8 +556,9 @@ static Bool landNoFind(Range rangeReturn, Range oldRangeReturn, Land land, Size
|
||||||
return ResUNIMPL;
|
return ResUNIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Res landNoFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)
|
static Res landNoFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)
|
||||||
{
|
{
|
||||||
|
AVER(foundReturn != NULL);
|
||||||
AVER(rangeReturn != NULL);
|
AVER(rangeReturn != NULL);
|
||||||
AVER(oldRangeReturn != NULL);
|
AVER(oldRangeReturn != NULL);
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
|
|
@ -554,6 +589,7 @@ DEFINE_CLASS(LandClass, class)
|
||||||
class->insert = landNoInsert;
|
class->insert = landNoInsert;
|
||||||
class->delete = landNoDelete;
|
class->delete = landNoDelete;
|
||||||
class->iterate = landNoIterate;
|
class->iterate = landNoIterate;
|
||||||
|
class->iterateAndDelete = landNoIterateAndDelete;
|
||||||
class->findFirst = landNoFind;
|
class->findFirst = landNoFind;
|
||||||
class->findLast = landNoFind;
|
class->findLast = landNoFind;
|
||||||
class->findLargest = landNoFind;
|
class->findLargest = landNoFind;
|
||||||
|
|
|
||||||
|
|
@ -75,15 +75,13 @@ static void describe(TestState state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Bool checkVisitor(Bool *deleteReturn, Land land, Range range,
|
static Bool checkVisitor(Land land, Range range, void *closureP, Size closureS)
|
||||||
void *closureP, Size closureS)
|
|
||||||
{
|
{
|
||||||
Addr base, limit;
|
Addr base, limit;
|
||||||
CheckTestClosure cl = closureP;
|
CheckTestClosure cl = closureP;
|
||||||
|
|
||||||
Insist(deleteReturn != NULL);
|
|
||||||
testlib_unused(land);
|
testlib_unused(land);
|
||||||
testlib_unused(closureS);
|
Insist(closureS == UNUSED_SIZE);
|
||||||
Insist(cl != NULL);
|
Insist(cl != NULL);
|
||||||
|
|
||||||
base = RangeBase(range);
|
base = RangeBase(range);
|
||||||
|
|
@ -110,12 +108,14 @@ static Bool checkVisitor(Bool *deleteReturn, Land land, Range range,
|
||||||
static void check(TestState state)
|
static void check(TestState state)
|
||||||
{
|
{
|
||||||
CheckTestClosureStruct closure;
|
CheckTestClosureStruct closure;
|
||||||
|
Bool b;
|
||||||
|
|
||||||
closure.state = state;
|
closure.state = state;
|
||||||
closure.limit = addrOfIndex(state, ArraySize);
|
closure.limit = addrOfIndex(state, ArraySize);
|
||||||
closure.oldLimit = state->block;
|
closure.oldLimit = state->block;
|
||||||
|
|
||||||
LandIterate(state->land, checkVisitor, (void *)&closure, 0);
|
b = LandIterate(state->land, checkVisitor, &closure, UNUSED_SIZE);
|
||||||
|
Insist(b);
|
||||||
|
|
||||||
if (closure.oldLimit == state->block)
|
if (closure.oldLimit == state->block)
|
||||||
Insist(BTIsSetRange(state->allocTable, 0,
|
Insist(BTIsSetRange(state->allocTable, 0,
|
||||||
|
|
|
||||||
108
mps/code/locus.c
108
mps/code/locus.c
|
|
@ -214,7 +214,8 @@ void ChainDestroy(Chain chain)
|
||||||
AVERT(Chain, chain);
|
AVERT(Chain, chain);
|
||||||
AVER(chain->activeTraces == TraceSetEMPTY);
|
AVER(chain->activeTraces == TraceSetEMPTY);
|
||||||
|
|
||||||
arena = chain->arena; genCount = chain->genCount;
|
arena = chain->arena;
|
||||||
|
genCount = chain->genCount;
|
||||||
RingRemove(&chain->chainRing);
|
RingRemove(&chain->chainRing);
|
||||||
chain->sig = SigInvalid;
|
chain->sig = SigInvalid;
|
||||||
for (i = 0; i < genCount; ++i) {
|
for (i = 0; i < genCount; ++i) {
|
||||||
|
|
@ -236,55 +237,67 @@ size_t ChainGens(Chain chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ChainAlloc -- allocate tracts in a generation */
|
/* ChainGen -- return a generation in a chain, or the arena top generation */
|
||||||
|
|
||||||
Res ChainAlloc(Seg *segReturn, Chain chain, Serial genNr, SegClass class,
|
GenDesc ChainGen(Chain chain, Index gen)
|
||||||
Size size, Pool pool, Bool withReservoirPermit,
|
{
|
||||||
ArgList args)
|
AVERT(Chain, chain);
|
||||||
|
AVER(gen <= chain->genCount);
|
||||||
|
|
||||||
|
if (gen < chain->genCount)
|
||||||
|
return &chain->gens[gen];
|
||||||
|
else
|
||||||
|
return &chain->arena->topGen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PoolGenAlloc -- allocate a segment in a pool generation */
|
||||||
|
|
||||||
|
Res PoolGenAlloc(Seg *segReturn, PoolGen pgen, SegClass class, Size size,
|
||||||
|
Bool withReservoirPermit, ArgList args)
|
||||||
{
|
{
|
||||||
SegPrefStruct pref;
|
SegPrefStruct pref;
|
||||||
Res res;
|
Res res;
|
||||||
Seg seg;
|
Seg seg;
|
||||||
ZoneSet zones, moreZones;
|
ZoneSet zones, moreZones;
|
||||||
Arena arena;
|
Arena arena;
|
||||||
|
GenDesc gen;
|
||||||
|
|
||||||
AVERT(Chain, chain);
|
AVER(segReturn != NULL);
|
||||||
AVER(genNr <= chain->genCount);
|
AVERT(PoolGen, pgen);
|
||||||
|
AVERT(SegClass, class);
|
||||||
|
AVER(size > 0);
|
||||||
|
AVERT(Bool, withReservoirPermit);
|
||||||
|
AVERT(ArgList, args);
|
||||||
|
|
||||||
arena = chain->arena;
|
arena = PoolArena(pgen->pool);
|
||||||
if (genNr < chain->genCount)
|
gen = pgen->gen;
|
||||||
zones = chain->gens[genNr].zones;
|
zones = gen->zones;
|
||||||
else
|
|
||||||
zones = arena->topGen.zones;
|
|
||||||
|
|
||||||
SegPrefInit(&pref);
|
SegPrefInit(&pref);
|
||||||
pref.high = FALSE;
|
pref.high = FALSE;
|
||||||
pref.zones = zones;
|
pref.zones = zones;
|
||||||
pref.avoid = ZoneSetBlacklist(arena);
|
pref.avoid = ZoneSetBlacklist(arena);
|
||||||
res = SegAlloc(&seg, class, &pref, size, pool, withReservoirPermit, args);
|
res = SegAlloc(&seg, class, &pref, size, pgen->pool, withReservoirPermit,
|
||||||
|
args);
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
moreZones = ZoneSetUnion(zones, ZoneSetOfSeg(arena, seg));
|
moreZones = ZoneSetUnion(zones, ZoneSetOfSeg(arena, seg));
|
||||||
|
gen->zones = moreZones;
|
||||||
|
|
||||||
if (!ZoneSetSuper(zones, moreZones)) {
|
if (!ZoneSetSuper(zones, moreZones)) {
|
||||||
/* Tracking the whole zoneset for each generation number gives
|
/* Tracking the whole zoneset for each generation gives more
|
||||||
* more understandable telemetry than just reporting the added
|
* understandable telemetry than just reporting the added
|
||||||
* zones. */
|
* zones. */
|
||||||
EVENT3(ArenaGenZoneAdd, arena, genNr, moreZones);
|
EVENT3(ArenaGenZoneAdd, arena, gen, moreZones);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (genNr < chain->genCount)
|
|
||||||
chain->gens[genNr].zones = moreZones;
|
|
||||||
else
|
|
||||||
chain->arena->topGen.zones = moreZones;
|
|
||||||
|
|
||||||
*segReturn = seg;
|
*segReturn = seg;
|
||||||
return ResOK;
|
return ResOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ChainDeferral -- time until next ephemeral GC for this chain */
|
/* ChainDeferral -- time until next ephemeral GC for this chain */
|
||||||
|
|
||||||
double ChainDeferral(Chain chain)
|
double ChainDeferral(Chain chain)
|
||||||
|
|
@ -394,55 +407,48 @@ void ChainEndGC(Chain chain, Trace trace)
|
||||||
|
|
||||||
/* PoolGenInit -- initialize a PoolGen */
|
/* PoolGenInit -- initialize a PoolGen */
|
||||||
|
|
||||||
Res PoolGenInit(PoolGen gen, Chain chain, Serial nr, Pool pool)
|
Res PoolGenInit(PoolGen pgen, GenDesc gen, Pool pool)
|
||||||
{
|
{
|
||||||
/* Can't check gen, because it's not been initialized. */
|
/* Can't check pgen, because it's not been initialized. */
|
||||||
AVER(gen != NULL);
|
AVER(pgen != NULL);
|
||||||
AVERT(Chain, chain);
|
AVERT(GenDesc, gen);
|
||||||
AVER(nr <= chain->genCount);
|
|
||||||
AVERT(Pool, pool);
|
AVERT(Pool, pool);
|
||||||
AVER(PoolHasAttr(pool, AttrGC));
|
AVER(PoolHasAttr(pool, AttrGC));
|
||||||
|
|
||||||
gen->nr = nr;
|
pgen->pool = pool;
|
||||||
gen->pool = pool;
|
pgen->gen = gen;
|
||||||
gen->chain = chain;
|
RingInit(&pgen->genRing);
|
||||||
RingInit(&gen->genRing);
|
pgen->totalSize = (Size)0;
|
||||||
gen->totalSize = (Size)0;
|
pgen->newSize = (Size)0;
|
||||||
gen->newSize = (Size)0;
|
pgen->sig = PoolGenSig;
|
||||||
gen->sig = PoolGenSig;
|
AVERT(PoolGen, pgen);
|
||||||
|
|
||||||
if(nr != chain->genCount) {
|
RingAppend(&gen->locusRing, &pgen->genRing);
|
||||||
RingAppend(&chain->gens[nr].locusRing, &gen->genRing);
|
|
||||||
} else {
|
|
||||||
/* Dynamic generation is linked to the arena, not the chain. */
|
|
||||||
RingAppend(&chain->arena->topGen.locusRing, &gen->genRing);
|
|
||||||
}
|
|
||||||
AVERT(PoolGen, gen);
|
|
||||||
return ResOK;
|
return ResOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* PoolGenFinish -- finish a PoolGen */
|
/* PoolGenFinish -- finish a PoolGen */
|
||||||
|
|
||||||
void PoolGenFinish(PoolGen gen)
|
void PoolGenFinish(PoolGen pgen)
|
||||||
{
|
{
|
||||||
AVERT(PoolGen, gen);
|
AVERT(PoolGen, pgen);
|
||||||
|
|
||||||
gen->sig = SigInvalid;
|
pgen->sig = SigInvalid;
|
||||||
RingRemove(&gen->genRing);
|
RingRemove(&pgen->genRing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* PoolGenCheck -- check a PoolGen */
|
/* PoolGenCheck -- check a PoolGen */
|
||||||
|
|
||||||
Bool PoolGenCheck(PoolGen gen)
|
Bool PoolGenCheck(PoolGen pgen)
|
||||||
{
|
{
|
||||||
CHECKS(PoolGen, gen);
|
CHECKS(PoolGen, pgen);
|
||||||
/* nothing to check about serial */
|
/* nothing to check about serial */
|
||||||
CHECKU(Pool, gen->pool);
|
CHECKU(Pool, pgen->pool);
|
||||||
CHECKU(Chain, gen->chain);
|
CHECKU(GenDesc, pgen->gen);
|
||||||
CHECKD_NOSIG(Ring, &gen->genRing);
|
CHECKD_NOSIG(Ring, &pgen->genRing);
|
||||||
CHECKL(gen->newSize <= gen->totalSize);
|
CHECKL(pgen->newSize <= pgen->totalSize);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,15 @@ typedef const struct SrcIdStruct {
|
||||||
#define UNUSED(param) ((void)param)
|
#define UNUSED(param) ((void)param)
|
||||||
|
|
||||||
|
|
||||||
|
/* UNUSED_POINTER, UNUSED_SIZE -- values for unused arguments
|
||||||
|
*
|
||||||
|
* Use these values for unused pointer, size closure arguments and
|
||||||
|
* check them in the callback or visitor.
|
||||||
|
*/
|
||||||
|
#define UNUSED_POINTER ((Pointer)0xB60405ED) /* PointeR UNUSED */
|
||||||
|
#define UNUSED_SIZE ((Size)0x520405ED) /* SiZe UNUSED */
|
||||||
|
|
||||||
|
|
||||||
/* PARENT -- parent structure
|
/* PARENT -- parent structure
|
||||||
*
|
*
|
||||||
* Given a pointer to a field of a structure this returns a pointer to
|
* Given a pointer to a field of a structure this returns a pointer to
|
||||||
|
|
|
||||||
|
|
@ -1013,13 +1013,14 @@ extern void LandDestroy(Land land);
|
||||||
extern void LandFinish(Land land);
|
extern void LandFinish(Land land);
|
||||||
extern Res LandInsert(Range rangeReturn, Land land, Range range);
|
extern Res LandInsert(Range rangeReturn, Land land, Range range);
|
||||||
extern Res LandDelete(Range rangeReturn, Land land, Range range);
|
extern Res LandDelete(Range rangeReturn, Land land, Range range);
|
||||||
extern void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS);
|
extern Bool LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS);
|
||||||
|
extern Bool LandIterateAndDelete(Land land, LandDeleteVisitor visitor, void *closureP, Size closureS);
|
||||||
extern Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
extern Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
||||||
extern Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
extern Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
||||||
extern Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
extern Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
||||||
extern Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high);
|
extern Res LandFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high);
|
||||||
extern Res LandDescribe(Land land, mps_lib_FILE *stream);
|
extern Res LandDescribe(Land land, mps_lib_FILE *stream);
|
||||||
extern void LandFlush(Land dest, Land src);
|
extern Bool LandFlush(Land dest, Land src);
|
||||||
|
|
||||||
extern Size LandSlowSize(Land land);
|
extern Size LandSlowSize(Land land);
|
||||||
extern Bool LandClassCheck(LandClass class);
|
extern Bool LandClassCheck(LandClass class);
|
||||||
|
|
|
||||||
|
|
@ -621,6 +621,7 @@ typedef struct LandClassStruct {
|
||||||
LandInsertMethod insert; /* insert a range into the land */
|
LandInsertMethod insert; /* insert a range into the land */
|
||||||
LandDeleteMethod delete; /* delete a range from the land */
|
LandDeleteMethod delete; /* delete a range from the land */
|
||||||
LandIterateMethod iterate; /* iterate over ranges in the land */
|
LandIterateMethod iterate; /* iterate over ranges in the land */
|
||||||
|
LandIterateAndDeleteMethod iterateAndDelete; /* iterate and maybe delete */
|
||||||
LandFindMethod findFirst; /* find first range of given size */
|
LandFindMethod findFirst; /* find first range of given size */
|
||||||
LandFindMethod findLast; /* find last range of given size */
|
LandFindMethod findLast; /* find last range of given size */
|
||||||
LandFindMethod findLargest; /* find largest range */
|
LandFindMethod findLargest; /* find largest range */
|
||||||
|
|
|
||||||
|
|
@ -271,10 +271,12 @@ typedef void (*LandFinishMethod)(Land land);
|
||||||
typedef Size (*LandSizeMethod)(Land land);
|
typedef Size (*LandSizeMethod)(Land land);
|
||||||
typedef Res (*LandInsertMethod)(Range rangeReturn, Land land, Range range);
|
typedef Res (*LandInsertMethod)(Range rangeReturn, Land land, Range range);
|
||||||
typedef Res (*LandDeleteMethod)(Range rangeReturn, Land land, Range range);
|
typedef Res (*LandDeleteMethod)(Range rangeReturn, Land land, Range range);
|
||||||
typedef Bool (*LandVisitor)(Bool *deleteReturn, Land land, Range range, void *closureP, Size closureS);
|
typedef Bool (*LandVisitor)(Land land, Range range, void *closureP, Size closureS);
|
||||||
typedef void (*LandIterateMethod)(Land land, LandVisitor visitor, void *closureP, Size closureS);
|
typedef Bool (*LandDeleteVisitor)(Bool *deleteReturn, Land land, Range range, void *closureP, Size closureS);
|
||||||
|
typedef Bool (*LandIterateMethod)(Land land, LandVisitor visitor, void *closureP, Size closureS);
|
||||||
|
typedef Bool (*LandIterateAndDeleteMethod)(Land land, LandDeleteVisitor visitor, void *closureP, Size closureS);
|
||||||
typedef Bool (*LandFindMethod)(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
typedef Bool (*LandFindMethod)(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete);
|
||||||
typedef Res (*LandFindInZonesMethod)(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high);
|
typedef Res (*LandFindInZonesMethod)(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high);
|
||||||
typedef Res (*LandDescribeMethod)(Land land, mps_lib_FILE *stream);
|
typedef Res (*LandDescribeMethod)(Land land, mps_lib_FILE *stream);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,6 @@
|
||||||
#include "poolawl.c"
|
#include "poolawl.c"
|
||||||
#include "poollo.c"
|
#include "poollo.c"
|
||||||
#include "poolsnc.c"
|
#include "poolsnc.c"
|
||||||
#include "pooln.c"
|
|
||||||
#include "poolmv2.c"
|
#include "poolmv2.c"
|
||||||
#include "poolmvff.c"
|
#include "poolmvff.c"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
* `MPS_` or `_mps_` and may use any identifiers with these prefixes in
|
* `MPS_` or `_mps_` and may use any identifiers with these prefixes in
|
||||||
* future.
|
* future.
|
||||||
*
|
*
|
||||||
* .naming.internal: Any idenfitier beginning with underscore is for
|
* .naming.internal: Any identifier beginning with an underscore is for
|
||||||
* internal use within the interface and may change or be withdrawn without
|
* internal use within the interface and may change or be withdrawn without
|
||||||
* warning.
|
* warning.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,54 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXAggregateTarget section */
|
/* Begin PBXAggregateTarget section */
|
||||||
|
2215A9A9192A47BB00E9E2CE /* testci */ = {
|
||||||
|
isa = PBXAggregateTarget;
|
||||||
|
buildConfigurationList = 2215A9AD192A47BB00E9E2CE /* Build configuration list for PBXAggregateTarget "testci" */;
|
||||||
|
buildPhases = (
|
||||||
|
2215A9AC192A47BB00E9E2CE /* ShellScript */,
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
2215A9AA192A47BB00E9E2CE /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = testci;
|
||||||
|
productName = testrun;
|
||||||
|
};
|
||||||
|
2215A9B1192A47C500E9E2CE /* testansi */ = {
|
||||||
|
isa = PBXAggregateTarget;
|
||||||
|
buildConfigurationList = 2215A9B5192A47C500E9E2CE /* Build configuration list for PBXAggregateTarget "testansi" */;
|
||||||
|
buildPhases = (
|
||||||
|
2215A9B4192A47C500E9E2CE /* ShellScript */,
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
2215A9B2192A47C500E9E2CE /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = testansi;
|
||||||
|
productName = testrun;
|
||||||
|
};
|
||||||
|
2215A9B9192A47CE00E9E2CE /* testall */ = {
|
||||||
|
isa = PBXAggregateTarget;
|
||||||
|
buildConfigurationList = 2215A9BD192A47CE00E9E2CE /* Build configuration list for PBXAggregateTarget "testall" */;
|
||||||
|
buildPhases = (
|
||||||
|
2215A9BC192A47CE00E9E2CE /* ShellScript */,
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
2215A9BA192A47CE00E9E2CE /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = testall;
|
||||||
|
productName = testrun;
|
||||||
|
};
|
||||||
|
2215A9C1192A47D500E9E2CE /* testpoll */ = {
|
||||||
|
isa = PBXAggregateTarget;
|
||||||
|
buildConfigurationList = 2215A9C5192A47D500E9E2CE /* Build configuration list for PBXAggregateTarget "testpoll" */;
|
||||||
|
buildPhases = (
|
||||||
|
2215A9C4192A47D500E9E2CE /* ShellScript */,
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
2215A9C2192A47D500E9E2CE /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = testpoll;
|
||||||
|
productName = testrun;
|
||||||
|
};
|
||||||
22CDE8EF16E9E97D00366D0A /* testrun */ = {
|
22CDE8EF16E9E97D00366D0A /* testrun */ = {
|
||||||
isa = PBXAggregateTarget;
|
isa = PBXAggregateTarget;
|
||||||
buildConfigurationList = 22CDE8F016E9E97E00366D0A /* Build configuration list for PBXAggregateTarget "testrun" */;
|
buildConfigurationList = 22CDE8F016E9E97E00366D0A /* Build configuration list for PBXAggregateTarget "testrun" */;
|
||||||
|
|
@ -79,6 +127,7 @@
|
||||||
/* End PBXAggregateTarget section */
|
/* End PBXAggregateTarget section */
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
2215A9C9192A495F00E9E2CE /* pooln.c in Sources */ = {isa = PBXBuildFile; fileRef = 22FACEDE18880933000FDBC1 /* pooln.c */; };
|
||||||
2231BB5118CA97D8002D6322 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
|
2231BB5118CA97D8002D6322 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
|
||||||
2231BB5318CA97D8002D6322 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
|
2231BB5318CA97D8002D6322 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
|
||||||
2231BB5F18CA97DC002D6322 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
|
2231BB5F18CA97DC002D6322 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
|
||||||
|
|
@ -287,6 +336,34 @@
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
2215A9AB192A47BB00E9E2CE /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 3104AFF1156D37A0000A585A;
|
||||||
|
remoteInfo = all;
|
||||||
|
};
|
||||||
|
2215A9B3192A47C500E9E2CE /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 3104AFF1156D37A0000A585A;
|
||||||
|
remoteInfo = all;
|
||||||
|
};
|
||||||
|
2215A9BB192A47CE00E9E2CE /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 3104AFF1156D37A0000A585A;
|
||||||
|
remoteInfo = all;
|
||||||
|
};
|
||||||
|
2215A9C3192A47D500E9E2CE /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 3104AFF1156D37A0000A585A;
|
||||||
|
remoteInfo = all;
|
||||||
|
};
|
||||||
2231BB4E18CA97D8002D6322 /* PBXContainerItemProxy */ = {
|
2231BB4E18CA97D8002D6322 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
|
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
|
||||||
|
|
@ -3321,6 +3398,10 @@
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
3104AFF1156D37A0000A585A /* all */,
|
3104AFF1156D37A0000A585A /* all */,
|
||||||
|
2215A9B9192A47CE00E9E2CE /* testall */,
|
||||||
|
2215A9B1192A47C500E9E2CE /* testansi */,
|
||||||
|
2215A9A9192A47BB00E9E2CE /* testci */,
|
||||||
|
2215A9C1192A47D500E9E2CE /* testpoll */,
|
||||||
22CDE8EF16E9E97D00366D0A /* testrun */,
|
22CDE8EF16E9E97D00366D0A /* testrun */,
|
||||||
31EEABFA156AAF9D00714D05 /* mps */,
|
31EEABFA156AAF9D00714D05 /* mps */,
|
||||||
3114A632156E94DB001E0AA3 /* abqtest */,
|
3114A632156E94DB001E0AA3 /* abqtest */,
|
||||||
|
|
@ -3374,6 +3455,62 @@
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
2215A9AC192A47BB00E9E2CE /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
2215A9B4192A47C500E9E2CE /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
2215A9BC192A47CE00E9E2CE /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
2215A9C4192A47D500E9E2CE /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
22CDE8F416E9E9D400366D0A /* ShellScript */ = {
|
22CDE8F416E9E9D400366D0A /* ShellScript */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|
@ -3385,7 +3522,7 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\"\n";
|
shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
@ -3801,8 +3938,9 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
31D60048156D3ECF00337B26 /* testlib.c in Sources */,
|
2215A9C9192A495F00E9E2CE /* pooln.c in Sources */,
|
||||||
31D6004B156D3EE600337B26 /* poolncv.c in Sources */,
|
31D6004B156D3EE600337B26 /* poolncv.c in Sources */,
|
||||||
|
31D60048156D3ECF00337B26 /* testlib.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
@ -3886,6 +4024,26 @@
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
|
2215A9AA192A47BB00E9E2CE /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 3104AFF1156D37A0000A585A /* all */;
|
||||||
|
targetProxy = 2215A9AB192A47BB00E9E2CE /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
2215A9B2192A47C500E9E2CE /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 3104AFF1156D37A0000A585A /* all */;
|
||||||
|
targetProxy = 2215A9B3192A47C500E9E2CE /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
2215A9BA192A47CE00E9E2CE /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 3104AFF1156D37A0000A585A /* all */;
|
||||||
|
targetProxy = 2215A9BB192A47CE00E9E2CE /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
2215A9C2192A47D500E9E2CE /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 3104AFF1156D37A0000A585A /* all */;
|
||||||
|
targetProxy = 2215A9C3192A47D500E9E2CE /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
2231BB4D18CA97D8002D6322 /* PBXTargetDependency */ = {
|
2231BB4D18CA97D8002D6322 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = 31EEABFA156AAF9D00714D05 /* mps */;
|
target = 31EEABFA156AAF9D00714D05 /* mps */;
|
||||||
|
|
@ -4329,6 +4487,90 @@
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
|
2215A9AE192A47BB00E9E2CE /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testrun copy";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
2215A9AF192A47BB00E9E2CE /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testrun copy";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
2215A9B0192A47BB00E9E2CE /* RASH */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testrun copy";
|
||||||
|
};
|
||||||
|
name = RASH;
|
||||||
|
};
|
||||||
|
2215A9B6192A47C500E9E2CE /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testci copy";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
2215A9B7192A47C500E9E2CE /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testci copy";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
2215A9B8192A47C500E9E2CE /* RASH */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testci copy";
|
||||||
|
};
|
||||||
|
name = RASH;
|
||||||
|
};
|
||||||
|
2215A9BE192A47CE00E9E2CE /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testansi copy";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
2215A9BF192A47CE00E9E2CE /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testansi copy";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
2215A9C0192A47CE00E9E2CE /* RASH */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testansi copy";
|
||||||
|
};
|
||||||
|
name = RASH;
|
||||||
|
};
|
||||||
|
2215A9C6192A47D500E9E2CE /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testall copy";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
2215A9C7192A47D500E9E2CE /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testall copy";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
2215A9C8192A47D500E9E2CE /* RASH */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_NAME = "testall copy";
|
||||||
|
};
|
||||||
|
name = RASH;
|
||||||
|
};
|
||||||
2231BB5618CA97D8002D6322 /* Debug */ = {
|
2231BB5618CA97D8002D6322 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
|
@ -5542,6 +5784,46 @@
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
2215A9AD192A47BB00E9E2CE /* Build configuration list for PBXAggregateTarget "testci" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
2215A9AE192A47BB00E9E2CE /* Debug */,
|
||||||
|
2215A9AF192A47BB00E9E2CE /* Release */,
|
||||||
|
2215A9B0192A47BB00E9E2CE /* RASH */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
2215A9B5192A47C500E9E2CE /* Build configuration list for PBXAggregateTarget "testansi" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
2215A9B6192A47C500E9E2CE /* Debug */,
|
||||||
|
2215A9B7192A47C500E9E2CE /* Release */,
|
||||||
|
2215A9B8192A47C500E9E2CE /* RASH */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
2215A9BD192A47CE00E9E2CE /* Build configuration list for PBXAggregateTarget "testall" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
2215A9BE192A47CE00E9E2CE /* Debug */,
|
||||||
|
2215A9BF192A47CE00E9E2CE /* Release */,
|
||||||
|
2215A9C0192A47CE00E9E2CE /* RASH */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
2215A9C5192A47D500E9E2CE /* Build configuration list for PBXAggregateTarget "testpoll" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
2215A9C6192A47D500E9E2CE /* Debug */,
|
||||||
|
2215A9C7192A47D500E9E2CE /* Release */,
|
||||||
|
2215A9C8192A47D500E9E2CE /* RASH */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
2231BB5518CA97D8002D6322 /* Build configuration list for PBXNativeTarget "locbwcss" */ = {
|
2231BB5518CA97D8002D6322 /* Build configuration list for PBXNativeTarget "locbwcss" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
|
||||||
|
|
@ -454,7 +454,6 @@ typedef struct AMCStruct { /* <design/poolamc/#struct> */
|
||||||
RankSet rankSet; /* rankSet for entire pool */
|
RankSet rankSet; /* rankSet for entire pool */
|
||||||
RingStruct genRing; /* ring of generations */
|
RingStruct genRing; /* ring of generations */
|
||||||
Bool gensBooted; /* used during boot (init) */
|
Bool gensBooted; /* used during boot (init) */
|
||||||
Chain chain; /* chain used by this pool */
|
|
||||||
size_t gens; /* number of generations */
|
size_t gens; /* number of generations */
|
||||||
amcGen *gen; /* (pointer to) array of generations */
|
amcGen *gen; /* (pointer to) array of generations */
|
||||||
amcGen nursery; /* the default mutator generation */
|
amcGen nursery; /* the default mutator generation */
|
||||||
|
|
@ -642,12 +641,12 @@ DEFINE_BUFFER_CLASS(amcBufClass, class)
|
||||||
|
|
||||||
/* amcGenCreate -- create a generation */
|
/* amcGenCreate -- create a generation */
|
||||||
|
|
||||||
static Res amcGenCreate(amcGen *genReturn, AMC amc, Serial genNr)
|
static Res amcGenCreate(amcGen *genReturn, AMC amc, GenDesc gen)
|
||||||
{
|
{
|
||||||
Arena arena;
|
Arena arena;
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
Pool pool;
|
Pool pool;
|
||||||
amcGen gen;
|
amcGen amcgen;
|
||||||
Res res;
|
Res res;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
|
@ -657,25 +656,25 @@ static Res amcGenCreate(amcGen *genReturn, AMC amc, Serial genNr)
|
||||||
res = ControlAlloc(&p, arena, sizeof(amcGenStruct), FALSE);
|
res = ControlAlloc(&p, arena, sizeof(amcGenStruct), FALSE);
|
||||||
if(res != ResOK)
|
if(res != ResOK)
|
||||||
goto failControlAlloc;
|
goto failControlAlloc;
|
||||||
gen = (amcGen)p;
|
amcgen = (amcGen)p;
|
||||||
|
|
||||||
res = BufferCreate(&buffer, EnsureamcBufClass(), pool, FALSE, argsNone);
|
res = BufferCreate(&buffer, EnsureamcBufClass(), pool, FALSE, argsNone);
|
||||||
if(res != ResOK)
|
if(res != ResOK)
|
||||||
goto failBufferCreate;
|
goto failBufferCreate;
|
||||||
|
|
||||||
res = PoolGenInit(&gen->pgen, amc->chain, genNr, pool);
|
res = PoolGenInit(&amcgen->pgen, gen, pool);
|
||||||
if(res != ResOK)
|
if(res != ResOK)
|
||||||
goto failGenInit;
|
goto failGenInit;
|
||||||
RingInit(&gen->amcRing);
|
RingInit(&amcgen->amcRing);
|
||||||
gen->segs = 0;
|
amcgen->segs = 0;
|
||||||
gen->forward = buffer;
|
amcgen->forward = buffer;
|
||||||
gen->sig = amcGenSig;
|
amcgen->sig = amcGenSig;
|
||||||
|
|
||||||
AVERT(amcGen, gen);
|
AVERT(amcGen, amcgen);
|
||||||
|
|
||||||
RingAppend(&amc->genRing, &gen->amcRing);
|
RingAppend(&amc->genRing, &amcgen->amcRing);
|
||||||
EVENT2(AMCGenCreate, amc, gen);
|
EVENT2(AMCGenCreate, amc, amcgen);
|
||||||
*genReturn = gen;
|
*genReturn = amcgen;
|
||||||
return ResOK;
|
return ResOK;
|
||||||
|
|
||||||
failGenInit:
|
failGenInit:
|
||||||
|
|
@ -718,8 +717,7 @@ static Res amcGenDescribe(amcGen gen, mps_lib_FILE *stream)
|
||||||
return ResFAIL;
|
return ResFAIL;
|
||||||
|
|
||||||
res = WriteF(stream,
|
res = WriteF(stream,
|
||||||
" amcGen $P ($U) {\n",
|
" amcGen $P {\n", (WriteFP)gen,
|
||||||
(WriteFP)gen, (WriteFU)amcGenNr(gen),
|
|
||||||
" buffer $P\n", gen->forward,
|
" buffer $P\n", gen->forward,
|
||||||
" segs $U, totalSize $U, newSize $U\n",
|
" segs $U, totalSize $U, newSize $U\n",
|
||||||
(WriteFU)gen->segs,
|
(WriteFU)gen->segs,
|
||||||
|
|
@ -801,6 +799,7 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
|
||||||
size_t genArraySize;
|
size_t genArraySize;
|
||||||
size_t genCount;
|
size_t genCount;
|
||||||
Bool interior = AMC_INTERIOR_DEFAULT;
|
Bool interior = AMC_INTERIOR_DEFAULT;
|
||||||
|
Chain chain;
|
||||||
ArgStruct arg;
|
ArgStruct arg;
|
||||||
|
|
||||||
/* Suppress a warning about this structure not being used when there
|
/* Suppress a warning about this structure not being used when there
|
||||||
|
|
@ -821,14 +820,14 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
|
||||||
ArgRequire(&arg, args, MPS_KEY_FORMAT);
|
ArgRequire(&arg, args, MPS_KEY_FORMAT);
|
||||||
pool->format = arg.val.format;
|
pool->format = arg.val.format;
|
||||||
if (ArgPick(&arg, args, MPS_KEY_CHAIN))
|
if (ArgPick(&arg, args, MPS_KEY_CHAIN))
|
||||||
amc->chain = arg.val.chain;
|
chain = arg.val.chain;
|
||||||
else
|
else
|
||||||
amc->chain = ArenaGlobals(arena)->defaultChain;
|
chain = ArenaGlobals(arena)->defaultChain;
|
||||||
if (ArgPick(&arg, args, MPS_KEY_INTERIOR))
|
if (ArgPick(&arg, args, MPS_KEY_INTERIOR))
|
||||||
interior = arg.val.b;
|
interior = arg.val.b;
|
||||||
|
|
||||||
AVERT(Format, pool->format);
|
AVERT(Format, pool->format);
|
||||||
AVERT(Chain, amc->chain);
|
AVERT(Chain, chain);
|
||||||
pool->alignment = pool->format->alignment;
|
pool->alignment = pool->format->alignment;
|
||||||
amc->rankSet = rankSet;
|
amc->rankSet = rankSet;
|
||||||
|
|
||||||
|
|
@ -864,7 +863,7 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
|
||||||
AVERT(AMC, amc);
|
AVERT(AMC, amc);
|
||||||
|
|
||||||
/* Init generations. */
|
/* Init generations. */
|
||||||
genCount = ChainGens(amc->chain);
|
genCount = ChainGens(chain);
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
|
@ -874,11 +873,10 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
|
||||||
if(res != ResOK)
|
if(res != ResOK)
|
||||||
goto failGensAlloc;
|
goto failGensAlloc;
|
||||||
amc->gen = p;
|
amc->gen = p;
|
||||||
for(i = 0; i < genCount + 1; ++i) {
|
for (i = 0; i <= genCount; ++i) {
|
||||||
res = amcGenCreate(&amc->gen[i], amc, (Serial)i);
|
res = amcGenCreate(&amc->gen[i], amc, ChainGen(chain, i));
|
||||||
if(res != ResOK) {
|
if (res != ResOK)
|
||||||
goto failGenAlloc;
|
goto failGenAlloc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Set up forwarding buffers. */
|
/* Set up forwarding buffers. */
|
||||||
for(i = 0; i < genCount; ++i) {
|
for(i = 0; i < genCount; ++i) {
|
||||||
|
|
@ -1020,8 +1018,8 @@ static Res AMCBufferFill(Addr *baseReturn, Addr *limitReturn,
|
||||||
alignedSize = SizeAlignUp(size, ArenaAlign(arena));
|
alignedSize = SizeAlignUp(size, ArenaAlign(arena));
|
||||||
MPS_ARGS_BEGIN(args) {
|
MPS_ARGS_BEGIN(args) {
|
||||||
MPS_ARGS_ADD_FIELD(args, amcKeySegGen, p, gen);
|
MPS_ARGS_ADD_FIELD(args, amcKeySegGen, p, gen);
|
||||||
res = ChainAlloc(&seg, amc->chain, PoolGenNr(pgen), amcSegClassGet(),
|
res = PoolGenAlloc(&seg, pgen, amcSegClassGet(), alignedSize,
|
||||||
alignedSize, pool, withReservoirPermit, args);
|
withReservoirPermit, args);
|
||||||
} MPS_ARGS_END(args);
|
} MPS_ARGS_END(args);
|
||||||
if(res != ResOK)
|
if(res != ResOK)
|
||||||
return res;
|
return res;
|
||||||
|
|
|
||||||
|
|
@ -691,14 +691,14 @@ static Res AMSSegCreate(Seg *segReturn, Pool pool, Size size,
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
goto failSize;
|
goto failSize;
|
||||||
|
|
||||||
res = ChainAlloc(&seg, ams->chain, ams->pgen.nr, (*ams->segClass)(),
|
res = PoolGenAlloc(&seg, &ams->pgen, (*ams->segClass)(), prefSize,
|
||||||
prefSize, pool, withReservoirPermit, argsNone);
|
withReservoirPermit, argsNone);
|
||||||
if (res != ResOK) { /* try to allocate one that's just large enough */
|
if (res != ResOK) { /* try to allocate one that's just large enough */
|
||||||
Size minSize = SizeAlignUp(size, ArenaAlign(arena));
|
Size minSize = SizeAlignUp(size, ArenaAlign(arena));
|
||||||
if (minSize == prefSize)
|
if (minSize == prefSize)
|
||||||
goto failSeg;
|
goto failSeg;
|
||||||
res = ChainAlloc(&seg, ams->chain, ams->pgen.nr, (*ams->segClass)(),
|
res = PoolGenAlloc(&seg, &ams->pgen, (*ams->segClass)(), prefSize,
|
||||||
prefSize, pool, withReservoirPermit, argsNone);
|
withReservoirPermit, argsNone);
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
goto failSeg;
|
goto failSeg;
|
||||||
}
|
}
|
||||||
|
|
@ -822,8 +822,7 @@ Res AMSInitInternal(AMS ams, Format format, Chain chain, unsigned gen,
|
||||||
pool->alignment = pool->format->alignment;
|
pool->alignment = pool->format->alignment;
|
||||||
ams->grainShift = SizeLog2(PoolAlignment(pool));
|
ams->grainShift = SizeLog2(PoolAlignment(pool));
|
||||||
|
|
||||||
ams->chain = chain;
|
res = PoolGenInit(&ams->pgen, ChainGen(chain, gen), pool);
|
||||||
res = PoolGenInit(&ams->pgen, ams->chain, gen, pool);
|
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
@ -1666,8 +1665,6 @@ static Res AMSDescribe(Pool pool, mps_lib_FILE *stream)
|
||||||
" size $W\n",
|
" size $W\n",
|
||||||
(WriteFW)ams->size,
|
(WriteFW)ams->size,
|
||||||
" grain shift $U\n", (WriteFU)ams->grainShift,
|
" grain shift $U\n", (WriteFU)ams->grainShift,
|
||||||
" chain $P\n",
|
|
||||||
(WriteFP)ams->chain,
|
|
||||||
NULL);
|
NULL);
|
||||||
if (res != ResOK) return res;
|
if (res != ResOK) return res;
|
||||||
|
|
||||||
|
|
@ -1761,7 +1758,6 @@ Bool AMSCheck(AMS ams)
|
||||||
CHECKL(IsSubclassPoly(AMS2Pool(ams)->class, AMSPoolClassGet()));
|
CHECKL(IsSubclassPoly(AMS2Pool(ams)->class, AMSPoolClassGet()));
|
||||||
CHECKL(PoolAlignment(AMS2Pool(ams)) == ((Size)1 << ams->grainShift));
|
CHECKL(PoolAlignment(AMS2Pool(ams)) == ((Size)1 << ams->grainShift));
|
||||||
CHECKL(PoolAlignment(AMS2Pool(ams)) == AMS2Pool(ams)->format->alignment);
|
CHECKL(PoolAlignment(AMS2Pool(ams)) == AMS2Pool(ams)->format->alignment);
|
||||||
CHECKD(Chain, ams->chain);
|
|
||||||
CHECKD(PoolGen, &ams->pgen);
|
CHECKD(PoolGen, &ams->pgen);
|
||||||
CHECKL(SizeIsAligned(ams->size, ArenaAlign(PoolArena(AMS2Pool(ams)))));
|
CHECKL(SizeIsAligned(ams->size, ArenaAlign(PoolArena(AMS2Pool(ams)))));
|
||||||
CHECKL(FUNCHECK(ams->segSize));
|
CHECKL(FUNCHECK(ams->segSize));
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ typedef Res (*AMSSegSizePolicyFunction)(Size *sizeReturn,
|
||||||
typedef struct AMSStruct {
|
typedef struct AMSStruct {
|
||||||
PoolStruct poolStruct; /* generic pool structure */
|
PoolStruct poolStruct; /* generic pool structure */
|
||||||
Shift grainShift; /* log2 of grain size */
|
Shift grainShift; /* log2 of grain size */
|
||||||
Chain chain; /* chain used by this pool */
|
|
||||||
PoolGenStruct pgen; /* generation representing the pool */
|
PoolGenStruct pgen; /* generation representing the pool */
|
||||||
Size size; /* total segment size of the pool */
|
Size size; /* total segment size of the pool */
|
||||||
AMSSegSizePolicyFunction segSize; /* SegSize policy */
|
AMSSegSizePolicyFunction segSize; /* SegSize policy */
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@ typedef Addr (*FindDependentMethod)(Addr object);
|
||||||
typedef struct AWLStruct {
|
typedef struct AWLStruct {
|
||||||
PoolStruct poolStruct;
|
PoolStruct poolStruct;
|
||||||
Shift alignShift;
|
Shift alignShift;
|
||||||
Chain chain; /* dummy chain */
|
|
||||||
PoolGenStruct pgen; /* generation representing the pool */
|
PoolGenStruct pgen; /* generation representing the pool */
|
||||||
Size size; /* allocated size in bytes */
|
Size size; /* allocated size in bytes */
|
||||||
Count succAccesses; /* number of successive single accesses */
|
Count succAccesses; /* number of successive single accesses */
|
||||||
|
|
@ -473,8 +472,8 @@ static Res AWLSegCreate(AWLSeg *awlsegReturn,
|
||||||
return ResMEMORY;
|
return ResMEMORY;
|
||||||
MPS_ARGS_BEGIN(args) {
|
MPS_ARGS_BEGIN(args) {
|
||||||
MPS_ARGS_ADD_FIELD(args, awlKeySegRankSet, u, rankSet);
|
MPS_ARGS_ADD_FIELD(args, awlKeySegRankSet, u, rankSet);
|
||||||
res = ChainAlloc(&seg, awl->chain, awl->pgen.nr, AWLSegClassGet(),
|
res = PoolGenAlloc(&seg, &awl->pgen, AWLSegClassGet(), size,
|
||||||
size, pool, reservoirPermit, args);
|
reservoirPermit, args);
|
||||||
} MPS_ARGS_END(args);
|
} MPS_ARGS_END(args);
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -570,9 +569,8 @@ static Res AWLInit(Pool pool, ArgList args)
|
||||||
|
|
||||||
AVERT(Chain, chain);
|
AVERT(Chain, chain);
|
||||||
AVER(gen <= ChainGens(chain));
|
AVER(gen <= ChainGens(chain));
|
||||||
awl->chain = chain;
|
|
||||||
|
|
||||||
res = PoolGenInit(&awl->pgen, chain, gen, pool);
|
res = PoolGenInit(&awl->pgen, ChainGen(chain, gen), pool);
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
goto failGenInit;
|
goto failGenInit;
|
||||||
|
|
||||||
|
|
@ -1307,7 +1305,6 @@ static Bool AWLCheck(AWL awl)
|
||||||
CHECKD(Pool, &awl->poolStruct);
|
CHECKD(Pool, &awl->poolStruct);
|
||||||
CHECKL(awl->poolStruct.class == AWLPoolClassGet());
|
CHECKL(awl->poolStruct.class == AWLPoolClassGet());
|
||||||
CHECKL((Align)1 << awl->alignShift == awl->poolStruct.alignment);
|
CHECKL((Align)1 << awl->alignShift == awl->poolStruct.alignment);
|
||||||
CHECKD(Chain, awl->chain);
|
|
||||||
/* Nothing to check about succAccesses. */
|
/* Nothing to check about succAccesses. */
|
||||||
CHECKL(FUNCHECK(awl->findDependent));
|
CHECKL(FUNCHECK(awl->findDependent));
|
||||||
/* Don't bother to check stats. */
|
/* Don't bother to check stats. */
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ typedef struct LOStruct *LO;
|
||||||
typedef struct LOStruct {
|
typedef struct LOStruct {
|
||||||
PoolStruct poolStruct; /* generic pool structure */
|
PoolStruct poolStruct; /* generic pool structure */
|
||||||
Shift alignShift; /* log_2 of pool alignment */
|
Shift alignShift; /* log_2 of pool alignment */
|
||||||
Chain chain; /* chain used by this pool */
|
|
||||||
PoolGenStruct pgen; /* generation representing the pool */
|
PoolGenStruct pgen; /* generation representing the pool */
|
||||||
Sig sig;
|
Sig sig;
|
||||||
} LOStruct;
|
} LOStruct;
|
||||||
|
|
@ -293,9 +292,9 @@ static Res loSegCreate(LOSeg *loSegReturn, Pool pool, Size size,
|
||||||
lo = PoolPoolLO(pool);
|
lo = PoolPoolLO(pool);
|
||||||
AVERT(LO, lo);
|
AVERT(LO, lo);
|
||||||
|
|
||||||
res = ChainAlloc(&seg, lo->chain, lo->pgen.nr, EnsureLOSegClass(),
|
res = PoolGenAlloc(&seg, &lo->pgen, EnsureLOSegClass(),
|
||||||
SizeAlignUp(size, ArenaAlign(PoolArena(pool))),
|
SizeAlignUp(size, ArenaAlign(PoolArena(pool))),
|
||||||
pool, withReservoirPermit, argsNone);
|
withReservoirPermit, argsNone);
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
@ -475,9 +474,11 @@ static Res LOInit(Pool pool, ArgList args)
|
||||||
Arena arena;
|
Arena arena;
|
||||||
Res res;
|
Res res;
|
||||||
ArgStruct arg;
|
ArgStruct arg;
|
||||||
|
Chain chain;
|
||||||
unsigned gen = LO_GEN_DEFAULT;
|
unsigned gen = LO_GEN_DEFAULT;
|
||||||
|
|
||||||
AVERT(Pool, pool);
|
AVERT(Pool, pool);
|
||||||
|
AVERT(ArgList, args);
|
||||||
|
|
||||||
arena = PoolArena(pool);
|
arena = PoolArena(pool);
|
||||||
|
|
||||||
|
|
@ -486,22 +487,22 @@ static Res LOInit(Pool pool, ArgList args)
|
||||||
ArgRequire(&arg, args, MPS_KEY_FORMAT);
|
ArgRequire(&arg, args, MPS_KEY_FORMAT);
|
||||||
pool->format = arg.val.format;
|
pool->format = arg.val.format;
|
||||||
if (ArgPick(&arg, args, MPS_KEY_CHAIN))
|
if (ArgPick(&arg, args, MPS_KEY_CHAIN))
|
||||||
lo->chain = arg.val.chain;
|
chain = arg.val.chain;
|
||||||
else {
|
else {
|
||||||
lo->chain = ArenaGlobals(arena)->defaultChain;
|
chain = ArenaGlobals(arena)->defaultChain;
|
||||||
gen = 1; /* avoid the nursery of the default chain by default */
|
gen = 1; /* avoid the nursery of the default chain by default */
|
||||||
}
|
}
|
||||||
if (ArgPick(&arg, args, MPS_KEY_GEN))
|
if (ArgPick(&arg, args, MPS_KEY_GEN))
|
||||||
gen = arg.val.u;
|
gen = arg.val.u;
|
||||||
|
|
||||||
AVERT(Format, pool->format);
|
AVERT(Format, pool->format);
|
||||||
AVERT(Chain, lo->chain);
|
AVERT(Chain, chain);
|
||||||
AVER(gen <= ChainGens(lo->chain));
|
AVER(gen <= ChainGens(chain));
|
||||||
|
|
||||||
pool->alignment = pool->format->alignment;
|
pool->alignment = pool->format->alignment;
|
||||||
lo->alignShift = SizeLog2((Size)PoolAlignment(pool));
|
lo->alignShift = SizeLog2((Size)PoolAlignment(pool));
|
||||||
|
|
||||||
res = PoolGenInit(&lo->pgen, lo->chain, gen, pool);
|
res = PoolGenInit(&lo->pgen, ChainGen(chain, gen), pool);
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
goto failGenInit;
|
goto failGenInit;
|
||||||
|
|
||||||
|
|
@ -815,7 +816,6 @@ static Bool LOCheck(LO lo)
|
||||||
CHECKL(lo->poolStruct.class == EnsureLOPoolClass());
|
CHECKL(lo->poolStruct.class == EnsureLOPoolClass());
|
||||||
CHECKL(ShiftCheck(lo->alignShift));
|
CHECKL(ShiftCheck(lo->alignShift));
|
||||||
CHECKL((Align)1 << lo->alignShift == PoolAlignment(&lo->poolStruct));
|
CHECKL((Align)1 << lo->alignShift == PoolAlignment(&lo->poolStruct));
|
||||||
CHECKD(Chain, lo->chain);
|
|
||||||
CHECKD(PoolGen, &lo->pgen);
|
CHECKD(PoolGen, &lo->pgen);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,8 @@ void MFSFinishTracts(Pool pool, MFSTractVisitor visitor,
|
||||||
static void MFSTractFreeVisitor(Pool pool, Addr base, Size size,
|
static void MFSTractFreeVisitor(Pool pool, Addr base, Size size,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
|
AVER(closureP == UNUSED_POINTER);
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureP);
|
UNUSED(closureP);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
ArenaFree(base, size, pool);
|
ArenaFree(base, size, pool);
|
||||||
|
|
@ -165,7 +167,7 @@ static void MFSFinish(Pool pool)
|
||||||
mfs = PoolPoolMFS(pool);
|
mfs = PoolPoolMFS(pool);
|
||||||
AVERT(MFS, mfs);
|
AVERT(MFS, mfs);
|
||||||
|
|
||||||
MFSFinishTracts(pool, MFSTractFreeVisitor, NULL, 0);
|
MFSFinishTracts(pool, MFSTractFreeVisitor, UNUSED_POINTER, UNUSED_SIZE);
|
||||||
|
|
||||||
mfs->sig = SigInvalid;
|
mfs->sig = SigInvalid;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,12 +152,6 @@ DEFINE_POOL_CLASS(MVTPoolClass, this)
|
||||||
|
|
||||||
/* Macros */
|
/* Macros */
|
||||||
|
|
||||||
|
|
||||||
/* .trans.something: the C language sucks */
|
|
||||||
#define unless(cond) if (!(cond))
|
|
||||||
#define when(cond) if (cond)
|
|
||||||
|
|
||||||
|
|
||||||
#define Pool2MVT(pool) PARENT(MVTStruct, poolStruct, pool)
|
#define Pool2MVT(pool) PARENT(MVTStruct, poolStruct, pool)
|
||||||
#define MVT2Pool(mvt) (&(mvt)->poolStruct)
|
#define MVT2Pool(mvt) (&(mvt)->poolStruct)
|
||||||
|
|
||||||
|
|
@ -760,6 +754,7 @@ static Bool MVTDeleteOverlapping(Bool *deleteReturn, void *element,
|
||||||
AVER(deleteReturn != NULL);
|
AVER(deleteReturn != NULL);
|
||||||
AVER(element != NULL);
|
AVER(element != NULL);
|
||||||
AVER(closureP != NULL);
|
AVER(closureP != NULL);
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
|
|
||||||
oldRange = element;
|
oldRange = element;
|
||||||
|
|
@ -826,7 +821,7 @@ static Res MVTInsert(MVT mvt, Addr base, Addr limit)
|
||||||
* with ranges on the ABQ, so ensure that the corresponding ranges
|
* with ranges on the ABQ, so ensure that the corresponding ranges
|
||||||
* are coalesced on the ABQ.
|
* are coalesced on the ABQ.
|
||||||
*/
|
*/
|
||||||
ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &newRange, 0);
|
ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &newRange, UNUSED_SIZE);
|
||||||
(void)MVTReserve(mvt, &newRange);
|
(void)MVTReserve(mvt, &newRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -855,7 +850,7 @@ static Res MVTDelete(MVT mvt, Addr base, Addr limit)
|
||||||
* might be on the ABQ, so ensure it is removed.
|
* might be on the ABQ, so ensure it is removed.
|
||||||
*/
|
*/
|
||||||
if (RangeSize(&rangeOld) >= mvt->reuseSize)
|
if (RangeSize(&rangeOld) >= mvt->reuseSize)
|
||||||
ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &rangeOld, 0);
|
ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &rangeOld, UNUSED_SIZE);
|
||||||
|
|
||||||
/* There might be fragments at the left or the right of the deleted
|
/* There might be fragments at the left or the right of the deleted
|
||||||
* range, and either might be big enough to go back on the ABQ.
|
* range, and either might be big enough to go back on the ABQ.
|
||||||
|
|
@ -1209,15 +1204,15 @@ static Bool MVTReturnSegs(MVT mvt, Range range, Arena arena)
|
||||||
* empty.
|
* empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Bool MVTRefillVisitor(Bool *deleteReturn, Land land, Range range,
|
static Bool MVTRefillVisitor(Land land, Range range,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
MVT mvt;
|
MVT mvt;
|
||||||
|
|
||||||
AVER(deleteReturn != NULL);
|
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
mvt = closureP;
|
mvt = closureP;
|
||||||
AVERT(MVT, mvt);
|
AVERT(MVT, mvt);
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
|
|
||||||
if (RangeSize(range) < mvt->reuseSize)
|
if (RangeSize(range) < mvt->reuseSize)
|
||||||
|
|
@ -1240,7 +1235,8 @@ static void MVTRefillABQIfEmpty(MVT mvt, Size size)
|
||||||
if (mvt->abqOverflow && ABQIsEmpty(MVTABQ(mvt))) {
|
if (mvt->abqOverflow && ABQIsEmpty(MVTABQ(mvt))) {
|
||||||
mvt->abqOverflow = FALSE;
|
mvt->abqOverflow = FALSE;
|
||||||
METER_ACC(mvt->refills, size);
|
METER_ACC(mvt->refills, size);
|
||||||
LandIterate(MVTFailover(mvt), &MVTRefillVisitor, mvt, 0);
|
/* The iteration stops if the ABQ overflows, so may finish or not. */
|
||||||
|
(void)LandIterate(MVTFailover(mvt), MVTRefillVisitor, mvt, UNUSED_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1250,7 +1246,6 @@ static void MVTRefillABQIfEmpty(MVT mvt, Size size)
|
||||||
typedef struct MVTContigencyClosureStruct
|
typedef struct MVTContigencyClosureStruct
|
||||||
{
|
{
|
||||||
MVT mvt;
|
MVT mvt;
|
||||||
Bool found;
|
|
||||||
RangeStruct range;
|
RangeStruct range;
|
||||||
Arena arena;
|
Arena arena;
|
||||||
Size min;
|
Size min;
|
||||||
|
|
@ -1259,7 +1254,7 @@ typedef struct MVTContigencyClosureStruct
|
||||||
Count hardSteps;
|
Count hardSteps;
|
||||||
} MVTContigencyClosureStruct, *MVTContigencyClosure;
|
} MVTContigencyClosureStruct, *MVTContigencyClosure;
|
||||||
|
|
||||||
static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range,
|
static Bool MVTContingencyVisitor(Land land, Range range,
|
||||||
void *closureP, Size closureS)
|
void *closureP, Size closureS)
|
||||||
{
|
{
|
||||||
MVT mvt;
|
MVT mvt;
|
||||||
|
|
@ -1267,13 +1262,13 @@ static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range,
|
||||||
Addr base, limit;
|
Addr base, limit;
|
||||||
MVTContigencyClosure cl;
|
MVTContigencyClosure cl;
|
||||||
|
|
||||||
AVER(deleteReturn != NULL);
|
|
||||||
AVERT(Land, land);
|
AVERT(Land, land);
|
||||||
AVERT(Range, range);
|
AVERT(Range, range);
|
||||||
AVER(closureP != NULL);
|
AVER(closureP != NULL);
|
||||||
cl = closureP;
|
cl = closureP;
|
||||||
mvt = cl->mvt;
|
mvt = cl->mvt;
|
||||||
AVERT(MVT, mvt);
|
AVERT(MVT, mvt);
|
||||||
|
AVER(closureS == UNUSED_SIZE);
|
||||||
UNUSED(closureS);
|
UNUSED(closureS);
|
||||||
|
|
||||||
base = RangeBase(range);
|
base = RangeBase(range);
|
||||||
|
|
@ -1287,7 +1282,6 @@ static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range,
|
||||||
/* verify that min will fit when seg-aligned */
|
/* verify that min will fit when seg-aligned */
|
||||||
if (size >= 2 * cl->min) {
|
if (size >= 2 * cl->min) {
|
||||||
RangeInit(&cl->range, base, limit);
|
RangeInit(&cl->range, base, limit);
|
||||||
cl->found = TRUE;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1295,7 +1289,6 @@ static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range,
|
||||||
cl->hardSteps++;
|
cl->hardSteps++;
|
||||||
if (MVTCheckFit(base, limit, cl->min, cl->arena)) {
|
if (MVTCheckFit(base, limit, cl->min, cl->arena)) {
|
||||||
RangeInit(&cl->range, base, limit);
|
RangeInit(&cl->range, base, limit);
|
||||||
cl->found = TRUE;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1309,14 +1302,12 @@ static Bool MVTContingencySearch(Addr *baseReturn, Addr *limitReturn,
|
||||||
MVTContigencyClosureStruct cls;
|
MVTContigencyClosureStruct cls;
|
||||||
|
|
||||||
cls.mvt = mvt;
|
cls.mvt = mvt;
|
||||||
cls.found = FALSE;
|
|
||||||
cls.arena = PoolArena(MVT2Pool(mvt));
|
cls.arena = PoolArena(MVT2Pool(mvt));
|
||||||
cls.min = min;
|
cls.min = min;
|
||||||
cls.steps = 0;
|
cls.steps = 0;
|
||||||
cls.hardSteps = 0;
|
cls.hardSteps = 0;
|
||||||
|
|
||||||
LandIterate(MVTFailover(mvt), MVTContingencyVisitor, (void *)&cls, 0);
|
if (LandIterate(MVTFailover(mvt), MVTContingencyVisitor, &cls, UNUSED_SIZE))
|
||||||
if (!cls.found)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
AVER(RangeSize(&cls.range) >= min);
|
AVER(RangeSize(&cls.range) >= min);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ extern PoolClass AMSTPoolClassGet(void);
|
||||||
|
|
||||||
typedef struct AMSTStruct {
|
typedef struct AMSTStruct {
|
||||||
AMSStruct amsStruct; /* generic AMS structure */
|
AMSStruct amsStruct; /* generic AMS structure */
|
||||||
Chain chain; /* chain to use */
|
|
||||||
Bool failSegs; /* fail seg splits & merges when true */
|
Bool failSegs; /* fail seg splits & merges when true */
|
||||||
Count splits; /* count of successful segment splits */
|
Count splits; /* count of successful segment splits */
|
||||||
Count merges; /* count of successful segment merges */
|
Count merges; /* count of successful segment merges */
|
||||||
|
|
@ -335,25 +334,30 @@ static Res AMSTInit(Pool pool, ArgList args)
|
||||||
Format format;
|
Format format;
|
||||||
Chain chain;
|
Chain chain;
|
||||||
Res res;
|
Res res;
|
||||||
static GenParamStruct genParam = { 1024, 0.2 };
|
unsigned gen = AMS_GEN_DEFAULT;
|
||||||
ArgStruct arg;
|
ArgStruct arg;
|
||||||
|
|
||||||
AVERT(Pool, pool);
|
AVERT(Pool, pool);
|
||||||
|
AVERT(ArgList, args);
|
||||||
|
|
||||||
|
if (ArgPick(&arg, args, MPS_KEY_CHAIN))
|
||||||
|
chain = arg.val.chain;
|
||||||
|
else {
|
||||||
|
chain = ArenaGlobals(PoolArena(pool))->defaultChain;
|
||||||
|
gen = 1; /* avoid the nursery of the default chain by default */
|
||||||
|
}
|
||||||
|
if (ArgPick(&arg, args, MPS_KEY_GEN))
|
||||||
|
gen = arg.val.u;
|
||||||
ArgRequire(&arg, args, MPS_KEY_FORMAT);
|
ArgRequire(&arg, args, MPS_KEY_FORMAT);
|
||||||
format = arg.val.format;
|
format = arg.val.format;
|
||||||
|
|
||||||
res = ChainCreate(&chain, pool->arena, 1, &genParam);
|
res = AMSInitInternal(Pool2AMS(pool), format, chain, gen, FALSE);
|
||||||
if (res != ResOK)
|
|
||||||
return res;
|
|
||||||
res = AMSInitInternal(Pool2AMS(pool), format, chain, 0, FALSE);
|
|
||||||
if (res != ResOK)
|
if (res != ResOK)
|
||||||
return res;
|
return res;
|
||||||
amst = Pool2AMST(pool);
|
amst = Pool2AMST(pool);
|
||||||
ams = Pool2AMS(pool);
|
ams = Pool2AMS(pool);
|
||||||
ams->segSize = AMSTSegSizePolicy;
|
ams->segSize = AMSTSegSizePolicy;
|
||||||
ams->segClass = AMSTSegClassGet;
|
ams->segClass = AMSTSegClassGet;
|
||||||
amst->chain = chain;
|
|
||||||
amst->failSegs = TRUE;
|
amst->failSegs = TRUE;
|
||||||
amst->splits = 0;
|
amst->splits = 0;
|
||||||
amst->merges = 0;
|
amst->merges = 0;
|
||||||
|
|
@ -388,7 +392,6 @@ static void AMSTFinish(Pool pool)
|
||||||
|
|
||||||
AMSFinish(pool);
|
AMSFinish(pool);
|
||||||
amst->sig = SigInvalid;
|
amst->sig = SigInvalid;
|
||||||
ChainDestroy(amst->chain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -758,14 +761,19 @@ static void *test(void *arg, size_t s)
|
||||||
mps_ap_t busy_ap;
|
mps_ap_t busy_ap;
|
||||||
mps_addr_t busy_init;
|
mps_addr_t busy_init;
|
||||||
const char *indent = " ";
|
const char *indent = " ";
|
||||||
|
mps_chain_t chain;
|
||||||
|
static mps_gen_param_s genParam = {1024, 0.2};
|
||||||
|
|
||||||
arena = (mps_arena_t)arg;
|
arena = (mps_arena_t)arg;
|
||||||
(void)s; /* unused */
|
(void)s; /* unused */
|
||||||
|
|
||||||
die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create");
|
die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create");
|
||||||
|
die(mps_chain_create(&chain, arena, 1, &genParam), "chain_create");
|
||||||
|
|
||||||
MPS_ARGS_BEGIN(args) {
|
MPS_ARGS_BEGIN(args) {
|
||||||
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format);
|
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format);
|
||||||
|
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain);
|
||||||
|
MPS_ARGS_ADD(args, MPS_KEY_GEN, 0);
|
||||||
die(mps_pool_create_k(&pool, arena, mps_class_amst(), args),
|
die(mps_pool_create_k(&pool, arena, mps_class_amst(), args),
|
||||||
"pool_create(amst)");
|
"pool_create(amst)");
|
||||||
} MPS_ARGS_END(args);
|
} MPS_ARGS_END(args);
|
||||||
|
|
@ -843,6 +851,7 @@ static void *test(void *arg, size_t s)
|
||||||
mps_root_destroy(exactRoot);
|
mps_root_destroy(exactRoot);
|
||||||
mps_root_destroy(ambigRoot);
|
mps_root_destroy(ambigRoot);
|
||||||
mps_pool_destroy(pool);
|
mps_pool_destroy(pool);
|
||||||
|
mps_chain_destroy(chain);
|
||||||
mps_fmt_destroy(format);
|
mps_fmt_destroy(format);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -1317,9 +1317,9 @@ void SplayNodeRefresh(SplayTree splay, Tree node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SplayNodeUpdate -- update the client property without splaying */
|
/* SplayNodeInit -- initialize client property without splaying */
|
||||||
|
|
||||||
void SplayNodeUpdate(SplayTree splay, Tree node)
|
void SplayNodeInit(SplayTree splay, Tree node)
|
||||||
{
|
{
|
||||||
AVERT(SplayTree, splay);
|
AVERT(SplayTree, splay);
|
||||||
AVERT(Tree, node);
|
AVERT(Tree, node);
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ extern Bool SplayFindLast(Tree *nodeReturn, SplayTree splay,
|
||||||
void *closureP, Size closureS);
|
void *closureP, Size closureS);
|
||||||
|
|
||||||
extern void SplayNodeRefresh(SplayTree splay, Tree node);
|
extern void SplayNodeRefresh(SplayTree splay, Tree node);
|
||||||
extern void SplayNodeUpdate(SplayTree splay, Tree node);
|
extern void SplayNodeInit(SplayTree splay, Tree node);
|
||||||
|
|
||||||
extern Res SplayTreeDescribe(SplayTree splay, mps_lib_FILE *stream,
|
extern Res SplayTreeDescribe(SplayTree splay, mps_lib_FILE *stream,
|
||||||
TreeDescribeMethod nodeDescribe);
|
TreeDescribeMethod nodeDescribe);
|
||||||
|
|
|
||||||
|
|
@ -1593,10 +1593,9 @@ static void TraceStartPoolGen(Chain chain, GenDesc desc, Bool top, Index i)
|
||||||
Ring n, nn;
|
Ring n, nn;
|
||||||
RING_FOR(n, &desc->locusRing, nn) {
|
RING_FOR(n, &desc->locusRing, nn) {
|
||||||
PoolGen gen = RING_ELT(PoolGen, genRing, n);
|
PoolGen gen = RING_ELT(PoolGen, genRing, n);
|
||||||
EVENT11(TraceStartPoolGen, chain, BOOLOF(top), i, desc,
|
EVENT10(TraceStartPoolGen, chain, BOOLOF(top), i, desc,
|
||||||
desc->capacity, desc->mortality, desc->zones,
|
desc->capacity, desc->mortality, desc->zones,
|
||||||
gen->pool, gen->nr, gen->totalSize,
|
gen->pool, gen->totalSize, gen->newSizeAtCreate);
|
||||||
gen->newSizeAtCreate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,8 @@ PFM = w3i3mv
|
||||||
|
|
||||||
PFMDEFS = /DCONFIG_PF_STRING="w3i3mv" /DCONFIG_PF_W3I3MV /DWIN32 /D_WINDOWS
|
PFMDEFS = /DCONFIG_PF_STRING="w3i3mv" /DCONFIG_PF_W3I3MV /DWIN32 /D_WINDOWS
|
||||||
|
|
||||||
!INCLUDE commpre.nmk
|
# MPM platform-specific sources.
|
||||||
!INCLUDE mv.nmk
|
MPMPF = \
|
||||||
|
|
||||||
# MPM sources: core plus platform-specific.
|
|
||||||
MPM = $(MPMCOMMON) \
|
|
||||||
<lockw3> \
|
<lockw3> \
|
||||||
<mpsiw3> \
|
<mpsiw3> \
|
||||||
<prmci3w3> \
|
<prmci3w3> \
|
||||||
|
|
@ -23,6 +20,9 @@ MPM = $(MPMCOMMON) \
|
||||||
<thw3i3> \
|
<thw3i3> \
|
||||||
<vmw3>
|
<vmw3>
|
||||||
|
|
||||||
|
!INCLUDE commpre.nmk
|
||||||
|
!INCLUDE mv.nmk
|
||||||
|
|
||||||
|
|
||||||
# Source to object file mappings and CFLAGS amalgamation
|
# Source to object file mappings and CFLAGS amalgamation
|
||||||
#
|
#
|
||||||
|
|
@ -41,14 +41,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
||||||
MPMOBJ0 = $(MPM:<=w3i3mv\hot\)
|
MPMOBJ0 = $(MPM:<=w3i3mv\hot\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i3mv\hot\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i3mv\hot\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i3mv\hot\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i3mv\hot\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i3mv\hot\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i3mv\hot\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i3mv\hot\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i3mv\hot\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i3mv\hot\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\hot\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\hot\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\hot\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\hot\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i3mv\hot\)
|
POOLNOBJ0 = $(POOLN:<=w3i3mv\hot\)
|
||||||
|
|
@ -61,14 +54,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
||||||
MPMOBJ0 = $(MPM:<=w3i3mv\cool\)
|
MPMOBJ0 = $(MPM:<=w3i3mv\cool\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i3mv\cool\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i3mv\cool\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i3mv\cool\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i3mv\cool\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i3mv\cool\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i3mv\cool\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i3mv\cool\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i3mv\cool\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i3mv\cool\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\cool\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\cool\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\cool\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\cool\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i3mv\cool\)
|
POOLNOBJ0 = $(POOLN:<=w3i3mv\cool\)
|
||||||
|
|
@ -81,61 +67,20 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
||||||
MPMOBJ0 = $(MPM:<=w3i3mv\rash\)
|
MPMOBJ0 = $(MPM:<=w3i3mv\rash\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i3mv\rash\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i3mv\rash\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i3mv\rash\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i3mv\rash\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i3mv\rash\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i3mv\rash\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i3mv\rash\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i3mv\rash\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i3mv\rash\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\rash\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\rash\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\rash\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\rash\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i3mv\rash\)
|
POOLNOBJ0 = $(POOLN:<=w3i3mv\rash\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\rash\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\rash\)
|
||||||
TESTTHROBJ0 = $(TESTTHR:<=w3i3mv\rash\)
|
TESTTHROBJ0 = $(TESTTHR:<=w3i3mv\rash\)
|
||||||
|
|
||||||
#!ELSEIF "$(VARIETY)" == "cv"
|
|
||||||
#CFLAGS=$(CFLAGSCOMMON) $(CFCV)
|
|
||||||
#LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCV)
|
|
||||||
#LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCV)
|
|
||||||
#MPMOBJ0 = $(MPM:<=w3i3mv\cv\)
|
|
||||||
#MPMOBJ = $(MPMOBJ0:>=.obj)
|
|
||||||
#PLINTHOBJ0 = $(PLINTH:<=w3i3mv\cv\)
|
|
||||||
#PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
|
||||||
#AMSOBJ0 = $(AMS:<=w3i3mv\cv\)
|
|
||||||
#AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
#AMCOBJ0 = $(AMC:<=w3i3mv\cv\)
|
|
||||||
#AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
#AWLOBJ0 = $(AWL:<=w3i3mv\cv\)
|
|
||||||
#AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
#LOOBJ0 = $(LO:<=w3i3mv\cv\)
|
|
||||||
#LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
#SNCOBJ0 = $(SNC:<=w3i3mv\cv\)
|
|
||||||
#SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
#DWOBJ0 = $(DW:<=w3i3mv\cv\)
|
|
||||||
#DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
#POOLNOBJ0 = $(POOLN:<=w3i3mv\cv\)
|
|
||||||
#POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
|
||||||
#TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\cv\)
|
|
||||||
#TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
|
||||||
#TESTTHROBJ0 = $(TESTTHR:<=w3i3mv\cv\)
|
|
||||||
#TESTTHROBJ = $(TESTTHROBJ0:>=.obj)
|
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# %%PART: When adding a new part, add new macros which expand to the object
|
# %%PART: When adding a new part, add new macros which expand to the object
|
||||||
# files included in the part
|
# files included in the part
|
||||||
|
|
||||||
MPMOBJ = $(MPMOBJ0:>=.obj)
|
MPMOBJ = $(MPMOBJ0:>=.obj)
|
||||||
PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
FMTDYOBJ = $(FMTDYOBJ0:>=.obj)
|
||||||
AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
MVFFOBJ = $(MVFFOBJ0:>=.obj)
|
|
||||||
DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
||||||
FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj)
|
FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj)
|
||||||
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,8 @@ PFM = w3i3pc
|
||||||
|
|
||||||
PFMDEFS = /DCONFIG_PF_STRING="w3i3pc" /DCONFIG_PF_W3I3PC /DWIN32 /D_WINDOWS
|
PFMDEFS = /DCONFIG_PF_STRING="w3i3pc" /DCONFIG_PF_W3I3PC /DWIN32 /D_WINDOWS
|
||||||
|
|
||||||
!INCLUDE commpre.nmk
|
# MPM platform-specific sources.
|
||||||
!INCLUDE pc.nmk
|
MPMPF = \
|
||||||
|
|
||||||
# MPM sources: core plus platform-specific.
|
|
||||||
MPM = $(MPMCOMMON) \
|
|
||||||
<lockw3> \
|
<lockw3> \
|
||||||
<mpsiw3> \
|
<mpsiw3> \
|
||||||
<prmci3w3> \
|
<prmci3w3> \
|
||||||
|
|
@ -23,6 +20,9 @@ MPM = $(MPMCOMMON) \
|
||||||
<thw3i3> \
|
<thw3i3> \
|
||||||
<vmw3>
|
<vmw3>
|
||||||
|
|
||||||
|
!INCLUDE commpre.nmk
|
||||||
|
!INCLUDE pc.nmk
|
||||||
|
|
||||||
|
|
||||||
# Source to object file mappings and CFLAGS amalgamation
|
# Source to object file mappings and CFLAGS amalgamation
|
||||||
#
|
#
|
||||||
|
|
@ -41,14 +41,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
||||||
MPMOBJ0 = $(MPM:<=w3i3pc\hot\)
|
MPMOBJ0 = $(MPM:<=w3i3pc\hot\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i3pc\hot\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i3pc\hot\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i3pc\hot\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i3pc\hot\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i3pc\hot\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i3pc\hot\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i3pc\hot\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i3pc\hot\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i3pc\hot\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\hot\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\hot\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i3pc\hot\)
|
POOLNOBJ0 = $(POOLN:<=w3i3pc\hot\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\hot\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\hot\)
|
||||||
|
|
@ -60,14 +53,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
||||||
MPMOBJ0 = $(MPM:<=w3i3pc\cool\)
|
MPMOBJ0 = $(MPM:<=w3i3pc\cool\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i3pc\cool\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i3pc\cool\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i3pc\cool\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i3pc\cool\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i3pc\cool\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i3pc\cool\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i3pc\cool\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i3pc\cool\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i3pc\cool\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\cool\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\cool\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i3pc\cool\)
|
POOLNOBJ0 = $(POOLN:<=w3i3pc\cool\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\cool\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\cool\)
|
||||||
|
|
@ -79,60 +65,19 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
||||||
MPMOBJ0 = $(MPM:<=w3i3pc\rash\)
|
MPMOBJ0 = $(MPM:<=w3i3pc\rash\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i3pc\rash\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i3pc\rash\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i3pc\rash\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i3pc\rash\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i3pc\rash\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i3pc\rash\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i3pc\rash\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i3pc\rash\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i3pc\rash\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\rash\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\rash\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i3pc\rash\)
|
POOLNOBJ0 = $(POOLN:<=w3i3pc\rash\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\rash\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\rash\)
|
||||||
TESTTHROBJ0 = $(TESTTHR:<=w3i3pc\rash\)
|
TESTTHROBJ0 = $(TESTTHR:<=w3i3pc\rash\)
|
||||||
|
|
||||||
#!ELSEIF "$(VARIETY)" == "cv"
|
|
||||||
#CFLAGS=$(CFLAGSCOMMON) $(CFCV)
|
|
||||||
#LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCV)
|
|
||||||
#LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCV)
|
|
||||||
#MPMOBJ0 = $(MPM:<=w3i3pc\cv\)
|
|
||||||
#MPMOBJ = $(MPMOBJ0:>=.obj)
|
|
||||||
#PLINTHOBJ0 = $(PLINTH:<=w3i3pc\cv\)
|
|
||||||
#PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
|
||||||
#AMSOBJ0 = $(AMS:<=w3i3pc\cv\)
|
|
||||||
#AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
#AMCOBJ0 = $(AMC:<=w3i3pc\cv\)
|
|
||||||
#AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
#AWLOBJ0 = $(AWL:<=w3i3pc\cv\)
|
|
||||||
#AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
#LOOBJ0 = $(LO:<=w3i3pc\cv\)
|
|
||||||
#LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
#SNCOBJ0 = $(SNC:<=w3i3pc\cv\)
|
|
||||||
#SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
#DWOBJ0 = $(DW:<=w3i3pc\cv\)
|
|
||||||
#DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
#POOLNOBJ0 = $(POOLN:<=w3i3pc\cv\)
|
|
||||||
#POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
|
||||||
#TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\cv\)
|
|
||||||
#TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
|
||||||
#TESTTHROBJ0 = $(TESTTHR:<=w3i3pc\cv\)
|
|
||||||
#TESTTHROBJ = $(TESTTHROBJ0:>=.obj)
|
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# %%PART: When adding a new part, add new macros which expand to the object
|
# %%PART: When adding a new part, add new macros which expand to the object
|
||||||
# files included in the part
|
# files included in the part
|
||||||
|
|
||||||
MPMOBJ = $(MPMOBJ0:>=.obj)
|
MPMOBJ = $(MPMOBJ0:>=.obj)
|
||||||
PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
FMTDYOBJ = $(FMTDYOBJ0:>=.obj)
|
||||||
AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
MVFFOBJ = $(MVFFOBJ0:>=.obj)
|
|
||||||
DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
||||||
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
||||||
TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,8 @@ PFM = w3i6mv
|
||||||
PFMDEFS = /DCONFIG_PF_STRING="w3i6mv" /DCONFIG_PF_W3I6MV /DWIN32 /D_WINDOWS
|
PFMDEFS = /DCONFIG_PF_STRING="w3i6mv" /DCONFIG_PF_W3I6MV /DWIN32 /D_WINDOWS
|
||||||
MASM = ml64
|
MASM = ml64
|
||||||
|
|
||||||
!INCLUDE commpre.nmk
|
# MPM platform-specific sources.
|
||||||
!INCLUDE mv.nmk
|
MPMPF = \
|
||||||
|
|
||||||
# MPM sources: core plus platform-specific.
|
|
||||||
MPM = $(MPMCOMMON) \
|
|
||||||
<lockw3> \
|
<lockw3> \
|
||||||
<mpsiw3> \
|
<mpsiw3> \
|
||||||
<prmci6w3> \
|
<prmci6w3> \
|
||||||
|
|
@ -24,6 +21,9 @@ MPM = $(MPMCOMMON) \
|
||||||
<thw3i6> \
|
<thw3i6> \
|
||||||
<vmw3>
|
<vmw3>
|
||||||
|
|
||||||
|
!INCLUDE commpre.nmk
|
||||||
|
!INCLUDE mv.nmk
|
||||||
|
|
||||||
|
|
||||||
# Source to object file mappings and CFLAGS amalgamation
|
# Source to object file mappings and CFLAGS amalgamation
|
||||||
#
|
#
|
||||||
|
|
@ -42,14 +42,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
||||||
MPMOBJ0 = $(MPM:<=w3i6mv\hot\)
|
MPMOBJ0 = $(MPM:<=w3i6mv\hot\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i6mv\hot\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i6mv\hot\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i6mv\hot\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i6mv\hot\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i6mv\hot\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i6mv\hot\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i6mv\hot\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i6mv\hot\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i6mv\hot\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\hot\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\hot\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\hot\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\hot\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i6mv\hot\)
|
POOLNOBJ0 = $(POOLN:<=w3i6mv\hot\)
|
||||||
|
|
@ -62,14 +55,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
||||||
MPMOBJ0 = $(MPM:<=w3i6mv\cool\)
|
MPMOBJ0 = $(MPM:<=w3i6mv\cool\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i6mv\cool\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i6mv\cool\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i6mv\cool\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i6mv\cool\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i6mv\cool\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i6mv\cool\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i6mv\cool\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i6mv\cool\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i6mv\cool\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\cool\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\cool\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\cool\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\cool\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i6mv\cool\)
|
POOLNOBJ0 = $(POOLN:<=w3i6mv\cool\)
|
||||||
|
|
@ -82,61 +68,20 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
||||||
MPMOBJ0 = $(MPM:<=w3i6mv\rash\)
|
MPMOBJ0 = $(MPM:<=w3i6mv\rash\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i6mv\rash\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i6mv\rash\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i6mv\rash\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i6mv\rash\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i6mv\rash\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i6mv\rash\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i6mv\rash\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i6mv\rash\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i6mv\rash\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\rash\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\rash\)
|
||||||
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\rash\)
|
FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\rash\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i6mv\rash\)
|
POOLNOBJ0 = $(POOLN:<=w3i6mv\rash\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i6mv\rash\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i6mv\rash\)
|
||||||
TESTTHROBJ0 = $(TESTTHR:<=w3i6mv\rash\)
|
TESTTHROBJ0 = $(TESTTHR:<=w3i6mv\rash\)
|
||||||
|
|
||||||
#!ELSEIF "$(VARIETY)" == "cv"
|
|
||||||
#CFLAGS=$(CFLAGSCOMMON) $(CFCV)
|
|
||||||
#LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCV)
|
|
||||||
#LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCV)
|
|
||||||
#MPMOBJ0 = $(MPM:<=w3i6mv\cv\)
|
|
||||||
#MPMOBJ = $(MPMOBJ0:>=.obj)
|
|
||||||
#PLINTHOBJ0 = $(PLINTH:<=w3i6mv\cv\)
|
|
||||||
#PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
|
||||||
#AMSOBJ0 = $(AMS:<=w3i6mv\cv\)
|
|
||||||
#AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
#AMCOBJ0 = $(AMC:<=w3i6mv\cv\)
|
|
||||||
#AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
#AWLOBJ0 = $(AWL:<=w3i6mv\cv\)
|
|
||||||
#AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
#LOOBJ0 = $(LO:<=w3i6mv\cv\)
|
|
||||||
#LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
#SNCOBJ0 = $(SNC:<=w3i6mv\cv\)
|
|
||||||
#SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
#DWOBJ0 = $(DW:<=w3i6mv\cv\)
|
|
||||||
#DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
#POOLNOBJ0 = $(POOLN:<=w3i6mv\cv\)
|
|
||||||
#POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
|
||||||
#TESTLIBOBJ0 = $(TESTLIB:<=w3i6mv\cv\)
|
|
||||||
#TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
|
||||||
#TESTTHROBJ0 = $(TESTTHR:<=w3i6mv\cv\)
|
|
||||||
#TESTTHROBJ = $(TESTTHROBJ0:>=.obj)
|
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# %%PART: When adding a new part, add new macros which expand to the object
|
# %%PART: When adding a new part, add new macros which expand to the object
|
||||||
# files included in the part
|
# files included in the part
|
||||||
|
|
||||||
MPMOBJ = $(MPMOBJ0:>=.obj)
|
MPMOBJ = $(MPMOBJ0:>=.obj)
|
||||||
PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
FMTDYOBJ = $(FMTDYOBJ0:>=.obj)
|
||||||
AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
MVFFOBJ = $(MVFFOBJ0:>=.obj)
|
|
||||||
DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
||||||
FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj)
|
FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj)
|
||||||
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,10 @@ PFM = w3i6pc
|
||||||
|
|
||||||
PFMDEFS = /DCONFIG_PF_STRING="w3i6pc" /DCONFIG_PF_W3I6PC /DWIN32 /D_WINDOWS
|
PFMDEFS = /DCONFIG_PF_STRING="w3i6pc" /DCONFIG_PF_W3I6PC /DWIN32 /D_WINDOWS
|
||||||
|
|
||||||
!INCLUDE commpre.nmk
|
|
||||||
!INCLUDE pc.nmk
|
|
||||||
|
|
||||||
CFLAGSCOMMONPRE = $(CFLAGSCOMMONPRE) /Tamd64-coff
|
CFLAGSCOMMONPRE = $(CFLAGSCOMMONPRE) /Tamd64-coff
|
||||||
|
|
||||||
# MPM sources: core plus platform-specific.
|
# MPM platform-specific sources.
|
||||||
MPM = $(MPMCOMMON) \
|
MPMPF = \
|
||||||
<lockw3> \
|
<lockw3> \
|
||||||
<mpsiw3> \
|
<mpsiw3> \
|
||||||
<prmci6w3> \
|
<prmci6w3> \
|
||||||
|
|
@ -27,6 +24,9 @@ MPM = $(MPMCOMMON) \
|
||||||
<thw3i6> \
|
<thw3i6> \
|
||||||
<vmw3>
|
<vmw3>
|
||||||
|
|
||||||
|
!INCLUDE commpre.nmk
|
||||||
|
!INCLUDE pc.nmk
|
||||||
|
|
||||||
|
|
||||||
# Source to object file mappings and CFLAGS amalgamation
|
# Source to object file mappings and CFLAGS amalgamation
|
||||||
#
|
#
|
||||||
|
|
@ -45,14 +45,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT)
|
||||||
MPMOBJ0 = $(MPM:<=w3i6pc\hot\)
|
MPMOBJ0 = $(MPM:<=w3i6pc\hot\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i6pc\hot\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i6pc\hot\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i6pc\hot\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i6pc\hot\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i6pc\hot\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i6pc\hot\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i6pc\hot\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i6pc\hot\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i6pc\hot\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\hot\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\hot\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i6pc\hot\)
|
POOLNOBJ0 = $(POOLN:<=w3i6pc\hot\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\hot\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\hot\)
|
||||||
|
|
@ -64,14 +57,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL)
|
||||||
MPMOBJ0 = $(MPM:<=w3i6pc\cool\)
|
MPMOBJ0 = $(MPM:<=w3i6pc\cool\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i6pc\cool\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i6pc\cool\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i6pc\cool\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i6pc\cool\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i6pc\cool\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i6pc\cool\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i6pc\cool\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i6pc\cool\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i6pc\cool\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\cool\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\cool\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i6pc\cool\)
|
POOLNOBJ0 = $(POOLN:<=w3i6pc\cool\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\cool\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\cool\)
|
||||||
|
|
@ -83,60 +69,19 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST)
|
||||||
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH)
|
||||||
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH)
|
||||||
MPMOBJ0 = $(MPM:<=w3i6pc\rash\)
|
MPMOBJ0 = $(MPM:<=w3i6pc\rash\)
|
||||||
PLINTHOBJ0 = $(PLINTH:<=w3i6pc\rash\)
|
FMTDYOBJ0 = $(FMTDY:<=w3i6pc\rash\)
|
||||||
AMSOBJ0 = $(AMS:<=w3i6pc\rash\)
|
|
||||||
AMCOBJ0 = $(AMC:<=w3i6pc\rash\)
|
|
||||||
AWLOBJ0 = $(AWL:<=w3i6pc\rash\)
|
|
||||||
LOOBJ0 = $(LO:<=w3i6pc\rash\)
|
|
||||||
SNCOBJ0 = $(SNC:<=w3i6pc\rash\)
|
|
||||||
MVFFOBJ0 = $(MVFF:<=w3i6pc\rash\)
|
|
||||||
DWOBJ0 = $(DW:<=w3i6pc\rash\)
|
|
||||||
FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\rash\)
|
FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\rash\)
|
||||||
POOLNOBJ0 = $(POOLN:<=w3i6pc\rash\)
|
POOLNOBJ0 = $(POOLN:<=w3i6pc\rash\)
|
||||||
TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\rash\)
|
TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\rash\)
|
||||||
TESTTHROBJ0 = $(TESTTHR:<=w3i6pc\rash\)
|
TESTTHROBJ0 = $(TESTTHR:<=w3i6pc\rash\)
|
||||||
|
|
||||||
#!ELSEIF "$(VARIETY)" == "cv"
|
|
||||||
#CFLAGS=$(CFLAGSCOMMON) $(CFCV)
|
|
||||||
#LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCV)
|
|
||||||
#LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCV)
|
|
||||||
#MPMOBJ0 = $(MPM:<=w3i6pc\cv\)
|
|
||||||
#MPMOBJ = $(MPMOBJ0:>=.obj)
|
|
||||||
#PLINTHOBJ0 = $(PLINTH:<=w3i6pc\cv\)
|
|
||||||
#PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
|
||||||
#AMSOBJ0 = $(AMS:<=w3i6pc\cv\)
|
|
||||||
#AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
#AMCOBJ0 = $(AMC:<=w3i6pc\cv\)
|
|
||||||
#AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
#AWLOBJ0 = $(AWL:<=w3i6pc\cv\)
|
|
||||||
#AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
#LOOBJ0 = $(LO:<=w3i6pc\cv\)
|
|
||||||
#LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
#SNCOBJ0 = $(SNC:<=w3i6pc\cv\)
|
|
||||||
#SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
#DWOBJ0 = $(DW:<=w3i6pc\cv\)
|
|
||||||
#DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
#POOLNOBJ0 = $(POOLN:<=w3i6pc\cv\)
|
|
||||||
#POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
|
||||||
#TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\cv\)
|
|
||||||
#TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
|
||||||
#TESTTHROBJ0 = $(TESTTHR:<=w3i6pc\cv\)
|
|
||||||
#TESTTHROBJ = $(TESTTHROBJ0:>=.obj)
|
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# %%PART: When adding a new part, add new macros which expand to the object
|
# %%PART: When adding a new part, add new macros which expand to the object
|
||||||
# files included in the part
|
# files included in the part
|
||||||
|
|
||||||
MPMOBJ = $(MPMOBJ0:>=.obj)
|
MPMOBJ = $(MPMOBJ0:>=.obj)
|
||||||
PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
FMTDYOBJ = $(FMTDYOBJ0:>=.obj)
|
||||||
AMSOBJ = $(AMSOBJ0:>=.obj)
|
|
||||||
AMCOBJ = $(AMCOBJ0:>=.obj)
|
|
||||||
AWLOBJ = $(AWLOBJ0:>=.obj)
|
|
||||||
LOOBJ = $(LOOBJ0:>=.obj)
|
|
||||||
SNCOBJ = $(SNCOBJ0:>=.obj)
|
|
||||||
MVFFOBJ = $(MVFFOBJ0:>=.obj)
|
|
||||||
DWOBJ = $(DWOBJ0:>=.obj)
|
|
||||||
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
|
||||||
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
POOLNOBJ = $(POOLNOBJ0:>=.obj)
|
||||||
TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj)
|
||||||
|
|
|
||||||
|
|
@ -124,9 +124,10 @@ _`.limit.zones`: ``CBSLandClass`` and ``CBSFastLandClass`` do not
|
||||||
support the ``LandFindInZones()`` generic function (the subclass
|
support the ``LandFindInZones()`` generic function (the subclass
|
||||||
``CBSZonedLandClass`` does support this operation).
|
``CBSZonedLandClass`` does support this operation).
|
||||||
|
|
||||||
_`.limit.iterate`: CBS does not support visitors setting
|
_`.limit.iterate`: CBS does not provide an implementation for the
|
||||||
``deleteReturn`` to ``TRUE`` when iterating over ranges with
|
``LandIterateAndDelete()`` generic function. This is because
|
||||||
``LandIterate()``.
|
``TreeTraverse()`` does not permit modification, for speed and to
|
||||||
|
avoid perturbing the splay tree balance.
|
||||||
|
|
||||||
_`.limit.flush`: CBS cannot be used as the source in a call to
|
_`.limit.flush`: CBS cannot be used as the source in a call to
|
||||||
``LandFlush()``. (Because of `.limit.iterate`_.)
|
``LandFlush()``. (Because of `.limit.iterate`_.)
|
||||||
|
|
@ -221,6 +222,11 @@ converting them when they reach all free in the bit set. Note that
|
||||||
this would make coalescence slightly less eager, by up to
|
this would make coalescence slightly less eager, by up to
|
||||||
``(word-width - 1)``.
|
``(word-width - 1)``.
|
||||||
|
|
||||||
|
_`.future.iterate.and.delete`: It would be possible to provide an
|
||||||
|
implementation for the ``LandIterateAndDelete()`` generic function by
|
||||||
|
calling ``TreeToVine()`` first, and then iterating over the vine
|
||||||
|
(where deletion is straightforward).
|
||||||
|
|
||||||
|
|
||||||
Risks
|
Risks
|
||||||
-----
|
-----
|
||||||
|
|
|
||||||
|
|
@ -45,17 +45,17 @@ arena_ The design of the MPS arena
|
||||||
arenavm_ Virtual memory arena
|
arenavm_ Virtual memory arena
|
||||||
bt_ Bit tables
|
bt_ Bit tables
|
||||||
buffer_ Allocation buffers and allocation points
|
buffer_ Allocation buffers and allocation points
|
||||||
cbs_ Coalescing Block Structure allocator
|
cbs_ Coalescing Block Structure land implementation
|
||||||
check_ Design of checking in MPS
|
check_ Design of checking in MPS
|
||||||
class-interface_ Design of the pool class interface
|
class-interface_ Design of the pool class interface
|
||||||
collection_ The collection framework
|
collection_ The collection framework
|
||||||
config_ The design of MPS configuration
|
config_ The design of MPS configuration
|
||||||
critical-path_ The critical path through the MPS
|
critical-path_ The critical path through the MPS
|
||||||
diag_ The design of MPS diagnostic feedback
|
diag_ The design of MPS diagnostic feedback
|
||||||
failover_ Fail-over allocator
|
failover_ Fail-over land implementation
|
||||||
finalize_ Finalization
|
finalize_ Finalization
|
||||||
fix_ The Design of the Generic Fix Function
|
fix_ The Design of the Generic Fix Function
|
||||||
freelist_ Free list allocator
|
freelist_ Free list land implementation
|
||||||
guide.hex.trans_ Guide to transliterating the alphabet into hexadecimal
|
guide.hex.trans_ Guide to transliterating the alphabet into hexadecimal
|
||||||
guide.impl.c.format_ Coding standard: conventions for the general format of C source code in the MPS
|
guide.impl.c.format_ Coding standard: conventions for the general format of C source code in the MPS
|
||||||
interface-c_ The design of the Memory Pool System interface to C
|
interface-c_ The design of the Memory Pool System interface to C
|
||||||
|
|
|
||||||
|
|
@ -77,15 +77,22 @@ Types
|
||||||
|
|
||||||
_`.type.land`: The type of a generic land instance.
|
_`.type.land`: The type of a generic land instance.
|
||||||
|
|
||||||
``typedef Bool (*LandVisitor)(Bool *deleteReturn, Land land, Range range, void *closureP, Size closureS);``
|
``typedef Bool (*LandVisitor)(Land land, Range range, void *closureP, Size closureS);``
|
||||||
|
|
||||||
_`.type.visitor`: Type ``LandVisitor`` is a callback function that may
|
_`.type.visitor`: Type ``LandVisitor`` is a callback function that may
|
||||||
be passed to ``LandIterate()``. It is called for every isolated
|
be passed to ``LandIterate()``. It is called for every isolated
|
||||||
contiguous range in address order. The function must return a ``Bool``
|
contiguous range in address order. The function must return a ``Bool``
|
||||||
|
indicating whether to continue with the iteration.
|
||||||
|
|
||||||
|
``typedef Bool (*LandDeleteVisitor)(Bool *deleteReturn, Land land, Range range, void *closureP, Size closureS);``
|
||||||
|
|
||||||
|
_`.type.visitor`: Type ``LandDeleteVisitor`` is a callback function that may
|
||||||
|
be passed to ``LandIterateAndDelete()``. It is called for every isolated
|
||||||
|
contiguous range in address order. The function must return a ``Bool``
|
||||||
indicating whether to continue with the iteration. It may additionally
|
indicating whether to continue with the iteration. It may additionally
|
||||||
update ``*deleteReturn`` to ``TRUE`` if the range must be deleted from
|
update ``*deleteReturn`` to ``TRUE`` if the range must be deleted from
|
||||||
the land, or ``FALSE`` if the range must be kept. (The default is to
|
the land, or ``FALSE`` if the range must be kept. (The default is to
|
||||||
keep the range, and not all land classes support deletion.)
|
keep the range.)
|
||||||
|
|
||||||
|
|
||||||
Generic functions
|
Generic functions
|
||||||
|
|
@ -164,13 +171,21 @@ strategy.
|
||||||
_`.function.delete.alias`: It is acceptable for ``rangeReturn`` and
|
_`.function.delete.alias`: It is acceptable for ``rangeReturn`` and
|
||||||
``range`` to share storage.
|
``range`` to share storage.
|
||||||
|
|
||||||
``void LandIterate(Land land, LandIterateMethod iterate, void *closureP, Size closureS)``
|
``Bool LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)``
|
||||||
|
|
||||||
_`.function.iterate`: ``LandIterate()`` is the function used to
|
_`.function.iterate`: ``LandIterate()`` is the function used to
|
||||||
iterate all isolated contiguous ranges in a land. It receives a
|
iterate all isolated contiguous ranges in a land. It receives a
|
||||||
pointer, ``Size`` closure pair to pass on to the iterator method, and
|
visitor function to invoke on every range, and a pointer, ``Size``
|
||||||
an iterator method to invoke on every range. If the iterator method
|
closure pair to pass on to the visitor function. If the visitor
|
||||||
returns ``FALSE``, then the iteration is terminated.
|
function returns ``FALSE``, then iteration is terminated and
|
||||||
|
``LandIterate()`` returns ``FALSE``. If all iterator method calls
|
||||||
|
return ``TRUE``, then ``LandIterate()`` returns ``TRUE``
|
||||||
|
|
||||||
|
``Bool LandIterateAndDelete(Land land, LandDeleteVisitor visitor, void *closureP, Size closureS)``
|
||||||
|
|
||||||
|
_`.function.iterate.and.delete`: As ``LandIterate()``, but the visitor
|
||||||
|
function additionally returns a Boolean indicating whether the range
|
||||||
|
should be deleted from the land.
|
||||||
|
|
||||||
``Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)``
|
``Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)``
|
||||||
|
|
||||||
|
|
@ -217,13 +232,14 @@ Like ``LandFindFirst()``, optionally delete the range (specifying
|
||||||
range in which the range was found via the ``oldRangeReturn``
|
range in which the range was found via the ``oldRangeReturn``
|
||||||
argument.
|
argument.
|
||||||
|
|
||||||
``Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)``
|
``Res LandFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)``
|
||||||
|
|
||||||
_`.function.find.zones`: Locate a block at least as big as ``size``
|
_`.function.find.zones`: Locate a block at least as big as ``size``
|
||||||
that lies entirely within the ``zoneSet``, return its range via the
|
that lies entirely within the ``zoneSet``, return its range via the
|
||||||
``rangeReturn`` argument, and return ``ResOK``. (The first such block,
|
``rangeReturn`` argument, set ``*foundReturn`` to ``TRUE``, and return
|
||||||
if ``high`` is ``FALSE``, or the last, if ``high`` is ``TRUE``.) If
|
``ResOK``. (The first such block, if ``high`` is ``FALSE``, or the
|
||||||
there is no such block, , return ``ResFAIL``.
|
last, if ``high`` is ``TRUE``.) If there is no such block, set
|
||||||
|
``*foundReturn`` to ``TRUE``, and return ``ResOK``.
|
||||||
|
|
||||||
Delete the range as for ``LandFindFirst()`` and ``LastFindLast()``
|
Delete the range as for ``LandFindFirst()`` and ``LastFindLast()``
|
||||||
(with the effect of ``FindDeleteLOW`` if ``high`` is ``FALSE`` and the
|
(with the effect of ``FindDeleteLOW`` if ``high`` is ``FALSE`` and the
|
||||||
|
|
@ -233,7 +249,7 @@ the ``oldRangeReturn`` argument.
|
||||||
|
|
||||||
_`.function.find.zones.fail`: It's possible that the range can't be
|
_`.function.find.zones.fail`: It's possible that the range can't be
|
||||||
deleted from the land because that would require allocation, in which
|
deleted from the land because that would require allocation, in which
|
||||||
case the result code will indicate the cause of the failure.
|
case the result code indicates the cause of the failure.
|
||||||
|
|
||||||
``Res LandDescribe(Land land, mps_lib_FILE *stream)``
|
``Res LandDescribe(Land land, mps_lib_FILE *stream)``
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ _`.def.splay-tree`: A *splay tree* is a self-adjusting binary tree as
|
||||||
described in [ST85]_ and [Sleator96]_.
|
described in [ST85]_ and [Sleator96]_.
|
||||||
|
|
||||||
_`.def.node`: A *node* is used in the typical data structure sense to
|
_`.def.node`: A *node* is used in the typical data structure sense to
|
||||||
mean an element of a tree (see also `.type.splay.node`_).
|
mean an element of a tree (see also `.type.tree`_).
|
||||||
|
|
||||||
_`.def.key`: A *key* is a value associated with each node; the keys
|
_`.def.key`: A *key* is a value associated with each node; the keys
|
||||||
are totally ordered by a client provided comparator.
|
are totally ordered by a client provided comparator.
|
||||||
|
|
@ -442,8 +442,7 @@ right trees. For the left tree, we traverse the right child line,
|
||||||
reversing pointers, until we reach the node that was the last node
|
reversing pointers, until we reach the node that was the last node
|
||||||
prior to the transplantation of the root's children. Then we update
|
prior to the transplantation of the root's children. Then we update
|
||||||
from that node back to the left tree's root, restoring pointers.
|
from that node back to the left tree's root, restoring pointers.
|
||||||
Updating the right tree is the same, mutatis mutandis. (See
|
Updating the right tree is the same, mutatis mutandis.
|
||||||
`.future.reverse`_ for an alternative approach).
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
|
|
|
||||||
|
|
@ -81,100 +81,107 @@ the client to specify preferred relative object locations ("this
|
||||||
object should be kept in the same cache line as that one"), to improve
|
object should be kept in the same cache line as that one"), to improve
|
||||||
cache locality.
|
cache locality.
|
||||||
|
|
||||||
|
|
||||||
Generations
|
Generations
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
The largest part of the current MPS strategy implementation is the
|
The largest part of the current MPS strategy implementation is the
|
||||||
support for generational GC. Generations are only fully supported for
|
support for generational garbage collections.
|
||||||
AMC (and AMCZ) pools. See under "Non-AMC Pools", below, for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
Data Structures
|
|
||||||
...............
|
|
||||||
|
|
||||||
The fundamental structure of generational GC is the ``Chain``,
|
General data structures
|
||||||
which describes a set of generations. A chain is created by client
|
.......................
|
||||||
code calling ``mps_chain_create()``, specifying the "size" and
|
|
||||||
"mortality" for each generation. When creating an AMC pool, the
|
|
||||||
client code must specify the chain which will control collections for
|
|
||||||
that pool. The same chain may be used for multiple pools.
|
|
||||||
|
|
||||||
Each generation in a chain has a ``GenDesc`` structure,
|
The fundamental structure of generational garbage collection is the
|
||||||
allocated in an array pointed to from the chain. Each AMC pool has a
|
``Chain``, which describes a sequence of generations.
|
||||||
set of ``PoolGen`` structures, one per generation. The PoolGens
|
|
||||||
for each generation point to the GenDesc and are linked together in a
|
A chain specifies the "capacity" and "mortality" for each generation.
|
||||||
ring on the GenDesc. These structures are (solely?) used to gather
|
When creating an automatically collected pool, the client code may
|
||||||
|
specify the chain which will control collections for that pool. The
|
||||||
|
same chain may be used for multiple pools. If no chain is specified,
|
||||||
|
the pool uses the arena's default generation chain.
|
||||||
|
|
||||||
|
Each generation in a chain has a ``GenDesc`` structure, allocated in
|
||||||
|
an array pointed to from the chain. In addition to the generations in
|
||||||
|
the chains, the arena has a unique ``GenDesc`` structure, named
|
||||||
|
``topGen`` and described in comments as "the dynamic generation"
|
||||||
|
(misleadingly: in fact it is the *least* dynamic generation).
|
||||||
|
|
||||||
|
Each automatically collected pool has a set of ``PoolGen`` structures,
|
||||||
|
one for each generation that it can allocate or promote into. The
|
||||||
|
``PoolGen`` structures for each generation point to the ``GenDesc``
|
||||||
|
for that generation, and are linked together in a ring on the
|
||||||
|
``GenDesc``. These structures are used to gather accounting
|
||||||
information for strategy decisions.
|
information for strategy decisions.
|
||||||
|
|
||||||
The arena has a unique ``GenDesc`` structure, named
|
The non-moving automatic pool classes (AMS, AWL and LO) do not support
|
||||||
``topGen`` and described in comments as "the dynamic generation"
|
generational collection, so they allocate into a single generation.
|
||||||
(although in fact it is the *least* dynamic generation). Each AMC
|
The moving automatic pool classes (AMC and AMCZ) have one pool
|
||||||
pool has one more PoolGen than there are GenDescs in the chain. The
|
generations for each generation in the chain, plus one pool generation
|
||||||
extra PoolGen refers to this topGen.
|
for the arena's "top generation".
|
||||||
|
|
||||||
AMC segments have a segment descriptor ``amcSegStruct`` which is
|
|
||||||
a ``GCSegStruct`` with two additional fields. One field
|
|
||||||
``segTypeP`` is a pointer either to the per-generation per-pool
|
|
||||||
``amcGen`` structure (a subclass of ``PoolGen``), or to a
|
|
||||||
nailboard (which then points to an amcGen). The other field
|
|
||||||
``new`` is a boolean used for keeping track of memory usage for
|
|
||||||
strategy reasons (see below under 'Accounting'). The ``amcGen``
|
|
||||||
is used for statistics (``->segs``) and forwarding buffers
|
|
||||||
(``->forward``).
|
|
||||||
|
|
||||||
The AMC pool class only ever allocates a segment in order to fill a
|
AMC data structures
|
||||||
buffer: either the buffer for a client Allocation Point, or a
|
...................
|
||||||
forwarding buffer. In order to support generational collection, there
|
|
||||||
is a subclass ``amcBuf`` of ``SegBuf``, with a
|
|
||||||
``gen`` field (pointing to a ``amcGen``). So in
|
|
||||||
``AMCBufferFill()`` the generation of the new segment can be
|
|
||||||
determined.
|
|
||||||
|
|
||||||
When an AMC pool is created, these ``amcGen`` and
|
An AMC pool creates an array of pool generation structures of type
|
||||||
``amcBuf`` structures are all created, and the
|
``amcGen`` (a subclass of ``PoolGen``). Each pool generation points to
|
||||||
``amcBuf->gen`` fields initialized so that the forwarding buffer
|
the *forwarding buffer* for that generation: this is the buffer that
|
||||||
of each amcGen knows that it belongs to the next "older" amcGen (apart
|
surviving objects are copied into.
|
||||||
from the "oldest" amcGen - that which refers to the topGen - whose
|
|
||||||
forwarding buffer belongs to itself).
|
|
||||||
|
|
||||||
When copying an object in ``AMCFix()``, the object's current
|
AMC segments point to the AMC pool generation that the segment belongs
|
||||||
generation is determined (``amcSegGen()``), and the object is
|
to, and AMC buffers point to the AMC pool generation that the buffer
|
||||||
copied to that amcGen's forwarding buffer, using the buffer protocol.
|
will be allocating into.
|
||||||
Thus, objects are "promoted" up the chain of generations until they
|
|
||||||
end up in the topGen, which is shared between all chains and all
|
The forwarding buffers are set up during AMC pool creation. Each
|
||||||
pools.
|
generation forwards into the next higher generation in the chain,
|
||||||
|
except for the top generation, which forwards to itself. Thus, objects
|
||||||
|
are "promoted" up the chain of generations until they end up in the
|
||||||
|
top generations, which is shared between all generational pools.
|
||||||
|
|
||||||
|
|
||||||
|
Collections
|
||||||
|
...........
|
||||||
|
|
||||||
|
Collections in the MPS start in one of two ways:
|
||||||
|
|
||||||
|
1. A collection of the world starts via ``traceCondemnAll()``. This
|
||||||
|
simply condemns all segments in all automatic pools.
|
||||||
|
|
||||||
|
2. A collection of some set of generations starts via ``TracePoll()``.
|
||||||
|
This calls ``ChainDeferral()`` for each chain; this function
|
||||||
|
indicates if the chain needs collecting, and if so, how urgent it
|
||||||
|
is to collect that chain. The most urgent chain in need of
|
||||||
|
collection (if any) is then condemned by calling
|
||||||
|
``ChainCondemnAuto()``.
|
||||||
|
|
||||||
|
This function chooses the set of generations to condemn, computes
|
||||||
|
the zoneset corresponding to the union those generations, and
|
||||||
|
condemns those zones by calling ``TraceCondemnZones()``.
|
||||||
|
|
||||||
|
Note that the condemnation is of every segment in an automatic pool
|
||||||
|
in any zone in the zoneset. It is not limited to the segments
|
||||||
|
actually associated with the condemned generations.
|
||||||
|
|
||||||
For statistics and reporting purposes, when ``STATISTICS`` is
|
|
||||||
on, each AMC pool has an array of ``PageRetStruct``s, one per
|
|
||||||
trace. This structure has many ``Count`` fields, and is
|
|
||||||
intended to help to assess AMC page retention code. See job001811.
|
|
||||||
|
|
||||||
Zones
|
Zones
|
||||||
.....
|
.....
|
||||||
|
|
||||||
All collections in the MPS start with condemnation of a complete
|
Each generation in each chain has a zoneset associated with it
|
||||||
``ZoneSet``. Each generation in each chain has a zoneset
|
(``gen->zones``); the condemned zoneset is the union of some number of
|
||||||
associated with it (``chain->gen[N].zones``); the condemned
|
generation's zonesets.
|
||||||
zoneset is the union of some number of generation's zonesets. It is
|
|
||||||
condemned by code in the chain system calling
|
|
||||||
``TraceCondemnZones()``. This is either for all chains
|
|
||||||
(``ChainCondemnAll()`` called for every chain from
|
|
||||||
``traceCondemnAll()``) or for some number of generations in a
|
|
||||||
single chain (``ChainCondemnAuto()`` called from
|
|
||||||
``TracePoll()``). Note that the condemnation is of every
|
|
||||||
automatic-pool segment in any zone in the zoneset. It is not limited
|
|
||||||
to the segments actually associated with the condemned generation(s).
|
|
||||||
|
|
||||||
An attempt is made to use distinct zonesets for different generations.
|
An attempt is made to use distinct zonesets for different generations.
|
||||||
Segments are allocated from ``AMCBufferFill()`` using ``ChainAlloc()``
|
Segments in automatic pools are allocated using ``PoolGenAlloc()``
|
||||||
which creates a ``SegPref`` using the zoneset from the generation's
|
which creates a ``SegPref`` using the zoneset from the generation's
|
||||||
``GenDesc``. The zoneset for each generation number starts out
|
``GenDesc``. The zoneset for each generation starts out empty. If the
|
||||||
empty. If the zoneset is empty, an attempt is made to allocate from a
|
zoneset is empty, an attempt is made to allocate from a free zone. The
|
||||||
free zone. The ``GenDesc`` zoneset is augmented with whichever zones the
|
``GenDesc`` zoneset is augmented with whichever zones the new segment
|
||||||
new segment occupies.
|
occupies.
|
||||||
|
|
||||||
Note that this zoneset can never shrink.
|
Note that this zoneset can never shrink.
|
||||||
|
|
||||||
|
|
||||||
Accounting
|
Accounting
|
||||||
..........
|
..........
|
||||||
|
|
||||||
|
|
@ -349,25 +356,6 @@ other uses of that:
|
||||||
- in ``AMCWhiten()``, if new is TRUE, the segment size is deducted
|
- in ``AMCWhiten()``, if new is TRUE, the segment size is deducted
|
||||||
from ``poolGen.newSize`` and new is set to FALSE.
|
from ``poolGen.newSize`` and new is set to FALSE.
|
||||||
|
|
||||||
Non-AMC Pools
|
|
||||||
.............
|
|
||||||
|
|
||||||
The implementations of AMS, AWL, and LO pool classes are all aware of
|
|
||||||
generations (this is necessary because all tracing is driven by the
|
|
||||||
generational data structures described above), but do not make use of
|
|
||||||
them. For LO and AWL, when a pool is created, a chain with a single
|
|
||||||
generation is also created, with size and mortality parameters
|
|
||||||
hard-wired into the pool-creation function (LOInit, AWLInit). For
|
|
||||||
AMS, a chain is passed as a pool creation parameter into
|
|
||||||
``mps_pool_create()``, but this chain must also have only a
|
|
||||||
single generation (otherwise ``ResPARAM`` is returned).
|
|
||||||
|
|
||||||
Note that these chains are separate from any chain used by an AMC pool
|
|
||||||
(except in the trivial case when a single-generation chain is used for
|
|
||||||
both AMC and AMS). Note also that these pools do not use or point to
|
|
||||||
the ``arena->topGen``, which applies only to AMC.
|
|
||||||
|
|
||||||
Non-AMC pools have no support for ramps.
|
|
||||||
|
|
||||||
Starting a Trace
|
Starting a Trace
|
||||||
................
|
................
|
||||||
|
|
@ -378,15 +366,18 @@ Trace Progress
|
||||||
..............
|
..............
|
||||||
TODO: When do we do some tracing work? How much tracing work do we do?
|
TODO: When do we do some tracing work? How much tracing work do we do?
|
||||||
|
|
||||||
|
|
||||||
Document History
|
Document History
|
||||||
----------------
|
----------------
|
||||||
- 2013-06-04 NB_ Checked this in although it's far from complete.
|
- 2013-06-04 NB_ Checked this in although it's far from complete.
|
||||||
Pasted in my 'ramping notes' from email, which mention some bugs
|
Pasted in my 'ramping notes' from email, which mention some bugs
|
||||||
which I may have fixed (TODO: check this).
|
which I may have fixed (TODO: check this).
|
||||||
- 2014-01-29 RB_ The arena no longer manages generation zonesets.
|
- 2014-01-29 RB_ The arena no longer manages generation zonesets.
|
||||||
|
- 2014-05-17 GDR_ Bring data structures and condemn logic up to date.
|
||||||
|
|
||||||
.. _RB: http://www.ravenbrook.com/consultants/rb
|
.. _GDR: http://www.ravenbrook.com/consultants/gdr/
|
||||||
.. _NB: http://www.ravenbrook.com/consultants/nb/
|
.. _NB: http://www.ravenbrook.com/consultants/nb/
|
||||||
|
.. _RB: http://www.ravenbrook.com/consultants/rb
|
||||||
|
|
||||||
|
|
||||||
Copyright and License
|
Copyright and License
|
||||||
|
|
|
||||||
3877
mps/manual/source/bib.rst
Normal file
3877
mps/manual/source/bib.rst
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -22,6 +22,34 @@ import sys
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
sys.path.insert(0, os.path.abspath('.'))
|
sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
|
# -- Project configuration -----------------------------------------------------
|
||||||
|
|
||||||
|
# The same set of sources builds the Memory Pool System documentation
|
||||||
|
# and the Memory Management Reference, depending on whether the MMREF
|
||||||
|
# environment variable is set.
|
||||||
|
|
||||||
|
if os.environ.get('MMREF'):
|
||||||
|
project = u'Memory Management Reference'
|
||||||
|
master_doc = 'index'
|
||||||
|
html_theme = 'mmref'
|
||||||
|
version = '4'
|
||||||
|
release = '4.0'
|
||||||
|
else:
|
||||||
|
project = u'Memory Pool System'
|
||||||
|
master_doc = 'index'
|
||||||
|
html_theme = 'mps'
|
||||||
|
html_sidebars = {
|
||||||
|
'**': ['localtoc.html', 'relations.html', 'links.html', 'contact.html'],
|
||||||
|
}
|
||||||
|
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||||
|
'../../code/version.c')) as f:
|
||||||
|
for line in f:
|
||||||
|
m = re.match(r'#define MPS_RELEASE "release/((\d+\.\d+)\.\d+)"', line)
|
||||||
|
if m:
|
||||||
|
release, version = m.groups()
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
# -- General configuration -----------------------------------------------------
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
# If your documentation needs a minimal Sphinx version, state it here.
|
||||||
|
|
@ -40,24 +68,9 @@ source_suffix = '.rst'
|
||||||
# The encoding of source files.
|
# The encoding of source files.
|
||||||
#source_encoding = 'utf-8-sig'
|
#source_encoding = 'utf-8-sig'
|
||||||
|
|
||||||
# The master toctree document.
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'Memory Pool System'
|
|
||||||
copyright = date.today().strftime(u'%Y, Ravenbrook Limited')
|
copyright = date.today().strftime(u'%Y, Ravenbrook Limited')
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
|
||||||
# |version| and |release|, also used in various other places throughout the
|
|
||||||
# built documents.
|
|
||||||
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
|
||||||
'../../code/version.c')) as f:
|
|
||||||
for line in f:
|
|
||||||
m = re.match(r'#define MPS_RELEASE "release/((\d+\.\d+)\.\d+)"', line)
|
|
||||||
if m:
|
|
||||||
release, version = m.groups()
|
|
||||||
break
|
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
#language = None
|
#language = None
|
||||||
|
|
@ -98,10 +111,6 @@ pygments_style = 'sphinx'
|
||||||
|
|
||||||
# -- Options for HTML output ---------------------------------------------------
|
# -- Options for HTML output ---------------------------------------------------
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
html_theme = 'mps'
|
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
# documentation.
|
# documentation.
|
||||||
|
|
@ -119,7 +128,7 @@ html_theme_path = ['themes']
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
# of the sidebar.
|
# of the sidebar.
|
||||||
html_logo = 'diagrams/logo.png'
|
html_logo = 'images/logo.png'
|
||||||
|
|
||||||
# The name of an image file (within the static path) to use as favicon of the
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
|
|
@ -129,7 +138,7 @@ html_logo = 'diagrams/logo.png'
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
html_static_path = []
|
html_static_path = ['images']
|
||||||
|
|
||||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||||
# using the given strftime format.
|
# using the given strftime format.
|
||||||
|
|
@ -139,11 +148,6 @@ html_static_path = []
|
||||||
# typographically correct entities.
|
# typographically correct entities.
|
||||||
html_use_smartypants = True
|
html_use_smartypants = True
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
|
||||||
html_sidebars = {
|
|
||||||
'**': ['localtoc.html', 'relations.html', 'links.html', 'contact.html'],
|
|
||||||
}
|
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to
|
# Additional templates that should be rendered to pages, maps page names to
|
||||||
# template names.
|
# template names.
|
||||||
#html_additional_pages = {}
|
#html_additional_pages = {}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
.. _license:
|
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
single: copyright
|
single: copyright
|
||||||
single: license
|
single: license
|
||||||
|
|
||||||
|
.. _license:
|
||||||
|
|
||||||
.. include:: ../../license.txt
|
.. include:: ../../license.txt
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@ TYPES = '''
|
||||||
|
|
||||||
AccessSet Accumulation Addr Align AllocFrame AllocPattern AP Arg
|
AccessSet Accumulation Addr Align AllocFrame AllocPattern AP Arg
|
||||||
Arena Attr Bool BootBlock BT Buffer BufferMode Byte Chain Chunk
|
Arena Attr Bool BootBlock BT Buffer BufferMode Byte Chain Chunk
|
||||||
Clock Compare Count Epoch FindDelete Format FrameState Fun Globals
|
Clock Compare Count Epoch FindDelete Format FrameState Fun GenDesc
|
||||||
Index Land LD Lock Message MessageType MutatorFaultContext Page
|
Globals Index Land LD Lock Message MessageType MutatorFaultContext
|
||||||
Pointer Pool PThreadext Range Rank RankSet Ref RefSet Res
|
Page Pointer Pool PoolGen PThreadext Range Rank RankSet Ref RefSet
|
||||||
Reservoir Ring Root RootMode RootVar ScanState Seg SegBuf SegPref
|
Res Reservoir Ring Root RootMode RootVar ScanState Seg SegBuf
|
||||||
SegPrefKind Serial Shift Sig Size Space SplayNode SplayTree
|
SegPref SegPrefKind Serial Shift Sig Size Space SplayNode
|
||||||
StackContext Thread Trace TraceId TraceSet TraceStartWhy
|
SplayTree StackContext Thread Trace TraceId TraceSet TraceStartWhy
|
||||||
TraceState ULongest VM Word ZoneSet
|
TraceState ULongest VM Word ZoneSet
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
@ -124,6 +124,15 @@ def convert_file(name, source, dest):
|
||||||
with open(dest, 'wb') as out:
|
with open(dest, 'wb') as out:
|
||||||
out.write(s.encode('utf-8'))
|
out.write(s.encode('utf-8'))
|
||||||
|
|
||||||
|
def newer(src, target):
|
||||||
|
"""Return True if src is newer (that is, modified more recently) than
|
||||||
|
target, False otherwise.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (not os.path.isfile(target)
|
||||||
|
or os.path.getmtime(target) < os.path.getmtime(src)
|
||||||
|
or os.path.getmtime(target) < os.path.getmtime(__file__))
|
||||||
|
|
||||||
# Mini-make
|
# Mini-make
|
||||||
def convert_updated(app):
|
def convert_updated(app):
|
||||||
app.info(bold('converting MPS design documents'))
|
app.info(bold('converting MPS design documents'))
|
||||||
|
|
@ -131,11 +140,11 @@ def convert_updated(app):
|
||||||
name = os.path.splitext(os.path.basename(design))[0]
|
name = os.path.splitext(os.path.basename(design))[0]
|
||||||
if name == 'index': continue
|
if name == 'index': continue
|
||||||
converted = 'source/design/%s.rst' % name
|
converted = 'source/design/%s.rst' % name
|
||||||
if (not os.path.isfile(converted)
|
if newer(design, converted):
|
||||||
or os.path.getmtime(converted) < os.path.getmtime(design)
|
|
||||||
or os.path.getmtime(converted) < os.path.getmtime(__file__)):
|
|
||||||
app.info('converting design %s' % name)
|
app.info('converting design %s' % name)
|
||||||
convert_file(name, design, converted)
|
convert_file(name, design, converted)
|
||||||
for diagram in glob.iglob('../design/*.svg'):
|
for diagram in glob.iglob('../design/*.svg'):
|
||||||
shutil.copyfile(diagram, 'source/design/%s' % os.path.basename(diagram))
|
target = os.path.join('source/design/', os.path.basename(diagram))
|
||||||
|
if newer(diagram, target):
|
||||||
|
shutil.copyfile(diagram, target)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,26 @@ Memory Management Glossary: A
|
||||||
|
|
||||||
.. seealso:: :term:`virtual address space`, :term:`physical address space`.
|
.. seealso:: :term:`virtual address space`, :term:`physical address space`.
|
||||||
|
|
||||||
|
address space layout randomization
|
||||||
|
|
||||||
|
.. aka:: *ASLR*.
|
||||||
|
|
||||||
|
The random placement in :term:`address space` of the
|
||||||
|
:term:`stack`, data segment, :term:`heap`, and so on, of a
|
||||||
|
process.
|
||||||
|
|
||||||
|
The purpose of ASLR is to make it harder for an attacker to
|
||||||
|
exploit buffer overflow bugs, by making it harder to determine
|
||||||
|
the addresses of data structures.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
ASLR also makes it hard to prepare a repeatable test case
|
||||||
|
for a program that performs computation based on the
|
||||||
|
addresses of objects, for example, hashing objects by
|
||||||
|
their address. See :ref:`guide-debug-aslr` for techniques
|
||||||
|
to deal with this.
|
||||||
|
|
||||||
address translation cache
|
address translation cache
|
||||||
|
|
||||||
.. see:: :term:`translation lookaside buffer`.
|
.. see:: :term:`translation lookaside buffer`.
|
||||||
|
|
@ -182,7 +202,11 @@ Memory Management Glossary: A
|
||||||
.. mps:specific::
|
.. mps:specific::
|
||||||
|
|
||||||
An alignment is represented by the unsigned integral type
|
An alignment is represented by the unsigned integral type
|
||||||
:c:type:`mps_align_t`. It must be a positive power of 2.
|
:c:type:`mps_align_t`. It must be a power of 2. The
|
||||||
|
alignment of objects allocated in a :term:`pool` may be
|
||||||
|
specified by passing the :c:macro:`MPS_KEY_ALIGN`
|
||||||
|
:term:`keyword argument` when calling
|
||||||
|
:c:func:`mps_pool_create_k`.
|
||||||
|
|
||||||
alive
|
alive
|
||||||
|
|
||||||
|
|
@ -389,6 +413,10 @@ Memory Management Glossary: A
|
||||||
class of :term:`arenas`. Arena classes include
|
class of :term:`arenas`. Arena classes include
|
||||||
:term:`client arenas` and :term:`virtual memory arenas`.
|
:term:`client arenas` and :term:`virtual memory arenas`.
|
||||||
|
|
||||||
|
ASLR
|
||||||
|
|
||||||
|
.. see:: :term:`address space layout randomization`.
|
||||||
|
|
||||||
assertion
|
assertion
|
||||||
|
|
||||||
A declaration in a program of a condition that is expected
|
A declaration in a program of a condition that is expected
|
||||||
|
|
@ -452,6 +480,12 @@ Memory Management Glossary: A
|
||||||
|
|
||||||
.. opposite:: :term:`manual memory management`.
|
.. opposite:: :term:`manual memory management`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
The MPS provides automatic memory management through
|
||||||
|
:term:`pool classes` such as :ref:`pool-amc`,
|
||||||
|
:ref:`pool-ams`, and :ref:`pool-awl`.
|
||||||
|
|
||||||
automatic storage duration
|
automatic storage duration
|
||||||
|
|
||||||
In :term:`C`, :term:`objects` that are declared with
|
In :term:`C`, :term:`objects` that are declared with
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ Memory Management Glossary: C
|
||||||
|
|
||||||
A cactus stack is a :term:`stack` with branches. When
|
A cactus stack is a :term:`stack` with branches. When
|
||||||
diagrammed, its shape resembles that of a `saguaro cactus
|
diagrammed, its shape resembles that of a `saguaro cactus
|
||||||
<http://www.azstarnet.com/%7Efosnp/factsaboutsaguaros.html>`_.
|
<http://en.wikipedia.org/wiki/Saguaro>`_.
|
||||||
|
|
||||||
In languages that support :term:`continuations`,
|
In languages that support :term:`continuations`,
|
||||||
:term:`activation records` can have :term:`indefinite extent`.
|
:term:`activation records` can have :term:`indefinite extent`.
|
||||||
|
|
@ -615,6 +615,12 @@ Memory Management Glossary: C
|
||||||
|
|
||||||
.. seealso:: :term:`broken heart`, :term:`forwarding pointer`, :term:`two-space collector`.
|
.. seealso:: :term:`broken heart`, :term:`forwarding pointer`, :term:`two-space collector`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
The :ref:`pool-amc` pool class implements copying garbage
|
||||||
|
collection (more precisely, :term:`mostly-copying garbage
|
||||||
|
collection`).
|
||||||
|
|
||||||
core
|
core
|
||||||
|
|
||||||
A historical synonym for :term:`main memory`, deriving from
|
A historical synonym for :term:`main memory`, deriving from
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,11 @@ Memory Management Glossary: F
|
||||||
|
|
||||||
.. similar:: :term:`in-band header`.
|
.. similar:: :term:`in-band header`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
:term:`Debugging pools` use fenceposts. See
|
||||||
|
:ref:`topic-debugging`.
|
||||||
|
|
||||||
fencepost error
|
fencepost error
|
||||||
fence post error
|
fence post error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ Memory Management Glossary: G
|
||||||
|
|
||||||
This term is often used when referring to particular
|
This term is often used when referring to particular
|
||||||
implementations or algorithms, for example, "the
|
implementations or algorithms, for example, "the
|
||||||
Boehm-Demers-Weiser *collector*".
|
Boehm--Demers--Weiser *collector*".
|
||||||
|
|
||||||
GB
|
GB
|
||||||
|
|
||||||
|
|
@ -132,16 +132,16 @@ Memory Management Glossary: G
|
||||||
.. mps:specific::
|
.. mps:specific::
|
||||||
|
|
||||||
The :term:`client program` specifies the generational
|
The :term:`client program` specifies the generational
|
||||||
structure of a :term:`pool` using a :term:`generation
|
structure of a :term:`pool` (or group of pools) using a
|
||||||
chain`. See :ref:`topic-collection`.
|
:term:`generation chain`. See :ref:`topic-collection`.
|
||||||
|
|
||||||
generation chain
|
generation chain
|
||||||
|
|
||||||
.. mps:specific::
|
.. mps:specific::
|
||||||
|
|
||||||
A data structure that specifies the structure of the
|
A data structure that specifies the structure of the
|
||||||
:term:`generations` in a :term:`pool`. See
|
:term:`generations` in a :term:`pool` (or group of pools).
|
||||||
:ref:`topic-collection`.
|
See :ref:`topic-collection`.
|
||||||
|
|
||||||
generation scavenging
|
generation scavenging
|
||||||
|
|
||||||
|
|
@ -174,6 +174,11 @@ Memory Management Glossary: G
|
||||||
|
|
||||||
.. seealso:: :term:`remembered set`.
|
.. seealso:: :term:`remembered set`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
The :ref:`pool-amc` and :ref:`pool-amcz` pool classes
|
||||||
|
support generational garbage collection.
|
||||||
|
|
||||||
generational hypothesis
|
generational hypothesis
|
||||||
|
|
||||||
.. aka:: *infant mortality*.
|
.. aka:: *infant mortality*.
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,12 @@ Memory Management Glossary: I
|
||||||
|
|
||||||
.. bibref:: :ref:`Appel et al. (1988) <AEL88>`, :ref:`Boehm et al. (1991) <BDS91>`.
|
.. bibref:: :ref:`Appel et al. (1988) <AEL88>`, :ref:`Boehm et al. (1991) <BDS91>`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
The MPS uses incremental collection, except for
|
||||||
|
collections started by calling
|
||||||
|
:c:func:`mps_arena_collect`.
|
||||||
|
|
||||||
incremental update
|
incremental update
|
||||||
|
|
||||||
Incremental-update algorithms for :term:`tracing <trace>`,
|
Incremental-update algorithms for :term:`tracing <trace>`,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ Memory Management Glossary
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
:hidden:
|
||||||
|
|
||||||
a
|
a
|
||||||
b
|
b
|
||||||
|
|
@ -31,3 +32,594 @@ Memory Management Glossary
|
||||||
v
|
v
|
||||||
w
|
w
|
||||||
z
|
z
|
||||||
|
|
||||||
|
All
|
||||||
|
===
|
||||||
|
|
||||||
|
:term:`absolute address <physical address>`
|
||||||
|
:term:`activation frame <activation record>`
|
||||||
|
:term:`activation record`
|
||||||
|
:term:`activation stack <control stack>`
|
||||||
|
:term:`active <live>`
|
||||||
|
:term:`address`
|
||||||
|
:term:`address space`
|
||||||
|
:term:`address space layout randomization`
|
||||||
|
:term:`address translation cache <translation lookaside buffer>`
|
||||||
|
:term:`address-ordered first fit`
|
||||||
|
:term:`aging space`
|
||||||
|
:term:`algebraic data type`
|
||||||
|
:term:`alignment`
|
||||||
|
:term:`alive <live>`
|
||||||
|
:term:`allocate`
|
||||||
|
:term:`allocation frame`
|
||||||
|
:term:`allocation mechanism`
|
||||||
|
:term:`allocation pattern`
|
||||||
|
:term:`allocation point`
|
||||||
|
:term:`allocation point protocol`
|
||||||
|
:term:`allocation policy`
|
||||||
|
:term:`allocation strategy`
|
||||||
|
:term:`allocator`
|
||||||
|
:term:`ambiguous reference`
|
||||||
|
:term:`ambiguous root`
|
||||||
|
:term:`arena`
|
||||||
|
:term:`arena class`
|
||||||
|
:term:`ASLR <address space layout randomization>`
|
||||||
|
:term:`assertion`
|
||||||
|
:term:`asynchronous garbage collector`
|
||||||
|
:term:`ATC <translation lookaside buffer>`
|
||||||
|
:term:`atomic object <leaf object>`
|
||||||
|
:term:`automatic memory management`
|
||||||
|
:term:`automatic storage duration`
|
||||||
|
|
||||||
|
:term:`backing store`
|
||||||
|
:term:`barrier (1)`
|
||||||
|
:term:`barrier (2)`
|
||||||
|
:term:`barrier hit <protection fault>`
|
||||||
|
:term:`base pointer`
|
||||||
|
:term:`best fit`
|
||||||
|
:term:`BIBOP`
|
||||||
|
:term:`big bag of pages <BIBOP>`
|
||||||
|
:term:`binary buddies`
|
||||||
|
:term:`bit array <bitmap>`
|
||||||
|
:term:`bit table <bitmap>`
|
||||||
|
:term:`bit vector <bitmap>`
|
||||||
|
:term:`bitmap`
|
||||||
|
:term:`bitmapped fit`
|
||||||
|
:term:`bitmask`
|
||||||
|
:term:`bitset <bitmap>`
|
||||||
|
:term:`black`
|
||||||
|
:term:`blacklisting`
|
||||||
|
:term:`black-listing`
|
||||||
|
:term:`block`
|
||||||
|
:term:`bounds error <overwriting error>`
|
||||||
|
:term:`boxed`
|
||||||
|
:term:`break-table`
|
||||||
|
:term:`brk`
|
||||||
|
:term:`broken heart`
|
||||||
|
:term:`bucket`
|
||||||
|
:term:`buddy system`
|
||||||
|
:term:`buffer`
|
||||||
|
:term:`bus error`
|
||||||
|
:term:`byte (1)`
|
||||||
|
:term:`byte (2)`
|
||||||
|
:term:`byte (3)`
|
||||||
|
:term:`byte (4)`
|
||||||
|
|
||||||
|
:term:`C89 <C90>`
|
||||||
|
:term:`C90`
|
||||||
|
:term:`C99`
|
||||||
|
:term:`cache (1)`
|
||||||
|
:term:`cache (2)`
|
||||||
|
:term:`cache memory <cache (1)>`
|
||||||
|
:term:`cache policy`
|
||||||
|
:term:`caching (3)`
|
||||||
|
:term:`cactus stack`
|
||||||
|
:term:`card`
|
||||||
|
:term:`card marking`
|
||||||
|
:term:`cell <object>`
|
||||||
|
:term:`Cheney collector`
|
||||||
|
:term:`Cheney scan <Cheney collector>`
|
||||||
|
:term:`clamped state`
|
||||||
|
:term:`client arena`
|
||||||
|
:term:`client object`
|
||||||
|
:term:`client pointer`
|
||||||
|
:term:`client program <mutator>`
|
||||||
|
:term:`closure`
|
||||||
|
:term:`coalesce`
|
||||||
|
:term:`collect`
|
||||||
|
:term:`collection <collection cycle>`
|
||||||
|
:term:`collection cycle`
|
||||||
|
:term:`collector (1) <garbage collector>`
|
||||||
|
:term:`collector (2)`
|
||||||
|
:term:`color`
|
||||||
|
:term:`colour`
|
||||||
|
:term:`commit limit`
|
||||||
|
:term:`committed (1) <mapped>`
|
||||||
|
:term:`committed (2)`
|
||||||
|
:term:`compactifying <compaction>`
|
||||||
|
:term:`compaction`
|
||||||
|
:term:`composite object`
|
||||||
|
:term:`comprehensive`
|
||||||
|
:term:`concurrent garbage collection <parallel garbage collection>`
|
||||||
|
:term:`condemned set`
|
||||||
|
:term:`connected`
|
||||||
|
:term:`cons (1)`
|
||||||
|
:term:`cons (2) <allocate>`
|
||||||
|
:term:`conservative garbage collection`
|
||||||
|
:term:`constant root`
|
||||||
|
:term:`constructor (1)`
|
||||||
|
:term:`constructor (2)`
|
||||||
|
:term:`continuation`
|
||||||
|
:term:`control stack`
|
||||||
|
:term:`cool`
|
||||||
|
:term:`copy method`
|
||||||
|
:term:`copying garbage collection`
|
||||||
|
:term:`core`
|
||||||
|
:term:`creation space`
|
||||||
|
:term:`critical path`
|
||||||
|
:term:`crossing map`
|
||||||
|
:term:`cyclic data structure`
|
||||||
|
|
||||||
|
:term:`dangling pointer`
|
||||||
|
:term:`data stack`
|
||||||
|
:term:`dead`
|
||||||
|
:term:`deallocate <free (1)>`
|
||||||
|
:term:`debugging pool`
|
||||||
|
:term:`deferred coalescing`
|
||||||
|
:term:`deferred reference counting`
|
||||||
|
:term:`dependent object`
|
||||||
|
:term:`derived pointer <interior pointer>`
|
||||||
|
:term:`derived type`
|
||||||
|
:term:`destructor (1)`
|
||||||
|
:term:`destructor (2)`
|
||||||
|
:term:`DGC <distributed garbage collection>`
|
||||||
|
:term:`direct method`
|
||||||
|
:term:`dirty bit`
|
||||||
|
:term:`distributed garbage collection`
|
||||||
|
:term:`double buddies`
|
||||||
|
:term:`double free`
|
||||||
|
:term:`doubleword`
|
||||||
|
:term:`doubly weak hash table`
|
||||||
|
:term:`DRAM <dynamic memory>`
|
||||||
|
:term:`dynamic allocation <heap allocation>`
|
||||||
|
:term:`dynamic extent`
|
||||||
|
:term:`dynamic memory`
|
||||||
|
:term:`dynamic RAM <dynamic memory>`
|
||||||
|
|
||||||
|
:term:`ecru <off-white>`
|
||||||
|
:term:`edge`
|
||||||
|
:term:`entry table (1)`
|
||||||
|
:term:`entry table (2)`
|
||||||
|
:term:`exact garbage collection`
|
||||||
|
:term:`exact reference`
|
||||||
|
:term:`exact root`
|
||||||
|
:term:`exact segregated fit`
|
||||||
|
:term:`execution stack <control stack>`
|
||||||
|
:term:`exit table`
|
||||||
|
:term:`extent <lifetime>`
|
||||||
|
:term:`external fragmentation`
|
||||||
|
|
||||||
|
:term:`fencepost`
|
||||||
|
:term:`fence post`
|
||||||
|
:term:`fencepost error`
|
||||||
|
:term:`fence post error`
|
||||||
|
:term:`Fibonacci buddies`
|
||||||
|
:term:`FIFO-ordered first fit`
|
||||||
|
:term:`file mapping <memory mapping>`
|
||||||
|
:term:`finalization`
|
||||||
|
:term:`finalized block`
|
||||||
|
:term:`first fit`
|
||||||
|
:term:`fix`
|
||||||
|
:term:`flip`
|
||||||
|
:term:`floating garbage`
|
||||||
|
:term:`foreign code`
|
||||||
|
:term:`format`
|
||||||
|
:term:`format method`
|
||||||
|
:term:`formatted object`
|
||||||
|
:term:`forward method`
|
||||||
|
:term:`forwarding marker`
|
||||||
|
:term:`forwarding object`
|
||||||
|
:term:`forwarding pointer`
|
||||||
|
:term:`fragmentation`
|
||||||
|
:term:`frame <in-band header>`
|
||||||
|
:term:`free (1)`
|
||||||
|
:term:`free (2)`
|
||||||
|
:term:`free (3)`
|
||||||
|
:term:`free (4) <unmapped>`
|
||||||
|
:term:`free block`
|
||||||
|
:term:`free block chain`
|
||||||
|
:term:`free list`
|
||||||
|
:term:`free store <heap>`
|
||||||
|
:term:`freestore <heap>`
|
||||||
|
:term:`from space`
|
||||||
|
:term:`fromspace`
|
||||||
|
:term:`function pointer`
|
||||||
|
:term:`function record <activation record>`
|
||||||
|
|
||||||
|
:term:`garbage`
|
||||||
|
:term:`garbage collection`
|
||||||
|
:term:`garbage collector`
|
||||||
|
:term:`GB <gigabyte>`
|
||||||
|
:term:`GC <garbage collection>`
|
||||||
|
:term:`General Protection Fault`
|
||||||
|
:term:`generation`
|
||||||
|
:term:`generation chain`
|
||||||
|
:term:`generation scavenging <generational garbage collection>`
|
||||||
|
:term:`generational garbage collection`
|
||||||
|
:term:`generational hypothesis`
|
||||||
|
:term:`gigabyte`
|
||||||
|
:term:`good fit`
|
||||||
|
:term:`GPF <General Protection Fault>`
|
||||||
|
:term:`grain`
|
||||||
|
:term:`graph`
|
||||||
|
:term:`gray`
|
||||||
|
:term:`grey`
|
||||||
|
:term:`gray list`
|
||||||
|
:term:`grey list`
|
||||||
|
|
||||||
|
:term:`handle`
|
||||||
|
:term:`header <in-band header>`
|
||||||
|
:term:`heap`
|
||||||
|
:term:`heap allocation`
|
||||||
|
:term:`hit`
|
||||||
|
:term:`hit rate`
|
||||||
|
:term:`hot`
|
||||||
|
:term:`huge page`
|
||||||
|
|
||||||
|
:term:`immediate data`
|
||||||
|
:term:`immune set`
|
||||||
|
:term:`immutable`
|
||||||
|
:term:`immutable object <value object>`
|
||||||
|
:term:`in-band header`
|
||||||
|
:term:`in parameter`
|
||||||
|
:term:`in/out parameter`
|
||||||
|
:term:`incremental garbage collection`
|
||||||
|
:term:`incremental update`
|
||||||
|
:term:`indefinite extent`
|
||||||
|
:term:`indexed fit`
|
||||||
|
:term:`indirect method`
|
||||||
|
:term:`infant mortality <generational hypothesis>`
|
||||||
|
:term:`inline allocation (1)`
|
||||||
|
:term:`inline allocation (2)`
|
||||||
|
:term:`inter-generational pointer`
|
||||||
|
:term:`interior pointer`
|
||||||
|
:term:`internal fragmentation`
|
||||||
|
:term:`invalid page fault`
|
||||||
|
:term:`inverted page table`
|
||||||
|
:term:`inverted page-table`
|
||||||
|
:term:`is-forwarded method`
|
||||||
|
|
||||||
|
:term:`kB <kilobyte>`
|
||||||
|
:term:`keyword argument`
|
||||||
|
:term:`kilobyte`
|
||||||
|
|
||||||
|
:term:`large object area`
|
||||||
|
:term:`large page <huge page>`
|
||||||
|
:term:`leaf object`
|
||||||
|
:term:`leak <memory leak>`
|
||||||
|
:term:`life <lifetime>`
|
||||||
|
:term:`lifetime`
|
||||||
|
:term:`LIFO-ordered first fit`
|
||||||
|
:term:`limited-field reference count`
|
||||||
|
:term:`linear addressing`
|
||||||
|
:term:`live`
|
||||||
|
:term:`load`
|
||||||
|
:term:`locality of reference`
|
||||||
|
:term:`location <memory location>`
|
||||||
|
:term:`location dependency`
|
||||||
|
:term:`lock free`
|
||||||
|
:term:`logical address <virtual address>`
|
||||||
|
:term:`longword <doubleword>`
|
||||||
|
|
||||||
|
:term:`machine word <word>`
|
||||||
|
:term:`main memory`
|
||||||
|
:term:`malloc`
|
||||||
|
:term:`manual memory management`
|
||||||
|
:term:`mapped`
|
||||||
|
:term:`mapping`
|
||||||
|
:term:`mark-compact`
|
||||||
|
:term:`mark-sweep`
|
||||||
|
:term:`mark-and-sweep`
|
||||||
|
:term:`marking`
|
||||||
|
:term:`MB <megabyte>`
|
||||||
|
:term:`megabyte`
|
||||||
|
:term:`memoization <caching (3)>`
|
||||||
|
:term:`memory (1)`
|
||||||
|
:term:`memory (2)`
|
||||||
|
:term:`memory (3) <main memory>`
|
||||||
|
:term:`memory (4)`
|
||||||
|
:term:`memory bandwidth`
|
||||||
|
:term:`memory cache <cache (1)>`
|
||||||
|
:term:`memory hierarchy <storage hierarchy>`
|
||||||
|
:term:`memory leak`
|
||||||
|
:term:`memory location`
|
||||||
|
:term:`memory management`
|
||||||
|
:term:`Memory Management Unit <MMU>`
|
||||||
|
:term:`memory manager`
|
||||||
|
:term:`memory mapping`
|
||||||
|
:term:`memory protection <protection>`
|
||||||
|
:term:`message`
|
||||||
|
:term:`message queue`
|
||||||
|
:term:`message type`
|
||||||
|
:term:`misaligned <unaligned>`
|
||||||
|
:term:`miss`
|
||||||
|
:term:`miss rate`
|
||||||
|
:term:`mmap`
|
||||||
|
:term:`MMU`
|
||||||
|
:term:`mostly-copying garbage collection`
|
||||||
|
:term:`mostly-exact garbage collection <semi-conservative garbage collection>`
|
||||||
|
:term:`mostly-precise garbage collection <semi-conservative garbage collection>`
|
||||||
|
:term:`moving garbage collector`
|
||||||
|
:term:`moving memory manager`
|
||||||
|
:term:`mutable`
|
||||||
|
:term:`mutator`
|
||||||
|
|
||||||
|
:term:`nailing <pinning>`
|
||||||
|
:term:`natural alignment`
|
||||||
|
:term:`nepotism`
|
||||||
|
:term:`next fit`
|
||||||
|
:term:`new space`
|
||||||
|
:term:`newspace <tospace>`
|
||||||
|
:term:`node`
|
||||||
|
:term:`non-moving garbage collector`
|
||||||
|
:term:`non-moving memory manager`
|
||||||
|
:term:`nursery generation <nursery space>`
|
||||||
|
:term:`nursery space`
|
||||||
|
|
||||||
|
:term:`object`
|
||||||
|
:term:`object format`
|
||||||
|
:term:`object pointer`
|
||||||
|
:term:`off-white`
|
||||||
|
:term:`old space <fromspace>`
|
||||||
|
:term:`oldspace <fromspace>`
|
||||||
|
:term:`one-bit reference count`
|
||||||
|
:term:`opaque type`
|
||||||
|
:term:`out parameter`
|
||||||
|
:term:`out-of-band header`
|
||||||
|
:term:`overcommit`
|
||||||
|
:term:`overwriting error`
|
||||||
|
|
||||||
|
:term:`padding`
|
||||||
|
:term:`padding method`
|
||||||
|
:term:`padding object`
|
||||||
|
:term:`page`
|
||||||
|
:term:`page fault`
|
||||||
|
:term:`page marking`
|
||||||
|
:term:`page protection <protection>`
|
||||||
|
:term:`page table`
|
||||||
|
:term:`paged in`
|
||||||
|
:term:`paged out`
|
||||||
|
:term:`paging`
|
||||||
|
:term:`palimpsest`
|
||||||
|
:term:`parallel garbage collection`
|
||||||
|
:term:`parked state`
|
||||||
|
:term:`perfect fit`
|
||||||
|
:term:`phantom reachable`
|
||||||
|
:term:`phantomly reachable`
|
||||||
|
:term:`phantom reference`
|
||||||
|
:term:`physical address`
|
||||||
|
:term:`physical address space`
|
||||||
|
:term:`physical memory (1)`
|
||||||
|
:term:`physical memory (2)`
|
||||||
|
:term:`physical storage <physical memory (2)>`
|
||||||
|
:term:`pig in the python`
|
||||||
|
:term:`pig in the snake <pig in the python>`
|
||||||
|
:term:`pinning`
|
||||||
|
:term:`placement policy <allocation policy>`
|
||||||
|
:term:`platform`
|
||||||
|
:term:`plinth`
|
||||||
|
:term:`pointer`
|
||||||
|
:term:`pool`
|
||||||
|
:term:`pool class`
|
||||||
|
:term:`precise garbage collection <exact garbage collection>`
|
||||||
|
:term:`precise reference <exact reference>`
|
||||||
|
:term:`precise root <exact root>`
|
||||||
|
:term:`premature free`
|
||||||
|
:term:`premature promotion <premature tenuring>`
|
||||||
|
:term:`premature tenuring`
|
||||||
|
:term:`primary storage <main memory>`
|
||||||
|
:term:`promotion`
|
||||||
|
:term:`protectable root`
|
||||||
|
:term:`protection`
|
||||||
|
:term:`protection exception <protection fault>`
|
||||||
|
:term:`protection fault`
|
||||||
|
:term:`protection violation <protection fault>`
|
||||||
|
|
||||||
|
:term:`quadword`
|
||||||
|
|
||||||
|
:term:`RAM`
|
||||||
|
:term:`random access memory <RAM>`
|
||||||
|
:term:`ramp allocation`
|
||||||
|
:term:`rank`
|
||||||
|
:term:`rash`
|
||||||
|
:term:`raw <unwrapped>`
|
||||||
|
:term:`reachable`
|
||||||
|
:term:`read barrier`
|
||||||
|
:term:`read fault`
|
||||||
|
:term:`read-only memory <ROM>`
|
||||||
|
:term:`real memory (1)`
|
||||||
|
:term:`real memory (2) <physical memory (1)>`
|
||||||
|
:term:`reclaim`
|
||||||
|
:term:`recycle`
|
||||||
|
:term:`reference`
|
||||||
|
:term:`reference counting`
|
||||||
|
:term:`reference object`
|
||||||
|
:term:`region inference`
|
||||||
|
:term:`register`
|
||||||
|
:term:`register set partitioning`
|
||||||
|
:term:`relocation`
|
||||||
|
:term:`remembered set`
|
||||||
|
:term:`remote reference`
|
||||||
|
:term:`replicating garbage collector`
|
||||||
|
:term:`reserved`
|
||||||
|
:term:`resident`
|
||||||
|
:term:`resident set`
|
||||||
|
:term:`result code`
|
||||||
|
:term:`resurrection`
|
||||||
|
:term:`ROM`
|
||||||
|
:term:`root`
|
||||||
|
:term:`root description`
|
||||||
|
:term:`root mode`
|
||||||
|
:term:`root set`
|
||||||
|
|
||||||
|
:term:`sbrk`
|
||||||
|
:term:`scalar data type`
|
||||||
|
:term:`scan`
|
||||||
|
:term:`scan method`
|
||||||
|
:term:`scan state`
|
||||||
|
:term:`scavenging garbage collection <copying garbage collection>`
|
||||||
|
:term:`SDRAM`
|
||||||
|
:term:`segmentation violation`
|
||||||
|
:term:`segmented addressing`
|
||||||
|
:term:`segregated allocation cache`
|
||||||
|
:term:`segregated fit`
|
||||||
|
:term:`segregated free list`
|
||||||
|
:term:`segregated free-list`
|
||||||
|
:term:`semi-conservative garbage collection`
|
||||||
|
:term:`semi-space`
|
||||||
|
:term:`semi-space collector <two-space collector>`
|
||||||
|
:term:`sequential fit`
|
||||||
|
:term:`sequential store buffer`
|
||||||
|
:term:`shared memory`
|
||||||
|
:term:`simple object`
|
||||||
|
:term:`simple segregated storage`
|
||||||
|
:term:`size`
|
||||||
|
:term:`size class`
|
||||||
|
:term:`skip method`
|
||||||
|
:term:`smart pointer`
|
||||||
|
:term:`snap-out`
|
||||||
|
:term:`snapshot at the beginning`
|
||||||
|
:term:`soft reference`
|
||||||
|
:term:`softly reachable`
|
||||||
|
:term:`space leak <memory leak>`
|
||||||
|
:term:`spare commit limit`
|
||||||
|
:term:`spare committed memory`
|
||||||
|
:term:`spaghetti stack <cactus stack>`
|
||||||
|
:term:`splat`
|
||||||
|
:term:`split`
|
||||||
|
:term:`SRAM <static memory (1)>`
|
||||||
|
:term:`SSB <sequential store buffer>`
|
||||||
|
:term:`stack`
|
||||||
|
:term:`stack allocation`
|
||||||
|
:term:`stack frame`
|
||||||
|
:term:`stack record <stack frame>`
|
||||||
|
:term:`static allocation`
|
||||||
|
:term:`static memory (1)`
|
||||||
|
:term:`static memory (2)`
|
||||||
|
:term:`static object`
|
||||||
|
:term:`static RAM <static memory (1)>`
|
||||||
|
:term:`static storage duration`
|
||||||
|
:term:`stepper function`
|
||||||
|
:term:`sticky reference count <limited-field reference count>`
|
||||||
|
:term:`stop-and-copy collection`
|
||||||
|
:term:`storage <memory (1)>`
|
||||||
|
:term:`storage hierarchy`
|
||||||
|
:term:`storage level`
|
||||||
|
:term:`storage management <memory management>`
|
||||||
|
:term:`store (1)`
|
||||||
|
:term:`store (2) <memory (1)>`
|
||||||
|
:term:`stretchy vector`
|
||||||
|
:term:`strict segregated fit`
|
||||||
|
:term:`strong reference`
|
||||||
|
:term:`strong root`
|
||||||
|
:term:`strong tri-color invariant`
|
||||||
|
:term:`strong tri-colour invariant`
|
||||||
|
:term:`strong tricolor invariant`
|
||||||
|
:term:`strong tricolour invariant`
|
||||||
|
:term:`strongly reachable`
|
||||||
|
:term:`suballocator`
|
||||||
|
:term:`subgraph`
|
||||||
|
:term:`superpage <huge page>`
|
||||||
|
:term:`sure reference <exact reference>`
|
||||||
|
:term:`swap space`
|
||||||
|
:term:`swapped in`
|
||||||
|
:term:`swapped out`
|
||||||
|
:term:`swapping`
|
||||||
|
:term:`sweeping`
|
||||||
|
:term:`synchronous garbage collector`
|
||||||
|
|
||||||
|
:term:`tabling <caching (3)>`
|
||||||
|
:term:`tag`
|
||||||
|
:term:`tagged architecture`
|
||||||
|
:term:`tagged reference`
|
||||||
|
:term:`TB (1) <terabyte>`
|
||||||
|
:term:`TB (2) <translation lookaside buffer>`
|
||||||
|
:term:`telemetry filter`
|
||||||
|
:term:`telemetry label`
|
||||||
|
:term:`telemetry stream`
|
||||||
|
:term:`tenuring <promotion>`
|
||||||
|
:term:`terabyte`
|
||||||
|
:term:`termination <finalization>`
|
||||||
|
:term:`thrash`
|
||||||
|
:term:`thread`
|
||||||
|
:term:`threatened set <condemned set>`
|
||||||
|
:term:`TLB <translation lookaside buffer>`
|
||||||
|
:term:`to space`
|
||||||
|
:term:`tospace`
|
||||||
|
:term:`trace`
|
||||||
|
:term:`tracing garbage collection`
|
||||||
|
:term:`translation buffer`
|
||||||
|
:term:`translation lookaside buffer`
|
||||||
|
:term:`transparent alias`
|
||||||
|
:term:`transparent type`
|
||||||
|
:term:`transport`
|
||||||
|
:term:`transport snap-out <snap-out>`
|
||||||
|
:term:`treadmill`
|
||||||
|
:term:`tri-color invariant`
|
||||||
|
:term:`tri-colour invariant`
|
||||||
|
:term:`tricolor invariant`
|
||||||
|
:term:`tricolour invariant`
|
||||||
|
:term:`tri-color marking`
|
||||||
|
:term:`tri-colour marking`
|
||||||
|
:term:`tricolor marking`
|
||||||
|
:term:`tricolour marking`
|
||||||
|
:term:`two-space collector`
|
||||||
|
:term:`two space collector`
|
||||||
|
:term:`type-accurate garbage collection <exact garbage collection>`
|
||||||
|
:term:`type punning`
|
||||||
|
|
||||||
|
:term:`unaligned`
|
||||||
|
:term:`unboxed`
|
||||||
|
:term:`unclamped state`
|
||||||
|
:term:`undead`
|
||||||
|
:term:`unmapped`
|
||||||
|
:term:`unreachable`
|
||||||
|
:term:`unsure reference <ambiguous reference>`
|
||||||
|
:term:`unwrapped`
|
||||||
|
:term:`use after free <premature free>`
|
||||||
|
|
||||||
|
:term:`value object`
|
||||||
|
:term:`variety`
|
||||||
|
:term:`vector data type`
|
||||||
|
:term:`virtual address`
|
||||||
|
:term:`virtual address space`
|
||||||
|
:term:`virtual memory`
|
||||||
|
:term:`virtual memory arena`
|
||||||
|
:term:`visitor function <stepper function>`
|
||||||
|
:term:`VM (1) <virtual memory>`
|
||||||
|
:term:`VM (2)`
|
||||||
|
|
||||||
|
:term:`weak-key hash table`
|
||||||
|
:term:`weak-value hash table`
|
||||||
|
:term:`weak hash table`
|
||||||
|
:term:`weak reference (1)`
|
||||||
|
:term:`weak reference (2)`
|
||||||
|
:term:`weak root`
|
||||||
|
:term:`weak tri-color invariant`
|
||||||
|
:term:`weak tri-colour invariant`
|
||||||
|
:term:`weak tricolor invariant`
|
||||||
|
:term:`weak tricolour invariant`
|
||||||
|
:term:`weakly reachable`
|
||||||
|
:term:`weighted buddies`
|
||||||
|
:term:`weighted reference counting`
|
||||||
|
:term:`white`
|
||||||
|
:term:`word`
|
||||||
|
:term:`working set`
|
||||||
|
:term:`worst fit`
|
||||||
|
:term:`wrapped`
|
||||||
|
:term:`wrapper`
|
||||||
|
:term:`write barrier`
|
||||||
|
:term:`write fault`
|
||||||
|
|
||||||
|
:term:`ZCT <zero count table>`
|
||||||
|
:term:`zero count table`
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,14 @@ Memory Management Glossary: L
|
||||||
If leaf objects can be identified, a :term:`garbage
|
If leaf objects can be identified, a :term:`garbage
|
||||||
collector` can make certain optimizations: leaf objects do
|
collector` can make certain optimizations: leaf objects do
|
||||||
not have to be :term:`scanned <scan>` for references nor
|
not have to be :term:`scanned <scan>` for references nor
|
||||||
are :term:`barrier (1)` needed to detect
|
are :term:`barriers (1)` needed to detect
|
||||||
and maintain references in the object.
|
and maintain references in the object.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
The :ref:`pool-amcz` and :ref:`pool-lo` pool classes are
|
||||||
|
designed for the storage of leaf objects.
|
||||||
|
|
||||||
leak
|
leak
|
||||||
|
|
||||||
.. see:: :term:`memory leak`.
|
.. see:: :term:`memory leak`.
|
||||||
|
|
|
||||||
|
|
@ -535,6 +535,11 @@ Memory Management Glossary: M
|
||||||
|
|
||||||
.. bibref:: :ref:`Bartlett (1989) <BARTLETT89>`, :ref:`Yip (1991) <YIP91>`.
|
.. bibref:: :ref:`Bartlett (1989) <BARTLETT89>`, :ref:`Yip (1991) <YIP91>`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
The :ref:`pool-amc` pool class implements mostly-copying
|
||||||
|
garbage collection.
|
||||||
|
|
||||||
mostly-exact garbage collection
|
mostly-exact garbage collection
|
||||||
|
|
||||||
.. see:: :term:`semi-conservative garbage collection`.
|
.. see:: :term:`semi-conservative garbage collection`.
|
||||||
|
|
|
||||||
|
|
@ -117,4 +117,10 @@ Memory Management Glossary: N
|
||||||
The size of the nursery space must be chosen carefully. Often
|
The size of the nursery space must be chosen carefully. Often
|
||||||
it is related to the size of :term:`physical memory (1)`.
|
it is related to the size of :term:`physical memory (1)`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
By default, a garbage-collected :term:`pool` allocates
|
||||||
|
into the first :term:`generation` in its :term:`generation
|
||||||
|
chain`, but this can be altered by setting the
|
||||||
|
:c:macro:`MPS_KEY_GEN` :term:`keyword argument` when
|
||||||
|
calling :c:func:`mps_pool_create_k`.
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ Memory Management Glossary: P
|
||||||
mutator changing :term:`objects` while collection
|
mutator changing :term:`objects` while collection
|
||||||
occurs. The problem is similar to that of :term:`incremental
|
occurs. The problem is similar to that of :term:`incremental
|
||||||
GC <incremental garbage collection>`, but harder. The solution
|
GC <incremental garbage collection>`, but harder. The solution
|
||||||
typically involves :term:`barrier (1)`.
|
typically involves :term:`barriers (1)`.
|
||||||
|
|
||||||
.. similar:: :term:`incremental <incremental garbage collection>`.
|
.. similar:: :term:`incremental <incremental garbage collection>`.
|
||||||
|
|
||||||
|
|
@ -222,7 +222,7 @@ Memory Management Glossary: P
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Class java.lang.ref.PhantomReference <http://download.java.net/jdk8/docs/api/java/lang/ref/PhantomReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Class java.lang.ref.PhantomReference <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/PhantomReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
phantom reference
|
phantom reference
|
||||||
|
|
||||||
|
|
@ -239,7 +239,7 @@ Memory Management Glossary: P
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Class java.lang.ref.PhantomReference <http://download.java.net/jdk8/docs/api/java/lang/ref/PhantomReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Class java.lang.ref.PhantomReference <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/PhantomReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
physical address
|
physical address
|
||||||
|
|
||||||
|
|
@ -321,6 +321,14 @@ Memory Management Glossary: P
|
||||||
|
|
||||||
.. seealso:: :term:`generational garbage collection`.
|
.. seealso:: :term:`generational garbage collection`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
A :term:`pool` can be configured to allocate into a
|
||||||
|
specific :term:`generation` in its :term:`generation
|
||||||
|
chain` by setting the :c:macro:`MPS_KEY_GEN`
|
||||||
|
:term:`keyword argument` when calling
|
||||||
|
:c:func:`mps_pool_create_k`.
|
||||||
|
|
||||||
pig in the snake
|
pig in the snake
|
||||||
|
|
||||||
.. see:: :term:`pig in the python`.
|
.. see:: :term:`pig in the python`.
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ Memory Management Glossary: R
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Package java.lang.ref <http://download.java.net/jdk8/docs/api/java/lang/ref/package-summary.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Package java.lang.ref <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/package-summary.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
read barrier
|
read barrier
|
||||||
|
|
||||||
|
|
@ -317,7 +317,7 @@ Memory Management Glossary: R
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Package java.lang.ref <http://download.java.net/jdk8/docs/api/java/lang/ref/package-summary.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Package java.lang.ref <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/package-summary.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
.. bibref:: :ref:`Dybvig et al. (1993) <DBE93>`.
|
.. bibref:: :ref:`Dybvig et al. (1993) <DBE93>`.
|
||||||
|
|
||||||
|
|
@ -471,6 +471,11 @@ Memory Management Glossary: R
|
||||||
|
|
||||||
.. seealso:: :term:`mapping`, :term:`mmap`.
|
.. seealso:: :term:`mapping`, :term:`mmap`.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
The function :c:func:`mps_arena_reserved` returns the
|
||||||
|
total address space reserved by an arena.
|
||||||
|
|
||||||
resident
|
resident
|
||||||
|
|
||||||
In a :term:`cache (2)` system, that part of the cached storage
|
In a :term:`cache (2)` system, that part of the cached storage
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ Memory Management Glossary: S
|
||||||
|
|
||||||
By overloading certain operators it is possible for the class
|
By overloading certain operators it is possible for the class
|
||||||
to present the illusion of being a pointer, so that
|
to present the illusion of being a pointer, so that
|
||||||
``operator\*``, ``operator-\>``, etc. can be used as normal.
|
``operator*``, ``operator->``, etc. can be used as normal.
|
||||||
Reference counting allows the objects that are referred to
|
Reference counting allows the objects that are referred to
|
||||||
using the smart pointer class to have their :term:`memory (1)`
|
using the smart pointer class to have their :term:`memory (1)`
|
||||||
automatically :term:`reclaimed` when they are no longer
|
automatically :term:`reclaimed` when they are no longer
|
||||||
|
|
@ -429,7 +429,7 @@ Memory Management Glossary: S
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Class java.lang.ref.SoftReference <http://download.java.net/jdk8/docs/api/java/lang/ref/SoftReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Class java.lang.ref.SoftReference <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/SoftReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
softly reachable
|
softly reachable
|
||||||
|
|
||||||
|
|
@ -453,7 +453,7 @@ Memory Management Glossary: S
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Class java.lang.ref.SoftReference <http://download.java.net/jdk8/docs/api/java/lang/ref/SoftReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Class java.lang.ref.SoftReference <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/SoftReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
space leak
|
space leak
|
||||||
|
|
||||||
|
|
@ -785,6 +785,26 @@ Memory Management Glossary: S
|
||||||
|
|
||||||
.. see:: :term:`memory (1)`.
|
.. see:: :term:`memory (1)`.
|
||||||
|
|
||||||
|
stretchy vector
|
||||||
|
|
||||||
|
A :term:`vector <vector data type>` that may grow or shrink to
|
||||||
|
accommodate adding or removing elements. Named after the
|
||||||
|
``<stretchy-vector>`` abstract class in Dylan.
|
||||||
|
|
||||||
|
.. relevance::
|
||||||
|
|
||||||
|
In the presence of an :term:`asynchronous garbage
|
||||||
|
collector`, the vector and its size may need to be updated
|
||||||
|
atomically.
|
||||||
|
|
||||||
|
.. link::
|
||||||
|
|
||||||
|
`Dylan Reference Manual: Collections <http://opendylan.org/books/drm/Collection_Classes>`_.
|
||||||
|
|
||||||
|
.. mps:specific::
|
||||||
|
|
||||||
|
See :ref:`guide-stretchy-vector`.
|
||||||
|
|
||||||
strict segregated fit
|
strict segregated fit
|
||||||
|
|
||||||
A :term:`segregated fit` :term:`allocation mechanism` which
|
A :term:`segregated fit` :term:`allocation mechanism` which
|
||||||
|
|
@ -806,7 +826,7 @@ Memory Management Glossary: S
|
||||||
collection>`, a strong reference is a :term:`reference` that
|
collection>`, a strong reference is a :term:`reference` that
|
||||||
keeps the :term:`object` it refers to :term:`alive <live>`.
|
keeps the :term:`object` it refers to :term:`alive <live>`.
|
||||||
|
|
||||||
A strong reference is the usual sort of reference; The term is
|
A strong reference is the usual sort of reference: the term is
|
||||||
usually used to draw a contrast with :term:`weak reference
|
usually used to draw a contrast with :term:`weak reference
|
||||||
(1)`.
|
(1)`.
|
||||||
|
|
||||||
|
|
@ -819,7 +839,7 @@ Memory Management Glossary: S
|
||||||
A strong root is a :term:`root` such that all
|
A strong root is a :term:`root` such that all
|
||||||
:term:`references` in it are :term:`strong references`.
|
:term:`references` in it are :term:`strong references`.
|
||||||
|
|
||||||
A strong root is the usual sort of root. The term is usually
|
A strong root is the usual sort of root: the term is usually
|
||||||
used to draw a contrast with :term:`weak root`.
|
used to draw a contrast with :term:`weak root`.
|
||||||
|
|
||||||
.. opposite:: :term:`weak root`.
|
.. opposite:: :term:`weak root`.
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ Memory Management Glossary: W
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Class java.lang.ref.WeakReference <http://download.java.net/jdk8/docs/api/java/lang/ref/WeakReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Class java.lang.ref.WeakReference <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
weak root
|
weak root
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ Memory Management Glossary: W
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Class java.lang.ref.WeakReference <http://download.java.net/jdk8/docs/api/java/lang/ref/WeakReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
`Class java.lang.ref.WeakReference <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html>`_, `Reference Objects and Garbage Collection <http://pawlan.com/monica/articles/refobjs/>`_.
|
||||||
|
|
||||||
weighted buddies
|
weighted buddies
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,21 +42,20 @@ General debugging advice
|
||||||
in production), and can generate profiling output in the form of
|
in production), and can generate profiling output in the form of
|
||||||
the :term:`telemetry stream`.
|
the :term:`telemetry stream`.
|
||||||
|
|
||||||
#. .. index::
|
#. If your program triggers an assertion failure in the MPS, consult
|
||||||
single: ASLR
|
:ref:`topic-error-cause` for suggestions as to the possible cause.
|
||||||
single: address space layout randomization
|
|
||||||
|
|
||||||
Prepare a reproducible test case if possible. The MPS may be
|
#. Prepare a reproducible test case if possible. The MPS may be
|
||||||
:term:`asynchronous <asynchronous garbage collector>`, but it is
|
:term:`asynchronous <asynchronous garbage collector>`, but it is
|
||||||
deterministic, so in single-threaded applications you should be
|
deterministic, so in single-threaded applications you should be
|
||||||
able to get consistent results. (But you need to beware of `address
|
able to get consistent results.
|
||||||
space layout randomization`_: if you perform computation based on
|
|
||||||
the addresses of objects, for example, hashing objects by their
|
|
||||||
address, then ASLR will cause your hash tables to be laid out
|
|
||||||
differently on each run, which may affect the order of memory
|
|
||||||
management operations.)
|
|
||||||
|
|
||||||
.. _address space layout randomization: http://en.wikipedia.org/wiki/Address_space_layout_randomization
|
However, you need to beware of :term:`address space layout
|
||||||
|
randomization`: if you perform computation based on the addresses
|
||||||
|
of objects, for example, hashing objects by their address, then
|
||||||
|
ASLR will cause your hash tables to be laid out differently on each
|
||||||
|
run, which may affect the order of memory management operations.
|
||||||
|
See :ref:`guide-debug-aslr` below.
|
||||||
|
|
||||||
A fact that assists with reproducibility is that the more
|
A fact that assists with reproducibility is that the more
|
||||||
frequently the collector runs, the sooner and more reliably errors
|
frequently the collector runs, the sooner and more reliably errors
|
||||||
|
|
@ -66,7 +65,10 @@ General debugging advice
|
||||||
result, by having a mode for testing in which you run frequent
|
result, by having a mode for testing in which you run frequent
|
||||||
collections (by calling :c:func:`mps_arena_collect` followed by
|
collections (by calling :c:func:`mps_arena_collect` followed by
|
||||||
:c:func:`mps_arena_release`), perhaps as frequently as every
|
:c:func:`mps_arena_release`), perhaps as frequently as every
|
||||||
allocation.
|
allocation. (This will of course make the system run very slowly,
|
||||||
|
but it ensures that if there are roots or references that are not
|
||||||
|
being scanned then the failure will occur close in time to the cause,
|
||||||
|
making it easier to diagnose.)
|
||||||
|
|
||||||
#. .. index::
|
#. .. index::
|
||||||
single: debugger
|
single: debugger
|
||||||
|
|
@ -86,13 +88,111 @@ General debugging advice
|
||||||
|
|
||||||
handle SIGSEGV pass nostop noprint
|
handle SIGSEGV pass nostop noprint
|
||||||
|
|
||||||
On these operating systems, you can add this commands to your
|
On these operating systems, you can add this command to your
|
||||||
``.gdbinit`` if you always want them to be run.
|
``.gdbinit`` if you always want it to be run.
|
||||||
|
|
||||||
On OS X barrier hits do not use signals and so do not enter the
|
On OS X, barrier hits do not use signals and so do not enter the
|
||||||
debugger.
|
debugger.
|
||||||
|
|
||||||
|
|
||||||
|
.. index::
|
||||||
|
single: ASLR
|
||||||
|
single: address space layout randomization
|
||||||
|
|
||||||
|
.. _guide-debug-aslr:
|
||||||
|
|
||||||
|
Address space layout randomization
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
:term:`Address space layout randomization` (ASLR) makes it hard to
|
||||||
|
prepare a repeatable test case for a program that performs computation
|
||||||
|
based on the addresses of objects, for example, hashing objects by
|
||||||
|
their address. If this is affecting you, you'll find it useful to
|
||||||
|
disable ASLR when testing.
|
||||||
|
|
||||||
|
Here's a small program that you can use to check if ASLR is enabled on
|
||||||
|
your system. It outputs addresses from four key memory areas in a
|
||||||
|
program (data segment, text segment, stack and heap):
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int data;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
void *heap = malloc(4);
|
||||||
|
int stack = 0;
|
||||||
|
printf("data: %p text: %p stack: %p heap: %p\n",
|
||||||
|
&data, (void *)main, &stack, heap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
When ASLR is turned on, running this program outputs different
|
||||||
|
addresses on each run. For example, here are four runs on OS X
|
||||||
|
10.9.3::
|
||||||
|
|
||||||
|
data: 0x10a532020 text: 0x10a531ed0 stack: 0x7fff556ceb1c heap: 0x7f9f80c03980
|
||||||
|
data: 0x10d781020 text: 0x10d780ed0 stack: 0x7fff5247fb1c heap: 0x7fe498c03980
|
||||||
|
data: 0x10164b020 text: 0x10164aed0 stack: 0x7fff5e5b5b1c heap: 0x7fb783c03980
|
||||||
|
data: 0x10c7f8020 text: 0x10c7f7ed0 stack: 0x7fff53408b1c heap: 0x7f9740403980
|
||||||
|
|
||||||
|
By contrast, here are four runs on FreeBSD 8.3::
|
||||||
|
|
||||||
|
data: 0x8049728 text: 0x8048470 stack: 0xbfbfebfc heap: 0x28201088
|
||||||
|
data: 0x8049728 text: 0x8048470 stack: 0xbfbfebfc heap: 0x28201088
|
||||||
|
data: 0x8049728 text: 0x8048470 stack: 0xbfbfebfc heap: 0x28201088
|
||||||
|
data: 0x8049728 text: 0x8048470 stack: 0xbfbfebfc heap: 0x28201088
|
||||||
|
|
||||||
|
Here's the situation on each of the operating systems supported by the MPS:
|
||||||
|
|
||||||
|
* **FreeBSD** (as of version 10.0) does not support ASLR, so there's
|
||||||
|
nothing to do.
|
||||||
|
|
||||||
|
* On **Windows** (Vista or later), ASLR is a property of the
|
||||||
|
executable, and it can be turned off at link time using the
|
||||||
|
|DYNAMICBASE|_.
|
||||||
|
|
||||||
|
.. |DYNAMICBASE| replace:: ``/DYNAMICBASE:NO`` linker option
|
||||||
|
.. _DYNAMICBASE: http://msdn.microsoft.com/en-us/library/bb384887.aspx
|
||||||
|
|
||||||
|
* On **Linux** (kernel version 2.6.12 or later), ASLR can be turned
|
||||||
|
off for a single process by running |setarch|_ with the ``-R``
|
||||||
|
option::
|
||||||
|
|
||||||
|
-R, --addr-no-randomize
|
||||||
|
Disables randomization of the virtual address space
|
||||||
|
|
||||||
|
.. |setarch| replace:: ``setarch``
|
||||||
|
.. _setarch: http://man7.org/linux/man-pages/man8/setarch.8.html
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
$ setarch $(uname -m) -R ./myprogram
|
||||||
|
|
||||||
|
* On **OS X** (10.7 or later), ASLR can be disabled for a single
|
||||||
|
process by starting the process using :c:func:`posix_spawn`, passing
|
||||||
|
the undocumented attribute ``0x100``, like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#include <spawn.h>
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
posix_spawnattr_t attr;
|
||||||
|
|
||||||
|
posix_spawnattr_init(&attr);
|
||||||
|
posix_spawnattr_setflags(&attr, 0x100);
|
||||||
|
posix_spawn(&pid, argv[0], NULL, &attr, argv, environ);
|
||||||
|
|
||||||
|
The MPS provides the source code for a command-line tool
|
||||||
|
implementing this (``tool/noaslr.c``). We've confirmed that this
|
||||||
|
works on OS X 10.9.3, but since the technique is undocumented, it
|
||||||
|
may well break in future releases. (If you know of a documented way
|
||||||
|
to achieve this, please :ref:`contact us <contact>`.)
|
||||||
|
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
single: underscanning
|
single: underscanning
|
||||||
single: bug; underscanning
|
single: bug; underscanning
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ Guide
|
||||||
overview
|
overview
|
||||||
build
|
build
|
||||||
lang
|
lang
|
||||||
|
vector
|
||||||
debug
|
debug
|
||||||
perf
|
perf
|
||||||
advanced
|
advanced
|
||||||
|
|
|
||||||
152
mps/manual/source/guide/vector.rst
Normal file
152
mps/manual/source/guide/vector.rst
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
.. index::
|
||||||
|
single: stretchy vectors
|
||||||
|
single: atomic updates
|
||||||
|
|
||||||
|
.. _guide-stretchy-vector:
|
||||||
|
|
||||||
|
The stretchy vector problem
|
||||||
|
============================
|
||||||
|
|
||||||
|
The :ref:`previous chapter <guide-lang-root>` pointed out that:
|
||||||
|
|
||||||
|
Because the MPS is :term:`asynchronous <asynchronous garbage
|
||||||
|
collector>`, it might be scanning, moving, or collecting, at any
|
||||||
|
point in time.
|
||||||
|
|
||||||
|
The consequences of this can take a while to sink in, so this chapter
|
||||||
|
discusses a particular instance that catches people out: the *stretchy
|
||||||
|
vector* problem (named after the |stretchy-vector|_ abstract class in
|
||||||
|
Dylan).
|
||||||
|
|
||||||
|
.. |stretchy-vector| replace:: ``<stretchy-vector>``
|
||||||
|
.. _stretchy-vector: http://opendylan.org/books/drm/Collection_Classes#stretchy-vector
|
||||||
|
|
||||||
|
A *stretchy vector* is a vector that can change length dynamically.
|
||||||
|
Such a vector is often implemented using two objects: an array, and a
|
||||||
|
header object that stores the length and a pointer to an array.
|
||||||
|
Stretching (or shrinking) such a vector involves five steps:
|
||||||
|
|
||||||
|
1. allocate a new array;
|
||||||
|
2. copy elements from the old array to the new array;
|
||||||
|
3. clear unused elements in the new array (if stretching);
|
||||||
|
4. update the pointer to the array in the header;
|
||||||
|
5. update the length in the header.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
typedef struct vector_s {
|
||||||
|
type_t type; /* TYPE_VECTOR */
|
||||||
|
size_t length; /* number of elements */
|
||||||
|
obj_t *array; /* array of elements */
|
||||||
|
} vector_s, *vector_t;
|
||||||
|
|
||||||
|
void resize_vector(vector_t vector, size_t new_length) {
|
||||||
|
obj_t *new_array = realloc(vector->array, new_length * sizeof(obj_t));
|
||||||
|
if (new_array == NULL)
|
||||||
|
error("out of memory in resize_vector");
|
||||||
|
if (vector->length < new_length) {
|
||||||
|
memset(&vector->array[vector->length], 0,
|
||||||
|
(new_length - vector->length) * sizeof(obj_t));
|
||||||
|
}
|
||||||
|
vector->array = new_array;
|
||||||
|
vector->length = new_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
When adapting this code to the MPS, the following problems must be
|
||||||
|
solved:
|
||||||
|
|
||||||
|
1. During step 2, the new array must be :term:`reachable` from the
|
||||||
|
roots, and :term:`scannable <scan>`. (If it's not reachable, then
|
||||||
|
it may be collected; if it's not scannable, then references it
|
||||||
|
contains will not be updated when they are moved by the collector.)
|
||||||
|
|
||||||
|
This can solved by storing the new array in a :term:`root` until
|
||||||
|
the header has been updated. If the thread's stack has been
|
||||||
|
registered as a root by calling :c:func:`mps_root_create_reg` then
|
||||||
|
any local variable will do.
|
||||||
|
|
||||||
|
2. References in the new array must not be scanned until they have been
|
||||||
|
copied or cleared. (Otherwise they will be invalid.)
|
||||||
|
|
||||||
|
This can be solved by clearing the new array before calling
|
||||||
|
:c:func:`mps_commit`.
|
||||||
|
|
||||||
|
3. The old array must be scanned at the old length (otherwise the scan
|
||||||
|
may run off the end of the old array when the vector grows), and
|
||||||
|
the new array must be scanned at the new length (otherwise the scan
|
||||||
|
may run off the end of the old array when the vector shrinks).
|
||||||
|
|
||||||
|
4. The array object must be scannable without referring to the header
|
||||||
|
object. (Because the header object may have been protected by the
|
||||||
|
MPS: see :ref:`topic-format-cautions`.)
|
||||||
|
|
||||||
|
Problems 3 and 4 can be solved by storing the length in the array. The
|
||||||
|
revised data structures and resizing code might look like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
typedef struct vector_s {
|
||||||
|
type_t type; /* TYPE_VECTOR */
|
||||||
|
obj_t array; /* TYPE_ARRAY object */
|
||||||
|
} vector_s, *vector_t;
|
||||||
|
|
||||||
|
typedef struct array_s {
|
||||||
|
type_t type; /* TYPE_ARRAY */
|
||||||
|
size_t length; /* number of elements */
|
||||||
|
obj_t array[0]; /* array of elements */
|
||||||
|
} array_s, *array_t;
|
||||||
|
|
||||||
|
void resize_vector(vector_t vector, size_t new_length) {
|
||||||
|
size_t size = ALIGN_OBJ(offsetof(array_s, array) + new_length * sizeof(obj_t));
|
||||||
|
mps_addr_t addr;
|
||||||
|
array_t array;
|
||||||
|
|
||||||
|
do {
|
||||||
|
mps_res_t res = mps_reserve(&addr, ap, size);
|
||||||
|
if (res != MPS_RES_OK) error("out of memory in resize_vector");
|
||||||
|
array = addr;
|
||||||
|
array->type = TYPE_ARRAY;
|
||||||
|
array->length = new_length;
|
||||||
|
memset(array->array, 0, new_length * sizeof(obj_t));
|
||||||
|
/* Now the new array is scannable, and it is reachable via the
|
||||||
|
* local variable 'array', so it is safe to commit it. */
|
||||||
|
} while(!mps_commit(ap, addr, size));
|
||||||
|
|
||||||
|
/* Copy elements after committing, so that the collector will
|
||||||
|
* update them if they move. */
|
||||||
|
memcpy(array->array, vector->array->array,
|
||||||
|
min(vector->array->length, new_length) * sizeof(obj_t));
|
||||||
|
vector->array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
Similar difficulties can arise even when adapting code written for
|
||||||
|
other garbage collectors. For example, here's the function
|
||||||
|
|setarrayvector|_ from Lua_:
|
||||||
|
|
||||||
|
.. |setarrayvector| replace:: ``setarrayvector()``
|
||||||
|
.. _setarrayvector: http://www.lua.org/source/5.2/ltable.c.html#setarrayvector
|
||||||
|
.. _Lua: http://www.lua.org
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static void setarrayvector (lua_State *L, Table *t, int size) {
|
||||||
|
int i;
|
||||||
|
luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
|
||||||
|
for (i=t->sizearray; i<size; i++)
|
||||||
|
setnilvalue(&t->array[i]);
|
||||||
|
t->sizearray = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lua's garbage collector is :term:`synchronous <synchronous garbage
|
||||||
|
collector>`, so it can be assumed that there cannot be a garbage
|
||||||
|
collection between the assignment to ``t->array`` (resulting from the
|
||||||
|
expansion of the |luaM_reallocvector|_ macro) and the assignment to
|
||||||
|
``t->sizearray``, and so the collector will always consistently see
|
||||||
|
either the old array or the new array, with the correct size. This
|
||||||
|
assumption will no longer be correct if this code is adapted to the
|
||||||
|
MPS.
|
||||||
|
|
||||||
|
.. |luaM_reallocvector| replace:: ``luaM_reallocvector()``
|
||||||
|
.. _luaM_reallocvector: http://www.lua.org/source/5.2/lmem.h.html#luaM_reallocvector
|
||||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
|
@ -1,7 +1,3 @@
|
||||||
.. Memory Pool System documentation master file, created by
|
|
||||||
sphinx-quickstart on Tue Oct 9 11:21:17 2012.
|
|
||||||
|
|
||||||
|
|
||||||
Memory Pool System
|
Memory Pool System
|
||||||
##################
|
##################
|
||||||
|
|
||||||
|
|
@ -15,26 +11,26 @@ Memory Pool System
|
||||||
design/old
|
design/old
|
||||||
|
|
||||||
|
|
||||||
Memory Management Reference
|
|
||||||
###########################
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
mmref/index
|
|
||||||
mmref/bib
|
|
||||||
mmref/credit
|
|
||||||
|
|
||||||
|
|
||||||
Appendices
|
Appendices
|
||||||
##########
|
##########
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
bib
|
||||||
glossary/index
|
glossary/index
|
||||||
copyright
|
copyright
|
||||||
contact
|
contact
|
||||||
release
|
release
|
||||||
|
|
||||||
* :ref:`genindex`
|
* :ref:`genindex`
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:hidden:
|
||||||
|
|
||||||
|
mmref/index
|
||||||
|
mmref-index
|
||||||
|
mmref/faq
|
||||||
|
mmref-copyright
|
||||||
|
mmref/credit
|
||||||
|
|
|
||||||
26
mps/manual/source/mmref-copyright.rst
Normal file
26
mps/manual/source/mmref-copyright.rst
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
Copyright
|
||||||
|
*********
|
||||||
|
|
||||||
|
|
||||||
|
Use subject to copyright restrictions
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
The copyright in The Memory Management Reference is owned by
|
||||||
|
`Ravenbrook Limited`_.
|
||||||
|
|
||||||
|
.. _Ravenbrook Limited: http://www.ravenbrook.com/
|
||||||
|
|
||||||
|
Permission to copy part or all of The Memory Management Reference for
|
||||||
|
personal or classroom use is granted without fee, provided that copies
|
||||||
|
are not made or distributed for profit or commercial advantage; that
|
||||||
|
the copyright notice, the title of the publication, and its date
|
||||||
|
appear; and that notice is given that copying is by permission of
|
||||||
|
Ravenbrook Limited. To copy otherwise, to republish, to post on
|
||||||
|
servers, or to redistribute to lists requires prior specific
|
||||||
|
permission.
|
||||||
|
|
||||||
|
|
||||||
|
Warranty disclaimer
|
||||||
|
===================
|
||||||
|
|
||||||
|
The Memory Management Reference is provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement.
|
||||||
56
mps/manual/source/mmref-index.rst
Normal file
56
mps/manual/source/mmref-index.rst
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
Home
|
||||||
|
****
|
||||||
|
|
||||||
|
Welcome to the **Memory Management Reference**! This is a resource for programmers and computer scientists interested in :term:`memory management` and :term:`garbage collection`.
|
||||||
|
|
||||||
|
|
||||||
|
.. admonition:: :ref:`glossary`
|
||||||
|
|
||||||
|
A glossary of more than 500 memory management terms, from
|
||||||
|
:term:`absolute address` to :term:`zero count table`.
|
||||||
|
|
||||||
|
.. image:: diagrams/treadmill.svg
|
||||||
|
:target: glossary_
|
||||||
|
|
||||||
|
.. _glossary: glossary/index.html#glossary
|
||||||
|
|
||||||
|
|
||||||
|
.. admonition:: :ref:`mmref-intro`
|
||||||
|
|
||||||
|
Articles giving a beginner's overview of memory management.
|
||||||
|
|
||||||
|
.. image:: diagrams/address.svg
|
||||||
|
:target: intro_
|
||||||
|
|
||||||
|
.. _intro: mmref/index.html#mmref-intro
|
||||||
|
|
||||||
|
|
||||||
|
.. admonition:: :ref:`bibliography`
|
||||||
|
|
||||||
|
Books and research papers related to memory management.
|
||||||
|
|
||||||
|
.. image:: diagrams/copying.svg
|
||||||
|
:target: bib_
|
||||||
|
|
||||||
|
.. _bib: bib.html#bibliography
|
||||||
|
|
||||||
|
|
||||||
|
.. admonition:: :ref:`mmref-faq`
|
||||||
|
|
||||||
|
Frequently asked questions about memory management.
|
||||||
|
|
||||||
|
.. image:: diagrams/snap-out.svg
|
||||||
|
:target: faq_
|
||||||
|
|
||||||
|
.. _faq: mmref/faq.html#mmref-faq
|
||||||
|
|
||||||
|
The Memory Management Reference is maintained by `Ravenbrook
|
||||||
|
Limited`_. We also maintain the `Memory Pool System`_ (an open-source,
|
||||||
|
thread-safe, :term:`incremental <incremental garbage collection>`
|
||||||
|
garbage collector), and we are happy to provide advanced memory
|
||||||
|
management solutions to language and application developers through
|
||||||
|
our `consulting service`_.
|
||||||
|
|
||||||
|
.. _Ravenbrook Limited: http://www.ravenbrook.com/
|
||||||
|
.. _consulting service: http://www.ravenbrook.com/services/mm/
|
||||||
|
.. _Memory Pool System: http://www.ravenbrook.com/project/mps/
|
||||||
|
|
@ -1,965 +0,0 @@
|
||||||
.. _bibliography:
|
|
||||||
|
|
||||||
Bibliography
|
|
||||||
************
|
|
||||||
|
|
||||||
* .. _AD97:
|
|
||||||
|
|
||||||
Ole Agesen, David L. Detlefs. 1997. "`Finding References in Java Stacks <http://www-plan.cs.colorado.edu/diwan/class-papers/finding-references-in-java.pdf>`_". Sun Labs. OOPSLA97 Workshop on Garbage Collection and Memory Management.
|
|
||||||
|
|
||||||
.. abstract: ad97.html
|
|
||||||
|
|
||||||
* .. _ADM98:
|
|
||||||
|
|
||||||
Ole Agesen, David L. Detlefs, J. Eliot B. Moss. 1998. "`Garbage Collection and Local Variable Type-precision and Liveness in Java Virtual Machines <http://pdf.aminer.org/000/542/332/garbage_collection_and_local_variable_type_precision_and_liveness_in.pdf>`_". ACM. Proceedings of the ACM SIGPLAN '98 conference on Programming language design and implementation, pp. 269--279.
|
|
||||||
|
|
||||||
.. abstract: adm98.html
|
|
||||||
|
|
||||||
* .. _AEL88:
|
|
||||||
|
|
||||||
Andrew Appel, John R. Ellis, Kai Li. 1988. "`Real-time Concurrent Collection on Stock Multiprocessors <http://apotheca.hpl.hp.com/ftp/pub/compaq/SRC/research-reports/SRC-025.pdf>`_". ACM, SIGPLAN. ACM PLDI 88, SIGPLAN Notices 23, 7 (July 88), pp. 11--20.
|
|
||||||
|
|
||||||
.. abstract: ael88.html
|
|
||||||
|
|
||||||
* .. _APPLE94:
|
|
||||||
|
|
||||||
Apple Computer, Inc. 1994. *Inside Macintosh: Memory*. Addison-Wesley. ISBN 0-201-63240-3.
|
|
||||||
|
|
||||||
.. abstract: apple94.html
|
|
||||||
|
|
||||||
* .. _ATTARDI94:
|
|
||||||
|
|
||||||
Giuseppe Attardi & Tito Flagella. 1994. "`A Customisable Memory Management Framework <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.50.257&rep=rep1&type=pdf>`_". TR-94-010.
|
|
||||||
|
|
||||||
.. abstract: attardi94.html
|
|
||||||
|
|
||||||
* .. _AFI98:
|
|
||||||
|
|
||||||
Giuseppe Attardi, Tito Flagella, Pietro Iglio. 1998. "`A customisable memory management framework for C++ <ftp://ftp.di.unipi.it/pub/Papers/attardi/SPE.ps.gz>`_". Software -- Practice and Experience. 28(11), 1143--1183.
|
|
||||||
|
|
||||||
.. abstract: afi98.html
|
|
||||||
|
|
||||||
* .. _AKPY98:
|
|
||||||
|
|
||||||
Alain Azagury, Elliot K. Kolodner, Erez Petrank, Zvi Yehudai. 1998. "`Combining Card Marking with Remembered Sets: How to Save Scanning Time <http://pdf.aminer.org/000/465/100/combining_card_marking_with_remembered_sets_how_to_save_scanning.pdf>`_". ACM. ISMM'98 pp. 10--19.
|
|
||||||
|
|
||||||
.. abstract: akpy98.html
|
|
||||||
|
|
||||||
* .. _BAKER77:
|
|
||||||
|
|
||||||
Henry G. Baker, Carl Hewitt. 1977. "`The Incremental Garbage Collection of Processes <http://home.pipeline.com/~hbaker1/Futures.html>`_". ACM. SIGPLAN Notices 12, 8 (August 1977), pp. 55--59.
|
|
||||||
|
|
||||||
.. abstract: baker77.html
|
|
||||||
|
|
||||||
* .. _BAKER78:
|
|
||||||
|
|
||||||
Henry G. Baker. 1978. "`List Processing in Real Time on a Serial Computer <http://home.pipeline.com/~hbaker1/RealTimeGC.html>`_". ACM. Communications of the ACM 21, 4 (April 1978), pp. 280--294.
|
|
||||||
|
|
||||||
.. abstract: baker78.html
|
|
||||||
|
|
||||||
* .. _BAKER79:
|
|
||||||
|
|
||||||
Henry G. Baker. 1979. "`Optimizing Allocation and Garbage Collection of Spaces <http://home.pipeline.com/~hbaker1/OptAlloc.html>`_". In Winston and Brown, eds. *Artificial Intelligence: An MIT Perspective.* MIT Press.
|
|
||||||
|
|
||||||
.. abstract: baker79.html
|
|
||||||
|
|
||||||
* .. _BAKER91:
|
|
||||||
|
|
||||||
Henry G. Baker. 1991. "`Cache-Conscious Copying Collectors <http://home.pipeline.com/~hbaker1/CacheCGC.html>`_". OOPSLA'91/GC'91 Workshop on Garbage Collection.
|
|
||||||
|
|
||||||
.. abstract: baker91.html
|
|
||||||
|
|
||||||
* .. _BAKER92A:
|
|
||||||
|
|
||||||
Henry G. Baker. 1992. "`Lively Linear Lisp -- 'Look Ma, No Garbage!' <http://home.pipeline.com/~hbaker1/LinearLisp.html>`_". ACM. SIGPLAN Notices 27, 8 (August 1992), pp. 89--98.
|
|
||||||
|
|
||||||
.. abstract: baker92a.html
|
|
||||||
|
|
||||||
* .. _BAKER92C:
|
|
||||||
|
|
||||||
Henry G. Baker. 1992. "`The Treadmill: Real-Time Garbage Collection Without Motion Sickness <http://home.pipeline.com/~hbaker1/NoMotionGC.html>`_". ACM. SIGPLAN Notices 27, 3 (March 1992), pp. 66--70.
|
|
||||||
|
|
||||||
.. abstract: baker92c.html
|
|
||||||
|
|
||||||
* .. _BAKER92:
|
|
||||||
|
|
||||||
Henry G. Baker. 1992. "`CONS Should not CONS its Arguments, or, a Lazy Alloc is a Smart Alloc <http://home.pipeline.com/~hbaker1/LazyAlloc.html>`_". ACM. SIGPLAN Notices 27, 3 (March 1992), 24--34.
|
|
||||||
|
|
||||||
.. abstract: baker92.html
|
|
||||||
|
|
||||||
* .. _BAKER92B:
|
|
||||||
|
|
||||||
Henry G. Baker. 1992. "`NREVERSAL of Fortune -- The Thermodynamics of Garbage Collection <http://home.pipeline.com/~hbaker1/ReverseGC.html>`_". Springer-Verlag. LNCS Vol. 637.
|
|
||||||
|
|
||||||
.. abstract: baker92b.html
|
|
||||||
|
|
||||||
* .. _BAKER93:
|
|
||||||
|
|
||||||
Henry G. Baker. 1993. "`'Infant Mortality' and Generational Garbage Collection <http://home.pipeline.com/~hbaker1/YoungGen.html>`_". ACM. SIGPLAN Notices 28, 4 (April 1993), pp. 55--57.
|
|
||||||
|
|
||||||
.. abstract: baker93.html
|
|
||||||
|
|
||||||
* .. _BAKER93A:
|
|
||||||
|
|
||||||
Henry G. Baker. 1993. "`Equal Rights for Functional Objects or, The More Things Change, The More They Are the Same <http://home.pipeline.com/~hbaker1/ObjectIdentity.html>`_". ACM. OOPS Messenger 4, 4 (October 1993), pp. 2--27.
|
|
||||||
|
|
||||||
.. abstract: baker93a.html
|
|
||||||
|
|
||||||
* .. _BAKER94:
|
|
||||||
|
|
||||||
Henry G. Baker. 1994. "`Minimizing Reference Count Updating with Deferred and Anchored Pointers for Functional Data Structures <http://home.pipeline.com/~hbaker1/LRefCounts.html>`_". ACM. SIGPLAN Notices 29, 9 (September 1994), pp. 38--43.
|
|
||||||
|
|
||||||
.. abstract: baker94.html
|
|
||||||
|
|
||||||
* .. _BAKER94A:
|
|
||||||
|
|
||||||
Henry G. Baker. 1994. "`Thermodynamics and Garbage Collection <http://home.pipeline.com/~hbaker1/ThermoGC.html>`_". ACM. SIGPLAN Notices 29, 4 (April 1994), pp. 58--63.
|
|
||||||
|
|
||||||
.. abstract: baker94a.html
|
|
||||||
|
|
||||||
* .. _BAKER95A:
|
|
||||||
|
|
||||||
Henry G. Baker. 1995. "`'Use-Once' Variables and Linear Objects -- Storage Management, Reflection and Multi-Threading <http://home.pipeline.com/~hbaker1/Use1Var.html>`_". ACM. SIGPLAN Notices 30, 1 (January 1995), pp. 45--52.
|
|
||||||
|
|
||||||
.. abstract: baker95a.html
|
|
||||||
|
|
||||||
* .. _BAKER95:
|
|
||||||
|
|
||||||
Henry G. Baker. 1995. *Memory Management: International Workshop IWMM'95*. Springer-Verlag. ISBN 3-540-60368-9.
|
|
||||||
|
|
||||||
.. abstract: baker95.html
|
|
||||||
|
|
||||||
* .. _BBW97:
|
|
||||||
|
|
||||||
Nick Barnes, Richard Brooksby, David Jones, Gavin Matthews, Pekka P. Pirinen, Nick Dalton, P. Tucker Withington. 1997. "`A Proposal for a Standard Memory Management Interface <ftp://ftp.dcs.gla.ac.uk/pub/drastic/gc/harlequin.ps>`_". OOPSLA97 Workshop on Garbage Collection and Memory Management.
|
|
||||||
|
|
||||||
* .. _ZORN93B:
|
|
||||||
|
|
||||||
David A. Barrett, Benjamin Zorn. 1993. "`Using Lifetime Predictors to Improve Memory Allocation Performance <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.56.6712&rep=rep1&type=pdf>`_". ACM. SIGPLAN'93 Conference on Programming Language Design and Implementation, pp. 187--196.
|
|
||||||
|
|
||||||
.. abstract: zorn93b.html
|
|
||||||
|
|
||||||
* .. _BARRETT93:
|
|
||||||
|
|
||||||
David A. Barrett, Benjamin Zorn. 1995. "`Garbage Collection using a Dynamic Threatening Boundary <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.1835&rep=rep1&type=pdf>`_". ACM. SIGPLAN'95 Conference on Programming Language Design and Implementation, pp. 301--314.
|
|
||||||
|
|
||||||
.. abstract: barrett93.html
|
|
||||||
|
|
||||||
* .. _BARTLETT88:
|
|
||||||
|
|
||||||
Joel F. Bartlett. 1988. "`Compacting Garbage Collection with Ambiguous Roots <http://computer-refuge.org/classiccmp/ftp.digital.com-jun2004/pub/Compaq/WRL/research-reports/WRL-TR-88.2.pdf>`_". Digital Equipment Corporation.
|
|
||||||
|
|
||||||
.. abstract: bartlett88.html
|
|
||||||
|
|
||||||
* .. _BARTLETT89:
|
|
||||||
|
|
||||||
Joel F. Bartlett. 1989. "`Mostly-Copying Garbage Collection Picks Up Generations and C++ <http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-TN-12.pdf>`_". Digital Equipment Corporation.
|
|
||||||
|
|
||||||
.. abstract: bartlett89.html
|
|
||||||
|
|
||||||
* .. _BC92:
|
|
||||||
|
|
||||||
Yves Bekkers & Jacques Cohen. 1992. "`Memory Management, International Workshop IWMM 92 <http://www.informatik.uni-trier.de/%7Eley/db/conf/iwmm/iwmm92.html>`_". Springer-Verlag. LNCS Vol. 637, ISBN 3-540-55940-X.
|
|
||||||
|
|
||||||
* .. _BB99:
|
|
||||||
|
|
||||||
Emery D. Berger, Robert D. Blumofe. 1999. "`Hoard: A Fast, Scalable, and Memory-Efficient Allocator for Shared-Memory Multiprocessors <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.81.5049&rep=rep1&type=pdf>`_". University of Texas at Austin. UTCS TR99-22.
|
|
||||||
|
|
||||||
.. abstract: bb99.html
|
|
||||||
|
|
||||||
* .. _BERGER01:
|
|
||||||
|
|
||||||
Emery D. Berger, Benjamin G. Zorn, Kathryn S. McKinley. 2001. "`Composing high-performance memory allocators <http://www.cs.utexas.edu/users/speedway/DaCapo/papers/pldi2001.pdf>`_" ACM SIGPLAN Conference on Programming Language Design and Implementation 2001, pp. 114--124.
|
|
||||||
|
|
||||||
* .. _BW88:
|
|
||||||
|
|
||||||
Hans-J. Boehm, Mark Weiser. 1988. "`Garbage collection in an uncooperative environment <http://www.hpl.hp.com/personal/Hans_Boehm/spe_gc_paper/preprint.pdf>`_". Software -- Practice and Experience. 18(9):807--820.
|
|
||||||
|
|
||||||
.. abstract: bw88.html
|
|
||||||
|
|
||||||
* .. _BDS91:
|
|
||||||
|
|
||||||
Hans-J. Boehm, Alan J. Demers, Scott Shenker. 1991. "`Mostly Parallel Garbage Collection <http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi91.ps.Z>`_". Xerox PARC. ACM PLDI 91, SIGPLAN Notices 26, 6 (June 1991), pp. 157--164.
|
|
||||||
|
|
||||||
.. abstract: bds91.html
|
|
||||||
|
|
||||||
* .. _BC92A:
|
|
||||||
|
|
||||||
Hans-J. Boehm, David Chase. 1992. "A Proposal for Garbage-Collector-Safe C Compilation". *Journal of C Language Translation.* vol. 4, 2 (December 1992), pp. 126--141.
|
|
||||||
|
|
||||||
* .. _BOEHM93:
|
|
||||||
|
|
||||||
Hans-J. Boehm. 1993. "`Space Efficient Conservative Garbage Collection <http://www.hpl.hp.com/personal/Hans_Boehm/gc/papers/pldi93.ps.Z>`_". ACM, SIGPLAN. Proceedings of the ACM SIGPLAN '91 Conference on Programming Language Design and Implementation, SIGPLAN Notices 28, 6, pp 197--206.
|
|
||||||
|
|
||||||
.. abstract: boehm93.html
|
|
||||||
|
|
||||||
* .. _BOEHM00:
|
|
||||||
|
|
||||||
Hans-J. Boehm. 2000. "`Reducing Garbage Collector Cache Misses <http://www.hpl.hp.com/techreports/2000/HPL-2000-99.html>`_". ACM. ISMM'00 pp. 59--64.
|
|
||||||
|
|
||||||
.. abstract: boehm00.html
|
|
||||||
|
|
||||||
* .. _BOEHM02:
|
|
||||||
|
|
||||||
Hans-J. Boehm. 2002. "`Destructors, Finalizers, and Synchronization <http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html>`_". HP Labs technical report HPL-2002-335.
|
|
||||||
|
|
||||||
* .. _BM77:
|
|
||||||
|
|
||||||
Robert S. Boyer and J. Strother Moore. 1977. "`A Fast String Searching Algorithm <http://www.cs.utexas.edu/~moore/publications/fstrpos.pdf>`_". *Communications of the ACM* 20(10):762--772.
|
|
||||||
|
|
||||||
* .. _BL72:
|
|
||||||
|
|
||||||
P. Branquart, J. Lewi. 1972. "A scheme of storage allocation and garbage collection for ALGOL 68". Elsevier/North-Holland. ALGOL 68 Implementation -- Proceedings of the IFIP Working Conference on ALGOL 68 Implementation, July 1970.
|
|
||||||
|
|
||||||
* .. _BROOKSBY02:
|
|
||||||
|
|
||||||
Richard Brooksby. 2002. "`The Memory Pool System: Thirty person-years of memory management development goes Open Source <http://www.ravenbrook.com/project/mps/doc/2002-01-30/ismm2002-paper/>`_". ISMM'02.
|
|
||||||
|
|
||||||
* .. _C1990:
|
|
||||||
|
|
||||||
International Standard ISO/IEC 9899:1990. "Programming languages — C".
|
|
||||||
|
|
||||||
* .. _C1999:
|
|
||||||
|
|
||||||
International Standard ISO/IEC 9899:1999. "`Programming languages — C <http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf>`_".
|
|
||||||
|
|
||||||
* .. _CGZ94:
|
|
||||||
|
|
||||||
Brad Calder, Dirk Grunwald, Benjamin Zorn. 1994. "`Quantifying Behavioral Differences Between C and C++ Programs <http://cseclassic.ucsd.edu/users/calder/papers/JplVersion.pdf>`_". *Journal of Programming Languages.* 2(4):313--351.
|
|
||||||
|
|
||||||
.. abstract: cgz94.html
|
|
||||||
|
|
||||||
* .. _CPC00:
|
|
||||||
|
|
||||||
Dante J. Cannarozzi, Michael P. Plezbert, Ron K. Cytron. 2000. "`Contaminated garbage collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.58.9649&rep=rep1&type=pdf>`_". ACM. Proceedings of the ACM SIGPLAN '00 conference on on Programming language design and implementation, pp. 264--273.
|
|
||||||
|
|
||||||
* .. _CW86:
|
|
||||||
|
|
||||||
Patrick J. Caudill, Allen Wirfs-Brock. 1986. "A Third-Generation Smalltalk-80 Implementation". ACM. SIGPLAN Notices. 21(11), OOPSLA'86 ACM Conference on Object-Oriented Systems, Languages and Applications.
|
|
||||||
|
|
||||||
* .. _CHENEY70:
|
|
||||||
|
|
||||||
C. J. Cheney. 1970. "A non-recursive list compacting algorithm". CACM. 13-11 pp. 677--678.
|
|
||||||
|
|
||||||
* .. _CHL98:
|
|
||||||
|
|
||||||
Perry Cheng, Robert Harper, Peter Lee. 1998. "`Generational stack collection and profile-driven pretenuring <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.43.9229&rep=rep1&type=pdf>`_". ACM. Proceedings of SIGPLAN'98 Conference on Programming Language Design and Implementation, pp. 162--173.
|
|
||||||
|
|
||||||
* .. _CL98:
|
|
||||||
|
|
||||||
Trishul M. Chilimbi, James R. Larus. 1998. "`Using Generational Garbage Collection To Implement Cache-Conscious Data Placement <http://ftp2.cs.wisc.edu/wwt/ismm98_cache_gc.pdf>`_". ACM. ISMM'98 pp. 37--48.
|
|
||||||
|
|
||||||
.. abstract: cl98.html
|
|
||||||
|
|
||||||
* .. _CH97:
|
|
||||||
|
|
||||||
William D Clinger & Lars T Hansen. 1997. "`Generational Garbage Collection and the Radioactive Decay Model <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.164.370&rep=rep1&type=pdf>`_". ACM. Proceedings of PLDI 1997.
|
|
||||||
|
|
||||||
.. abstract: ch97.html
|
|
||||||
|
|
||||||
* .. _COHEN81:
|
|
||||||
|
|
||||||
Jacques Cohen. 1981. "Garbage collection of linked data structures". Computing Surveys. Vol. 13, no. 3.
|
|
||||||
|
|
||||||
.. abstract: cohen81.html
|
|
||||||
|
|
||||||
* .. _CCZ98:
|
|
||||||
|
|
||||||
Dominique Colnet, Philippe Coucaud, Olivier Zendra. 1998. "`Compiler Support to Customize the Mark and Sweep Algorithm <http://pdf.aminer.org/000/465/134/compiler_support_to_customize_the_mark_and_sweep_algorithm.pdf>`_". ACM. ISMM'98 pp. 154--165.
|
|
||||||
|
|
||||||
.. abstract: ccz98.html
|
|
||||||
|
|
||||||
* .. _CWZ93:
|
|
||||||
|
|
||||||
Jonathan E. Cook, Alexander L. Wolf, Benjamin Zorn. 1994. "`Partition Selection Policies in Object Database Garbage Collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.53.3656&rep=rep1&type=pdf>`_". ACM. SIGMOD. International Conference on the Management of Data (SIGMOD'94), pp. 371--382.
|
|
||||||
|
|
||||||
.. abstract: cwz93.html
|
|
||||||
|
|
||||||
* .. _CKWZ96:
|
|
||||||
|
|
||||||
Jonathan E. Cook, Artur Klauser, Alexander L. Wolf, Benjamin Zorn. 1996. "`Semi-automatic, Self-adaptive Control of Garbage Collection Rates in Object Databases <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.46.8140&rep=rep1&type=pdf>`_". ACM, SIGMOD. International Conference on the Management of Data (SIGMOD'96), pp. 377--388.
|
|
||||||
|
|
||||||
* .. _CNS92:
|
|
||||||
|
|
||||||
Eric Cooper, Scott Nettles, Indira Subramanian. 1992. "Improving the Performance of SML Garbage Collection using Application-Specific Virtual Memory Management". ACM Conference on LISP and Functional Programming, pp. 43--52.
|
|
||||||
|
|
||||||
.. abstract: cns92.html
|
|
||||||
|
|
||||||
* .. _DACONTA93:
|
|
||||||
|
|
||||||
Michael C. Daconta. 1993. *C Pointers and Dynamic Memory Management.* Wiley. ISBN 0-471-56152-5.
|
|
||||||
|
|
||||||
* .. _DACONTA95:
|
|
||||||
|
|
||||||
Michael C. Daconta. 1995. *C++ Pointers and Dynamic Memory Management.* Wiley. ISBN 0-471-04998-0.
|
|
||||||
|
|
||||||
.. abstract: daconta95.html
|
|
||||||
|
|
||||||
* .. _DAHL63:
|
|
||||||
|
|
||||||
O.-J. Dahl. 1963. "The SIMULA Storage Allocation Scheme". Norsk Regnesentral. NCC Document no. 162.
|
|
||||||
|
|
||||||
* .. _DENNING68:
|
|
||||||
|
|
||||||
P. J. Denning. 1968. "Thrashing: Its Causes and Prevention". Proceedings AFIPS,1968 Fall Joint Computer Conference, vol. 33, pp. 915--922.
|
|
||||||
|
|
||||||
* .. _DENNING70:
|
|
||||||
|
|
||||||
P. J. Denning. 1970. "`Virtual Memory <http://denninginstitute.com/pjd/PUBS/VirtMem_1970.pdf>`_". ACM. ACM Computing Surveys, vol. 2, no. 3, pp. 153--190, Sept. 1970.
|
|
||||||
|
|
||||||
* .. _DS72:
|
|
||||||
|
|
||||||
P. J. Denning, S. C. Schwartz. 1972. "`Properties of the Working-set Model <http://denninginstitute.com/pjd/PUBS/WSProp_1972.pdf>`_". CACM. vol. 15, no. 3, pp. 191--198.
|
|
||||||
|
|
||||||
* .. _DETLEFS92:
|
|
||||||
|
|
||||||
David L. Detlefs. 1992. "`Garbage collection and runtime typing as a C++ library <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.71.2755&rep=rep1&type=pdf>`_". USENIX C++ Conference.
|
|
||||||
|
|
||||||
* .. _ZORN93:
|
|
||||||
|
|
||||||
David L. Detlefs, Al Dosser, Benjamin Zorn. 1994. "`Memory Allocation Costs in Large C and C++ Programs <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.30.3073&rep=rep1&type=pdf>`_". Software -- Practice and Experience. 24(6):527--542.
|
|
||||||
|
|
||||||
.. abstract: zorn93.html
|
|
||||||
|
|
||||||
* .. _DB76:
|
|
||||||
|
|
||||||
L. Peter Deutsch, Daniel G. Bobrow. 1976. "`An Efficient, Incremental, Automatic Garbage Collector <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.63.4603&rep=rep1&type=pdf>`_". CACM. vol. 19, no. 9, pp. 522--526.
|
|
||||||
|
|
||||||
* .. _DLMSS76:
|
|
||||||
|
|
||||||
E. W. Dijkstra, Leslie Lamport, A. J. Martin, C. S. Scholten, E. F. M. Steffens. 1976. "`On-the-fly Garbage Collection: An Exercise in Cooperation <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.63.4752&rep=rep1&type=pdf>`_". Springer-Verlag. Lecture Notes in Computer Science, Vol. 46.
|
|
||||||
|
|
||||||
* .. _DMH92:
|
|
||||||
|
|
||||||
Amer Diwan, Richard L. Hudson, J. Eliot B. Moss. 1992. "`Compiler Support for Garbage Collection in a Statically Typed Language <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.87.71&rep=rep1&type=pdf>`_". ACM. Proceedings of the 5th ACM SIGPLAN conference on Programming language design and implementation, pp. 273--282.
|
|
||||||
|
|
||||||
.. abstract: dmh92.html
|
|
||||||
|
|
||||||
* .. _DTM93:
|
|
||||||
|
|
||||||
Amer Diwan, David Tarditi, J. Eliot B. Moss. 1993. "`Memory Subsystem Performance of Programs with Intensive Heap Allocation <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.27.9220&rep=rep1&type=pdf>`_". Carnegie Mellon University. CMU-CS-93-227.
|
|
||||||
|
|
||||||
.. abstract: dtm93.html
|
|
||||||
|
|
||||||
* .. _DTM93A:
|
|
||||||
|
|
||||||
Amer Diwan, David Tarditi, J. Eliot B. Moss. 1994. "`Memory Subsystem Performance of Programs Using Copying Garbage Collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.27.9220&rep=rep1&type=pdf>`_". ACM. CMU-CS-93-210, also in POPL '94.
|
|
||||||
|
|
||||||
.. abstract: dtm93a.html
|
|
||||||
|
|
||||||
* .. _DOLIGEZ93:
|
|
||||||
|
|
||||||
Damien Doligez & Xavier Leroy. 1993. "`A concurrent, generational garbage collector for a multithreaded implementation of ML <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.52.9494&rep=rep1&type=pdf>`_". ACM. POPL '93, 113--123.
|
|
||||||
|
|
||||||
.. abstract: doligez93.html
|
|
||||||
|
|
||||||
* .. _DOLIGEZ94:
|
|
||||||
|
|
||||||
Damien Doligez & Georges Gonthier. 1994. "`Portable, unobtrusive garbage collection for multiprocessor systems <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.52.4710&rep=rep1&type=pdf>`_". ACM. POPL '94, 70--83.
|
|
||||||
|
|
||||||
.. abstract: doligez94.html
|
|
||||||
|
|
||||||
* .. _DBE93:
|
|
||||||
|
|
||||||
R. Kent Dybvig, Carl Bruggeman, David Eby. 1993. "`Guardians in a Generation-Based Garbage Collector <http://www.cs.indiana.edu/~dyb/pubs/guardians-pldi93.pdf>`_". SIGPLAN. Proceedings of the ACM SIGPLAN '93 Conference on Programming Language Design and Implementation, June 1993.
|
|
||||||
|
|
||||||
.. abstract: dbe93.html
|
|
||||||
|
|
||||||
* .. _EDELSON92A:
|
|
||||||
|
|
||||||
Daniel R. Edelson. 1992. "`Smart pointers: They're smart, but they're not pointers <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.54.530&rep=rep1&type=pdf>`_". USENIX C++ Conference.
|
|
||||||
|
|
||||||
* .. _EDELSON92:
|
|
||||||
|
|
||||||
Daniel R. Edelson. 1992. "Comparing Two Garbage Collectors for C++". University of California at Santa Cruz. Technical Report UCSC-CRL-93-20.
|
|
||||||
|
|
||||||
* .. _EDWARDS:
|
|
||||||
|
|
||||||
Daniel J. Edwards. n.d. "`Lisp II Garbage Collector <ftp://publications.ai.mit.edu/ai-publications/0-499/AIM-019.ps>`_". MIT. AI Memo 19 (AIM-19).
|
|
||||||
|
|
||||||
.. abstract: edwards.html
|
|
||||||
|
|
||||||
* .. _ELLIS93:
|
|
||||||
|
|
||||||
John R. Ellis, David L. Detlefs. 1993. "`Safe, Efficient Garbage Collection for C++ <http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-102.pdf>`_". Xerox PARC.
|
|
||||||
|
|
||||||
.. abstract: ellis93.html
|
|
||||||
|
|
||||||
* .. _FERREIRA96:
|
|
||||||
|
|
||||||
Paulo Ferreira. 1996. "`Larchant: garbage collection in a cached distributed shared store with persistence by reachability <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.31.8434&rep=rep1&type=pdf>`_". Université Paris VI. Thése de doctorat.
|
|
||||||
|
|
||||||
.. abstract: ferreira96.html
|
|
||||||
|
|
||||||
* .. _FS98:
|
|
||||||
|
|
||||||
Paulo Ferreira & Marc Shapiro. 1998. "`Modelling a Distributed Cached Store for Garbage Collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.6176&rep=rep1&type=pdf>`_". Springer-Verlag. Proceedings of 12th European Conference on Object-Oriented Programming, ECOOP98, LNCS 1445.
|
|
||||||
|
|
||||||
* .. _FW76:
|
|
||||||
|
|
||||||
Daniel P Friedman, David S. Wise. 1976. "`Garbage collecting a heap which includes a scatter table <http://www.cs.indiana.edu/pub/techreports/TR34.pdf>`_". *Information Processing Letters.* 5, 6 (December 1976): 161--164.
|
|
||||||
|
|
||||||
* .. _FW77:
|
|
||||||
|
|
||||||
Daniel P Friedman, David S. Wise. 1977. "`The One Bit Reference Count <http://www.cs.indiana.edu/pub/techreports/TR57.pdf>`_". *BIT.* (17)3: 351--359.
|
|
||||||
|
|
||||||
.. abstract: fw77.html
|
|
||||||
|
|
||||||
* .. _FW79:
|
|
||||||
|
|
||||||
Daniel P Friedman, David S. Wise. 1979. "`Reference counting can manage the circular environments of mutual recursion <http://www.cs.indiana.edu/pub/techreports/TR73.pdf>`_". *Information Processing Letters.* 8, 1 (January 1979): 41--45.
|
|
||||||
|
|
||||||
* .. _GZH93:
|
|
||||||
|
|
||||||
Dirk Grunwald, Benjamin Zorn, R. Henderson. 1993. "`Improving the Cache Locality of Memory Allocation <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.43.6621&rep=rep1&type=pdf>`_". SIGPLAN. SIGPLAN '93, Conference on PLDI, June 1993, Albuquerque, New Mexico.
|
|
||||||
|
|
||||||
.. abstract: gzh93.html
|
|
||||||
|
|
||||||
* .. _GRUN92:
|
|
||||||
|
|
||||||
Dirk Grunwald & Benjamin Zorn. 1993. "`CustoMalloc: Efficient Synthesized Memory Allocators <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.35.5260&rep=rep1&type=pdf>`_". Software -- Practice and Experience. 23(8):851--869.
|
|
||||||
|
|
||||||
.. abstract: grun92.html
|
|
||||||
|
|
||||||
* .. _GUDEMAN93:
|
|
||||||
|
|
||||||
David Gudeman. 1993. "`Representing Type Information in Dynamically Typed Languages <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.4394&rep=rep1&type=pdf>`_". University of Arizona at Tucson. Technical Report TR 93-27.
|
|
||||||
|
|
||||||
.. abstract: gudeman93.html
|
|
||||||
|
|
||||||
* .. _HARRIS99:
|
|
||||||
|
|
||||||
Timothy Harris. 1999. "`Early storage reclamation in a tracing garbage collector <http://www.timharris.co.uk/papers/1999-sigplan.pdf>`_". ACM. ACM SIG-PLAN Notices 34:4, pp. 46--53.
|
|
||||||
|
|
||||||
.. abstract: harris99.html
|
|
||||||
|
|
||||||
* .. _HENRIK94:
|
|
||||||
|
|
||||||
Roger Henriksson. 1994. "Scheduling Real Time Garbage Collection". Department of Computer Science at Lund University. LU-CS-TR:94-129.
|
|
||||||
|
|
||||||
.. abstract: henrik94.html
|
|
||||||
|
|
||||||
* .. _HENRIK96:
|
|
||||||
|
|
||||||
Roger Henriksson. 1996. "`Adaptive Scheduling of Incremental Copying Garbage Collection for Interactive Applications <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.51.1554&rep=rep1&type=pdf>`_". NWPER96.
|
|
||||||
|
|
||||||
.. abstract: henrik96.html
|
|
||||||
|
|
||||||
* .. _HENRIKSSON98:
|
|
||||||
|
|
||||||
Roger Henriksson. 1998. "`Scheduling Garbage Collection in Embedded Systems <http://lup.lub.lu.se/luur/download?func=downloadFile&recordOId=18921&fileOId=630830>`_". Department of Computer Science at Lund University. Ph.D. thesis.
|
|
||||||
|
|
||||||
.. abstract: henriksson98.html
|
|
||||||
|
|
||||||
* .. _HOSKING91:
|
|
||||||
|
|
||||||
Antony L. Hosking. 1991. "`Main memory management for persistence <ftp://ftp.cs.purdue.edu/pub/hosking/papers/oopsla91gc-alh.pdf>`_". ACM. Proceedings of the ACM OOPSLA'91 Workshop on Garbage Collection.
|
|
||||||
|
|
||||||
* .. _HMS92:
|
|
||||||
|
|
||||||
Antony L. Hosking, J. Eliot B. Moss, Darko Stefanovic. 1992. "`A comparative performance evaluation of write barrier implementations <ftp://ftp.cs.purdue.edu/pub/hosking/papers/oopsla92.pdf>`_". ACM. OOPSLA'92 Conference Proceedings, ACM SIGPLAN Notices 27(10), pp 92--109.
|
|
||||||
|
|
||||||
* .. _HH93:
|
|
||||||
|
|
||||||
Antony L. Hosking, Richard L. Hudson. 1993. "`Remembered sets can also play cards <ftp://ftp.cs.purdue.edu/pub/hosking/papers/gc-workshop93c.pdf>`_". ACM. Proceedings of the ACM OOPSLA'93 Workshop on Memory Management and Garbage Collection.
|
|
||||||
|
|
||||||
* .. _HM93:
|
|
||||||
|
|
||||||
Antony L. Hosking, J. Eliot B. Moss. 1993. "`Protection traps and alternatives for memory management of an object-oriented language <ftp://ftp.cs.purdue.edu/pub/hosking/papers/sosp93.pdf>`_". ACM. Proceedings of the Fourteenth ACM Symposium on Operating Systems Principles, ACM Operating Systems Review 27(5), pp 106--119.
|
|
||||||
|
|
||||||
* .. _HMDW91:
|
|
||||||
|
|
||||||
Richard L. Hudson, J. Eliot B. Moss, Amer Diwan, Christopher F. Weight. 1991. "`A Language-Independent Garbage Collector Toolkit <http://scholarworks.umass.edu/cgi/viewcontent.cgi?article=1210&context=cs_faculty_pubs>`_". University of Massachusetts at Amherst. COINS Technical Report 91--47.
|
|
||||||
|
|
||||||
.. abstract: hmdw91.html
|
|
||||||
|
|
||||||
* .. _HM92:
|
|
||||||
|
|
||||||
Richard L. Hudson, J. Eliot B. Moss. 1992. "`Incremental Collection of Mature Objects <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.53.3883&rep=rep1&type=pdf>`_". Springer-Verlag. LNCS #637 International Workshop on Memory Management, St. Malo, France, Sept. 1992, pp. 388--403.
|
|
||||||
|
|
||||||
.. abstract: hm92.html
|
|
||||||
|
|
||||||
* .. _HMMM97:
|
|
||||||
|
|
||||||
Richard L. Hudson, Ron Morrison, J. Eliot B. Moss, David S. Munro. 1997. "`Garbage Collecting the World: One Car at a Time <http://www.cs.umass.edu/~moss/papers/oopsla-1997-gc-world.pdf>`_". ACM. Proc. OOPSLA 97, pp. 162--175.
|
|
||||||
|
|
||||||
.. abstract: hmmm97.html
|
|
||||||
|
|
||||||
* .. _ISO90:
|
|
||||||
|
|
||||||
"International Standard ISO/IEC 9899:1990 Programming languages — C".
|
|
||||||
|
|
||||||
* .. _JOHNSTONE97:
|
|
||||||
|
|
||||||
Mark S. Johnstone. 1997. "`Non-Compacting Memory Allocation and Real-Time Garbage Collection <ftp://ftp.cs.utexas.edu/pub/garbage/johnstone-dissertation.ps.gz>`_". University of Texas at Austin.
|
|
||||||
|
|
||||||
.. abstract: johnstone97.html
|
|
||||||
|
|
||||||
* .. _JW98:
|
|
||||||
|
|
||||||
Mark S. Johnstone, Paul R. Wilson. 1998. "`The Memory Fragmentation Problem: Solved? <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.3382&rep=rep1&type=pdf>`_". ACM. ISMM'98 pp. 26--36.
|
|
||||||
|
|
||||||
.. abstract: jw98.html
|
|
||||||
|
|
||||||
* .. _JONES92:
|
|
||||||
|
|
||||||
Richard E. Jones. 1992. "`Tail recursion without space leaks <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.5083&rep=rep1&type=pdf>`_". *Journal of Functional Programming.* 2(1):73--79.
|
|
||||||
|
|
||||||
* .. _JL92:
|
|
||||||
|
|
||||||
Richard E. Jones, Rafael Lins. 1992. "`Cyclic weighted reference counting without delay <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.43.8499&rep=rep1&type=pdf>`_". Computing Laboratory, The University of Kent at Canterbury. Technical Report 28-92.
|
|
||||||
|
|
||||||
.. abstract: jl92.html
|
|
||||||
|
|
||||||
* .. _JONES96:
|
|
||||||
|
|
||||||
Richard E. Jones, Rafael Lins. 1996. "`Garbage Collection: Algorithms for Automatic Dynamic Memory Management <http://www.cs.ukc.ac.uk/people/staff/rej/gcbook/gcbook.html>`_". Wiley. ISBN 0-471-94148-4.
|
|
||||||
|
|
||||||
.. abstract: jones96.html
|
|
||||||
|
|
||||||
* .. _ACM98:
|
|
||||||
|
|
||||||
Richard E. Jones. 1998. "`ISMM'98 International Symposium on Memory Management <http://www.acm.org/pubs/contents/proceedings/plan/286860/>`_". ACM. ISBN 1-58113-114-3.
|
|
||||||
|
|
||||||
.. abstract: acm98.html
|
|
||||||
|
|
||||||
* .. _JONES12:
|
|
||||||
|
|
||||||
Richard E. Jones, Antony Hosking, and Eliot Moss. 2012. "`The Garbage Collection Handbook <http://gchandbook.org/>`_". Chapman & Hall.
|
|
||||||
|
|
||||||
* .. _JOYNER96:
|
|
||||||
|
|
||||||
Ian Joyner. 1996. "`C++??: A Critique of C++ <http://www.emu.edu.tr/aelci/Courses/D-318/D-318-Files/cppcrit/index.htm>`_.".
|
|
||||||
|
|
||||||
* .. _KANEFSKY89:
|
|
||||||
|
|
||||||
Bob Kanefsky. 1989. "`Recursive Memory Allocation <http://www.songworm.com/db/songworm-parody/RecursiveMemoryAllocation.html>`_". Bob Kanefsky. Songworm 3, p.?.
|
|
||||||
|
|
||||||
* .. _KQH98:
|
|
||||||
|
|
||||||
Jin-Soo Kim, Xiaohan Qin, Yarsun Hsu. 1998. "`Memory Characterization of a Parallel Data Mining Workload <http://csl.skku.edu/papers/wwc98.pdf>`_". IEEE. Proc. Workload Characterization: Methodology and Case Studies, pp. .
|
|
||||||
|
|
||||||
.. abstract: kqh98.html
|
|
||||||
|
|
||||||
* .. _KH00:
|
|
||||||
|
|
||||||
Jin-Soo Kim & Yarsun Hsu. 2000. "Memory system behavior of Java programs: methodology and analysis". ACM. Proc. International conference on measurements and modeling of computer systems, pp. 264--274.
|
|
||||||
|
|
||||||
* .. _KOLODNER92:
|
|
||||||
|
|
||||||
Elliot K. Kolodner. 1992. "Atomic Incremental Garbage Collection and Recovery for a Large Stable Heap". Laboratory for Computer Science at MIT. MIT-LCS-TR-534.
|
|
||||||
|
|
||||||
.. abstract: kolodner92.html
|
|
||||||
|
|
||||||
* .. _LK98:
|
|
||||||
|
|
||||||
Per-Åke Larson & Murali Krishnan. 1998. "`Memory Allocation for Long-Running Server Applications <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.1947&rep=rep1&type=pdf>`_". ACM. ISMM'98 pp. 176--185.
|
|
||||||
|
|
||||||
.. abstract: lk98.html
|
|
||||||
|
|
||||||
* .. _LH83:
|
|
||||||
|
|
||||||
Henry Lieberman & Carl Hewitt. 1983. "`A real-time garbage collector based on the lifetimes of objects <http://web.media.mit.edu/~lieber/Lieberary/GC/Realtime/Realtime.html>`_". ACM. 26(6):419--429.
|
|
||||||
|
|
||||||
* .. _MM59:
|
|
||||||
|
|
||||||
J. McCarthy, M. L. Minsky. 1959. "Artificial Intelligence, Quarterly Progress Report no. 53". Research Laboratory of Electronics at MIT.
|
|
||||||
|
|
||||||
* .. _MCCARTHY60:
|
|
||||||
|
|
||||||
J. McCarthy. 1960. "`Recursive Functions of Symbolic Expressions and Their Computation by Machine <http://www-formal.stanford.edu/jmc/recursive.html>`_". CACM.
|
|
||||||
|
|
||||||
.. abstract: mccarthy60.html
|
|
||||||
|
|
||||||
* .. _MCCARTHY79:
|
|
||||||
|
|
||||||
John McCarthy. 1979. "`History of Lisp <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.16.4634&rep=rep1&type=pdf>`_". In *History of programming languages I*, pp. 173–185. ACM.
|
|
||||||
|
|
||||||
* .. _PTM98:
|
|
||||||
|
|
||||||
Veljko Milutinovic, Jelica Protic, Milo Tomasevic. 1997. "`Distributed shared memory: concepts and systems <http://www.cs.umass.edu/~mcorner/courses/691J/papers/VM/protic_dsm/protic_dsm.pdf>`_". IEEE Computer Society Press. ISBN 0-8186-7737-6.
|
|
||||||
|
|
||||||
.. abstract: ptm98.html
|
|
||||||
|
|
||||||
* .. _MINSKY63:
|
|
||||||
|
|
||||||
M. L. Minsky. 1963. "A LISP Garbage Collector Algorithm Using Serial Secondary Storage". MIT. Memorandum MAC-M-129, Artificial Intelligence Project, Memo 58 (revised).
|
|
||||||
|
|
||||||
* .. _MOON84:
|
|
||||||
|
|
||||||
David Moon. 1984. "`Garbage Collection in a Large Lisp System <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.125.2438&rep=rep1&type=pdf>`_". ACM. Symposium on Lisp and Functional Programming, August 1984.
|
|
||||||
|
|
||||||
* .. _MOON85:
|
|
||||||
|
|
||||||
David Moon. 1985. "Architecture of the Symbolics 3600". IEEE. 12th International Symposium on Computer Architecture, pp. 76--83.
|
|
||||||
|
|
||||||
* .. _MOON87:
|
|
||||||
|
|
||||||
David Moon. 1990. "Symbolics Architecture". Wiley. Chapter 3 of *Computers for Artificial Intelligence Processing*, ISBN 0-471-84811-5.
|
|
||||||
|
|
||||||
* .. _MOON91:
|
|
||||||
|
|
||||||
David Moon. 1991. "Genera Retrospective". IEEE. 1991 International Workshop on Object Orientation in Operating Systems, order #2265.
|
|
||||||
|
|
||||||
* .. _MORDEC84:
|
|
||||||
|
|
||||||
Ben-Ari Mordechai. 1984. "Algorithms for On-the-fly Garbage Collection". *TOPLAS* 6(3): 333--344 (1984).
|
|
||||||
|
|
||||||
* .. _MOREAU98:
|
|
||||||
|
|
||||||
Luc Moreau. 1998. "`Hierarchical Distributed Reference Counting <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.49.4593&rep=rep1&type=pdf>`_". ACM. ISMM'98 pp. 57--67.
|
|
||||||
|
|
||||||
* .. _MFH95:
|
|
||||||
|
|
||||||
Greg Morrisett, Matthias Felleisen, Robert Harper. 1995. "`Abstract Models of Memory Management <http://www.eecs.harvard.edu/~greg/papers/fpca_gc.ps>`_". Carnegie Mellon University. CMU-CS-FOX-95-01.
|
|
||||||
|
|
||||||
.. abstract: mfh95.html
|
|
||||||
|
|
||||||
* .. _MBMM99:
|
|
||||||
|
|
||||||
David S. Munro, Alfred Brown, Ron Morrison, J. Eliot B. Moss. 1999. "`Incremental Garbage Collection of a Persistent Object Store using PMOS <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.36.3687&rep=rep1&type=pdf>`_". Morgan Kaufmann. in Advances in Persistent Object Systems, pp. 78--91.
|
|
||||||
|
|
||||||
.. abstract: mbmm99.html
|
|
||||||
|
|
||||||
* .. _NOPH92:
|
|
||||||
|
|
||||||
Scott Nettles, James O'Toole, David Pierce, Nickolas Haines. 1992. "`Replication-Based Incremental Copying Collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.28.4233&rep=rep1&type=pdf>`_". IWMM'92.
|
|
||||||
|
|
||||||
.. abstract: noph92.html
|
|
||||||
|
|
||||||
* .. _NETTLES92:
|
|
||||||
|
|
||||||
Scott Nettles. 1992. "`A Larch Specification of Copying Garbage Collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.1498&rep=rep1&type=pdf>`_". Carnegie Mellon University. CMU-CS-92-219.
|
|
||||||
|
|
||||||
.. abstract: nettles92.html
|
|
||||||
|
|
||||||
* .. _NO93A:
|
|
||||||
|
|
||||||
Scott Nettles & James O'Toole. 1993. "Implementing Orthogonal Persistence: A Simple Optimization Using Replicating Collection". USENIX. IWOOOS'93.
|
|
||||||
|
|
||||||
.. abstract: no93a.html
|
|
||||||
|
|
||||||
* .. _NO93:
|
|
||||||
|
|
||||||
Scott Nettles & James O'Toole. 1993. "`Real-Time Replication Garbage Collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.69.1875&rep=rep1&type=pdf>`_". ACM. PLDI'93.
|
|
||||||
|
|
||||||
.. abstract: no93.html
|
|
||||||
|
|
||||||
* .. _NIELSEN77:
|
|
||||||
|
|
||||||
Norman R. Nielsen. 1977. "Dynamic Memory Allocation in Computer Simulation". ACM. CACM 20:11.
|
|
||||||
|
|
||||||
.. abstract: nielsen77.html
|
|
||||||
|
|
||||||
* .. _OTOOLE90:
|
|
||||||
|
|
||||||
James O'Toole. 1990. "Garbage Collecting Locally".
|
|
||||||
|
|
||||||
.. abstract: otoole90.html
|
|
||||||
|
|
||||||
* .. _ON94:
|
|
||||||
|
|
||||||
James O'Toole & Scott Nettles. 1994. "`Concurrent Replicating Garbage Collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.49.5001&rep=rep1&type=pdf>`_". ACM. LFP'94.
|
|
||||||
|
|
||||||
.. abstract: on94.html
|
|
||||||
|
|
||||||
* .. _JRR99:
|
|
||||||
|
|
||||||
Simon Peyton Jones, Norman Ramsey, Fermin Reig. 1999. "`C--: a portable assembly language that supports garbage collection <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.11.1815&rep=rep1&type=pdf>`_". Springer-Verlag. International Conference on Principles and Practice of Declarative Programming 1999, LNCS 1702, pp. 1--28.
|
|
||||||
|
|
||||||
.. abstract: jrr99.html
|
|
||||||
|
|
||||||
* .. _PIEPER93:
|
|
||||||
|
|
||||||
John S. Pieper. 1993. "Compiler Techniques for Managing Data Motion". Carnegie Mellon University. Technical report number CMU-CS-93-217.
|
|
||||||
|
|
||||||
.. abstract: pieper93.html
|
|
||||||
|
|
||||||
* .. _PIRINEN98:
|
|
||||||
|
|
||||||
Pekka P. Pirinen. 1998. "Barrier techniques for incremental tracing". ACM. ISMM'98 pp. 20--25.
|
|
||||||
|
|
||||||
.. abstract: pirinen98.html
|
|
||||||
|
|
||||||
* .. _PRINTEZIS96:
|
|
||||||
|
|
||||||
Tony Printezis. 1996. "Disk Garbage Collection Strategies for Persistent Java". Proceedings of the First International Workshop on Persistence and Java.
|
|
||||||
|
|
||||||
.. abstract: printezis96.html
|
|
||||||
|
|
||||||
* .. _PC96:
|
|
||||||
|
|
||||||
Tony Printezis & Quentin Cutts. 1996. "Measuring the Allocation Rate of Napier88". Department of Computing Science at University of Glasgow. TR ?.
|
|
||||||
|
|
||||||
* .. _REINHOLD93:
|
|
||||||
|
|
||||||
M. B. Reinhold. 1993. "`Cache Performance of Garbage Collected Programming Languages <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.18.5454&rep=rep1&type=pdf>`_". Laboratory for Computer Science at MIT. MIT/LCS/TR-581.
|
|
||||||
|
|
||||||
.. abstract: reinhold93.html
|
|
||||||
|
|
||||||
* .. _ROBSON77:
|
|
||||||
|
|
||||||
J. M. Robson. 1977. "Worst case fragmentation of first fit and best fit storage allocation strategies". ACM. ACM Computer Journal, 20(3):242--244.
|
|
||||||
|
|
||||||
* .. _RR97:
|
|
||||||
|
|
||||||
Gustavo Rodriguez-Rivera & Vince Russo. 1997. "Non-intrusive Cloning Garbage Collection with Stock Operating System Support". Software -- Practice and Experience. 27:8.
|
|
||||||
|
|
||||||
.. abstract: rr97.html
|
|
||||||
|
|
||||||
* .. _ROJEMO95:
|
|
||||||
|
|
||||||
Niklas Röjemo. 1995. "Highlights from nhc -- a space-efficient Haskell compiler". Chalmers University of Technology.
|
|
||||||
|
|
||||||
.. abstract: rojemo95.html
|
|
||||||
|
|
||||||
* .. _ROJEMO95A:
|
|
||||||
|
|
||||||
Niklas Röjemo. 1995. "Generational garbage collection for lazy functional languages without temporary space leaks". Chalmers University of Technology.
|
|
||||||
|
|
||||||
* .. _RR96:
|
|
||||||
|
|
||||||
Niklas Röjemo & Colin Runciman. 1996. "Lag, drag, void and use -- heap profiling and space-efficient compilation revisited". ACM, SIGPLAN. ICFP'96, ACM SIGPLAN Notices 31:6, ISBN 0-89791-770-7, pp. 34--41.
|
|
||||||
|
|
||||||
.. abstract: rr96.html
|
|
||||||
|
|
||||||
* .. _RW99:
|
|
||||||
|
|
||||||
David J. Roth, David S. Wise. 1999. "`One-bit counts between unique and sticky <http://www.cs.indiana.edu/pub/techreports/TR516.pdf>`_". ACM. ISMM'98, pp. 49--56.
|
|
||||||
|
|
||||||
.. abstract: rw99.html
|
|
||||||
|
|
||||||
* .. _ROVNER85:
|
|
||||||
|
|
||||||
Paul Rovner. 1985. "`On Adding Garbage Collection and Runtime Types to a Strongly-Typed, Statically-Checked, Concurrent Language <http://e3k.computer-refuge.org/bitsavers/pdf/xerox/parc/techReports/CSL-84-7_On_Adding_Garbage_Collection_and_Runtime_Types_to_a_Strongly-Typed_Statically-Checked_Concurrent_Language.pdf>`_". Xerox PARC. TR CSL-84-7.
|
|
||||||
|
|
||||||
* .. _RUNCIMAN92:
|
|
||||||
|
|
||||||
Colin Runciman & David Wakeling. 1992. "`Heap Profiling of Lazy Functional Programs <ftp://ftp.cs.york.ac.uk/reports/YCS-92-172.ps.Z>`_". University of York.
|
|
||||||
|
|
||||||
.. abstract: runciman92.html
|
|
||||||
|
|
||||||
* .. _RR94:
|
|
||||||
|
|
||||||
Colin Runciman & Niklas Röjemo. 1994. "`New dimensions in heap profiling <http://www.cs.york.ac.uk/plasma/publications/pdf/RuncimanWakelingJFP93.pdf>`_". University of York.
|
|
||||||
|
|
||||||
.. abstract: rr94.html
|
|
||||||
|
|
||||||
* .. _RR96A:
|
|
||||||
|
|
||||||
Colin Runciman & Niklas Röjemo. 1996. "Two-pass heap profiling: a matter of life and death". Department of Computer Science, University of York.
|
|
||||||
|
|
||||||
* .. _SG95:
|
|
||||||
|
|
||||||
Jacob Seligmann & Steffen Grarup. 1995. "`Incremental Mature Garbage Collection Using the Train Algorithm <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.32.7307&rep=rep1&type=pdf>`_". Springer-Verlag. ECOOP'95, Lecture Notes in Computer Science, Vol. 952, pp. 235--252, ISBN 3-540-60160-0.
|
|
||||||
|
|
||||||
.. abstract: sg95.html
|
|
||||||
|
|
||||||
* .. _SB00:
|
|
||||||
|
|
||||||
Manuel Serrano, Hans-J. Boehm. 2000. "`Understanding memory allocation of Scheme programs <http://www.hpl.hp.com/techreports/2000/HPL-2000-62.html>`_". ACM. Proceedings of International Conference on Functional Programming 2000.
|
|
||||||
|
|
||||||
* .. _SHAPIRO94:
|
|
||||||
|
|
||||||
Marc Shapiro & Paulo Ferreira. 1994. "`Larchant-RDOSS: a distributed shared persistent memory and its garbage collector <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.52.8468&rep=rep1&type=pdf>`_". INRIA. INRIA Rapport de Recherche no. 2399; Cornell Computer Science TR94-1466.
|
|
||||||
|
|
||||||
.. abstract: shapiro94.html
|
|
||||||
|
|
||||||
* .. _SHAW87:
|
|
||||||
|
|
||||||
Robert A. Shaw. 1987. "Improving Garbage Collector Performance in Virtual Memory". Stanford University. CSL-TR-87-323.
|
|
||||||
|
|
||||||
* .. _SHAW88:
|
|
||||||
|
|
||||||
Robert A. Shaw. 1988. "Empirical Analysis of a LISP System". Stanford University. CSL-TR-88-351.
|
|
||||||
|
|
||||||
* .. _SINGHAL92:
|
|
||||||
|
|
||||||
Vivek Singhal, Sheetal V. Kakkad, Paul R. Wilson. 1992. "`Texas: An Efficient, Portable Persistent Store <ftp://ftp.cs.utexas.edu/pub/garbage/texaspstore.ps>`_". University of Texas at Austin.
|
|
||||||
|
|
||||||
.. abstract: singhal92.html
|
|
||||||
|
|
||||||
* .. _SOBALVARRO88:
|
|
||||||
|
|
||||||
P. G. Sobalvarro. 1988. "`A Lifetime-based Garbage Collector for LISP Systems on General-Purpose Computers <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.57.2188&rep=rep1&type=pdf>`_". MIT. AITR-1417.
|
|
||||||
|
|
||||||
.. abstract: sobalvarro88.html
|
|
||||||
|
|
||||||
* .. _STEELE75:
|
|
||||||
|
|
||||||
Guy L. Steele. 1975. "`Multiprocessing Compactifying Garbage Collection <http://www.cs.utexas.edu/users/mckinley/395Tmm/talks/Mar-23-CMS.pdf>`_". CACM. 18:9 pp. 495--508.
|
|
||||||
|
|
||||||
* .. _STEELE76:
|
|
||||||
|
|
||||||
Guy L. Steele. 1976. "Corrigendum: Multiprocessing Compactifying Garbage Collection". CACM. 19:6 p.354.
|
|
||||||
|
|
||||||
* .. _STEELE77:
|
|
||||||
|
|
||||||
Guy L. Steele. 1977. "Data Representation in PDP-10 MACLISP". MIT. AI Memo 421.
|
|
||||||
|
|
||||||
* .. _SLC99:
|
|
||||||
|
|
||||||
James M. Stichnoth, Guei-Yuan Lueh, Michal Cierniak. 1999. "`Support for Garbage Collection at Every Instruction in a Java Compiler <http://www.acm.org/pubs/citations/proceedings/pldi/301618/p118-stichnoth/>`_". SIGPLAN. Proceedings of the 1999 ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI). SIGPLAN Notices 34(5). pp. 118--127.
|
|
||||||
|
|
||||||
* .. _SCN84:
|
|
||||||
|
|
||||||
Will R Stoye, T J W Clarke, Arthur C Norman. 1984. "Some Practical Methods for Rapid Combinator Reduction". In LFP 1984, 159--166.
|
|
||||||
|
|
||||||
* .. _TD95:
|
|
||||||
|
|
||||||
David Tarditi & Amer Diwan. 1995. "`Measuring the Cost of Storage Management <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.4550&rep=rep1&type=pdf>`_". Carnegie Mellon University. CMU-CS-94-201.
|
|
||||||
|
|
||||||
.. abstract: td95.html
|
|
||||||
|
|
||||||
* .. _TJ94:
|
|
||||||
|
|
||||||
Stephen Thomas, Richard E. Jones. 1994. "Garbage Collection for Shared Environment Closure Reducers". Computing Laboratory, The University of Kent at Canterbury. Technical Report 31-94.
|
|
||||||
|
|
||||||
.. abstract: tj94.html
|
|
||||||
|
|
||||||
* .. _THOMAS95:
|
|
||||||
|
|
||||||
Stephen Thomas. 1995. "Garbage Collection in Shared-Environment Closure Reducers: Space-Efficient Depth First Copying using a Tailored Approach". *Information Processing Letters.* 56:1, pp. 1--7.
|
|
||||||
|
|
||||||
* .. _TT97:
|
|
||||||
|
|
||||||
Mads Tofte & Jean-Pierre Talpin. 1997. "`Region-Based Memory Management <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.75.9105&rep=rep1&type=pdf>`_". Information and Computation 132(2), pp. 109--176.
|
|
||||||
|
|
||||||
.. abstract: tt97.html
|
|
||||||
|
|
||||||
* .. _UNGAR84:
|
|
||||||
|
|
||||||
Dave Ungar. 1984. "`Generation Scavenging: A Non-disruptive High Performance Storage Reclamation Algorithm <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.122.4295&rep=rep1&type=pdf>`_". ACM, SIGSOFT, SIGPLAN. Practical Programming Environments Conference.
|
|
||||||
|
|
||||||
* .. _UNGAR88:
|
|
||||||
|
|
||||||
Dave Ungar & Frank Jackson. 1988. "`Tenuring Policies for Generation-Based Storage Reclamation <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.115.2810&rep=rep1&type=pdf>`_". SIGPLAN. OOPSLA '88 Conference Proceedings, ACM SIGPLAN Notices, Vol. 23, No. 11, pp. 1--17.
|
|
||||||
|
|
||||||
.. abstract: ungar88.html
|
|
||||||
|
|
||||||
* .. _VO96:
|
|
||||||
|
|
||||||
Kiem-Phong Vo. 1996. "Vmalloc: A General and Efficient Memory Allocator". Software -- Practice and Experience. 26(3): 357--374 (1996).
|
|
||||||
|
|
||||||
.. abstract: vo96.html
|
|
||||||
|
|
||||||
* .. _WW76:
|
|
||||||
|
|
||||||
Daniel C. Watson, David S. Wise. 1976. "Tuning Garwick's algorithm for repacking sequential storage". *BIT.* 16, 4 (December 1976): 442--450.
|
|
||||||
|
|
||||||
* .. _WLM92:
|
|
||||||
|
|
||||||
Paul R. Wilson, Michael S. Lam, Thomas G. Moher. 1992. "Caching Considerations for Generational Garbage Collection". ACM. L&FP 92.
|
|
||||||
|
|
||||||
.. abstract: wlm92.html
|
|
||||||
|
|
||||||
* .. _WIL92A:
|
|
||||||
|
|
||||||
Paul R. Wilson, Sheetal V. Kakkad. 1992. "`Pointer Swizzling at Page Fault Time <ftp://ftp.cs.utexas.edu/pub/garbage/swizz.ps>`_". University of Texas at Austin.
|
|
||||||
|
|
||||||
.. abstract: wil92a.html
|
|
||||||
|
|
||||||
* .. _WIL94:
|
|
||||||
|
|
||||||
Paul R. Wilson. 1994. "`Uniprocessor Garbage Collection Techniques <ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps>`_". University of Texas.
|
|
||||||
|
|
||||||
.. abstract: wil94.html
|
|
||||||
|
|
||||||
* .. _WIL95:
|
|
||||||
|
|
||||||
Paul R. Wilson, Mark S. Johnstone, Michael Neely, David Boles. 1995. "`Dynamic Storage Allocation: A Survey and Critical Review <ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps>`_". University of Texas at Austin.
|
|
||||||
|
|
||||||
.. abstract: wil95.html
|
|
||||||
|
|
||||||
* .. _WISE78:
|
|
||||||
|
|
||||||
David S. Wise. 1978. "`The double buddy system <http://www.cs.indiana.edu/ftp/techreports/>`_". Department of Computer Science at Indiana University. Technical Report 79.
|
|
||||||
|
|
||||||
* .. _WISE79:
|
|
||||||
|
|
||||||
David S. Wise. 1979. "`Morris's garbage compaction algorithm restores reference counts <http://www.cs.indiana.edu/ftp/techreports/TR75.pdf>`_". TOPLAS. 1, 1 (July l979): 115--120.
|
|
||||||
|
|
||||||
* .. _WISE85:
|
|
||||||
|
|
||||||
David S. Wise. 1985. "`Design for a multiprocessing heap with on-board reference counting <http://www.cs.indiana.edu/ftp/techreports/TR163.pdf>`_". Springer-Verlag. In J.-P. Jouannaud (ed.), Functional Programming Languages and Computer Architecture, Lecture Notes in Computer Science 201: 289--304.
|
|
||||||
|
|
||||||
* .. _WISE92:
|
|
||||||
|
|
||||||
.. _WISE93:
|
|
||||||
|
|
||||||
David S. Wise. 1993. "`Stop-and-copy and one-bit reference counting <http://www.cs.indiana.edu/ftp/techreports/TR360.pdf>`_". *Information Processing Letters.* 46, 5 (July 1993): 243--249.
|
|
||||||
|
|
||||||
.. abstract: wise92.html
|
|
||||||
|
|
||||||
* .. _WW95:
|
|
||||||
|
|
||||||
David S. Wise, Joshua Walgenbach. 1996. "`Static and Dynamic Partitioning of Pointers as Links and Threads <http://www.cs.indiana.edu/ftp/techreports/TR437.pdf>`_". SIGPLAN. Proc. 1996 ACM SIGPLAN Intl. Conf. on Functional Programming, SIGPLAN Not. 31, 6 (June 1996), pp. 42--49.
|
|
||||||
|
|
||||||
* .. _WHHHO94:
|
|
||||||
|
|
||||||
David S. Wise, Brian Heck, Caleb Hess, Willie Hunt, Eric Ost. 1997. "`Uniprocessor Performance of a Reference-Counting Hardware Heap <http://www.cs.indiana.edu/ftp/techreports/TR401.pdf>`_". *LISP and Symbolic Computation.* 10, 2 (July 1997), pp. 159--181.
|
|
||||||
|
|
||||||
* .. _WITHINGTON91:
|
|
||||||
|
|
||||||
P. Tucker Withington. 1991. "`How Real is 'Real-Time' Garbage Collection? <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.116.3169&rep=rep1&type=pdf>`_". ACM. OOPSLA/ECOOP '91 Workshop on Garbage Collection in Object-Oriented Systems.
|
|
||||||
|
|
||||||
.. abstract: withington91.html
|
|
||||||
|
|
||||||
* .. _YIP91:
|
|
||||||
|
|
||||||
G. May Yip. 1991. "`Incremental, Generational Mostly-Copying Garbage Collection in Uncooperative Environments <http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-8.pdf>`_". Digital Equipment Corporation.
|
|
||||||
|
|
||||||
.. abstract: yip91.html
|
|
||||||
|
|
||||||
* .. _YUASA90:
|
|
||||||
|
|
||||||
Taiichi Yuasa. 1990. "Real-Time Garbage Collection on General-Purpose Machines". Journal of Software and Systems. 11:3 pp. 181--198.
|
|
||||||
|
|
||||||
* .. _ZORN88:
|
|
||||||
|
|
||||||
Benjamin Zorn & Paul Hilfinger. 1988. "`A Memory Allocation Profiler for C and Lisp Programs <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.6.1689&rep=rep1&type=pdf>`_". USENIX. Proceedings for the Summer 1988 USENIX Conference, pp. 223--237.
|
|
||||||
|
|
||||||
.. abstract: zorn88.html
|
|
||||||
|
|
||||||
* .. _ZORN89:
|
|
||||||
|
|
||||||
Benjamin Zorn. 1989. "`Comparative Performance Evaluation of Garbage Collection Algorithms <http://www.eecs.berkeley.edu/Pubs/TechRpts/1989/CSD-89-544.pdf>`_". Computer Science Division (EECS) of University of California at Berkeley. Technical Report UCB/CSD 89/544 and PhD thesis.
|
|
||||||
|
|
||||||
.. abstract: zorn89.html
|
|
||||||
|
|
||||||
* .. _ZORN90B:
|
|
||||||
|
|
||||||
Benjamin Zorn. 1990. "Comparing Mark-and-sweep and Stop-and-copy Garbage Collection". ACM. Conference on Lisp and Functional Programming, pp. 87--98.
|
|
||||||
|
|
||||||
.. abstract: zorn90b.html
|
|
||||||
|
|
||||||
* .. _ZORN90:
|
|
||||||
|
|
||||||
Benjamin Zorn. 1990. "`Barrier Methods for Garbage Collection <http://www.cs.colorado.edu/department/publications/reports/docs/CU-CS-494-90.pdf>`_". University of Colorado at Boulder. Technical Report CU-CS-494-90.
|
|
||||||
|
|
||||||
.. abstract: zorn90.html
|
|
||||||
|
|
||||||
* .. _ZORN91:
|
|
||||||
|
|
||||||
Benjamin Zorn. 1991. "`The Effect of Garbage Collection on Cache Performance <http://www.cs.colorado.edu/department/publications/reports/docs/CU-CS-528-91.pdf>`_". University of Colorado at Boulder. Technical Report CU-CS-528-91.
|
|
||||||
|
|
||||||
.. abstract: zorn91.html
|
|
||||||
|
|
||||||
* .. _ZORN92B:
|
|
||||||
|
|
||||||
Benjamin Zorn & Dirk Grunwald. 1992. "`Empirical Measurements of Six Allocation-intensive C Programs <http://www.cs.colorado.edu/department/publications/reports/docs/CU-CS-604-92.pdf>`_". ACM, SIGPLAN. SIGPLAN notices, 27(12):71--80.
|
|
||||||
|
|
||||||
.. abstract: zorn92b.html
|
|
||||||
|
|
||||||
* .. _ZORN92:
|
|
||||||
|
|
||||||
Benjamin Zorn. 1993. "`The Measured Cost of Conservative Garbage Collection <http://www.cs.colorado.edu/department/publications/reports/docs/CU-CS-573-92.pdf>`_". Software -- Practice and Experience. 23(7):733--756.
|
|
||||||
|
|
||||||
.. abstract: zorn92.html
|
|
||||||
|
|
||||||
* .. _ZORN92A:
|
|
||||||
|
|
||||||
Benjamin Zorn & Dirk Grunwald. 1994. "`Evaluating Models of Memory Allocation <http://www.cs.colorado.edu/department/publications/reports/docs/CU-CS-603-92.pdf>`_". ACM. Transactions on Modeling and Computer Simulation 4(1):107--131.
|
|
||||||
|
|
||||||
.. abstract: zorn92a.html
|
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ Reference.
|
||||||
The Adaptive Memory Management Group no longer exists, and Harlequin
|
The Adaptive Memory Management Group no longer exists, and Harlequin
|
||||||
has become a part of `Global Graphics
|
has become a part of `Global Graphics
|
||||||
<http://www.globalgraphics.com/>`_. However, most of the group's work
|
<http://www.globalgraphics.com/>`_. However, most of the group's work
|
||||||
has been aquired by `Ravenbrook Limited`, whose directors are Richard
|
has been aquired by `Ravenbrook Limited`_, whose directors are Richard
|
||||||
Brooksby, the group's chief architect and manager, and Nick Barnes, a
|
Brooksby, the group's chief architect and manager, and Nick Barnes, a
|
||||||
senior group member.
|
senior group member.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,12 @@ garbage collection>` for :term:`C` exist as add-on libraries.
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Boehm–Weiser collector <http://www.hpl.hp.com/personal/Hans_Boehm/gc/>`_.
|
`Memory Pool System <http://www.ravenbrook.com/project/mps/>`_,
|
||||||
|
`Boehm–Demers–Weiser collector <http://hboehm.info/gc/>`_.
|
||||||
|
|
||||||
|
|
||||||
Why do I need to test the return value from ``malloc``? Surely it always succeeds?
|
Why do I need to test the return value from malloc? Surely it always succeeds?
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
For small programs, and during light testing, it is true that
|
For small programs, and during light testing, it is true that
|
||||||
:term:`malloc` usually succeeds. Unfortunately, there are all sorts of
|
:term:`malloc` usually succeeds. Unfortunately, there are all sorts of
|
||||||
|
|
@ -73,8 +74,8 @@ when out of memory, wrap :term:`malloc` in something like this::
|
||||||
Undefined behavior is worth eliminating even in small programs.
|
Undefined behavior is worth eliminating even in small programs.
|
||||||
|
|
||||||
|
|
||||||
What's the point of having a garbage collector? Why not use ``malloc`` and ``free``?
|
What's the point of having a garbage collector? Why not use malloc and free?
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
:term:`Manual memory management`, such as :term:`malloc` and
|
:term:`Manual memory management`, such as :term:`malloc` and
|
||||||
:term:`free (2)`, forces the programmer to keep track of which memory
|
:term:`free (2)`, forces the programmer to keep track of which memory
|
||||||
|
|
@ -90,12 +91,12 @@ problem, rather than the tedious details of the implementation.
|
||||||
.. seealso:: :term:`garbage collection`
|
.. seealso:: :term:`garbage collection`
|
||||||
|
|
||||||
|
|
||||||
What's wrong with ANSI ``malloc`` in the C library?
|
What's wrong with ANSI malloc in the C library?
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
:term:`Malloc` provides a very basic :term:`manual memory management`
|
The :term:`malloc` function provides a very basic :term:`manual memory
|
||||||
service. However, it does not provide the following things, which may
|
management` service. However, it does not provide the following
|
||||||
be desirable in your memory manager:
|
things, which may be desirable in your memory manager:
|
||||||
|
|
||||||
* high performance for specified block sizes;
|
* high performance for specified block sizes;
|
||||||
* :term:`tagged references`;
|
* :term:`tagged references`;
|
||||||
|
|
@ -130,11 +131,12 @@ semi-conservative garbage collectors for C++.
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Boehm–Weiser collector <http://www.hpl.hp.com/personal/Hans_Boehm/gc/>`_.
|
`Memory Pool System <http://www.ravenbrook.com/project/mps/>`_,
|
||||||
|
`Boehm–Demers–Weiser collector <http://hboehm.info/gc/>`_.
|
||||||
|
|
||||||
|
|
||||||
Why is ``delete`` so slow?
|
Why is delete so slow?
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Often ``delete`` must perform a more complex task than simply freeing
|
Often ``delete`` must perform a more complex task than simply freeing
|
||||||
the memory associated with an object; this is known as
|
the memory associated with an object; this is known as
|
||||||
|
|
@ -163,12 +165,12 @@ In :term:`C++`, it may be that class libraries expect you to call
|
||||||
|
|
||||||
Failing this, if there is a genuine :term:`memory leak` in a class
|
Failing this, if there is a genuine :term:`memory leak` in a class
|
||||||
library for which you don't have the source, then the only thing you
|
library for which you don't have the source, then the only thing you
|
||||||
can try is to add a :term:`garbage collector`. The Boehm–Weiser
|
can try is to add a :term:`garbage collector`.
|
||||||
collector will work with C++.
|
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Boehm–Weiser collector <http://www.hpl.hp.com/personal/Hans_Boehm/gc/>`_.
|
`Memory Pool System <http://www.ravenbrook.com/project/mps/>`_,
|
||||||
|
`Boehm–Demers–Weiser collector <http://hboehm.info/gc/>`_.
|
||||||
|
|
||||||
|
|
||||||
Can't I get all the benefits of garbage collection using C++ constructors and destructors?
|
Can't I get all the benefits of garbage collection using C++ constructors and destructors?
|
||||||
|
|
@ -400,7 +402,7 @@ Where can I find out more about garbage collection?
|
||||||
Many modern languages have :term:`garbage collection` built in, and
|
Many modern languages have :term:`garbage collection` built in, and
|
||||||
the language documentation should give details. For some other
|
the language documentation should give details. For some other
|
||||||
languages, garbage collection can be added, for example via the
|
languages, garbage collection can be added, for example via the
|
||||||
Boehm–Weiser collector.
|
Memory Pool System, or the Boehm–Demers–Weiser collector.
|
||||||
|
|
||||||
.. seealso:: :term:`garbage collection`
|
.. seealso:: :term:`garbage collection`
|
||||||
|
|
||||||
|
|
@ -408,22 +410,25 @@ Boehm–Weiser collector.
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Boehm–Weiser collector <http://www.hpl.hp.com/personal/Hans_Boehm/gc/>`_,
|
`Memory Pool System <http://www.ravenbrook.com/project/mps/>`_,
|
||||||
|
`Boehm–Demers–Weiser collector <http://hboehm.info/gc/>`_,
|
||||||
`GC-LIST FAQ <http://iecc.com/gclist/GC-faq.html>`_.
|
`GC-LIST FAQ <http://iecc.com/gclist/GC-faq.html>`_.
|
||||||
|
|
||||||
|
|
||||||
Where can I get a garbage collector?
|
Where can I get a garbage collector?
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The Boehm–Weiser collector is suitable for C or C++. The best way to
|
The Memory Pool System and the Boehm–Demers–Weiser collector are
|
||||||
get a garbage collector, however, is to program in a language that
|
suitable for C or C++. The best way to get a garbage collector,
|
||||||
provides garbage collection.
|
however, is to program in a language that provides garbage collection
|
||||||
|
natively.
|
||||||
|
|
||||||
.. seealso:: :term:`garbage collection`
|
.. seealso:: :term:`garbage collection`
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Boehm–Weiser collector <http://www.hpl.hp.com/personal/Hans_Boehm/gc/>`_.
|
`Memory Pool System <http://www.ravenbrook.com/project/mps/>`_,
|
||||||
|
`Boehm–Demers–Weiser collector <http://hboehm.info/gc/>`_.
|
||||||
|
|
||||||
|
|
||||||
Why does my program use so much memory?
|
Why does my program use so much memory?
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _mmref-intro:
|
||||||
|
|
||||||
Introduction to memory management
|
Introduction to memory management
|
||||||
#################################
|
#################################
|
||||||
|
|
||||||
|
|
@ -9,5 +11,3 @@ Introduction to memory management
|
||||||
alloc
|
alloc
|
||||||
recycle
|
recycle
|
||||||
lang
|
lang
|
||||||
faq
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,9 @@ Memory management in various languages
|
||||||
library functions for :term:`memory (2)` management in C,
|
library functions for :term:`memory (2)` management in C,
|
||||||
:term:`malloc` and :term:`free (2)`, have become almost
|
:term:`malloc` and :term:`free (2)`, have become almost
|
||||||
synonymous with :term:`manual memory management`), although
|
synonymous with :term:`manual memory management`), although
|
||||||
with the Boehm-Weiser :term:`collector (1)`, it is now
|
with the Memory Pool System, or the Boehm–Demers–Weiser
|
||||||
possible to use :term:`garbage collection`.
|
collector, it is now possible to use :term:`garbage
|
||||||
|
collection`.
|
||||||
|
|
||||||
The language is notorious for fostering memory management
|
The language is notorious for fostering memory management
|
||||||
bugs, including:
|
bugs, including:
|
||||||
|
|
@ -86,7 +87,8 @@ Memory management in various languages
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
`Boehm-Weiser collector <http://www.hpl.hp.com/personal/Hans_Boehm/gc/>`_,
|
`Memory Pool System <http://www.ravenbrook.com/project/mps/>`_,
|
||||||
|
`Boehm–Demers–Weiser collector <http://hboehm.info/gc/>`_,
|
||||||
`C standardization <http://www.open-std.org/jtc1/sc22/wg14/>`_,
|
`C standardization <http://www.open-std.org/jtc1/sc22/wg14/>`_,
|
||||||
`comp.lang.c Frequently Asked Questions <http://c-faq.com/>`_.
|
`comp.lang.c Frequently Asked Questions <http://c-faq.com/>`_.
|
||||||
|
|
||||||
|
|
@ -148,11 +150,11 @@ Memory management in various languages
|
||||||
The :term:`garbage collector` in the .NET Framework is
|
The :term:`garbage collector` in the .NET Framework is
|
||||||
configurable to run in soft real time, or in batch mode.
|
configurable to run in soft real time, or in batch mode.
|
||||||
|
|
||||||
The Mono runtime comes with two collectors: the Boehm–Weiser
|
The Mono runtime comes with two collectors: the
|
||||||
:term:`conservative collector <conservative garbage
|
Boehm–Demers–Weiser :term:`conservative collector
|
||||||
collection>`, and a :term:`generational <generational garbage
|
<conservative garbage collection>`, and a :term:`generational
|
||||||
collection>` :term:`copying collector <copying garbage
|
<generational garbage collection>` :term:`copying collector
|
||||||
collection>`.
|
<copying garbage collection>`.
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
|
|
@ -173,9 +175,9 @@ Memory management in various languages
|
||||||
abstraction level of C++ makes the bookkeeping required for
|
abstraction level of C++ makes the bookkeeping required for
|
||||||
:term:`manual memory management` even harder. Although the
|
:term:`manual memory management` even harder. Although the
|
||||||
standard library provides only manual memory management, with
|
standard library provides only manual memory management, with
|
||||||
the Boehm-Weiser :term:`collector (1)`, it is now possible to
|
the Memory Pool System, or the Boehm–Demers–Weiser collector,
|
||||||
use :term:`garbage collection`. :term:`Smart pointers` are
|
it is now possible to use :term:`garbage collection`.
|
||||||
another popular solution.
|
:term:`Smart pointers` are another popular solution.
|
||||||
|
|
||||||
The language is notorious for fostering memory management
|
The language is notorious for fostering memory management
|
||||||
bugs, including:
|
bugs, including:
|
||||||
|
|
@ -222,6 +224,8 @@ Memory management in various languages
|
||||||
|
|
||||||
.. link::
|
.. link::
|
||||||
|
|
||||||
|
`Memory Pool System <http://www.ravenbrook.com/project/mps/>`_,
|
||||||
|
`Boehm–Demers–Weiser collector <http://hboehm.info/gc/>`_,
|
||||||
`comp.lang.c++ FAQ <http://www.parashift.com/c++-faq/>`_,
|
`comp.lang.c++ FAQ <http://www.parashift.com/c++-faq/>`_,
|
||||||
`C++ standardization <http://www.open-std.org/jtc1/sc22/wg21/>`_.
|
`C++ standardization <http://www.open-std.org/jtc1/sc22/wg21/>`_.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,16 +183,16 @@ AMS interface
|
||||||
takes three keyword arguments: :c:macro:`MPS_KEY_FORMAT` and
|
takes three keyword arguments: :c:macro:`MPS_KEY_FORMAT` and
|
||||||
:c:macro:`MPS_KEY_CHAIN` are as described above, and
|
:c:macro:`MPS_KEY_CHAIN` are as described above, and
|
||||||
:c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
|
:c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
|
||||||
options. See :c:type:`mps_debug_option_s`.
|
options. See :c:type:`mps_pool_debug_option_s`.
|
||||||
|
|
||||||
.. deprecated:: starting with version 1.112.
|
.. deprecated:: starting with version 1.112.
|
||||||
|
|
||||||
When using :c:func:`mps_pool_create`, pass the format,
|
When using :c:func:`mps_pool_create`, pass the arguments like
|
||||||
chain, and debugging options like this::
|
this::
|
||||||
|
|
||||||
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
||||||
mps_class_t mps_class_ams_debug(),
|
mps_class_t mps_class_ams_debug(),
|
||||||
mps_debug_option_s debug_option,
|
mps_pool_debug_option_s debug_option,
|
||||||
mps_fmt_t fmt,
|
mps_fmt_t fmt,
|
||||||
mps_chain_t chain,
|
mps_chain_t chain,
|
||||||
mps_bool_t support_ambiguous)
|
mps_bool_t support_ambiguous)
|
||||||
|
|
|
||||||
|
|
@ -100,35 +100,35 @@ it makes no sense to ask whether they may contain :term:`weak
|
||||||
references (1)`.
|
references (1)`.
|
||||||
|
|
||||||
|
|
||||||
============================================= ===== ===== ===== ===== ===== ===== ===== ===== ===== =====
|
.. csv-table::
|
||||||
Property AMC AMCZ AMS AWL LO MFS MV MVFF MVT SNC
|
:header: "Property", ":ref:`AMC <pool-amc>`", ":ref:`AMCZ <pool-amcz>`", ":ref:`AMS <pool-ams>`", ":ref:`AWL <pool-awl>`", ":ref:`LO <pool-lo>`", ":ref:`MFS <pool-mfs>`", ":ref:`MV <pool-mv>`", ":ref:`MVFF <pool-mvff>`", ":ref:`MVT <pool-mvt>`", ":ref:`SNC <pool-snc>`"
|
||||||
============================================= ===== ===== ===== ===== ===== ===== ===== ===== ===== =====
|
:widths: 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
Supports :c:func:`mps_alloc`? no no no no no yes yes yes no no
|
|
||||||
Supports :c:func:`mps_free`? no no no no no yes yes yes yes no
|
Supports :c:func:`mps_alloc`?, no, no, no, no, no, yes, yes, yes, no, no
|
||||||
Supports allocation points? yes yes yes yes yes no yes yes yes yes
|
Supports :c:func:`mps_free`?, no, no, no, no, no, yes, yes, yes, yes, no
|
||||||
Supports allocation frames? yes yes yes yes yes no no yes yes yes
|
Supports allocation points?, yes, yes, yes, yes, yes, no, yes, yes, yes, yes
|
||||||
Supports segregated allocation caches? no no no no no yes yes yes no no
|
Supports allocation frames?, yes, yes, yes, yes, yes, no, no, yes, yes, yes
|
||||||
Timing of collections? [2]_ auto auto auto auto auto --- --- --- --- ---
|
Supports segregated allocation caches?, no, no, no, no, no, yes, yes, yes, no, no
|
||||||
May contain references? [3]_ yes no yes yes no no no no no yes
|
Timing of collections? [2]_, auto, auto, auto, auto, auto, ---, ---, ---, ---, ---
|
||||||
May contain exact references? [4]_ yes --- yes yes --- --- --- --- --- yes
|
May contain references? [3]_, yes, no, yes, yes, no, no, no, no, no, yes
|
||||||
May contain ambiguous references? [4]_ no --- no no --- --- --- --- --- no
|
May contain exact references? [4]_, yes, ---, yes, yes, ---, ---, ---, ---, ---, yes
|
||||||
May contain weak references? [4]_ no --- no yes --- --- --- --- --- no
|
May contain ambiguous references? [4]_, no, ---, no, no, ---, ---, ---, ---, ---, no
|
||||||
Allocations fixed or variable in size? var var var var var fixed var var var var
|
May contain weak references? [4]_, no, ---, no, yes, ---, ---, ---, ---, ---, no
|
||||||
Alignment? [5]_ conf conf conf conf conf [6]_ [6]_ [7]_ [7]_ conf
|
Allocations fixed or variable in size?, var, var, var, var, var, fixed, var, var, var, var
|
||||||
Dependent objects? [8]_ no --- no yes --- --- --- --- --- no
|
Alignment? [5]_, conf, conf, conf, conf, conf, [6]_, [6]_, [7]_, [7]_, conf
|
||||||
May use remote references? [9]_ no --- no no --- --- --- --- --- no
|
Dependent objects? [8]_, no, ---, no, yes, ---, ---, ---, ---, ---, no
|
||||||
Blocks are automatically managed? [10]_ yes yes yes yes yes no no no no no
|
May use remote references? [9]_, no, ---, no, no, ---, ---, ---, ---, ---, no
|
||||||
Blocks are promoted between generations yes yes no no no --- --- --- --- ---
|
Blocks are automatically managed? [10]_, yes, yes, yes, yes, yes, no, no, no, no, no
|
||||||
Blocks are manually managed? [10]_ no no no no no yes yes yes yes yes
|
Blocks are promoted between generations, yes, yes, no, no, no, ---, ---, ---, ---, ---
|
||||||
Blocks are scanned? [11]_ yes no yes yes no no no no no yes
|
Blocks are manually managed? [10]_, no, no, no, no, no, yes, yes, yes, yes, yes
|
||||||
Blocks support base pointers only? [12]_ no no yes yes yes --- --- --- --- yes
|
Blocks are scanned? [11]_, yes, no, yes, yes, no, no, no, no, no, yes
|
||||||
Blocks support internal pointers? [12]_ yes yes no no no --- --- --- --- no
|
Blocks support base pointers only? [12]_, no, no, yes, yes, yes, ---, ---, ---, ---, yes
|
||||||
Blocks may be protected by barriers? yes no yes yes yes no no no no yes
|
Blocks support internal pointers? [12]_, yes, yes, no, no, no, ---, ---, ---, ---, no
|
||||||
Blocks may move? yes yes no no no no no no no no
|
Blocks may be protected by barriers?, yes, no, yes, yes, yes, no, no, no, no, yes
|
||||||
Blocks may be finalized? yes yes yes yes yes no no no no no
|
Blocks may move?, yes, yes, no, no, no, no, no, no, no, no
|
||||||
Blocks must be formatted? [11]_ yes yes yes yes yes no no no no yes
|
Blocks may be finalized?, yes, yes, yes, yes, yes, no, no, no, no, no
|
||||||
Blocks may use :term:`in-band headers`? yes yes yes yes yes --- --- --- --- no
|
Blocks must be formatted? [11]_, yes, yes, yes, yes, yes, no, no, no, no, yes
|
||||||
============================================= ===== ===== ===== ===== ===== ===== ===== ===== ===== =====
|
Blocks may use :term:`in-band headers`?, yes, yes, yes, yes, yes, ---, ---, ---, ---, no
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,16 +122,17 @@ MV interface
|
||||||
takes four keyword arguments: :c:macro:`MPS_KEY_EXTEND_SIZE`,
|
takes four keyword arguments: :c:macro:`MPS_KEY_EXTEND_SIZE`,
|
||||||
:c:macro:`MPS_KEY_MEAN_SIZE`, :c:macro:`MPS_KEY_MAX_SIZE` are as
|
:c:macro:`MPS_KEY_MEAN_SIZE`, :c:macro:`MPS_KEY_MAX_SIZE` are as
|
||||||
described above, and :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS`
|
described above, and :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS`
|
||||||
specifies the debugging options. See :c:type:`mps_debug_option_s`.
|
specifies the debugging options. See
|
||||||
|
:c:type:`mps_pool_debug_option_s`.
|
||||||
|
|
||||||
.. deprecated:: starting with version 1.112.
|
.. deprecated:: starting with version 1.112.
|
||||||
|
|
||||||
When using :c:func:`mps_pool_create`, pass the debugging
|
When using :c:func:`mps_pool_create`, pass the arguments like
|
||||||
options, segment size, mean size, and maximum size like this::
|
this::
|
||||||
|
|
||||||
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
||||||
mps_class_t mps_class_mv_debug(),
|
mps_class_t mps_class_mv_debug(),
|
||||||
mps_debug_option_s debug_option,
|
mps_pool_debug_option_s debug_option,
|
||||||
mps_size_t extend_size,
|
mps_size_t extend_size,
|
||||||
mps_size_t average_size,
|
mps_size_t average_size,
|
||||||
mps_size_t maximum_size)
|
mps_size_t maximum_size)
|
||||||
|
|
|
||||||
|
|
@ -207,16 +207,16 @@ MVFF interface
|
||||||
:c:macro:`MPS_KEY_MVFF_SLOT_HIGH`, and
|
:c:macro:`MPS_KEY_MVFF_SLOT_HIGH`, and
|
||||||
:c:macro:`MPS_KEY_MVFF_FIRST_FIT` are as described above, and
|
:c:macro:`MPS_KEY_MVFF_FIRST_FIT` are as described above, and
|
||||||
:c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
|
:c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
|
||||||
options. See :c:type:`mps_debug_option_s`.
|
options. See :c:type:`mps_pool_debug_option_s`.
|
||||||
|
|
||||||
.. deprecated:: starting with version 1.112.
|
.. deprecated:: starting with version 1.112.
|
||||||
|
|
||||||
When using :c:func:`mps_pool_create`, pass the debugging
|
When using :c:func:`mps_pool_create`, pass the arguments like
|
||||||
options, and other arguments like this::
|
this::
|
||||||
|
|
||||||
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
||||||
mps_class_t mps_class_mvff_debug(),
|
mps_class_t mps_class_mvff_debug(),
|
||||||
mps_debug_option_s debug_option,
|
mps_pool_debug_option_s debug_option,
|
||||||
size_t extend_size,
|
size_t extend_size,
|
||||||
size_t average_size,
|
size_t average_size,
|
||||||
mps_align_t alignment,
|
mps_align_t alignment,
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ New features
|
||||||
Interface changes
|
Interface changes
|
||||||
.................
|
.................
|
||||||
|
|
||||||
#. There is now a default value (currently 1 \ :term:`megabyte`) for
|
#. There is now a default value (currently 256 \ :term:`megabytes`)
|
||||||
the :c:macro:`MPS_KEY_ARENA_SIZE` keyword argument to
|
for the :c:macro:`MPS_KEY_ARENA_SIZE` keyword argument to
|
||||||
:c:func:`mps_arena_create_k` when creating a virtual memory arena.
|
:c:func:`mps_arena_create_k` when creating a virtual memory arena.
|
||||||
See :c:func:`mps_arena_class_vm`.
|
See :c:func:`mps_arena_class_vm`.
|
||||||
|
|
||||||
|
|
@ -87,10 +87,9 @@ Other changes
|
||||||
|
|
||||||
.. _job003756: https://www.ravenbrook.com/project/mps/issue/job003756/
|
.. _job003756: https://www.ravenbrook.com/project/mps/issue/job003756/
|
||||||
|
|
||||||
#. :ref:`pool-ams` pools get reliably collected, even in the case
|
#. An :ref:`pool-ams` pool gets collected even if it is the only pool
|
||||||
where an AMS pool is the only pool on its generation chain and is
|
on its generation chain and is allocating into a generation other
|
||||||
allocating into some generation other than the nursery. See
|
than the nursery. See job003771_.
|
||||||
job003771_.
|
|
||||||
|
|
||||||
.. _job003771: https://www.ravenbrook.com/project/mps/issue/job003771/
|
.. _job003771: https://www.ravenbrook.com/project/mps/issue/job003771/
|
||||||
|
|
||||||
|
|
@ -104,6 +103,44 @@ Other changes
|
||||||
Release 1.113.0
|
Release 1.113.0
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
New features
|
||||||
|
............
|
||||||
|
|
||||||
|
#. In previous releases there was an implicit connection between
|
||||||
|
blocks allocated by :ref:`pool-awl` and :ref:`pool-lo` pools, and
|
||||||
|
blocks allocated by other automatically managed pool classes.
|
||||||
|
|
||||||
|
In particular, blocks allocated by AWL and LO pools were garbage
|
||||||
|
collected together with blocks allocated by :ref:`pool-ams` pools,
|
||||||
|
and blocks allocated by :ref:`pool-amc` pools in generation 1 of
|
||||||
|
their chains.
|
||||||
|
|
||||||
|
This is no longer the case: to arrange for blocks to be collected
|
||||||
|
together you need to ensure that they are allocated in the *same*
|
||||||
|
generation chain, using the :c:macro:`MPS_KEY_CHAIN` and
|
||||||
|
:c:macro:`MPS_KEY_GEN` keyword arguments to
|
||||||
|
:c:func:`mps_pool_create_k`.
|
||||||
|
|
||||||
|
So if you have code like this::
|
||||||
|
|
||||||
|
res = mps_pool_create(&my_amc, arena, mps_class_amc(), my_chain);
|
||||||
|
res = mps_pool_create(&my_awl, arena, mps_class_awl());
|
||||||
|
|
||||||
|
and you want to retain the connection between these pools, then you
|
||||||
|
must ensure that they use the same generation chain::
|
||||||
|
|
||||||
|
MPS_ARGS_BEGIN(args) {
|
||||||
|
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, my_chain);
|
||||||
|
res = mps_pool_create_k(&my_amc, arena, mps_class_amc(), args);
|
||||||
|
} MPS_ARGS_END(args);
|
||||||
|
|
||||||
|
MPS_ARGS_BEGIN(args) {
|
||||||
|
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, my_chain);
|
||||||
|
MPS_ARGS_ADD(args, MPS_KEY_GEN, 1);
|
||||||
|
res = mps_pool_create_k(&my_awl, arena, mps_class_awl(), args);
|
||||||
|
} MPS_ARGS_END(args);
|
||||||
|
|
||||||
|
|
||||||
Interface changes
|
Interface changes
|
||||||
.................
|
.................
|
||||||
|
|
||||||
|
|
@ -176,17 +213,23 @@ Interface changes
|
||||||
|
|
||||||
#. Functions that take a variable number of arguments
|
#. Functions that take a variable number of arguments
|
||||||
(:c:func:`mps_arena_create`, :c:func:`mps_pool_create`,
|
(:c:func:`mps_arena_create`, :c:func:`mps_pool_create`,
|
||||||
:c:func:`mps_ap_create`, :c:func:`mps_fmt_create_A`) and their
|
:c:func:`mps_ap_create`) and their ``va_list`` alternatives
|
||||||
``va_list`` alternatives (:c:func:`mps_arena_create_v` etc.) are
|
(:c:func:`mps_arena_create_v` etc.) are now deprecated in favour of
|
||||||
now deprecated in favour of functions that use a :term:`keyword
|
functions that use a :term:`keyword argument` interface
|
||||||
argument` interface (:c:func:`mps_arena_create_k`,
|
(:c:func:`mps_arena_create_k`, :c:func:`mps_pool_create_k`,
|
||||||
:c:func:`mps_pool_create_k`, :c:func:`mps_ap_create_k`,
|
:c:func:`mps_ap_create_k`).
|
||||||
:c:func:`mps_fmt_create_k`). The new interface provides better
|
|
||||||
reporting of errors, provides default values for arguments, and
|
|
||||||
provides forward compatibility. See :ref:`topic-keyword`.
|
|
||||||
|
|
||||||
The old interface continues to be supported, but new features will
|
Similarly, the object format variant structures
|
||||||
become available through the keyword interface only.
|
(:c:type:`mps_fmt_A_s` etc.) and the functions that take them as
|
||||||
|
arguments (:c:func:`mps_fmt_create_A` etc.) are now deprecated in
|
||||||
|
favour of :c:func:`mps_fmt_create_k`.
|
||||||
|
|
||||||
|
The new interfaces provide better reporting of errors, default
|
||||||
|
values for arguments, and forward compatibility. See
|
||||||
|
:ref:`topic-keyword`.
|
||||||
|
|
||||||
|
The old interfaces continue to be supported for now, but new
|
||||||
|
features will become available through the keyword interface only.
|
||||||
|
|
||||||
#. :ref:`pool-mfs` pools no longer refuse to manage blocks that are
|
#. :ref:`pool-mfs` pools no longer refuse to manage blocks that are
|
||||||
smaller than the platform alignment. They now round up smaller
|
smaller than the platform alignment. They now round up smaller
|
||||||
|
|
@ -220,8 +263,9 @@ Other changes
|
||||||
|
|
||||||
.. _job003435: https://www.ravenbrook.com/project/mps/issue/job003435/
|
.. _job003435: https://www.ravenbrook.com/project/mps/issue/job003435/
|
||||||
|
|
||||||
#. :ref:`pool-mvt` no longer triggers an assertion failure when it
|
#. An :ref:`pool-mvt` pool no longer triggers an assertion failure
|
||||||
runs out of space on its reserved block queue. See job003486_.
|
when it runs out of space on its reserved block queue. See
|
||||||
|
job003486_.
|
||||||
|
|
||||||
.. _job003486: https://www.ravenbrook.com/project/mps/issue/job003486/
|
.. _job003486: https://www.ravenbrook.com/project/mps/issue/job003486/
|
||||||
|
|
||||||
|
|
@ -258,13 +302,13 @@ New features
|
||||||
<telemetry-mpseventsql>` loads an event stream into a SQLite
|
<telemetry-mpseventsql>` loads an event stream into a SQLite
|
||||||
database for further analysis. See :ref:`topic-telemetry`.
|
database for further analysis. See :ref:`topic-telemetry`.
|
||||||
|
|
||||||
#. The new pool class MFS provide manually managed allocation of
|
#. The new pool class :ref:`pool-mfs` provides manually managed
|
||||||
fixed-size objects. See :ref:`pool-mfs`.
|
allocation of fixed-size objects.
|
||||||
|
|
||||||
#. The new pool class MVT provide manually managed allocation of
|
#. The new pool class :ref:`pool-mvt` provides manually managed
|
||||||
variable-size objects using a *temporal fit* allocation policy
|
allocation of variable-size objects using a *temporal fit*
|
||||||
(that is, objects that are allocated togther are expected to be
|
allocation policy (that is, objects that are allocated togther are
|
||||||
freed together). See :ref:`pool-mvt`.
|
expected to be freed together).
|
||||||
|
|
||||||
|
|
||||||
Interface changes
|
Interface changes
|
||||||
|
|
|
||||||
41
mps/manual/source/themes/mmref/layout.html
Normal file
41
mps/manual/source/themes/mmref/layout.html
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
{#
|
||||||
|
scrolls/layout.html
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sphinx layout template for the scrolls theme, originally written
|
||||||
|
by Armin Ronacher.
|
||||||
|
|
||||||
|
:copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
|
||||||
|
:license: BSD, see LICENSE for details.
|
||||||
|
#}
|
||||||
|
{%- extends "basic/layout.html" %}
|
||||||
|
{% set script_files = script_files + ['_static/theme_extras.js'] %}
|
||||||
|
{% set css_files = css_files + ['_static/print.css'] %}
|
||||||
|
{# do not display relbars #}
|
||||||
|
{% block relbar1 %}{% endblock %}
|
||||||
|
{% block relbar2 %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div id="content">
|
||||||
|
<div class="header">
|
||||||
|
<h1 class="heading"><a href="{{ pathto('index') }}"><span>Memory Management Reference</span></a></h1>
|
||||||
|
</div>
|
||||||
|
<div class="relnav">
|
||||||
|
{%- if prev and '/' not in prev.link and 'mmref-' not in prev.link %}
|
||||||
|
<a href="{{ prev.link|e }}">« {{ prev.title }}</a> |
|
||||||
|
{%- endif %}
|
||||||
|
<a href="{{ pathto(current_page_name) if current_page_name else '#' }}">{{ title }}</a>
|
||||||
|
{%- if next and '/' not in next.link and 'mmref-' not in next.link %}
|
||||||
|
| <a href="{{ next.link|e }}">{{ next.title }} »</a>
|
||||||
|
{%- endif %}
|
||||||
|
</div>
|
||||||
|
<div id="contentwrapper">
|
||||||
|
{%- if display_toc %}
|
||||||
|
<div id="toc">
|
||||||
|
<h3>{{ _('Table Of Contents') }}</h3>
|
||||||
|
{{ toc }}
|
||||||
|
</div>
|
||||||
|
{%- endif %}
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
BIN
mps/manual/source/themes/mmref/static/metal.png
Normal file
BIN
mps/manual/source/themes/mmref/static/metal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
161
mps/manual/source/themes/mmref/static/mmref.css_t
Normal file
161
mps/manual/source/themes/mmref/static/mmref.css_t
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
/* -*- css -*- */
|
||||||
|
|
||||||
|
@import url('scrolls.css');
|
||||||
|
|
||||||
|
sup {
|
||||||
|
vertical-align: top;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl.glossary dt {
|
||||||
|
font-family: {{ theme_headfont }};
|
||||||
|
}
|
||||||
|
|
||||||
|
div.header {
|
||||||
|
background-image: none;
|
||||||
|
background-color: {{ theme_headerbg }};
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.heading {
|
||||||
|
height: auto;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.heading:hover {
|
||||||
|
background: {{ theme_headerhover }};
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.heading a {
|
||||||
|
background-image: none;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.heading span {
|
||||||
|
display: block;
|
||||||
|
color: {{ theme_textcolor }};
|
||||||
|
}
|
||||||
|
|
||||||
|
a, a:visited, a.reference.internal {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.reference em {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.reference.internal:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid {{ theme_underlinecolor }};
|
||||||
|
}
|
||||||
|
|
||||||
|
.xref.std-term {
|
||||||
|
font-style: normal;
|
||||||
|
color: {{ theme_textcolor }};
|
||||||
|
border-bottom: 1px dotted {{ theme_underlinecolor }};
|
||||||
|
}
|
||||||
|
|
||||||
|
div.seealso, div.admonition {
|
||||||
|
background: url(metal.png);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.admonition_title:after {
|
||||||
|
content: ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition p.admonition-title + p + p {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.figure {
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.figure img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.align-center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl.glossary dt {
|
||||||
|
font-size: 120%;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.glossary-alphabet {
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.admonition-ref-glossary, div.admonition-ref-bibliography, div.admonition-ref-mmref-intro, div.admonition-ref-mmref-faq {
|
||||||
|
width: 45%;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition-ref-glossary, div.admonition-ref-mmref-intro {
|
||||||
|
height:400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition-ref-bibliography, div.admonition-ref-mmref-faq {
|
||||||
|
height:230px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition-ref-glossary, div.admonition-ref-bibliography {
|
||||||
|
margin-right: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition-ref-mmref-intro, div.admonition-ref-mmref-faq {
|
||||||
|
margin-left: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.admonition a.image-reference img {
|
||||||
|
width: 90%;
|
||||||
|
margin-left: 5%;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#home h1 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#home h1 + p {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format the glossary index in two columns. */
|
||||||
|
|
||||||
|
div#memory-management-glossary div#all {
|
||||||
|
-webkit-columns: 2;
|
||||||
|
-moz-columns: 2;
|
||||||
|
-o-columns: 2;
|
||||||
|
-ms-columns: 2;
|
||||||
|
columns: 2;
|
||||||
|
padding-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#memory-management-glossary div#all h2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#memory-management-glossary div#all a.reference.internal:after {
|
||||||
|
content: "\A";
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
BIN
mps/manual/source/themes/mmref/static/watermark.png
Normal file
BIN
mps/manual/source/themes/mmref/static/watermark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
237
mps/manual/source/themes/mmref/static/watermark.svg
Normal file
237
mps/manual/source/themes/mmref/static/watermark.svg
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="744.09448819"
|
||||||
|
height="1052.3622047"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="watermark.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:cx="378.89381"
|
||||||
|
inkscape:cy="952.37262"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1559"
|
||||||
|
inkscape:window-height="984"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#e8e8e8;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3717"
|
||||||
|
width="434"
|
||||||
|
height="742"
|
||||||
|
x="198.57143"
|
||||||
|
y="-281.35214"
|
||||||
|
inkscape:export-filename="/Users/gdr/info.ravenbrook.com/project/mps/master/manual/source/themes/mmref/static/watermark.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||||
|
x="200"
|
||||||
|
y="-270.49493"
|
||||||
|
id="text2985"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan2987"
|
||||||
|
x="200"
|
||||||
|
y="-270.49493"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">2e2f 6d70 7369 2e63 0073 697a 6520 3e20</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-247.99493"
|
||||||
|
id="tspan2989"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">3000 6d70 735f 6172 656e 615f 6f20 213d</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-225.49493"
|
||||||
|
id="tspan2991"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">204e 554c 4c00 6d70 735f 706f 6f6c 5f6f</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-202.99493"
|
||||||
|
id="tspan2993"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">2021 3d20 4e55 4c4c 006d 7073 5f66 6d74</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-180.49493"
|
||||||
|
id="tspan2995"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">5f6f 2021 3d20 4e55 4c4c 006d 7073 5f66</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-157.99493"
|
||||||
|
id="tspan2997"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">6d74 5f41 2021 3d20 4e55 4c4c 006d 7073</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-135.49493"
|
||||||
|
id="tspan2999"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">5f66 6d74 5f42 2021 3d20 4e55 4c4c 006d</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-112.99493"
|
||||||
|
id="tspan3001"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">7073 5f66 6d74 2021 3d20 4e55 4c4c 006d</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-90.494934"
|
||||||
|
id="tspan3003"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">7073 5f66 6d74 5f66 6978 6564 2021 3d20</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-67.994934"
|
||||||
|
id="tspan3005"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">4e55 4c4c 0054 4553 5454 2846 6f72 6d61</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-45.494934"
|
||||||
|
id="tspan3007"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">742c 2066 6f72 6d61 7429 0054 4553 5454</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-22.994934"
|
||||||
|
id="tspan3009"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">2850 6f6f 6c2c 2070 6f6f 6c29 0070 5f6f</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="-0.49493408"
|
||||||
|
id="tspan3011"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">2021 3d20 4e55 4c4c 006d 7073 5f61 705f</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="22.005066"
|
||||||
|
id="tspan3013"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">6f20 213d 204e 554c 4c00 6d70 735f 6170</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="44.505066"
|
||||||
|
id="tspan3015"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">2021 3d20 4e55 4c4c 0054 4553 5454 2842</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="67.005066"
|
||||||
|
id="tspan3017"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">7566 6665 722c 2062 7566 2900 5445 5354</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="89.505066"
|
||||||
|
id="tspan3019"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">5428 4275 6666 6572 2c20 4275 6666 6572</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="112.00507"
|
||||||
|
id="tspan3021"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">4f66 4150 286d 7073 5f61 7029 2900 6d70</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="134.50507"
|
||||||
|
id="tspan3023"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">735f 6170 2d3e 696e 6974 203d 3d20 6d70</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="157.00507"
|
||||||
|
id="tspan3025"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">735f 6170 2d3e 616c 6c6f 6300 7020 213d</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="179.50507"
|
||||||
|
id="tspan3027"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">204e 554c 4c00 7020 3d3d 206d 7073 5f61</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="202.00507"
|
||||||
|
id="tspan3029"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">702d 3e69 6e69 7400 2876 6f69 6420 2a29</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="224.50507"
|
||||||
|
id="tspan3031"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">2828 6368 6172 202a 296d 7073 5f61 702d</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="247.00507"
|
||||||
|
id="tspan3033"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">3e69 6e69 7420 2b20 7369 7a65 2920 3d3d</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="269.50507"
|
||||||
|
id="tspan3035"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">206d 7073 5f61 702d 3e61 6c6c 6f63 0066</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="292.00507"
|
||||||
|
id="tspan3037"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">7261 6d65 5f6f 2021 3d20 4e55 4c4c 0053</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="314.50507"
|
||||||
|
id="tspan3039"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">697a 6549 7341 6c69 676e 6564 2873 697a</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="337.00507"
|
||||||
|
id="tspan3041"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">652c 2042 7566 6665 7250 6f6f 6c28 6275</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="359.50507"
|
||||||
|
id="tspan3043"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">6629 2d3e 616c 6967 6e6d 656e 7429 006d</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="382.00507"
|
||||||
|
id="tspan3045"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">7073 5f73 6163 5f6f 2021 3d20 4e55 4c4c</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="404.50507"
|
||||||
|
id="tspan3047"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">0054 4553 5454 2853 4143 2c20 7361 6329</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="427.00507"
|
||||||
|
id="tspan3049"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">0054 4553 5454 2853 4143 2c20 5341 434f</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="200"
|
||||||
|
y="449.50507"
|
||||||
|
id="tspan3119"
|
||||||
|
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro;fill:#e0e0e0;fill-opacity:1">6645 7874 6572 6e61 6c53 4143 286d 7073</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 16 KiB |
18
mps/manual/source/themes/mmref/theme.conf
Normal file
18
mps/manual/source/themes/mmref/theme.conf
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Colour scheme: <http://www.colourlovers.com/palette/490780/The_First_Raindrop>
|
||||||
|
|
||||||
|
[theme]
|
||||||
|
inherit = scrolls
|
||||||
|
stylesheet = mmref.css
|
||||||
|
|
||||||
|
[options]
|
||||||
|
headerbg = transparent
|
||||||
|
headerhover = #81A8B8
|
||||||
|
subheadlinecolor = #000000
|
||||||
|
linkcolor = #5D7985
|
||||||
|
visitedlinkcolor = #5D7985
|
||||||
|
admonitioncolor = #A4BCC2
|
||||||
|
textcolor = #000000
|
||||||
|
underlinecolor = #A4BCC2
|
||||||
|
|
||||||
|
bodyfont = 'Optima', sans-serif
|
||||||
|
headfont = 'Verdana', sans-serif
|
||||||
|
|
@ -139,6 +139,9 @@ dl.glossary dt, dl.type dt, dl.function dt, dl.macro dt {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
font-size: 120%;
|
font-size: 120%;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl.type dt, dl.function dt, dl.macro dt {
|
||||||
/* Use a hanging indent so that long wrapped prototypes are easier to read. */
|
/* Use a hanging indent so that long wrapped prototypes are easier to read. */
|
||||||
padding-left: 4em;
|
padding-left: 4em;
|
||||||
text-indent: -4em;
|
text-indent: -4em;
|
||||||
|
|
@ -185,7 +188,7 @@ p.glossary-alphabet {
|
||||||
}
|
}
|
||||||
|
|
||||||
sup {
|
sup {
|
||||||
vertical-align: 20%;
|
vertical-align: top;
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,3 +220,22 @@ li.toctree-l1, li.toctree-l2, li.toctree-l3 {
|
||||||
padding-top: 0 !important;
|
padding-top: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Format the glossary index in two columns. */
|
||||||
|
|
||||||
|
div#memory-management-glossary div#all {
|
||||||
|
-webkit-columns: 2;
|
||||||
|
-moz-columns: 2;
|
||||||
|
-o-columns: 2;
|
||||||
|
-ms-columns: 2;
|
||||||
|
columns: 2;
|
||||||
|
padding-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#memory-management-glossary div#all h2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#memory-management-glossary div#all a.reference.internal:after {
|
||||||
|
content: "\A";
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ Virtual memory arenas
|
||||||
accepts one :term:`keyword argument` on all platforms:
|
accepts one :term:`keyword argument` on all platforms:
|
||||||
|
|
||||||
* :c:macro:`MPS_KEY_ARENA_SIZE` (type :c:type:`size_t`, default
|
* :c:macro:`MPS_KEY_ARENA_SIZE` (type :c:type:`size_t`, default
|
||||||
2\ :superscript:`20`) is the initial amount of virtual address
|
256\ :term:`megabytes`) is the initial amount of virtual address
|
||||||
space, in :term:`bytes (1)`, that the arena will reserve (this
|
space, in :term:`bytes (1)`, that the arena will reserve (this
|
||||||
space is initially reserved so that the arena can subsequently
|
space is initially reserved so that the arena can subsequently
|
||||||
use it without interference from other parts of the program, but
|
use it without interference from other parts of the program, but
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,13 @@ cause), please :ref:`let us know <contact>` so that we can improve
|
||||||
this documentation.
|
this documentation.
|
||||||
|
|
||||||
|
|
||||||
|
``buffer.c: BufferIsReady(buffer)``
|
||||||
|
|
||||||
|
The client program called :c:func:`mps_reserve` twice on the same
|
||||||
|
:term:`allocation point` without calling :c:func:`mps_commit`. See
|
||||||
|
:ref:`topic-allocation-point-protocol`.
|
||||||
|
|
||||||
|
|
||||||
``dbgpool.c: fencepost check on free``
|
``dbgpool.c: fencepost check on free``
|
||||||
|
|
||||||
The client program wrote to a location after the end, or before
|
The client program wrote to a location after the end, or before
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ the block was allocated.
|
||||||
to do the finalization. In such an implementation, the client
|
to do the finalization. In such an implementation, the client
|
||||||
program's finalization code may end up running concurrently with
|
program's finalization code may end up running concurrently with
|
||||||
other code that accesses the underlying resource, and so access to
|
other code that accesses the underlying resource, and so access to
|
||||||
the resource need to be guarded with a lock, but then an unlucky
|
the resource needs to be guarded with a lock, but then an unlucky
|
||||||
scheduling of finalization can result in deadlock. See :ref:`Boehm
|
scheduling of finalization can result in deadlock. See :ref:`Boehm
|
||||||
(2002) <BOEHM02>` for a detailed discussion of this issue.
|
(2002) <BOEHM02>` for a detailed discussion of this issue.
|
||||||
|
|
||||||
|
|
@ -170,8 +170,9 @@ Cautions
|
||||||
|
|
||||||
#. The MPS does not finalize objects in the context of
|
#. The MPS does not finalize objects in the context of
|
||||||
:c:func:`mps_arena_destroy` or :c:func:`mps_pool_destroy`.
|
:c:func:`mps_arena_destroy` or :c:func:`mps_pool_destroy`.
|
||||||
:c:func:`mps_pool_destroy` should therefore not be invoked on pools
|
Moreover, if you have pools containing objects registered for
|
||||||
containing objects registered for finalization.
|
finalization, you must destroy these pools by following the “safe
|
||||||
|
tear-down” procedure described under :c:func:`mps_pool_destroy`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
@ -189,11 +190,6 @@ Cautions
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
You can safely destroy pools containing objects registered for
|
|
||||||
finalization if you follow the "safe tear-down" procedure
|
|
||||||
described under :c:func:`mps_pool_destroy`, but the objects do
|
|
||||||
not get finalized.
|
|
||||||
|
|
||||||
The only reliable way to ensure that all finalizable objects
|
The only reliable way to ensure that all finalizable objects
|
||||||
are finalized is to maintain a table of :term:`weak
|
are finalized is to maintain a table of :term:`weak
|
||||||
references (1)` to all such objects. The weak references don't
|
references (1)` to all such objects. The weak references don't
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ out parameter, like this::
|
||||||
res = mps_alloc((mps_addr_t *)&fp, pool, sizeof(struct foo));
|
res = mps_alloc((mps_addr_t *)&fp, pool, sizeof(struct foo));
|
||||||
|
|
||||||
This is known as :term:`type punning`, and its behaviour is not
|
This is known as :term:`type punning`, and its behaviour is not
|
||||||
defined in ANSI/ISO Standard C. See :ref:`ISO/IEC 9899:1990 <ISO90>`
|
defined in ANSI/ISO Standard C. See :ref:`ISO/IEC 9899:1990 <C1990>`
|
||||||
§6.3.2.3, which defines the conversion of a pointer from one type to
|
§6.3.2.3, which defines the conversion of a pointer from one type to
|
||||||
another: the behaviour of this cast is not covered by any of the cases
|
another: the behaviour of this cast is not covered by any of the cases
|
||||||
in the standard.
|
in the standard.
|
||||||
|
|
@ -209,7 +209,7 @@ Instead, we recommend this approach::
|
||||||
|
|
||||||
This has defined behaviour because conversion from ``void *`` to any
|
This has defined behaviour because conversion from ``void *`` to any
|
||||||
other :term:`object pointer` type is defined by :ref:`ISO/IEC
|
other :term:`object pointer` type is defined by :ref:`ISO/IEC
|
||||||
9899:1990 <ISO90>` §6.3.2.3.1.
|
9899:1990 <C1990>` §6.3.2.3.1.
|
||||||
|
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
|
|
@ -219,7 +219,7 @@ Macros
|
||||||
------
|
------
|
||||||
|
|
||||||
#. For function-like macros, the MPS follows the same convention as
|
#. For function-like macros, the MPS follows the same convention as
|
||||||
the Standard C library. To quote :ref:`ISO/IEC 9899:1990 <ISO90>`
|
the Standard C library. To quote :ref:`ISO/IEC 9899:1990 <C1990>`
|
||||||
§7.1.7:
|
§7.1.7:
|
||||||
|
|
||||||
Any function declared in a header may additionally be
|
Any function declared in a header may additionally be
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ Library module
|
||||||
|
|
||||||
This function is intended to have the same semantics as the
|
This function is intended to have the same semantics as the
|
||||||
:c:func:`fputc` function of the ANSI C Standard (:ref:`ISO/IEC
|
:c:func:`fputc` function of the ANSI C Standard (:ref:`ISO/IEC
|
||||||
9899:1990 <ISO90>` §7.11.7.3).
|
9899:1990 <C1990>` §7.11.7.3).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
@ -314,7 +314,7 @@ Library module
|
||||||
|
|
||||||
This function is intended to have the same semantics as the
|
This function is intended to have the same semantics as the
|
||||||
:c:func:`fputs` function of the ANSI C Standard (:ref:`ISO/IEC
|
:c:func:`fputs` function of the ANSI C Standard (:ref:`ISO/IEC
|
||||||
9899:1990 <ISO90>` §7.11.7.4).
|
9899:1990 <C1990>` §7.11.7.4).
|
||||||
|
|
||||||
Return a non-negative integer if successful, or
|
Return a non-negative integer if successful, or
|
||||||
:c:func:`mps_lib_get_EOF` if not.
|
:c:func:`mps_lib_get_EOF` if not.
|
||||||
|
|
@ -383,7 +383,7 @@ Library module
|
||||||
|
|
||||||
This function is intended to have the same semantics as the
|
This function is intended to have the same semantics as the
|
||||||
:c:func:`memcmp` function of the ANSI C Standard (:ref:`ISO/IEC
|
:c:func:`memcmp` function of the ANSI C Standard (:ref:`ISO/IEC
|
||||||
9899:1990 <ISO90>` §7.11.4.1).
|
9899:1990 <C1990>` §7.11.4.1).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
@ -406,7 +406,7 @@ Library module
|
||||||
|
|
||||||
This function is intended to have the same semantics as the
|
This function is intended to have the same semantics as the
|
||||||
:c:func:`memcpy` function of the ANSI C Standard (:ref:`ISO/IEC
|
:c:func:`memcpy` function of the ANSI C Standard (:ref:`ISO/IEC
|
||||||
9899:1990 <ISO90>` §7.11.2.1).
|
9899:1990 <C1990>` §7.11.2.1).
|
||||||
|
|
||||||
The MPS never passes overlapping blocks to
|
The MPS never passes overlapping blocks to
|
||||||
:c:func:`mps_lib_memcpy`.
|
:c:func:`mps_lib_memcpy`.
|
||||||
|
|
@ -432,7 +432,7 @@ Library module
|
||||||
|
|
||||||
This function is intended to have the same semantics as the
|
This function is intended to have the same semantics as the
|
||||||
:c:func:`memset` function of the ANSI C Standard (:ref:`ISO/IEC
|
:c:func:`memset` function of the ANSI C Standard (:ref:`ISO/IEC
|
||||||
9899:1990 <ISO90>` §7.11.6.1).
|
9899:1990 <C1990>` §7.11.6.1).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@ region to be scanned. They must carry out the following steps:
|
||||||
function as soon as practicable.
|
function as soon as practicable.
|
||||||
|
|
||||||
#. If :c:func:`MPS_FIX2` returns :c:macro:`MPS_RES_OK`, it may have
|
#. If :c:func:`MPS_FIX2` returns :c:macro:`MPS_RES_OK`, it may have
|
||||||
updated the reference. If necessary, make sure that the updated
|
updated the reference. Make sure that the updated reference is
|
||||||
reference is stored back to the region being scanned.
|
stored back into the region being scanned.
|
||||||
|
|
||||||
#. Call the macro :c:func:`MPS_SCAN_END` on the scan state.
|
#. Call the macro :c:func:`MPS_SCAN_END` on the scan state.
|
||||||
|
|
||||||
|
|
@ -463,15 +463,18 @@ Fixing interface
|
||||||
|
|
||||||
:term:`Fix` a :term:`reference`.
|
:term:`Fix` a :term:`reference`.
|
||||||
|
|
||||||
``ss`` is the :term:`scan state` that was passed to the scan method.
|
``ss`` is the :term:`scan state` that was passed to the
|
||||||
|
:term:`scan method`.
|
||||||
|
|
||||||
``ref_io`` points to the reference.
|
``ref_io`` points to the reference.
|
||||||
|
|
||||||
Returns :c:macro:`MPS_RES_OK` if successful: in this case the
|
Returns :c:macro:`MPS_RES_OK` if successful. In this case the
|
||||||
reference may have been updated, and the scan method must continue
|
reference may have been updated, and so the scan method must store
|
||||||
to scan the :term:`block`. If it returns any other result, the
|
the updated reference back to the region being scanned. The scan
|
||||||
:term:`scan method` must return that result as soon as possible,
|
method must continue to scan the :term:`block`.
|
||||||
without fixing any further references.
|
|
||||||
|
If it returns any other result, the scan method must return that
|
||||||
|
result as soon as possible, without fixing any further references.
|
||||||
|
|
||||||
This macro must only be used within a :term:`scan method`, between
|
This macro must only be used within a :term:`scan method`, between
|
||||||
:c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`.
|
:c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`.
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,10 @@ All relative paths are relative to
|
||||||
|
|
||||||
On other platforms they are as shown above.
|
On other platforms they are as shown above.
|
||||||
|
|
||||||
|
#. Check that there are no performance regressions by comparing the
|
||||||
|
benchmarks (``djbench`` and ``gcbench``) for the last release and
|
||||||
|
this one.
|
||||||
|
|
||||||
|
|
||||||
5. Making the release (automated procedure)
|
5. Making the release (automated procedure)
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Ravenbrook
|
|
||||||
# <http://www.ravenbrook.com/>
|
|
||||||
#
|
|
||||||
# BRANCH -- CREATE VERSION OR TASK BRANCH
|
# BRANCH -- CREATE VERSION OR TASK BRANCH
|
||||||
#
|
|
||||||
# Gareth Rees, Ravenbrook Limited, 2014-03-18
|
# Gareth Rees, Ravenbrook Limited, 2014-03-18
|
||||||
#
|
#
|
||||||
|
# $Id$
|
||||||
|
# Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
|
||||||
|
#
|
||||||
#
|
#
|
||||||
# 1. INTRODUCTION
|
# 1. INTRODUCTION
|
||||||
#
|
#
|
||||||
|
|
|
||||||
102
mps/tool/noaslr.c
Normal file
102
mps/tool/noaslr.c
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/* noaslr.c: Disable ASLR on OS X Mavericks
|
||||||
|
*
|
||||||
|
* $Id: //info.ravenbrook.com/project/mps/master/code/eventcnv.c#26 $
|
||||||
|
* Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
|
||||||
|
*
|
||||||
|
* This is a command-line tool that runs another program with address
|
||||||
|
* space layout randomization (ASLR) disabled.
|
||||||
|
*
|
||||||
|
* The technique is taken from GDB via "How gdb disables ASLR in Mac
|
||||||
|
* OS X Lion"
|
||||||
|
* <http://reverse.put.as/2011/08/11/how-gdb-disables-aslr-in-mac-os-x-lion/>
|
||||||
|
*
|
||||||
|
* On OS X Mavericks, the _POSIX_SPAWN_DISABLE_ASLR constant is not
|
||||||
|
* defined in any header, but the LLDB sources reveal its value, and
|
||||||
|
* experimentally this value works.
|
||||||
|
* <https://llvm.org/svn/llvm-project/lldb/trunk/tools/darwin-debug/darwin-debug.cpp>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <spawn.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef _POSIX_SPAWN_DISABLE_ASLR
|
||||||
|
#define _POSIX_SPAWN_DISABLE_ASLR 0x100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
extern char **environ;
|
||||||
|
pid_t pid;
|
||||||
|
posix_spawnattr_t attr;
|
||||||
|
int res, status = 1;
|
||||||
|
char *default_argv[] = {"/bin/sh", NULL};
|
||||||
|
|
||||||
|
if (argc >= 2)
|
||||||
|
++ argv;
|
||||||
|
else
|
||||||
|
argv = default_argv;
|
||||||
|
|
||||||
|
res = posix_spawnattr_init(&attr);
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = posix_spawnattr_setflags(&attr, _POSIX_SPAWN_DISABLE_ASLR);
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = posix_spawn(&pid, argv[0], NULL, &attr, argv, environ);
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (waitpid(pid, &status, 0) == -1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!WIFEXITED(status))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return WEXITSTATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Ravenbrook
|
|
||||||
# <http://www.ravenbrook.com/>
|
|
||||||
#
|
|
||||||
# RELEASE -- MAKE A RELEASE
|
# RELEASE -- MAKE A RELEASE
|
||||||
#
|
|
||||||
# Gareth Rees, Ravenbrook Limited, 2014-03-18
|
# Gareth Rees, Ravenbrook Limited, 2014-03-18
|
||||||
#
|
#
|
||||||
|
# $Id$
|
||||||
|
# Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
|
||||||
|
#
|
||||||
#
|
#
|
||||||
# 1. INTRODUCTION
|
# 1. INTRODUCTION
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue