diff --git a/mps/.travis.yml b/mps/.travis.yml index 07a0dd66528..bc1dfd5bfb1 100644 --- a/mps/.travis.yml +++ b/mps/.travis.yml @@ -9,3 +9,5 @@ notifications: email: - mps-travis@ravenbrook.com irc: "irc.freenode.net#memorypoolsystem" +script: + - ./configure --prefix=$PWD/prefix && make install && make test diff --git a/mps/code/abqtest.c b/mps/code/abqtest.c index 367bafe730b..9aad3351cb6 100644 --- a/mps/code/abqtest.c +++ b/mps/code/abqtest.c @@ -96,6 +96,7 @@ static Bool TestDeleteCallback(Bool *deleteReturn, void *element, { TestBlock *a = (TestBlock *)element; TestClosure cl = (TestClosure)closureP; + AVER(closureS == UNUSED_SIZE); UNUSED(closureS); if (*a == cl->b) { *deleteReturn = TRUE; @@ -144,7 +145,7 @@ static void step(void) cdie(b != NULL, "found to delete"); cl.b = b; cl.res = ResFAIL; - ABQIterate(&abq, TestDeleteCallback, &cl, 0); + ABQIterate(&abq, TestDeleteCallback, &cl, UNUSED_SIZE); cdie(cl.res == ResOK, "ABQIterate"); } } diff --git a/mps/code/amcssth.c b/mps/code/amcssth.c index b96df985028..7c7bbf2ecb1 100644 --- a/mps/code/amcssth.c +++ b/mps/code/amcssth.c @@ -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)"); ramping = 1; while (collections < collectionsCOUNT) { - unsigned long c; + mps_word_t c; size_t r; 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) { collections = c; 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); for (i = 0; i < exactRootsCOUNT; ++i) diff --git a/mps/code/ananmv.nmk b/mps/code/ananmv.nmk index ecf97540ece..ea68b19ee68 100644 --- a/mps/code/ananmv.nmk +++ b/mps/code/ananmv.nmk @@ -7,11 +7,8 @@ PFM = ananmv PFMDEFS = /DCONFIG_PF_ANSI /DCONFIG_THREAD_SINGLE -!INCLUDE commpre.nmk -!INCLUDE mv.nmk - -# MPM sources: core plus platform-specific. -MPM = $(MPMCOMMON) \ +# MPM platform-specific sources. +MPMPF = \ \ \ \ @@ -20,6 +17,9 @@ MPM = $(MPMCOMMON) \ \ +!INCLUDE commpre.nmk +!INCLUDE mv.nmk + # Source to object file mappings and CFLAGS amalgamation # @@ -38,14 +38,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT) MPMOBJ0 = $(MPM:<=ananmv\hot\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=ananmv\hot\) FMTTESTOBJ0 = $(FMTTEST:<=ananmv\hot\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\hot\) POOLNOBJ0 = $(POOLN:<=ananmv\hot\) @@ -58,14 +51,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL) MPMOBJ0 = $(MPM:<=ananmv\cool\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=ananmv\cool\) FMTTESTOBJ0 = $(FMTTEST:<=ananmv\cool\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\cool\) POOLNOBJ0 = $(POOLN:<=ananmv\cool\) @@ -78,61 +64,20 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH) MPMOBJ0 = $(MPM:<=ananmv\rash\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=ananmv\rash\) FMTTESTOBJ0 = $(FMTTEST:<=ananmv\rash\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=ananmv\rash\) POOLNOBJ0 = $(POOLN:<=ananmv\rash\) TESTLIBOBJ0 = $(TESTLIB:<=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 # %%PART: When adding a new part, add new macros which expand to the object # files included in the part MPMOBJ = $(MPMOBJ0:>=.obj) -PLINTHOBJ = $(PLINTHOBJ0:>=.obj) -AMSOBJ = $(AMSOBJ0:>=.obj) -AMCOBJ = $(AMCOBJ0:>=.obj) -AWLOBJ = $(AWLOBJ0:>=.obj) -LOOBJ = $(LOOBJ0:>=.obj) -SNCOBJ = $(SNCOBJ0:>=.obj) -MVFFOBJ = $(MVFFOBJ0:>=.obj) -DWOBJ = $(DWOBJ0:>=.obj) +FMTDYOBJ = $(FMTDYOBJ0:>=.obj) FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj) FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj) POOLNOBJ = $(POOLNOBJ0:>=.obj) diff --git a/mps/code/arena.c b/mps/code/arena.c index bd631e2ac49..d270adf7499 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -360,6 +360,8 @@ static void arenaMFSPageFreeVisitor(Pool pool, Addr base, Size size, void *closureP, Size closureS) { AVERT(Pool, pool); + AVER(closureP == UNUSED_POINTER); + AVER(closureS == UNUSED_SIZE); UNUSED(closureP); UNUSED(closureS); UNUSED(size); @@ -386,9 +388,9 @@ void ArenaDestroy(Arena arena) LandFinish(ArenaFreeLand(arena)); /* The CBS block pool can't free its own memory via ArenaFree because - that would use the CBSZoned. */ - MFSFinishTracts(ArenaCBSBlockPool(arena), - arenaMFSPageFreeVisitor, NULL, 0); + that would use the freeLand. */ + MFSFinishTracts(ArenaCBSBlockPool(arena), arenaMFSPageFreeVisitor, + UNUSED_POINTER, UNUSED_SIZE); PoolFinish(ArenaCBSBlockPool(arena)); /* Call class-specific finishing. This will call ArenaFinish. */ @@ -687,7 +689,7 @@ static Res arenaExtendCBSBlockPool(Range pageRangeReturn, Arena arena) 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 * so that it doesn't get reallocated. @@ -843,7 +845,7 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high, Arena arena; RangeStruct range, oldRange; Chunk chunk; - Bool b; + Bool found, b; Index baseIndex; Count pages; Res res; @@ -860,8 +862,8 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high, /* Step 1. Find a range of address space. */ - res = LandFindInZones(&range, &oldRange, ArenaFreeLand(arena), - size, zones, high); + res = LandFindInZones(&found, &range, &oldRange, ArenaFreeLand(arena), + size, zones, high); if (res == ResLIMIT) { /* found block, but couldn't store info */ RangeStruct pageRange; @@ -869,17 +871,17 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high, if (res != ResOK) /* disastrously short on memory */ return res; arenaExcludePage(arena, &pageRange); - res = LandFindInZones(&range, &oldRange, ArenaFreeLand(arena), - size, zones, high); + res = LandFindInZones(&found, &range, &oldRange, ArenaFreeLand(arena), + size, zones, high); AVER(res != ResLIMIT); } - if (res == ResFAIL) /* out of address space */ - return ResRESOURCE; - AVER(res == ResOK); /* unexpected error from ZoneCBS */ if (res != ResOK) /* defensive return */ return res; + + if (!found) /* out of address space */ + return ResRESOURCE; /* Step 2. Make memory available in the address space range. */ diff --git a/mps/code/boot.c b/mps/code/boot.c index eff8409fc1e..af365d3b4f1 100644 --- a/mps/code/boot.c +++ b/mps/code/boot.c @@ -30,7 +30,7 @@ Bool BootBlockCheck(BootBlock boot) CHECKL(boot->limit != NULL); CHECKL(boot->base <= boot->alloc); CHECKL(boot->alloc <= boot->limit); - CHECKL(boot->alloc < boot->limit); + CHECKL(boot->base < boot->limit); return TRUE; } diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 0b8c28de777..2cb93d1dc64 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -140,12 +140,8 @@ static Bool cbsTestTree(SplayTree splay, Tree tree, AVERT(SplayTree, splay); AVERT(Tree, tree); -#if 0 AVER(closureP == NULL); AVER(size > 0); -#endif - UNUSED(closureP); - UNUSED(size); AVER(IsLandSubclass(cbsLand(cbsOfSplay(splay)), CBSFastLandClass)); block = cbsFastBlockOfTree(tree); @@ -405,7 +401,7 @@ static Res cbsBlockAlloc(CBSBlock *blockReturn, CBS cbs, Range range) block->base = RangeBase(range); block->limit = RangeLimit(range); - SplayNodeUpdate(cbsSplay(cbs), cbsBlockTree(block)); + SplayNodeInit(cbsSplay(cbs), cbsBlockTree(block)); AVERT(CBSBlock, block); *blockReturn = block; @@ -713,16 +709,6 @@ static Res cbsZonedSplayNodeDescribe(Tree tree, mps_lib_FILE *stream) /* 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 . */ @@ -741,22 +727,21 @@ static Bool cbsIterateVisit(Tree tree, void *closureP, Size closureS) CBSBlock cbsBlock; Land land = closure->land; CBS cbs = cbsOfLand(land); - Bool delete = FALSE; Bool cont = TRUE; + AVER(closureS == UNUSED_SIZE); UNUSED(closureS); cbsBlock = cbsBlockOfTree(tree); RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock)); - cont = (*closure->visitor)(&delete, land, &range, closure->closureP, closure->closureS); - AVER(!delete); /* */ + cont = (*closure->visitor)(land, &range, closure->closureP, closure->closureS); if (!cont) return FALSE; METER_ACC(cbs->treeSearch, cbs->treeSize); return TRUE; } -static void cbsIterate(Land land, LandVisitor visitor, +static Bool cbsIterate(Land land, LandVisitor visitor, void *closureP, Size closureS) { CBS cbs; @@ -777,8 +762,8 @@ static void cbsIterate(Land land, LandVisitor visitor, closure.visitor = visitor; closure.closureP = closureP; closure.closureS = closureS; - (void)TreeTraverse(SplayTreeRoot(splay), splay->compare, splay->nodeKey, - cbsIterateVisit, &closure, 0); + return TreeTraverse(SplayTreeRoot(splay), splay->compare, splay->nodeKey, + cbsIterateVisit, &closure, UNUSED_SIZE); } @@ -895,15 +880,15 @@ typedef struct cbsTestNodeInZonesClosureStruct { } cbsTestNodeInZonesClosureStruct, *cbsTestNodeInZonesClosure; static Bool cbsTestNodeInZones(SplayTree splay, Tree tree, - void *closureP, Size closureSize) + void *closureP, Size closureS) { CBSBlock block = cbsBlockOfTree(tree); cbsTestNodeInZonesClosure closure = closureP; RangeInZoneSet search; UNUSED(splay); - AVER(closureSize == sizeof(cbsTestNodeInZonesClosureStruct)); - UNUSED(closureSize); + AVER(closureS == UNUSED_SIZE); + UNUSED(closureS); search = closure->high ? RangeInZoneSetLast : RangeInZoneSetFirst; @@ -913,15 +898,15 @@ static Bool cbsTestNodeInZones(SplayTree splay, Tree tree, } static Bool cbsTestTreeInZones(SplayTree splay, Tree tree, - void *closureP, Size closureSize) + void *closureP, Size closureS) { CBSFastBlock fastBlock = cbsFastBlockOfTree(tree); CBSZonedBlock zonedBlock = cbsZonedBlockOfTree(tree); cbsTestNodeInZonesClosure closure = closureP; UNUSED(splay); - AVER(closureSize == sizeof(cbsTestNodeInZonesClosureStruct)); - UNUSED(closureSize); + AVER(closureS == UNUSED_SIZE); + UNUSED(closureS); return fastBlock->maxSize >= closure->size && ZoneSetInter(zonedBlock->zones, closure->zoneSet) != ZoneSetEMPTY; @@ -1009,17 +994,20 @@ static Bool cbsFindLargest(Range rangeReturn, Range oldRangeReturn, } -static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn, - Land land, Size size, +static Res cbsFindInZones(Bool *foundReturn, Range rangeReturn, + Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high) { CBS cbs; + CBSBlock block; Tree tree; cbsTestNodeInZonesClosureStruct closure; Res res; LandFindMethod landFind; SplayFindMethod splayFind; + RangeStruct rangeStruct, oldRangeStruct; + AVER(foundReturn != NULL); AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(Land, land); @@ -1033,16 +1021,14 @@ static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn, splayFind = high ? SplayFindLast : SplayFindFirst; if (zoneSet == ZoneSetEMPTY) - return ResFAIL; + goto fail; if (zoneSet == ZoneSetUNIV) { FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW; - if ((*landFind)(rangeReturn, oldRangeReturn, land, size, fd)) - return ResOK; - else - return ResFAIL; + *foundReturn = (*landFind)(rangeReturn, oldRangeReturn, land, size, fd); + return ResOK; } 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 zones in zoneSet too small for size.*/ @@ -1051,31 +1037,34 @@ static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn, closure.zoneSet = zoneSet; closure.size = size; closure.high = high; - if (splayFind(&tree, cbsSplay(cbs), - cbsTestNodeInZones, - cbsTestTreeInZones, - &closure, sizeof(closure))) { - CBSBlock block = cbsBlockOfTree(tree); - RangeStruct rangeStruct, oldRangeStruct; + if (!(*splayFind)(&tree, cbsSplay(cbs), + cbsTestNodeInZones, cbsTestTreeInZones, + &closure, UNUSED_SIZE)) + goto fail; - AVER(CBSBlockBase(block) <= closure.base); - AVER(AddrOffset(closure.base, closure.limit) >= size); - AVER(ZoneSetSub(ZoneSetOfRange(LandArena(land), closure.base, closure.limit), zoneSet)); - AVER(closure.limit <= CBSBlockLimit(block)); + block = cbsBlockOfTree(tree); - 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) { /* enough memory to split block */ - RangeCopy(rangeReturn, &rangeStruct); - RangeCopy(oldRangeReturn, &oldRangeStruct); - } - } else - res = ResFAIL; + AVER(CBSBlockBase(block) <= closure.base); + AVER(AddrOffset(closure.base, closure.limit) >= size); + AVER(ZoneSetSub(ZoneSetOfRange(LandArena(land), closure.base, closure.limit), zoneSet)); + AVER(closure.limit <= CBSBlockLimit(block)); - 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; } diff --git a/mps/code/chain.h b/mps/code/chain.h index ec5bc228ebf..eb4e9e78df7 100644 --- a/mps/code/chain.h +++ b/mps/code/chain.h @@ -44,9 +44,8 @@ typedef struct PoolGenStruct *PoolGen; typedef struct PoolGenStruct { Sig sig; - Serial nr; /* generation number */ 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) */ RingStruct genRing; 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 ChainEndGC(Chain chain, Trace trace); extern size_t ChainGens(Chain chain); -extern Res ChainAlloc(Seg *segReturn, Chain chain, Serial genNr, - 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 GenDesc ChainGen(Chain chain, Index gen); +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 */ diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk index 367e2ff6501..6e5adce14f5 100644 --- a/mps/code/comm.gmk +++ b/mps/code/comm.gmk @@ -163,7 +163,6 @@ FMTDYTST = fmtdy.c fmtno.c fmtdytst.c FMTHETST = fmthe.c fmtdy.c fmtno.c fmtdytst.c FMTSCM = fmtscheme.c PLINTH = mpsliban.c mpsioan.c -EVENTPROC = eventcnv.c table.c MPMCOMMON = \ abq.c \ arena.c \ @@ -212,7 +211,7 @@ MPMCOMMON = \ tract.c \ tree.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 @@ -224,40 +223,16 @@ MPM = $(MPMCOMMON) $(MPMPF) ifdef VARIETY MPMOBJ = $(MPM:%.c=$(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) -FMTDYDEP = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d) FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o) -FMTDYTSTDEP = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.d) FMTHETSTOBJ = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.o) -FMTHETSTDEP = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.d) 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) -PLINTHDEP = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.d) -EVENTPROCOBJ = $(EVENTPROC:%.c=$(PFM)/$(VARIETY)/%.o) -EVENTPROCDEP = $(EVENTPROC:%.c=$(PFM)/$(VARIETY)/%.d) +POOLNOBJ = $(POOLN:%.c=$(PFM)/$(VARIETY)/%.o) +TESTLIBOBJ = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.o) +TESTTHROBJ = $(TESTTHR:%.c=$(PFM)/$(VARIETY)/%.o) endif @@ -413,10 +388,7 @@ endif $(PFM)/rash/mps.a: $(PFM)/rash/mps.o $(PFM)/hot/mps.a: $(PFM)/hot/mps.o - -$(PFM)/cool/mps.a: \ - $(MPMOBJ) $(AMCOBJ) $(AMSOBJ) $(AWLOBJ) $(LOOBJ) $(SNCOBJ) \ - $(MV2OBJ) $(MVFFOBJ) $(PLINTHOBJ) $(POOLNOBJ) +$(PFM)/cool/mps.a: $(MPMOBJ) # OTHER GENUINE TARGETS @@ -473,7 +445,7 @@ $(PFM)/$(VARIETY)/bttest: $(PFM)/$(VARIETY)/bttest.o \ $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a $(PFM)/$(VARIETY)/djbench: $(PFM)/$(VARIETY)/djbench.o \ - $(TESTLIBOBJ) $(TESTTHROBJ) $(PFM)/$(VARIETY)/mps.a + $(TESTLIBOBJ) $(TESTTHROBJ) $(PFM)/$(VARIETY)/exposet0: $(PFM)/$(VARIETY)/exposet0.o \ $(FMTDYTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a @@ -491,7 +463,7 @@ $(PFM)/$(VARIETY)/fotest: $(PFM)/$(VARIETY)/fotest.o \ $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a $(PFM)/$(VARIETY)/gcbench: $(PFM)/$(VARIETY)/gcbench.o \ - $(FMTDYTSTOBJ) $(TESTLIBOBJ) $(TESTTHROBJ) $(PFM)/$(VARIETY)/mps.a + $(FMTDYTSTOBJ) $(TESTLIBOBJ) $(TESTTHROBJ) $(PFM)/$(VARIETY)/landtest: $(PFM)/$(VARIETY)/landtest.o \ $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a @@ -527,7 +499,7 @@ $(PFM)/$(VARIETY)/nailboardtest: $(PFM)/$(VARIETY)/nailboardtest.o \ $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a $(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 \ $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a @@ -630,29 +602,28 @@ else ifeq ($(VARIETY),hot) include $(PFM)/$(VARIETY)/mps.d else -# %%PART: When adding a new part, add the dependency file macro for the new -# part here. +include $(MPM:%.c=$(PFM)/$(VARIETY)/%.d) +endif # VARIETY != hot +endif # VARIETY != rash + +# %%PART: When adding a new part, add the dependencies file for the +# new part here. include \ - $(MPMDEP) \ - $(AMCDEP) \ - $(AMSDEP) \ - $(AWLDEP) \ - $(EVENTPROCDEP) \ - $(FMTDYDEP) \ - $(FMTDYTSTDEP) \ - $(FMTHETSTDEP) \ - $(FMTSCMDEP) \ - $(LODEP) \ - $(PLINTHDEP) \ - $(POOLNDEP) \ - $(TESTLIBDEP) -endif -endif + $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(POOLN:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(TESTTHR:%.c=$(PFM)/$(VARIETY)/%.d) \ + $(EXTRA_TARGETS:mps%=$(PFM)/$(VARIETY)/%.d) \ + $(TEST_TARGETS:%=$(PFM)/$(VARIETY)/%.d) -endif -endif +endif # !defined TARGET +endif # !defined VARIETY -endif +endif # !defined gendep # Library diff --git a/mps/code/commpost.nmk b/mps/code/commpost.nmk index 3fbe828ca34..40beeb7fc58 100644 --- a/mps/code/commpost.nmk +++ b/mps/code/commpost.nmk @@ -92,12 +92,9 @@ $(PFM)\hot\mps.lib: $(PFM)\hot\mps.obj $(ECHO) $@ $(LIBMAN) $(LIBFLAGS) /OUT:$@ $** -$(PFM)\cool\mps.lib: \ - $(MPMOBJ) $(AMCOBJ) $(AMSOBJ) $(AWLOBJ) $(LOOBJ) $(SNCOBJ) \ - $(MVFFOBJ) $(PLINTHOBJ) $(POOLNOBJ) +$(PFM)\cool\mps.lib: $(MPMOBJ) $(ECHO) $@ - $(CC) /c $(CFLAGS) /Fo$(PFM)\$(VARIETY)\version.obj version.c - $(LIBMAN) $(LIBFLAGS) /OUT:$@ $** $(PFM)\$(VARIETY)\version.obj + $(LIBMAN) $(LIBFLAGS) /OUT:$@ $** # 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)\mps.lib $(TESTLIBOBJ) -$(PFM)\$(VARIETY)\poolncv.exe: $(PFM)\$(VARIETY)\poolncv.obj \ - $(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ) +$(PFM)\$(VARIETY)\poolncv.exe: $(PFM)\$(VARIETY)\poolncv.obj \ + $(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ) $(POOLNOBJ) $(PFM)\$(VARIETY)\qs.exe: $(PFM)\$(VARIETY)\qs.obj \ $(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ) diff --git a/mps/code/commpre.nmk b/mps/code/commpre.nmk index 24c457c8041..dbb20936fea 100644 --- a/mps/code/commpre.nmk +++ b/mps/code/commpre.nmk @@ -166,6 +166,7 @@ MPMCOMMON=\ \ \ \ + \ PLINTH = AMC = @@ -175,11 +176,12 @@ LO = MVFF = POOLN = SNC = -DW = +FMTDY = FMTTEST = FMTSCHEME = TESTLIB = TESTTHR = +MPM = $(MPMCOMMON) $(MPMPF) $(AMC) $(AMS) $(AWL) $(LO) $(MV2) $(MVFF) $(PLINTH) # CHECK PARAMETERS @@ -194,9 +196,15 @@ TESTTHR = !IFNDEF PFMDEFS !ERROR commpre.nmk: PFMDEFS not defined !ENDIF +!IFNDEF MPM +!ERROR commpre.nmk: MPM not defined +!ENDIF !IFNDEF MPMCOMMON !ERROR commpre.nmk: MPMCOMMON not defined !ENDIF +!IFNDEF MPMPF +!ERROR commpre.nmk: MPMPF not defined +!ENDIF !IFNDEF PLINTH !ERROR commpre.nmk: PLINTH not defined !ENDIF @@ -215,8 +223,8 @@ TESTTHR = !IFNDEF SNC !ERROR commpre.nmk: SNC not defined !ENDIF -!IFNDEF DW -!ERROR commpre.nmk: DW not defined +!IFNDEF FMTDY +!ERROR commpre.nmk: FMTDY not defined !ENDIF !IFNDEF FMTTEST !ERROR commpre.nmk: FMTTEST not defined diff --git a/mps/code/config.h b/mps/code/config.h index bf9731c5875..a4433ea108c 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -292,6 +292,11 @@ /* Attribute for functions that may be unused in some build configurations. * GCC: + * + * 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) #define ATTRIBUTE_UNUSED __attribute__((__unused__)) @@ -420,7 +425,7 @@ pool to be very heavily used. */ #define CONTROL_EXTEND_BY 4096 -#define VM_ARENA_SIZE_DEFAULT ((Size)1 << 20) +#define VM_ARENA_SIZE_DEFAULT ((Size)1 << 28) /* Stack configuration */ diff --git a/mps/code/dbgpool.c b/mps/code/dbgpool.c index 77c1d6eaf40..75cd14feddc 100644 --- a/mps/code/dbgpool.c +++ b/mps/code/dbgpool.c @@ -190,7 +190,10 @@ static Res DebugPoolInit(Pool pool, ArgList args) /* This pool has to be like the arena control pool: the blocks */ /* allocated must be accessible using void*. */ 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); res = PoolCreate(&debug->tagPool, PoolArena(pool), PoolClassMFS(), pcArgs); } MPS_ARGS_END(pcArgs); diff --git a/mps/code/djbench.c b/mps/code/djbench.c index c1f37f412b2..00bb5d3f954 100644 --- a/mps/code/djbench.c +++ b/mps/code/djbench.c @@ -48,6 +48,7 @@ static double pact = 0.2; /* probability per pass of acting */ static unsigned rinter = 75; /* pass interval for recursion */ static unsigned rmax = 10; /* maximum recursion depth */ static mps_bool_t zoned = TRUE; /* arena allocates using zones */ +static size_t arenasize = 256ul * 1024 * 1024; /* arena size */ #define DJRUN(fname, alloc, free) \ 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) { 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); DJMUST(mps_arena_create_k(&arena, mps_arena_class_vm(), args)); } MPS_ARGS_END(args); @@ -201,6 +202,7 @@ static struct option longopts[] = { {"rinter", required_argument, NULL, 'r'}, {"rmax", required_argument, NULL, 'd'}, {"seed", required_argument, NULL, 'x'}, + {"arena-size", required_argument, NULL, 'm'}, {"arena-unzoned", no_argument, NULL, 'z'}, {NULL, 0, NULL, 0} }; @@ -235,7 +237,7 @@ int main(int argc, char *argv[]) { 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) { case 't': nthreads = (unsigned)strtoul(optarg, NULL, 10); @@ -267,6 +269,20 @@ int main(int argc, char *argv[]) { case 'z': zoned = FALSE; 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: fprintf(stderr, "Usage: %s [option...] [test...]\n" diff --git a/mps/code/eventdef.h b/mps/code/eventdef.h index 0d3efe3b9cb..edfa650f014 100644 --- a/mps/code/eventdef.h +++ b/mps/code/eventdef.h @@ -36,8 +36,8 @@ */ #define EVENT_VERSION_MAJOR ((unsigned)1) -#define EVENT_VERSION_MEDIAN ((unsigned)1) -#define EVENT_VERSION_MINOR ((unsigned)7) +#define EVENT_VERSION_MEDIAN ((unsigned)2) +#define EVENT_VERSION_MINOR ((unsigned)0) /* EVENT_LIST -- list of event types and general properties @@ -722,9 +722,8 @@ PARAM(X, 5, D, mortality) /* mortality of generation */ \ PARAM(X, 6, W, zone) /* zone set of generation */ \ PARAM(X, 7, P, pool) /* pool */ \ - PARAM(X, 8, W, serial) /* pool gen serial number */ \ - PARAM(X, 9, W, totalSize) /* total size of pool gen */ \ - PARAM(X, 10, W, newSizeAtCreate) /* new size of pool gen at trace create */ + PARAM(X, 8, W, totalSize) /* total size of pool gen */ \ + PARAM(X, 9, W, newSizeAtCreate) /* new size of pool gen at trace create */ #define EVENT_TraceCondemnZones_PARAMS(PARAM, X) \ PARAM(X, 0, P, trace) /* the trace */ \ @@ -733,7 +732,7 @@ #define EVENT_ArenaGenZoneAdd_PARAMS(PARAM, X) \ 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 */ #define EVENT_ArenaUseFreeZone_PARAMS(PARAM, X) \ diff --git a/mps/code/failover.c b/mps/code/failover.c index e8a0dbc7dae..7e9f07d7b8c 100644 --- a/mps/code/failover.c +++ b/mps/code/failover.c @@ -96,7 +96,7 @@ static Res failoverInsert(Range rangeReturn, Land land, Range range) /* Provide more opportunities for coalescence. See * . */ - LandFlush(fo->primary, fo->secondary); + (void)LandFlush(fo->primary, fo->secondary); res = LandInsert(rangeReturn, fo->primary, range); 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 * . */ - LandFlush(fo->primary, fo->secondary); + (void)LandFlush(fo->primary, fo->secondary); 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. */ return LandDelete(rangeReturn, fo->secondary, range); } else if (res != ResOK) { - /* Range was found in primary, but couldn't be deleted, perhaps - * because the primary is out of memory. Delete the whole of - * oldRange, and re-insert the fragments (which might end up in - * the secondary). See . + /* Range was found in primary, but couldn't be deleted. The only + * case we expect to encounter here is the case where the primary + * is out of memory. (In particular, we don't handle the case of a + * 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 + * . */ res = LandDelete(&dummyRange, fo->primary, &oldRange); 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 * re-entrant and fail the landEnter check. */ 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); - AVER(res == ResOK); + AVER(res == ResOK); + } } RangeInit(&right, RangeLimit(range), RangeLimit(&oldRange)); if (!RangeIsEmpty(&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); - AVER(res == ResOK); + AVER(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; @@ -173,8 +186,8 @@ static void failoverIterate(Land land, LandVisitor visitor, void *closureP, Size AVERT(Failover, fo); AVER(visitor != NULL); - LandIterate(fo->primary, visitor, closureP, closureS); - LandIterate(fo->secondary, visitor, closureP, closureS); + return LandIterate(fo->primary, 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); /* See . */ - LandFlush(fo->primary, fo->secondary); + (void)LandFlush(fo->primary, fo->secondary); return LandFindFirst(rangeReturn, oldRangeReturn, fo->primary, 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); /* See . */ - LandFlush(fo->primary, fo->secondary); + (void)LandFlush(fo->primary, fo->secondary); return LandFindLast(rangeReturn, oldRangeReturn, fo->primary, 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); /* See . */ - LandFlush(fo->primary, fo->secondary); + (void)LandFlush(fo->primary, fo->secondary); return LandFindLargest(rangeReturn, oldRangeReturn, fo->primary, 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; + Bool found = FALSE; + Res res; + AVER(FALSE); /* TODO: this code is completely untested! */ + AVER(foundReturn != NULL); AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(Land, land); @@ -248,10 +265,14 @@ static Bool failoverFindInZones(Range rangeReturn, Range oldRangeReturn, Land la AVERT(Bool, high); /* See . */ - LandFlush(fo->primary, fo->secondary); + (void)LandFlush(fo->primary, fo->secondary); - return LandFindInZones(rangeReturn, oldRangeReturn, fo->primary, size, zoneSet, high) - || LandFindInZones(rangeReturn, oldRangeReturn, fo->secondary, size, zoneSet, high); + res = LandFindInZones(&found, rangeReturn, oldRangeReturn, fo->primary, size, zoneSet, high); + if (res != ResOK || !found) + res = LandFindInZones(&found, rangeReturn, oldRangeReturn, fo->secondary, size, zoneSet, high); + + *foundReturn = found; + return res; } diff --git a/mps/code/fotest.c b/mps/code/fotest.c index 2729395c0df..788253b570d 100644 --- a/mps/code/fotest.c +++ b/mps/code/fotest.c @@ -52,13 +52,11 @@ static Res oomAlloc(Addr *pReturn, Pool pool, Size size, UNUSED(pool); UNUSED(size); UNUSED(withReservoirPermit); - switch (rnd() % 4) { + switch (rnd() % 3) { case 0: return ResRESOURCE; case 1: return ResMEMORY; - case 2: - return ResLIMIT; default: return ResCOMMIT_LIMIT; } diff --git a/mps/code/freelist.c b/mps/code/freelist.c index 1e071e06763..2be00189aa8 100644 --- a/mps/code/freelist.c +++ b/mps/code/freelist.c @@ -14,7 +14,7 @@ SRCID(freelist, "$Id$"); #define freelistOfLand(land) PARENT(FreelistStruct, landStruct, land) -#define freelistAlignment(fl) LandAlignment(&fl->landStruct) +#define freelistAlignment(fl) LandAlignment(&(fl)->landStruct) typedef union FreelistBlockUnion { @@ -32,7 +32,7 @@ typedef union FreelistBlockUnion { /* freelistEND -- the end of a list * * 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 * defining freelistEND as ((FreelistBlock)2) or similar (it must be * 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, make next follow prev in the list. * 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, @@ -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) +{ + 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; FreelistBlock prev, cur, next; @@ -448,6 +478,7 @@ static void freelistIterate(Land land, LandVisitor visitor, fl = freelistOfLand(land); AVERT(Freelist, fl); AVER(FUNCHECK(visitor)); + /* closureP and closureS are arbitrary */ prev = freelistEND; cur = fl->list; @@ -468,8 +499,9 @@ static void freelistIterate(Land land, LandVisitor visitor, } cur = next; 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, - Land land, Size size, +static Res freelistFindInZones(Bool *foundReturn, Range rangeReturn, + Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high) { Freelist fl; @@ -665,16 +697,14 @@ static Res freelistFindInZones(Range rangeReturn, Range oldRangeReturn, search = high ? RangeInZoneSetLast : RangeInZoneSetFirst; if (zoneSet == ZoneSetEMPTY) - return ResFAIL; + goto fail; if (zoneSet == ZoneSetUNIV) { FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW; - if ((*landFind)(rangeReturn, oldRangeReturn, land, size, fd)) - return ResOK; - else - return ResFAIL; + *foundReturn = (*landFind)(rangeReturn, oldRangeReturn, land, size, fd); + return ResOK; } if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land))) - return ResFAIL; + goto fail; prev = freelistEND; cur = fl->list; @@ -697,10 +727,15 @@ static Res freelistFindInZones(Range rangeReturn, Range oldRangeReturn, } if (!found) - return ResFAIL; + goto fail; freelistDeleteFromBlock(oldRangeReturn, fl, &foundRange, foundPrev, foundCur); RangeCopy(rangeReturn, &foundRange); + *foundReturn = TRUE; + return ResOK; + +fail: + *foundReturn = FALSE; return ResOK; } @@ -711,17 +746,16 @@ static Res freelistFindInZones(Range rangeReturn, Range oldRangeReturn, * closureP. */ -static Bool freelistDescribeVisitor(Bool *deleteReturn, Land land, Range range, +static Bool freelistDescribeVisitor(Land land, Range range, void *closureP, Size closureS) { Res res; mps_lib_FILE *stream = closureP; - if (deleteReturn == NULL) return FALSE; if (!TESTT(Land, land)) return FALSE; if (!RangeCheck(range)) return FALSE; if (stream == NULL) return FALSE; - UNUSED(closureS); + if (closureS != UNUSED_SIZE) return FALSE; res = WriteF(stream, " [$P,", (WriteFP)RangeBase(range), @@ -737,6 +771,7 @@ static Res freelistDescribe(Land land, mps_lib_FILE *stream) { Freelist fl; Res res; + Bool b; if (!TESTT(Land, land)) return ResFAIL; fl = freelistOfLand(land); @@ -748,7 +783,8 @@ static Res freelistDescribe(Land land, mps_lib_FILE *stream) " listSize = $U\n", (WriteFU)fl->listSize, NULL); - LandIterate(land, freelistDescribeVisitor, stream, 0); + b = LandIterate(land, freelistDescribeVisitor, stream, UNUSED_SIZE); + if (!b) return ResFAIL; res = WriteF(stream, "}\n", NULL); return res; @@ -766,6 +802,7 @@ DEFINE_LAND_CLASS(FreelistLandClass, class) class->insert = freelistInsert; class->delete = freelistDelete; class->iterate = freelistIterate; + class->iterateAndDelete = freelistIterateAndDelete; class->findFirst = freelistFindFirst; class->findLast = freelistFindLast; class->findLargest = freelistFindLargest; diff --git a/mps/code/gcbench.c b/mps/code/gcbench.c index c958128ce4f..733dc0a925b 100644 --- a/mps/code/gcbench.c +++ b/mps/code/gcbench.c @@ -12,6 +12,7 @@ #include "testthr.h" #include "fmtdy.h" #include "fmtdytst.h" +#include "mpm.h" #include /* fprintf, printf, putchars, sscanf, stderr, stdout */ #include /* alloca, exit, EXIT_FAILURE, EXIT_SUCCESS, strtoul */ @@ -244,6 +245,7 @@ static void arena_setup(gcthread_fn_t fn, } MPS_ARGS_END(args); watch(fn, name); mps_arena_park(arena); + printf("%u chunks\n", (unsigned)RingLength(&arena->chunkRing)); mps_pool_destroy(pool); mps_fmt_destroy(format); if (ngen > 0) diff --git a/mps/code/land.c b/mps/code/land.c index 9ff8257151c..19f26057623 100644 --- a/mps/code/land.c +++ b/mps/code/land.c @@ -28,8 +28,9 @@ Bool FindDeleteCheck(FindDelete findDelete) /* landEnter, landLeave -- Avoid re-entrance * - * .enter-leave: The visitor function passed to LandIterate is not - * allowed to call methods of that land. These functions enforce this. + * .enter-leave: The visitor functions passed to LandIterate and + * 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 * visitor functions. These are marked with the tag of this comment. @@ -233,15 +234,37 @@ Res LandDelete(Range rangeReturn, Land land, Range range) * See */ -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); AVER(FUNCHECK(visitor)); landEnter(land); - (*land->class->iterate)(land, visitor, closureP, closureS); + b = (*land->class->iterate)(land, visitor, closureP, closureS); landLeave(land); + return b; +} + + +/* LandIterateAndDelete -- iterate over isolated ranges of addresses + * in land, deleting some of them + * + * See + */ + +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 res; + Bool b; AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); @@ -261,11 +284,11 @@ Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size AVER(FindDeleteCheck(findDelete)); landEnter(land); - res = (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size, - findDelete); + b = (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size, + findDelete); 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 res; + Bool b; AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); @@ -285,11 +308,11 @@ Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, AVER(FindDeleteCheck(findDelete)); landEnter(land); - res = (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size, - findDelete); + b = (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size, + findDelete); 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 res; + Bool b; AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); @@ -309,11 +332,11 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si AVER(FindDeleteCheck(findDelete)); landEnter(land); - res = (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size, - findDelete); + b = (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size, + findDelete); landLeave(land); - return res; + return b; } @@ -322,10 +345,11 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si * See */ -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; + AVER(foundReturn != NULL); AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(Land, land); @@ -334,8 +358,8 @@ Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size siz AVERT(Bool, high); landEnter(land); - res = (*land->class->findInZones)(rangeReturn, oldRangeReturn, land, size, - zoneSet, high); + res = (*land->class->findInZones)(foundReturn, rangeReturn, oldRangeReturn, + land, size, zoneSet, high); landLeave(land); return res; @@ -390,6 +414,7 @@ static Bool landFlushVisitor(Bool *deleteReturn, Land land, Range range, AVERT(Land, land); AVERT(Range, range); AVER(closureP != NULL); + AVER(closureS == UNUSED_SIZE); UNUSED(closureS); dest = closureP; @@ -409,12 +434,12 @@ static Bool landFlushVisitor(Bool *deleteReturn, Land land, Range range, * See */ -void LandFlush(Land dest, Land src) +Bool LandFlush(Land dest, Land src) { AVERT(Land, dest); 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 */ -static Bool landSizeVisitor(Bool *deleteReturn, Land land, Range range, +static Bool landSizeVisitor(Land land, Range range, void *closureP, Size closureS) { Size *size; - AVER(deleteReturn != NULL); AVERT(Land, land); AVERT(Range, range); AVER(closureP != NULL); + AVER(closureS == UNUSED_SIZE); UNUSED(closureS); size = closureP; *size += RangeSize(range); - *deleteReturn = FALSE; return TRUE; } @@ -483,7 +507,8 @@ static Bool landSizeVisitor(Bool *deleteReturn, Land land, Range range, Size LandSlowSize(Land land) { Size size = 0; - LandIterate(land, landSizeVisitor, &size, 0); + Bool b = LandIterate(land, landSizeVisitor, &size, UNUSED_SIZE); + AVER(b); return size; } @@ -503,13 +528,22 @@ static Res landNoDelete(Range rangeReturn, Land land, Range range) 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); AVER(visitor != NULL); UNUSED(closureP); 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) @@ -522,8 +556,9 @@ static Bool landNoFind(Range rangeReturn, Range oldRangeReturn, Land land, Size 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(oldRangeReturn != NULL); AVERT(Land, land); @@ -554,6 +589,7 @@ DEFINE_CLASS(LandClass, class) class->insert = landNoInsert; class->delete = landNoDelete; class->iterate = landNoIterate; + class->iterateAndDelete = landNoIterateAndDelete; class->findFirst = landNoFind; class->findLast = landNoFind; class->findLargest = landNoFind; diff --git a/mps/code/landtest.c b/mps/code/landtest.c index ef13e196600..af6beff29ac 100644 --- a/mps/code/landtest.c +++ b/mps/code/landtest.c @@ -75,15 +75,13 @@ static void describe(TestState state) { } -static Bool checkVisitor(Bool *deleteReturn, Land land, Range range, - void *closureP, Size closureS) +static Bool checkVisitor(Land land, Range range, void *closureP, Size closureS) { Addr base, limit; CheckTestClosure cl = closureP; - Insist(deleteReturn != NULL); testlib_unused(land); - testlib_unused(closureS); + Insist(closureS == UNUSED_SIZE); Insist(cl != NULL); base = RangeBase(range); @@ -110,12 +108,14 @@ static Bool checkVisitor(Bool *deleteReturn, Land land, Range range, static void check(TestState state) { CheckTestClosureStruct closure; + Bool b; closure.state = state; closure.limit = addrOfIndex(state, ArraySize); 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) Insist(BTIsSetRange(state->allocTable, 0, diff --git a/mps/code/locus.c b/mps/code/locus.c index 34df5a85400..f246d3b3b5c 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -214,7 +214,8 @@ void ChainDestroy(Chain chain) AVERT(Chain, chain); AVER(chain->activeTraces == TraceSetEMPTY); - arena = chain->arena; genCount = chain->genCount; + arena = chain->arena; + genCount = chain->genCount; RingRemove(&chain->chainRing); chain->sig = SigInvalid; 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, - Size size, Pool pool, Bool withReservoirPermit, - ArgList args) +GenDesc ChainGen(Chain chain, Index gen) +{ + 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; Res res; Seg seg; ZoneSet zones, moreZones; Arena arena; + GenDesc gen; - AVERT(Chain, chain); - AVER(genNr <= chain->genCount); + AVER(segReturn != NULL); + AVERT(PoolGen, pgen); + AVERT(SegClass, class); + AVER(size > 0); + AVERT(Bool, withReservoirPermit); + AVERT(ArgList, args); - arena = chain->arena; - if (genNr < chain->genCount) - zones = chain->gens[genNr].zones; - else - zones = arena->topGen.zones; + arena = PoolArena(pgen->pool); + gen = pgen->gen; + zones = gen->zones; SegPrefInit(&pref); pref.high = FALSE; pref.zones = zones; 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) return res; moreZones = ZoneSetUnion(zones, ZoneSetOfSeg(arena, seg)); + gen->zones = moreZones; if (!ZoneSetSuper(zones, moreZones)) { - /* Tracking the whole zoneset for each generation number gives - * more understandable telemetry than just reporting the added + /* Tracking the whole zoneset for each generation gives more + * understandable telemetry than just reporting the added * 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; return ResOK; } - /* ChainDeferral -- time until next ephemeral GC for this chain */ double ChainDeferral(Chain chain) @@ -394,55 +407,48 @@ void ChainEndGC(Chain chain, Trace trace) /* 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. */ - AVER(gen != NULL); - AVERT(Chain, chain); - AVER(nr <= chain->genCount); + /* Can't check pgen, because it's not been initialized. */ + AVER(pgen != NULL); + AVERT(GenDesc, gen); AVERT(Pool, pool); AVER(PoolHasAttr(pool, AttrGC)); - gen->nr = nr; - gen->pool = pool; - gen->chain = chain; - RingInit(&gen->genRing); - gen->totalSize = (Size)0; - gen->newSize = (Size)0; - gen->sig = PoolGenSig; + pgen->pool = pool; + pgen->gen = gen; + RingInit(&pgen->genRing); + pgen->totalSize = (Size)0; + pgen->newSize = (Size)0; + pgen->sig = PoolGenSig; + AVERT(PoolGen, pgen); - if(nr != chain->genCount) { - 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); + RingAppend(&gen->locusRing, &pgen->genRing); return ResOK; } /* PoolGenFinish -- finish a PoolGen */ -void PoolGenFinish(PoolGen gen) +void PoolGenFinish(PoolGen pgen) { - AVERT(PoolGen, gen); + AVERT(PoolGen, pgen); - gen->sig = SigInvalid; - RingRemove(&gen->genRing); + pgen->sig = SigInvalid; + RingRemove(&pgen->genRing); } /* PoolGenCheck -- check a PoolGen */ -Bool PoolGenCheck(PoolGen gen) +Bool PoolGenCheck(PoolGen pgen) { - CHECKS(PoolGen, gen); + CHECKS(PoolGen, pgen); /* nothing to check about serial */ - CHECKU(Pool, gen->pool); - CHECKU(Chain, gen->chain); - CHECKD_NOSIG(Ring, &gen->genRing); - CHECKL(gen->newSize <= gen->totalSize); + CHECKU(Pool, pgen->pool); + CHECKU(GenDesc, pgen->gen); + CHECKD_NOSIG(Ring, &pgen->genRing); + CHECKL(pgen->newSize <= pgen->totalSize); return TRUE; } diff --git a/mps/code/misc.h b/mps/code/misc.h index 7380421d5c5..853903b58fa 100644 --- a/mps/code/misc.h +++ b/mps/code/misc.h @@ -152,6 +152,15 @@ typedef const struct SrcIdStruct { #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 * * Given a pointer to a field of a structure this returns a pointer to diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 5e959f1dd9c..2f4647674f0 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -1013,13 +1013,14 @@ extern void LandDestroy(Land land); extern void LandFinish(Land land); extern Res LandInsert(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 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 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 void LandFlush(Land dest, Land src); +extern Bool LandFlush(Land dest, Land src); extern Size LandSlowSize(Land land); extern Bool LandClassCheck(LandClass class); diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 8ce4d14f01a..86087a31102 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -621,6 +621,7 @@ typedef struct LandClassStruct { LandInsertMethod insert; /* insert a range into the land */ LandDeleteMethod delete; /* delete a range from 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 findLast; /* find last range of given size */ LandFindMethod findLargest; /* find largest range */ diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h index 04f73a7e42d..c9c5b029c4a 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h @@ -271,10 +271,12 @@ typedef void (*LandFinishMethod)(Land land); typedef Size (*LandSizeMethod)(Land land); typedef Res (*LandInsertMethod)(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 void (*LandIterateMethod)(Land land, LandVisitor visitor, void *closureP, Size closureS); +typedef Bool (*LandVisitor)(Land land, Range range, 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 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); diff --git a/mps/code/mps.c b/mps/code/mps.c index c3bd22ffe53..115996ba7a0 100644 --- a/mps/code/mps.c +++ b/mps/code/mps.c @@ -87,7 +87,6 @@ #include "poolawl.c" #include "poollo.c" #include "poolsnc.c" -#include "pooln.c" #include "poolmv2.c" #include "poolmvff.c" diff --git a/mps/code/mps.h b/mps/code/mps.h index 9f56309d81e..4aed9227348 100644 --- a/mps/code/mps.h +++ b/mps/code/mps.h @@ -13,7 +13,7 @@ * `MPS_` or `_mps_` and may use any identifiers with these prefixes in * 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 * warning. * diff --git a/mps/code/mps.xcodeproj/project.pbxproj b/mps/code/mps.xcodeproj/project.pbxproj index b860a77f0f5..39a2d76f8ea 100644 --- a/mps/code/mps.xcodeproj/project.pbxproj +++ b/mps/code/mps.xcodeproj/project.pbxproj @@ -7,6 +7,54 @@ objects = { /* 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 */ = { isa = PBXAggregateTarget; buildConfigurationList = 22CDE8F016E9E97E00366D0A /* Build configuration list for PBXAggregateTarget "testrun" */; @@ -79,6 +127,7 @@ /* End PBXAggregateTarget 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 */; }; 2231BB5318CA97D8002D6322 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; }; 2231BB5F18CA97DC002D6322 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; }; @@ -287,6 +336,34 @@ /* End PBXBuildFile 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 */ = { isa = PBXContainerItemProxy; containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */; @@ -3321,6 +3398,10 @@ projectRoot = ""; targets = ( 3104AFF1156D37A0000A585A /* all */, + 2215A9B9192A47CE00E9E2CE /* testall */, + 2215A9B1192A47C500E9E2CE /* testansi */, + 2215A9A9192A47BB00E9E2CE /* testci */, + 2215A9C1192A47D500E9E2CE /* testpoll */, 22CDE8EF16E9E97D00366D0A /* testrun */, 31EEABFA156AAF9D00714D05 /* mps */, 3114A632156E94DB001E0AA3 /* abqtest */, @@ -3374,6 +3455,62 @@ /* End PBXProject 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 */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -3385,7 +3522,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\"\n"; + shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -3801,8 +3938,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 31D60048156D3ECF00337B26 /* testlib.c in Sources */, + 2215A9C9192A495F00E9E2CE /* pooln.c in Sources */, 31D6004B156D3EE600337B26 /* poolncv.c in Sources */, + 31D60048156D3ECF00337B26 /* testlib.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3886,6 +4024,26 @@ /* End PBXSourcesBuildPhase 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 */ = { isa = PBXTargetDependency; target = 31EEABFA156AAF9D00714D05 /* mps */; @@ -4329,6 +4487,90 @@ /* End PBXTargetDependency 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 */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5542,6 +5784,46 @@ /* End XCBuildConfiguration 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" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index ff5d809df67..87f43d2c608 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -454,7 +454,6 @@ typedef struct AMCStruct { /* */ RankSet rankSet; /* rankSet for entire pool */ RingStruct genRing; /* ring of generations */ Bool gensBooted; /* used during boot (init) */ - Chain chain; /* chain used by this pool */ size_t gens; /* number of generations */ amcGen *gen; /* (pointer to) array of generations */ amcGen nursery; /* the default mutator generation */ @@ -642,12 +641,12 @@ DEFINE_BUFFER_CLASS(amcBufClass, class) /* amcGenCreate -- create a generation */ -static Res amcGenCreate(amcGen *genReturn, AMC amc, Serial genNr) +static Res amcGenCreate(amcGen *genReturn, AMC amc, GenDesc gen) { Arena arena; Buffer buffer; Pool pool; - amcGen gen; + amcGen amcgen; Res res; void *p; @@ -657,25 +656,25 @@ static Res amcGenCreate(amcGen *genReturn, AMC amc, Serial genNr) res = ControlAlloc(&p, arena, sizeof(amcGenStruct), FALSE); if(res != ResOK) goto failControlAlloc; - gen = (amcGen)p; + amcgen = (amcGen)p; res = BufferCreate(&buffer, EnsureamcBufClass(), pool, FALSE, argsNone); if(res != ResOK) goto failBufferCreate; - res = PoolGenInit(&gen->pgen, amc->chain, genNr, pool); + res = PoolGenInit(&amcgen->pgen, gen, pool); if(res != ResOK) goto failGenInit; - RingInit(&gen->amcRing); - gen->segs = 0; - gen->forward = buffer; - gen->sig = amcGenSig; + RingInit(&amcgen->amcRing); + amcgen->segs = 0; + amcgen->forward = buffer; + amcgen->sig = amcGenSig; - AVERT(amcGen, gen); + AVERT(amcGen, amcgen); - RingAppend(&amc->genRing, &gen->amcRing); - EVENT2(AMCGenCreate, amc, gen); - *genReturn = gen; + RingAppend(&amc->genRing, &amcgen->amcRing); + EVENT2(AMCGenCreate, amc, amcgen); + *genReturn = amcgen; return ResOK; failGenInit: @@ -718,8 +717,7 @@ static Res amcGenDescribe(amcGen gen, mps_lib_FILE *stream) return ResFAIL; res = WriteF(stream, - " amcGen $P ($U) {\n", - (WriteFP)gen, (WriteFU)amcGenNr(gen), + " amcGen $P {\n", (WriteFP)gen, " buffer $P\n", gen->forward, " segs $U, totalSize $U, newSize $U\n", (WriteFU)gen->segs, @@ -801,6 +799,7 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) size_t genArraySize; size_t genCount; Bool interior = AMC_INTERIOR_DEFAULT; + Chain chain; ArgStruct arg; /* 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); pool->format = arg.val.format; if (ArgPick(&arg, args, MPS_KEY_CHAIN)) - amc->chain = arg.val.chain; + chain = arg.val.chain; else - amc->chain = ArenaGlobals(arena)->defaultChain; + chain = ArenaGlobals(arena)->defaultChain; if (ArgPick(&arg, args, MPS_KEY_INTERIOR)) interior = arg.val.b; AVERT(Format, pool->format); - AVERT(Chain, amc->chain); + AVERT(Chain, chain); pool->alignment = pool->format->alignment; amc->rankSet = rankSet; @@ -864,7 +863,7 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) AVERT(AMC, amc); /* Init generations. */ - genCount = ChainGens(amc->chain); + genCount = ChainGens(chain); { void *p; @@ -874,11 +873,10 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) if(res != ResOK) goto failGensAlloc; amc->gen = p; - for(i = 0; i < genCount + 1; ++i) { - res = amcGenCreate(&amc->gen[i], amc, (Serial)i); - if(res != ResOK) { + for (i = 0; i <= genCount; ++i) { + res = amcGenCreate(&amc->gen[i], amc, ChainGen(chain, i)); + if (res != ResOK) goto failGenAlloc; - } } /* Set up forwarding buffers. */ for(i = 0; i < genCount; ++i) { @@ -1020,8 +1018,8 @@ static Res AMCBufferFill(Addr *baseReturn, Addr *limitReturn, alignedSize = SizeAlignUp(size, ArenaAlign(arena)); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD_FIELD(args, amcKeySegGen, p, gen); - res = ChainAlloc(&seg, amc->chain, PoolGenNr(pgen), amcSegClassGet(), - alignedSize, pool, withReservoirPermit, args); + res = PoolGenAlloc(&seg, pgen, amcSegClassGet(), alignedSize, + withReservoirPermit, args); } MPS_ARGS_END(args); if(res != ResOK) return res; diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 134d1228be0..96783e85583 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -691,14 +691,14 @@ static Res AMSSegCreate(Seg *segReturn, Pool pool, Size size, if (res != ResOK) goto failSize; - res = ChainAlloc(&seg, ams->chain, ams->pgen.nr, (*ams->segClass)(), - prefSize, pool, withReservoirPermit, argsNone); + res = PoolGenAlloc(&seg, &ams->pgen, (*ams->segClass)(), prefSize, + withReservoirPermit, argsNone); if (res != ResOK) { /* try to allocate one that's just large enough */ Size minSize = SizeAlignUp(size, ArenaAlign(arena)); if (minSize == prefSize) goto failSeg; - res = ChainAlloc(&seg, ams->chain, ams->pgen.nr, (*ams->segClass)(), - prefSize, pool, withReservoirPermit, argsNone); + res = PoolGenAlloc(&seg, &ams->pgen, (*ams->segClass)(), prefSize, + withReservoirPermit, argsNone); if (res != ResOK) goto failSeg; } @@ -822,8 +822,7 @@ Res AMSInitInternal(AMS ams, Format format, Chain chain, unsigned gen, pool->alignment = pool->format->alignment; ams->grainShift = SizeLog2(PoolAlignment(pool)); - ams->chain = chain; - res = PoolGenInit(&ams->pgen, ams->chain, gen, pool); + res = PoolGenInit(&ams->pgen, ChainGen(chain, gen), pool); if (res != ResOK) return res; @@ -1666,8 +1665,6 @@ static Res AMSDescribe(Pool pool, mps_lib_FILE *stream) " size $W\n", (WriteFW)ams->size, " grain shift $U\n", (WriteFU)ams->grainShift, - " chain $P\n", - (WriteFP)ams->chain, NULL); if (res != ResOK) return res; @@ -1761,7 +1758,6 @@ Bool AMSCheck(AMS ams) CHECKL(IsSubclassPoly(AMS2Pool(ams)->class, AMSPoolClassGet())); CHECKL(PoolAlignment(AMS2Pool(ams)) == ((Size)1 << ams->grainShift)); CHECKL(PoolAlignment(AMS2Pool(ams)) == AMS2Pool(ams)->format->alignment); - CHECKD(Chain, ams->chain); CHECKD(PoolGen, &ams->pgen); CHECKL(SizeIsAligned(ams->size, ArenaAlign(PoolArena(AMS2Pool(ams))))); CHECKL(FUNCHECK(ams->segSize)); diff --git a/mps/code/poolams.h b/mps/code/poolams.h index 96cec6c6c7b..dd5a85889ed 100644 --- a/mps/code/poolams.h +++ b/mps/code/poolams.h @@ -41,7 +41,6 @@ typedef Res (*AMSSegSizePolicyFunction)(Size *sizeReturn, typedef struct AMSStruct { PoolStruct poolStruct; /* generic pool structure */ Shift grainShift; /* log2 of grain size */ - Chain chain; /* chain used by this pool */ PoolGenStruct pgen; /* generation representing the pool */ Size size; /* total segment size of the pool */ AMSSegSizePolicyFunction segSize; /* SegSize policy */ diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 21edaaec1cb..75a1e895a5e 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -84,7 +84,6 @@ typedef Addr (*FindDependentMethod)(Addr object); typedef struct AWLStruct { PoolStruct poolStruct; Shift alignShift; - Chain chain; /* dummy chain */ PoolGenStruct pgen; /* generation representing the pool */ Size size; /* allocated size in bytes */ Count succAccesses; /* number of successive single accesses */ @@ -473,8 +472,8 @@ static Res AWLSegCreate(AWLSeg *awlsegReturn, return ResMEMORY; MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD_FIELD(args, awlKeySegRankSet, u, rankSet); - res = ChainAlloc(&seg, awl->chain, awl->pgen.nr, AWLSegClassGet(), - size, pool, reservoirPermit, args); + res = PoolGenAlloc(&seg, &awl->pgen, AWLSegClassGet(), size, + reservoirPermit, args); } MPS_ARGS_END(args); if (res != ResOK) return res; @@ -570,9 +569,8 @@ static Res AWLInit(Pool pool, ArgList args) AVERT(Chain, 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) goto failGenInit; @@ -1307,7 +1305,6 @@ static Bool AWLCheck(AWL awl) CHECKD(Pool, &awl->poolStruct); CHECKL(awl->poolStruct.class == AWLPoolClassGet()); CHECKL((Align)1 << awl->alignShift == awl->poolStruct.alignment); - CHECKD(Chain, awl->chain); /* Nothing to check about succAccesses. */ CHECKL(FUNCHECK(awl->findDependent)); /* Don't bother to check stats. */ diff --git a/mps/code/poollo.c b/mps/code/poollo.c index 3420e22b9ab..38168b4a637 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -24,7 +24,6 @@ typedef struct LOStruct *LO; typedef struct LOStruct { PoolStruct poolStruct; /* generic pool structure */ Shift alignShift; /* log_2 of pool alignment */ - Chain chain; /* chain used by this pool */ PoolGenStruct pgen; /* generation representing the pool */ Sig sig; } LOStruct; @@ -293,9 +292,9 @@ static Res loSegCreate(LOSeg *loSegReturn, Pool pool, Size size, lo = PoolPoolLO(pool); AVERT(LO, lo); - res = ChainAlloc(&seg, lo->chain, lo->pgen.nr, EnsureLOSegClass(), - SizeAlignUp(size, ArenaAlign(PoolArena(pool))), - pool, withReservoirPermit, argsNone); + res = PoolGenAlloc(&seg, &lo->pgen, EnsureLOSegClass(), + SizeAlignUp(size, ArenaAlign(PoolArena(pool))), + withReservoirPermit, argsNone); if (res != ResOK) return res; @@ -475,9 +474,11 @@ static Res LOInit(Pool pool, ArgList args) Arena arena; Res res; ArgStruct arg; + Chain chain; unsigned gen = LO_GEN_DEFAULT; AVERT(Pool, pool); + AVERT(ArgList, args); arena = PoolArena(pool); @@ -486,22 +487,22 @@ static Res LOInit(Pool pool, ArgList args) ArgRequire(&arg, args, MPS_KEY_FORMAT); pool->format = arg.val.format; if (ArgPick(&arg, args, MPS_KEY_CHAIN)) - lo->chain = arg.val.chain; + chain = arg.val.chain; else { - lo->chain = ArenaGlobals(arena)->defaultChain; + chain = ArenaGlobals(arena)->defaultChain; gen = 1; /* avoid the nursery of the default chain by default */ } if (ArgPick(&arg, args, MPS_KEY_GEN)) gen = arg.val.u; AVERT(Format, pool->format); - AVERT(Chain, lo->chain); - AVER(gen <= ChainGens(lo->chain)); + AVERT(Chain, chain); + AVER(gen <= ChainGens(chain)); pool->alignment = pool->format->alignment; 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) goto failGenInit; @@ -815,7 +816,6 @@ static Bool LOCheck(LO lo) CHECKL(lo->poolStruct.class == EnsureLOPoolClass()); CHECKL(ShiftCheck(lo->alignShift)); CHECKL((Align)1 << lo->alignShift == PoolAlignment(&lo->poolStruct)); - CHECKD(Chain, lo->chain); CHECKD(PoolGen, &lo->pgen); return TRUE; } diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index b40094d839c..c203c5697b6 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -151,6 +151,8 @@ void MFSFinishTracts(Pool pool, MFSTractVisitor visitor, static void MFSTractFreeVisitor(Pool pool, Addr base, Size size, void *closureP, Size closureS) { + AVER(closureP == UNUSED_POINTER); + AVER(closureS == UNUSED_SIZE); UNUSED(closureP); UNUSED(closureS); ArenaFree(base, size, pool); @@ -165,7 +167,7 @@ static void MFSFinish(Pool pool) mfs = PoolPoolMFS(pool); AVERT(MFS, mfs); - MFSFinishTracts(pool, MFSTractFreeVisitor, NULL, 0); + MFSFinishTracts(pool, MFSTractFreeVisitor, UNUSED_POINTER, UNUSED_SIZE); mfs->sig = SigInvalid; } diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index 45a38592946..4dd85c184e5 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -152,12 +152,6 @@ DEFINE_POOL_CLASS(MVTPoolClass, this) /* 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 MVT2Pool(mvt) (&(mvt)->poolStruct) @@ -760,6 +754,7 @@ static Bool MVTDeleteOverlapping(Bool *deleteReturn, void *element, AVER(deleteReturn != NULL); AVER(element != NULL); AVER(closureP != NULL); + AVER(closureS == UNUSED_SIZE); UNUSED(closureS); 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 * are coalesced on the ABQ. */ - ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &newRange, 0); + ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &newRange, UNUSED_SIZE); (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. */ 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 * 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. */ -static Bool MVTRefillVisitor(Bool *deleteReturn, Land land, Range range, +static Bool MVTRefillVisitor(Land land, Range range, void *closureP, Size closureS) { MVT mvt; - AVER(deleteReturn != NULL); AVERT(Land, land); mvt = closureP; AVERT(MVT, mvt); + AVER(closureS == UNUSED_SIZE); UNUSED(closureS); if (RangeSize(range) < mvt->reuseSize) @@ -1240,7 +1235,8 @@ static void MVTRefillABQIfEmpty(MVT mvt, Size size) if (mvt->abqOverflow && ABQIsEmpty(MVTABQ(mvt))) { mvt->abqOverflow = FALSE; 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 { MVT mvt; - Bool found; RangeStruct range; Arena arena; Size min; @@ -1259,7 +1254,7 @@ typedef struct MVTContigencyClosureStruct Count hardSteps; } MVTContigencyClosureStruct, *MVTContigencyClosure; -static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range, +static Bool MVTContingencyVisitor(Land land, Range range, void *closureP, Size closureS) { MVT mvt; @@ -1267,13 +1262,13 @@ static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range, Addr base, limit; MVTContigencyClosure cl; - AVER(deleteReturn != NULL); AVERT(Land, land); AVERT(Range, range); AVER(closureP != NULL); cl = closureP; mvt = cl->mvt; AVERT(MVT, mvt); + AVER(closureS == UNUSED_SIZE); UNUSED(closureS); base = RangeBase(range); @@ -1287,7 +1282,6 @@ static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range, /* verify that min will fit when seg-aligned */ if (size >= 2 * cl->min) { RangeInit(&cl->range, base, limit); - cl->found = TRUE; return FALSE; } @@ -1295,7 +1289,6 @@ static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range, cl->hardSteps++; if (MVTCheckFit(base, limit, cl->min, cl->arena)) { RangeInit(&cl->range, base, limit); - cl->found = TRUE; return FALSE; } @@ -1309,14 +1302,12 @@ static Bool MVTContingencySearch(Addr *baseReturn, Addr *limitReturn, MVTContigencyClosureStruct cls; cls.mvt = mvt; - cls.found = FALSE; cls.arena = PoolArena(MVT2Pool(mvt)); cls.min = min; cls.steps = 0; cls.hardSteps = 0; - LandIterate(MVTFailover(mvt), MVTContingencyVisitor, (void *)&cls, 0); - if (!cls.found) + if (LandIterate(MVTFailover(mvt), MVTContingencyVisitor, &cls, UNUSED_SIZE)) return FALSE; AVER(RangeSize(&cls.range) >= min); diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index 2843b900dfb..10a4595d003 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -40,7 +40,6 @@ extern PoolClass AMSTPoolClassGet(void); typedef struct AMSTStruct { AMSStruct amsStruct; /* generic AMS structure */ - Chain chain; /* chain to use */ Bool failSegs; /* fail seg splits & merges when true */ Count splits; /* count of successful segment splits */ Count merges; /* count of successful segment merges */ @@ -335,25 +334,30 @@ static Res AMSTInit(Pool pool, ArgList args) Format format; Chain chain; Res res; - static GenParamStruct genParam = { 1024, 0.2 }; + unsigned gen = AMS_GEN_DEFAULT; ArgStruct arg; 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); format = arg.val.format; - res = ChainCreate(&chain, pool->arena, 1, &genParam); - if (res != ResOK) - return res; - res = AMSInitInternal(Pool2AMS(pool), format, chain, 0, FALSE); + res = AMSInitInternal(Pool2AMS(pool), format, chain, gen, FALSE); if (res != ResOK) return res; amst = Pool2AMST(pool); ams = Pool2AMS(pool); ams->segSize = AMSTSegSizePolicy; ams->segClass = AMSTSegClassGet; - amst->chain = chain; amst->failSegs = TRUE; amst->splits = 0; amst->merges = 0; @@ -388,7 +392,6 @@ static void AMSTFinish(Pool pool) AMSFinish(pool); amst->sig = SigInvalid; - ChainDestroy(amst->chain); } @@ -758,14 +761,19 @@ static void *test(void *arg, size_t s) mps_ap_t busy_ap; mps_addr_t busy_init; const char *indent = " "; + mps_chain_t chain; + static mps_gen_param_s genParam = {1024, 0.2}; arena = (mps_arena_t)arg; (void)s; /* unused */ 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_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), "pool_create(amst)"); } MPS_ARGS_END(args); @@ -843,6 +851,7 @@ static void *test(void *arg, size_t s) mps_root_destroy(exactRoot); mps_root_destroy(ambigRoot); mps_pool_destroy(pool); + mps_chain_destroy(chain); mps_fmt_destroy(format); return NULL; diff --git a/mps/code/splay.c b/mps/code/splay.c index 278f038b9b5..1b0e8afb8fd 100644 --- a/mps/code/splay.c +++ b/mps/code/splay.c @@ -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(Tree, node); diff --git a/mps/code/splay.h b/mps/code/splay.h index d6496ff9977..24b97c4b055 100644 --- a/mps/code/splay.h +++ b/mps/code/splay.h @@ -69,7 +69,7 @@ extern Bool SplayFindLast(Tree *nodeReturn, SplayTree splay, void *closureP, Size closureS); 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, TreeDescribeMethod nodeDescribe); diff --git a/mps/code/trace.c b/mps/code/trace.c index 219c6d89a2c..970745cd125 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -1593,10 +1593,9 @@ static void TraceStartPoolGen(Chain chain, GenDesc desc, Bool top, Index i) Ring n, nn; RING_FOR(n, &desc->locusRing, nn) { 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, - gen->pool, gen->nr, gen->totalSize, - gen->newSizeAtCreate); + gen->pool, gen->totalSize, gen->newSizeAtCreate); } } diff --git a/mps/code/w3i3mv.nmk b/mps/code/w3i3mv.nmk index a0f919335b1..458fd033484 100644 --- a/mps/code/w3i3mv.nmk +++ b/mps/code/w3i3mv.nmk @@ -7,11 +7,8 @@ PFM = w3i3mv PFMDEFS = /DCONFIG_PF_STRING="w3i3mv" /DCONFIG_PF_W3I3MV /DWIN32 /D_WINDOWS -!INCLUDE commpre.nmk -!INCLUDE mv.nmk - -# MPM sources: core plus platform-specific. -MPM = $(MPMCOMMON) \ +# MPM platform-specific sources. +MPMPF = \ \ \ \ @@ -23,6 +20,9 @@ MPM = $(MPMCOMMON) \ \ +!INCLUDE commpre.nmk +!INCLUDE mv.nmk + # Source to object file mappings and CFLAGS amalgamation # @@ -41,14 +41,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT) MPMOBJ0 = $(MPM:<=w3i3mv\hot\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i3mv\hot\) FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\hot\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\hot\) POOLNOBJ0 = $(POOLN:<=w3i3mv\hot\) @@ -61,14 +54,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL) MPMOBJ0 = $(MPM:<=w3i3mv\cool\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i3mv\cool\) FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\cool\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\cool\) POOLNOBJ0 = $(POOLN:<=w3i3mv\cool\) @@ -81,61 +67,20 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH) MPMOBJ0 = $(MPM:<=w3i3mv\rash\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i3mv\rash\) FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\rash\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i3mv\rash\) POOLNOBJ0 = $(POOLN:<=w3i3mv\rash\) TESTLIBOBJ0 = $(TESTLIB:<=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 # %%PART: When adding a new part, add new macros which expand to the object # files included in the part MPMOBJ = $(MPMOBJ0:>=.obj) -PLINTHOBJ = $(PLINTHOBJ0:>=.obj) -AMSOBJ = $(AMSOBJ0:>=.obj) -AMCOBJ = $(AMCOBJ0:>=.obj) -AWLOBJ = $(AWLOBJ0:>=.obj) -LOOBJ = $(LOOBJ0:>=.obj) -SNCOBJ = $(SNCOBJ0:>=.obj) -MVFFOBJ = $(MVFFOBJ0:>=.obj) -DWOBJ = $(DWOBJ0:>=.obj) +FMTDYOBJ = $(FMTDYOBJ0:>=.obj) FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj) FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj) POOLNOBJ = $(POOLNOBJ0:>=.obj) diff --git a/mps/code/w3i3pc.nmk b/mps/code/w3i3pc.nmk index ad56deca83a..f3e848a94dd 100644 --- a/mps/code/w3i3pc.nmk +++ b/mps/code/w3i3pc.nmk @@ -7,11 +7,8 @@ PFM = w3i3pc PFMDEFS = /DCONFIG_PF_STRING="w3i3pc" /DCONFIG_PF_W3I3PC /DWIN32 /D_WINDOWS -!INCLUDE commpre.nmk -!INCLUDE pc.nmk - -# MPM sources: core plus platform-specific. -MPM = $(MPMCOMMON) \ +# MPM platform-specific sources. +MPMPF = \ \ \ \ @@ -23,6 +20,9 @@ MPM = $(MPMCOMMON) \ \ +!INCLUDE commpre.nmk +!INCLUDE pc.nmk + # Source to object file mappings and CFLAGS amalgamation # @@ -41,14 +41,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT) MPMOBJ0 = $(MPM:<=w3i3pc\hot\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i3pc\hot\) FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\hot\) POOLNOBJ0 = $(POOLN:<=w3i3pc\hot\) TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\hot\) @@ -60,14 +53,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL) MPMOBJ0 = $(MPM:<=w3i3pc\cool\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i3pc\cool\) FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\cool\) POOLNOBJ0 = $(POOLN:<=w3i3pc\cool\) TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\cool\) @@ -79,60 +65,19 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH) MPMOBJ0 = $(MPM:<=w3i3pc\rash\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i3pc\rash\) FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\rash\) POOLNOBJ0 = $(POOLN:<=w3i3pc\rash\) TESTLIBOBJ0 = $(TESTLIB:<=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 # %%PART: When adding a new part, add new macros which expand to the object # files included in the part MPMOBJ = $(MPMOBJ0:>=.obj) -PLINTHOBJ = $(PLINTHOBJ0:>=.obj) -AMSOBJ = $(AMSOBJ0:>=.obj) -AMCOBJ = $(AMCOBJ0:>=.obj) -AWLOBJ = $(AWLOBJ0:>=.obj) -LOOBJ = $(LOOBJ0:>=.obj) -SNCOBJ = $(SNCOBJ0:>=.obj) -MVFFOBJ = $(MVFFOBJ0:>=.obj) -DWOBJ = $(DWOBJ0:>=.obj) +FMTDYOBJ = $(FMTDYOBJ0:>=.obj) FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj) POOLNOBJ = $(POOLNOBJ0:>=.obj) TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj) diff --git a/mps/code/w3i6mv.nmk b/mps/code/w3i6mv.nmk index 9d20b498525..5cfa511db91 100644 --- a/mps/code/w3i6mv.nmk +++ b/mps/code/w3i6mv.nmk @@ -8,11 +8,8 @@ PFM = w3i6mv PFMDEFS = /DCONFIG_PF_STRING="w3i6mv" /DCONFIG_PF_W3I6MV /DWIN32 /D_WINDOWS MASM = ml64 -!INCLUDE commpre.nmk -!INCLUDE mv.nmk - -# MPM sources: core plus platform-specific. -MPM = $(MPMCOMMON) \ +# MPM platform-specific sources. +MPMPF = \ \ \ \ @@ -24,6 +21,9 @@ MPM = $(MPMCOMMON) \ \ +!INCLUDE commpre.nmk +!INCLUDE mv.nmk + # Source to object file mappings and CFLAGS amalgamation # @@ -42,14 +42,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT) MPMOBJ0 = $(MPM:<=w3i6mv\hot\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i6mv\hot\) FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\hot\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\hot\) POOLNOBJ0 = $(POOLN:<=w3i6mv\hot\) @@ -62,14 +55,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL) MPMOBJ0 = $(MPM:<=w3i6mv\cool\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i6mv\cool\) FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\cool\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\cool\) POOLNOBJ0 = $(POOLN:<=w3i6mv\cool\) @@ -82,61 +68,20 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH) MPMOBJ0 = $(MPM:<=w3i6mv\rash\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i6mv\rash\) FMTTESTOBJ0 = $(FMTTEST:<=w3i6mv\rash\) FMTSCHEMEOBJ0 = $(FMTSCHEME:<=w3i6mv\rash\) POOLNOBJ0 = $(POOLN:<=w3i6mv\rash\) TESTLIBOBJ0 = $(TESTLIB:<=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 # %%PART: When adding a new part, add new macros which expand to the object # files included in the part MPMOBJ = $(MPMOBJ0:>=.obj) -PLINTHOBJ = $(PLINTHOBJ0:>=.obj) -AMSOBJ = $(AMSOBJ0:>=.obj) -AMCOBJ = $(AMCOBJ0:>=.obj) -AWLOBJ = $(AWLOBJ0:>=.obj) -LOOBJ = $(LOOBJ0:>=.obj) -SNCOBJ = $(SNCOBJ0:>=.obj) -MVFFOBJ = $(MVFFOBJ0:>=.obj) -DWOBJ = $(DWOBJ0:>=.obj) +FMTDYOBJ = $(FMTDYOBJ0:>=.obj) FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj) FMTSCHEMEOBJ = $(FMTSCHEMEOBJ0:>=.obj) POOLNOBJ = $(POOLNOBJ0:>=.obj) diff --git a/mps/code/w3i6pc.nmk b/mps/code/w3i6pc.nmk index 687a0a6f204..58488b757f7 100644 --- a/mps/code/w3i6pc.nmk +++ b/mps/code/w3i6pc.nmk @@ -9,13 +9,10 @@ PFM = w3i6pc PFMDEFS = /DCONFIG_PF_STRING="w3i6pc" /DCONFIG_PF_W3I6PC /DWIN32 /D_WINDOWS -!INCLUDE commpre.nmk -!INCLUDE pc.nmk - CFLAGSCOMMONPRE = $(CFLAGSCOMMONPRE) /Tamd64-coff -# MPM sources: core plus platform-specific. -MPM = $(MPMCOMMON) \ +# MPM platform-specific sources. +MPMPF = \ \ \ \ @@ -27,6 +24,9 @@ MPM = $(MPMCOMMON) \ \ +!INCLUDE commpre.nmk +!INCLUDE pc.nmk + # Source to object file mappings and CFLAGS amalgamation # @@ -45,14 +45,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT) MPMOBJ0 = $(MPM:<=w3i6pc\hot\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i6pc\hot\) FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\hot\) POOLNOBJ0 = $(POOLN:<=w3i6pc\hot\) TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\hot\) @@ -64,14 +57,7 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL) MPMOBJ0 = $(MPM:<=w3i6pc\cool\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i6pc\cool\) FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\cool\) POOLNOBJ0 = $(POOLN:<=w3i6pc\cool\) TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\cool\) @@ -83,60 +69,19 @@ CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST) LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH) LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH) MPMOBJ0 = $(MPM:<=w3i6pc\rash\) -PLINTHOBJ0 = $(PLINTH:<=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\) +FMTDYOBJ0 = $(FMTDY:<=w3i6pc\rash\) FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\rash\) POOLNOBJ0 = $(POOLN:<=w3i6pc\rash\) TESTLIBOBJ0 = $(TESTLIB:<=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 # %%PART: When adding a new part, add new macros which expand to the object # files included in the part MPMOBJ = $(MPMOBJ0:>=.obj) -PLINTHOBJ = $(PLINTHOBJ0:>=.obj) -AMSOBJ = $(AMSOBJ0:>=.obj) -AMCOBJ = $(AMCOBJ0:>=.obj) -AWLOBJ = $(AWLOBJ0:>=.obj) -LOOBJ = $(LOOBJ0:>=.obj) -SNCOBJ = $(SNCOBJ0:>=.obj) -MVFFOBJ = $(MVFFOBJ0:>=.obj) -DWOBJ = $(DWOBJ0:>=.obj) +FMTDYOBJ = $(FMTDYOBJ0:>=.obj) FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj) POOLNOBJ = $(POOLNOBJ0:>=.obj) TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj) diff --git a/mps/design/cbs.txt b/mps/design/cbs.txt index c0661f2f792..496cc5ea246 100644 --- a/mps/design/cbs.txt +++ b/mps/design/cbs.txt @@ -124,9 +124,10 @@ _`.limit.zones`: ``CBSLandClass`` and ``CBSFastLandClass`` do not support the ``LandFindInZones()`` generic function (the subclass ``CBSZonedLandClass`` does support this operation). -_`.limit.iterate`: CBS does not support visitors setting -``deleteReturn`` to ``TRUE`` when iterating over ranges with -``LandIterate()``. +_`.limit.iterate`: CBS does not provide an implementation for the +``LandIterateAndDelete()`` generic function. This is because +``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 ``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 ``(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 ----- diff --git a/mps/design/index.txt b/mps/design/index.txt index d5fe0a7658f..39594723074 100644 --- a/mps/design/index.txt +++ b/mps/design/index.txt @@ -45,17 +45,17 @@ arena_ The design of the MPS arena arenavm_ Virtual memory arena bt_ Bit tables buffer_ Allocation buffers and allocation points -cbs_ Coalescing Block Structure allocator +cbs_ Coalescing Block Structure land implementation check_ Design of checking in MPS class-interface_ Design of the pool class interface collection_ The collection framework config_ The design of MPS configuration critical-path_ The critical path through the MPS diag_ The design of MPS diagnostic feedback -failover_ Fail-over allocator +failover_ Fail-over land implementation finalize_ Finalization 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.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 diff --git a/mps/design/land.txt b/mps/design/land.txt index 11f192fa6ff..b4b8bd212a1 100644 --- a/mps/design/land.txt +++ b/mps/design/land.txt @@ -77,15 +77,22 @@ Types _`.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 be passed to ``LandIterate()``. It is called for every isolated 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 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 -keep the range, and not all land classes support deletion.) +keep the range.) Generic functions @@ -164,13 +171,21 @@ strategy. _`.function.delete.alias`: It is acceptable for ``rangeReturn`` and ``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 iterate all isolated contiguous ranges in a land. It receives a -pointer, ``Size`` closure pair to pass on to the iterator method, and -an iterator method to invoke on every range. If the iterator method -returns ``FALSE``, then the iteration is terminated. +visitor function to invoke on every range, and a pointer, ``Size`` +closure pair to pass on to the visitor function. If the visitor +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)`` @@ -217,13 +232,14 @@ Like ``LandFindFirst()``, optionally delete the range (specifying range in which the range was found via the ``oldRangeReturn`` 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`` that lies entirely within the ``zoneSet``, return its range via the -``rangeReturn`` argument, and return ``ResOK``. (The first such block, -if ``high`` is ``FALSE``, or the last, if ``high`` is ``TRUE``.) If -there is no such block, , return ``ResFAIL``. +``rangeReturn`` argument, set ``*foundReturn`` to ``TRUE``, and return +``ResOK``. (The first such block, if ``high`` is ``FALSE``, or the +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()`` (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 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)`` diff --git a/mps/design/splay.txt b/mps/design/splay.txt index 4290b703ac1..fefb40fe8a9 100644 --- a/mps/design/splay.txt +++ b/mps/design/splay.txt @@ -51,7 +51,7 @@ _`.def.splay-tree`: A *splay tree* is a self-adjusting binary tree as described in [ST85]_ and [Sleator96]_. _`.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 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 prior to the transplantation of the root's children. Then we update from that node back to the left tree's root, restoring pointers. -Updating the right tree is the same, mutatis mutandis. (See -`.future.reverse`_ for an alternative approach). +Updating the right tree is the same, mutatis mutandis. Usage diff --git a/mps/design/strategy.txt b/mps/design/strategy.txt index 4b09c3cc004..7d04687c5d3 100644 --- a/mps/design/strategy.txt +++ b/mps/design/strategy.txt @@ -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 cache locality. + Generations ----------- The largest part of the current MPS strategy implementation is the -support for generational GC. Generations are only fully supported for -AMC (and AMCZ) pools. See under "Non-AMC Pools", below, for more -information. +support for generational garbage collections. -Data Structures -............... -The fundamental structure of generational GC is the ``Chain``, -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. +General data structures +....................... -Each generation in a chain has a ``GenDesc`` structure, -allocated in an array pointed to from the chain. Each AMC pool has a -set of ``PoolGen`` structures, one per generation. The PoolGens -for each generation point to the GenDesc and are linked together in a -ring on the GenDesc. These structures are (solely?) used to gather +The fundamental structure of generational garbage collection is the +``Chain``, which describes a sequence of generations. + +A chain specifies the "capacity" and "mortality" for each generation. +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. -The arena has a unique ``GenDesc`` structure, named -``topGen`` and described in comments as "the dynamic generation" -(although in fact it is the *least* dynamic generation). Each AMC -pool has one more PoolGen than there are GenDescs in the chain. The -extra PoolGen refers to this topGen. +The non-moving automatic pool classes (AMS, AWL and LO) do not support +generational collection, so they allocate into a single generation. +The moving automatic pool classes (AMC and AMCZ) have one pool +generations for each generation in the chain, plus one pool generation +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 -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. +AMC data structures +................... -When an AMC pool is created, these ``amcGen`` and -``amcBuf`` structures are all created, and the -``amcBuf->gen`` fields initialized so that the forwarding buffer -of each amcGen knows that it belongs to the next "older" amcGen (apart -from the "oldest" amcGen - that which refers to the topGen - whose -forwarding buffer belongs to itself). +An AMC pool creates an array of pool generation structures of type +``amcGen`` (a subclass of ``PoolGen``). Each pool generation points to +the *forwarding buffer* for that generation: this is the buffer that +surviving objects are copied into. -When copying an object in ``AMCFix()``, the object's current -generation is determined (``amcSegGen()``), and the object is -copied to that amcGen's forwarding buffer, using the buffer protocol. -Thus, objects are "promoted" up the chain of generations until they -end up in the topGen, which is shared between all chains and all -pools. +AMC segments point to the AMC pool generation that the segment belongs +to, and AMC buffers point to the AMC pool generation that the buffer +will be allocating into. -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. +The forwarding buffers are set up during AMC pool creation. Each +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. + Zones ..... -All collections in the MPS start with condemnation of a complete -``ZoneSet``. Each generation in each chain has a zoneset -associated with it (``chain->gen[N].zones``); the condemned -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). +Each generation in each chain has a zoneset associated with it +(``gen->zones``); the condemned zoneset is the union of some number of +generation's zonesets. 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 -``GenDesc``. The zoneset for each generation number starts out -empty. If the zoneset is empty, an attempt is made to allocate from a -free zone. The ``GenDesc`` zoneset is augmented with whichever zones the -new segment occupies. +``GenDesc``. The zoneset for each generation starts out empty. If the +zoneset is empty, an attempt is made to allocate from a free zone. The +``GenDesc`` zoneset is augmented with whichever zones the new segment +occupies. Note that this zoneset can never shrink. + Accounting .......... @@ -349,25 +356,6 @@ other uses of that: - in ``AMCWhiten()``, if new is TRUE, the segment size is deducted 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 ................ @@ -378,15 +366,18 @@ Trace Progress .............. TODO: When do we do some tracing work? How much tracing work do we do? + Document History ---------------- - 2013-06-04 NB_ Checked this in although it's far from complete. Pasted in my 'ramping notes' from email, which mention some bugs 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/ +.. _RB: http://www.ravenbrook.com/consultants/rb Copyright and License diff --git a/mps/manual/source/bib.rst b/mps/manual/source/bib.rst new file mode 100644 index 00000000000..f32b6d33422 --- /dev/null +++ b/mps/manual/source/bib.rst @@ -0,0 +1,3877 @@ +.. _bibliography: + +Bibliography +************ + +* .. _AD97: + + Ole Agesen, David L. Detlefs. 1997. "`Finding References in Java Stacks `_". Sun Labs. OOPSLA97 Workshop on Garbage Collection and Memory Management. + + .. admonition:: Abstract + + Exact garbage collection for the strongly-typed Java language may + seem straightforward. Unfortunately, a single pair of bytecodes in + the Java Virtual Machine instruction set presents an obstacle that + has thus far not been discussed in the literature. We explain the + problem, outline the space of possible solutions, and present a + solution utilizing bytecode-preprocessing to enable exact garbage + collection while maintaining compatibility with existing compiled + Java class files. + +* .. _ADM98: + + Ole Agesen, David L. Detlefs, J. Eliot B. Moss. 1998. "`Garbage Collection and Local Variable Type-precision and Liveness in Java Virtual Machines `_". ACM. Proceedings of the ACM SIGPLAN '98 conference on Programming language design and implementation, pp. 269--279. + + .. admonition:: Abstract + + Full precision in garbage collection implies retaining only those + heap allocated objects that will actually be used in the future. + Since full precision is not computable in general, garbage + collectors use safe (i.e., conservative) approximations such as + reachability from a set of root references. Ambiguous roots + collectors (commonly called "conservative") can be overly + conservative because they overestimate the root set, and thereby + retain unexpectedly large amounts of garbage. We consider two more + precise collection schemes for Java virtual machines (JVMs). One + uses a type analysis to obtain a type-precise root set (only those + variables that contain references); the other adds a live variable + analysis to reduce the root set to only the live reference + variables. Even with the Java programming language's strong + typing, it turns out that the JVM specification has a feature that + makes type-precise root sets difficult to compute. We explain the + problem and ways in which it can be solved. + + Our experimental results include measurements of the costs of the + type and liveness analyses at load time, of the incremental + benefits at run time of the liveness analysis over the + type-analysis alone, and of various map sixes and counts. We find + that the liveness analysis often produces little or no improvement + in heap size, sometimes modest improvements, and occasionally the + improvement is dramatic. While further study is in order, we + conclude that the main benefit of the liveness analysis is + preventing bad surprises. + +* .. _AEL88: + + Andrew Appel, John R. Ellis, Kai Li. 1988. "`Real-time Concurrent Collection on Stock Multiprocessors `_". ACM, SIGPLAN. ACM PLDI 88, SIGPLAN Notices 23, 7 (July 88), pp. 11--20. + + .. admonition:: Abstract + + We've designed and implemented a copying garbage-collection + algorithm that is efficient, real-time, concurrent, runs on + commercial uniprocessors and shared-memory multiprocessors, and + requires no change to compilers. The algorithm uses standard + virtual-memory hardware to detect references to "from space" + objects and to synchronize the collector and mutator threads. + We've implemented and measured a prototype running on SRC's + 5-processor Firefly. It will be straightforward to merge our + techniques with generational collection. An incremental, + non-concurrent version could be implemented easily on many + versions of Unix. + +* .. _APPLE94: + + Apple Computer, Inc. 1994. *Inside Macintosh: Memory*. Addison-Wesley. ISBN 0-201-63240-3. + + .. admonition:: Abstract + + Inside Macintosh: Memory describes the parts of the Macintosh® + Operating System that allow you to directly allocate, release, or + otherwise manipulate memory. Everyone who programs Macintosh + computers should read this book. + + Inside Macintosh: Memory shows in detail how your application can + manage the memory partition it is allocated and perform other + memory-related operations. It also provides a complete technical + reference for the Memory Manager, the Virtual Memory Manager, and + other memory-related utilities provided by the system software. + +* .. _ATTARDI94: + + Giuseppe Attardi & Tito Flagella. 1994. "`A Customisable Memory Management Framework `_". TR-94-010. + + .. admonition:: Abstract + + Memory management is a critical issue for many large + object-oriented applications, but in C++ only explicit memory + reclamation through the delete operator is generally available. We + analyse different possibilities for memory management in C++ and + present a dynamic memory management framework which can be + customised to the need of specific applications. The framework + allows full integration and coexistence of different memory + management techniques. The Customisable Memory Management (CMM) is + based on a primary collector which exploits an evolution of + Bartlett's mostly copying garbage collector. Specialised + collectors can be built for separate memory heaps. A Heap class + encapsulates the allocation strategy for each heap. We show how to + emulate different garbage collection styles or user-specific + memory management techniques. The CMM is implemented in C++ + without any special support in the language or the compiler. The + techniques used in the CMM are general enough to be applicable + also to other languages. + +* .. _AFI98: + + Giuseppe Attardi, Tito Flagella, Pietro Iglio. 1998. "`A customisable memory management framework for C++ `_". Software -- Practice and Experience. 28(11), 1143--1183. + + .. admonition:: Abstract + + Automatic garbage collection relieves programmers from the burden + of managing memory themselves and several techniques have been + developed that make garbage collection feasible in many + situations, including real time applications or within traditional + programming languages. However optimal performance cannot always + be achieved by a uniform general purpose solution. Sometimes an + algorithm exhibits a predictable pattern of memory usage that + could be better handled specifically, delaying as much as possible + the intervention of the general purpose collector. This leads to + the requirement for algorithm specific customisation of the + collector strategies. We present a dynamic memory management + framework which can be customised to the needs of an algorithm, + while preserving the convenience of automatic collection in the + normal case. The Customisable Memory Manager (CMM) organises + memory in multiple heaps. Each heap is an instance of a C++ class + which abstracts and encapsulates a particular storage discipline. + The default heap for collectable objects uses the technique of + mostly copying garbage collection, providing good performance and + memory compaction. Customisation of the collector is achieved + exploiting object orientation by defining specialised versions of + the collector methods for each heap class. The object oriented + interface to the collector enables coexistence and coordination + among the various collectors as well as integration with + traditional code unaware of garbage collection. The CMM is + implemented in C++ without any special support in the language or + the compiler. The techniques used in the CMM are general enough to + be applicable also to other languages. The performance of the CMM + is analysed and compared to other conservative collectors for + C/C++ in various configurations. + +* .. _AKPY98: + + Alain Azagury, Elliot K. Kolodner, Erez Petrank, Zvi Yehudai. 1998. "`Combining Card Marking with Remembered Sets: How to Save Scanning Time `_". ACM. ISMM'98 pp. 10--19. + + .. admonition:: Abstract + + We consider the combination of card marking with remembered sets + for generational garbage collection as suggested by Hosking and + Moss. When more than two generations are used, a naive + implementation may cause excessive and wasteful scanning of the + cards and thus increase the collection time. We offer a simple + data structure and a corresponding algorithm to keep track of + which cards need be scanned for which generation. We then extend + these ideas for the Train Algorithm of Hudson and Moss. Here, the + solution is more involved, and allows tracking of which card + should be scanned for which car-collection in the train. + +* .. _BAKER77: + + Henry G. Baker, Carl Hewitt. 1977. "`The Incremental Garbage Collection of Processes `_". ACM. SIGPLAN Notices 12, 8 (August 1977), pp. 55--59. + + .. admonition:: Abstract + + This paper investigates some problems associated with an argument + evaluation order that we call "future" order, which is different + from both call-by-name and call-by-value. In call-by-future, each + formal parameter of a function is bound to a separate process + (called a "future") dedicated to the evaluation of the + corresponding argument. This mechanism allows the fully parallel + evaluation of arguments to a function, and has been shown to + augment the expressive power of a language. + + We discuss an approach to a problem that arises in this context: + futures which were thought to be relevant when they were created + become irrelevant through being ignored in the body of the + expression where they were bound. The problem of irrelevant + processes also appears in multiprocessing problem-solving systems + which start several processors working on the same problem but + with different methods, and return with the solution which + finishes first. This "parallel method strategy" has the drawback + that the processes which are investigating the losing methods must + be identified, stopped, and reassigned to more useful tasks. + + The solution we propose is that of garbage collection. We propose + that the goal structure of the solution plan be explicitly + represented in memory as part of the graph memory (like Lisp's + heap) so that a garbage collection algorithm can discover which + processes are performing useful work, and which can be recycled + for a new task. An incremental algorithm for the unified garbage + collection of storage and processes is described. + +* .. _BAKER78: + + Henry G. Baker. 1978. "`List Processing in Real Time on a Serial Computer `_". ACM. Communications of the ACM 21, 4 (April 1978), pp. 280--294. + + .. admonition:: Abstract + + A real-time list processing system is one in which the time + required by the elementary list operations (e.g. CONS, CAR, CDR, + RPLACA, RPLACD, EQ, and ATOM in LISP) is bounded by a (small) + constant. Classical implementations of list processing systems + lack this property because allocating a list cell from the heap + may cause a garbage collection, which process requires time + proportional to the heap size to finish. A real-time list + processing system is presented which continuously reclaims + garbage, including directed cycles, while linearizing and + compacting the accessible cells into contiguous locations to avoid + fragmenting the free storage pool. The program is small and + requires no time-sharing interrupts, making it suitable for + microcode. Finally, the system requires the same average time, and + not more than twice the space, of a classical implementation, and + those space requirements can be reduced to approximately classical + proportions by compact list representation. Arrays of different + sizes, a program stack, and hash linking are simple extensions to + our system, and reference counting is found to be inferior for + many applications. + +* .. _BAKER79: + + Henry G. Baker. 1979. "`Optimizing Allocation and Garbage Collection of Spaces `_". In Winston and Brown, eds. *Artificial Intelligence: An MIT Perspective.* MIT Press. + + .. admonition:: Abstract + + MACLISP, unlike some other implementations of LISP, allocates + storage for different types of objects in noncontiguous areas + called "spaces". These spaces partition the active storage into + disjoint areas, each of which holds a different type of object. + For example, "list cells" are stored in one space, "full-word + integers" reside in another space, "full-word floating point + numbers" in another, and so on. + + Allocating space in this manner has several advantages. An + object's type can easily be computed from a pointer to it, without + any memory references to the object itself. Thus, the LISP + primitive ATOM(x) can easily compute its result without even + paging in x. Another advantage is that the type of an object does + not require any storage within the object, so that arithmetic with + hardware data types such as full-word integers can use hardware + instructions directly. + + There are problems associated with this method of storage and type + management, however. When all data types are allocated from the + same heap, there is no problem with varying demand for the + different data types; all data types require storage from the same + pool, so that only the total amount of storage is important. Once + different data types must be allocated from different spaces, + however, the relative sizes of the spaces becomes important. + +* .. _BAKER91: + + Henry G. Baker. 1991. "`Cache-Conscious Copying Collectors `_". OOPSLA'91/GC'91 Workshop on Garbage Collection. + + .. admonition:: Abstract + + Garbage collectors must minimize the scarce resources of cache + space and off-chip communications bandwidth to optimize + performance on modern single-chip computer architectures. + Strategies for achieving these goals in the context of copying + garbage collection are discussed. A multi-processor + mutator/collector system is analyzed. Finally, the Intel 80860XP + architecture is studied. + +* .. _BAKER92A: + + Henry G. Baker. 1992. "`Lively Linear Lisp -- 'Look Ma, No Garbage!' `_". ACM. SIGPLAN Notices 27, 8 (August 1992), pp. 89--98. + + .. admonition:: Abstract + + Linear logic has been proposed as one solution to the problem of + garbage collection and providing efficient "update-in-place" + capabilities within a more functional language. Linear logic + conserves accessibility, and hence provides a "mechanical + metaphor" which is more appropriate for a distributed-memory + parallel processor in which copying is explicit. However, linear + logic's lack of sharing may introduce significant inefficiencies + of its own. + + We show an efficient implementation of linear logic called "Linear + Lisp" that runs within a constant factor of non-linear logic. This + Linear Lisp allows RPLACX operations, and manages storage as + safely as a non-linear Lisp, but does not need a garbage + collector. Since it offers assignments but no sharing, it occupies + a twilight zone between functional languages and imperative + languages. Our Linear Lisp Machine offers many of the same + capabilities as combinator/graph reduction machines, but without + their copying and garbage collection problems. + +* .. _BAKER92C: + + Henry G. Baker. 1992. "`The Treadmill: Real-Time Garbage Collection Without Motion Sickness `_". ACM. SIGPLAN Notices 27, 3 (March 1992), pp. 66--70. + + .. admonition:: Abstract + + A simple real-time garbage collection algorithm is presented which + does not copy, thereby avoiding some of the problems caused by the + asynchronous motion of objects. This in-place "treadmill" garbage + collection scheme has approximately the same complexity as other + non-moving garbage collectors, thus making it usable in a + high-level language implementation where some pointers cannot be + traced. The treadmill is currently being used in a Lisp system + built in Ada. + +* .. _BAKER92: + + Henry G. Baker. 1992. "`CONS Should not CONS its Arguments, or, a Lazy Alloc is a Smart Alloc `_". ACM. SIGPLAN Notices 27, 3 (March 1992), 24--34. + + .. admonition:: Abstract + + "Lazy allocation" is a model for allocating objects on the + execution stack of a high-level language which does not create + dangling references. Our model provides safe transportation into + the heap for objects that may survive the deallocation of the + surrounding stack frame. Space for objects that do not survive the + deallocation of the surrounding stack frame is reclaimed without + additional effort when the stack is popped. Lazy allocation thus + performs a first-level garbage collection, and if the language + supports garbage collection of the heap, then our model can reduce + the amortized cost of allocation in such a heap by filtering out + the short-lived objects that can be more efficiently managed in + LIFO order. A run-time mechanism called "result expectation" + further filters out unneeded results from functions called only + for their effects. In a shared-memory multi-processor environment, + this filtering reduces contention for the allocation and + management of global memory. + + Our model performs simple local operations, and is therefore + suitable for an interpreter or a hardware implementation. Its + overheads for functional data are associated only with + *assignments*, making lazy allocation attractive for "mostly + functional" programming styles. Many existing stack allocation + optimizations can be seen as instances of this generic model, in + which some portion of these local operations have been optimized + away through static analysis techniques. + + Important applications of our model include the efficient + allocation of temporary data structures that are passed as + arguments to anonymous procedures which may or may not use these + data structures in a stack-like fashion. The most important of + these objects are functional arguments (funargs), which require + some run-time allocation to preserve the local environment. Since + a funarg is sometimes returned as a first-class value, its + lifetime can survive the stack frame in which it was created. + Arguments which are evaluated in a lazy fashion (Scheme "delays" + or "suspensions") are similarly handled. Variable-length argument + "lists" themselves can be allocated in this fashion, allowing + these objects to become "first-class". Finally, lazy allocation + correctly handles the allocation of a Scheme control stack, + allowing Scheme continuations to become first-class values. + +* .. _BAKER92B: + + Henry G. Baker. 1992. "`NREVERSAL of Fortune -- The Thermodynamics of Garbage Collection `_". Springer-Verlag. LNCS Vol. 637. + + .. admonition:: Abstract + + The need to *reverse* a computation arises in many contexts -- + debugging, editor undoing, optimistic concurrency undoing, + speculative computation undoing, trace scheduling, exception + handling undoing, database recovery, optimistic discrete event + simulations, subjunctive computing, etc. The need to *analyze* a + reversed computation arises in the context of static analysis -- + liveness analysis, strictness analysis, type inference, etc. + Traditional means for restoring a computation to a previous state + involve checkpoints; checkpoints require time to copy, as well as + space to store, the copied material. Traditional reverse abstract + interpretation produces relatively poor information due to its + inability to guess the previous values of assigned-to variables. + + We propose an abstract computer model and a programming language + -- Psi-Lisp -- whose primitive operations are injective and hence + reversible, thus allowing arbitrary undoing without the overheads + of checkpointing. Such a computer can be built from reversible + conservative logic circuits, with the serendipitous advantage of + dissipating far less heat than traditional Boolean AND/OR/NOT + circuits. Unlike functional languages, which have one "state" for + all times, Psi-Lisp has at all times one "state", with unique + predecessor and successor states. + + Compiling into a reversible pseudocode can have benefits even when + targeting a traditional computer. Certain optimizations, e.g., + update-in-place, and compile-time garbage collection may be more + easily performed, because the information may be elicited without + the difficult and time-consuming iterative abstract interpretation + required for most non-reversible models. + + In a reversible machine, garbage collection for recycling storage + can always be performed by a reversed (sub)computation. While this + "collection is reversed mutation" insight does not reduce space + requirements when used for the computation as a whole, it does + save space when used to recycle at finer scales. This insight also + provides an explanation for the fundamental importance of the + push-down stack both for recognizing palindromes and for managing + storage. + + Reversible computers are related to *Prolog*, *linear logic* and + *chemical abstract machines*. + +* .. _BAKER93: + + Henry G. Baker. 1993. "`'Infant Mortality' and Generational Garbage Collection `_". ACM. SIGPLAN Notices 28, 4 (April 1993), pp. 55--57. + + .. admonition:: Abstract + + Generation-based garbage collection has been advocated by + appealing to the intuitive but vague notion that "young objects + are more likely to die than old objects". The intuition is, that + if a generation-based garbage collection scheme focuses its effort + on scanning recently created objects, then its scanning efforts + will pay off more in the form of more recovered garbage, than if + it scanned older objects. In this note, we show a counterexample + of a system in which "infant mortality" is as high as you please, + but for which generational garbage collection is ineffective for + improving the average mark/cons ratio. Other benefits, such as + better locality and a smaller number of large delays, may still + make generational garbage collection attractive for such a system, + however. + +* .. _BAKER93A: + + Henry G. Baker. 1993. "`Equal Rights for Functional Objects or, The More Things Change, The More They Are the Same `_". ACM. OOPS Messenger 4, 4 (October 1993), pp. 2--27. + + .. admonition:: Abstract + + We argue that intensional object identity in object-oriented + programming languages and databases is best defined operationally + by side-effect semantics. A corollary is that "functional" objects + have extensional semantics. This model of object identity, which + is analogous to the normal forms of relational algebra, provides + cleaner semantics for the value-transmission operations and + built-in primitive equality predicate of a programming language, + and eliminates the confusion surrounding "call-by-value" and + "call-by-reference" as well as the confusion of multiple equality + predicates. + + Implementation issues are discussed, and this model is shown to + have significant performance advantages in persistent, parallel, + distributed and multilingual processing environments. This model + also provides insight into the "type equivalence" problem of + Algol-68, Pascal and Ada. + +* .. _BAKER94: + + Henry G. Baker. 1994. "`Minimizing Reference Count Updating with Deferred and Anchored Pointers for Functional Data Structures `_". ACM. SIGPLAN Notices 29, 9 (September 1994), pp. 38--43. + + .. admonition:: Abstract + + "Reference counting" can be an attractive form of dynamic storage + management. It recovers storage promptly and (with a garbage stack + instead of a free list) it can be made "real-time" -- i.e., all + accesses can be performed in constant time. Its major drawbacks + are its inability to reclaim cycles, its count storage, and its + count update overhead. Update overhead is especially irritating + for functional (read-only) data where updates may dirty pristine + cache lines and pages. + + We show how reference count updating can be largely eliminated for + functional data structures by using the "linear style" of + programming that is inspired by Girard's linear logic, and by + distinguishing normal pointers from "anchored pointers", which + indicate not only the object itself, but also the depth of the + stack frame that anchors the object. An "anchor" for a pointer is + essentially an enclosing data structure that is temporarily locked + from being collected for the duration of the anchored pointer's + existence by a deferred reference count. An "anchored pointer" + thus implies a reference count increment that has been deferred + until it is either cancelled or performed. + + Anchored pointers are generalizations of "borrowed" pointers and + "phantom" pointers. Anchored pointers can provide a solution to + the "derived pointer problem" in garbage collection. + +* .. _BAKER94A: + + Henry G. Baker. 1994. "`Thermodynamics and Garbage Collection `_". ACM. SIGPLAN Notices 29, 4 (April 1994), pp. 58--63. + + .. admonition:: Abstract + + We discuss the principles of statistical thermodynamics and their + application to storage management problems. We point out problems + which result from imprecise usage of the terms "information", + "state", "reversible", "conservative", etc. + +* .. _BAKER95A: + + Henry G. Baker. 1995. "`'Use-Once' Variables and Linear Objects -- Storage Management, Reflection and Multi-Threading `_". ACM. SIGPLAN Notices 30, 1 (January 1995), pp. 45--52. + + .. admonition:: Abstract + + Programming languages should have 'use-once' variables in addition + to the usual 'multiple-use' variables. 'Use-once' variables are + bound to linear (unshared, unaliased, or singly-referenced) + objects. Linear objects are cheap to access and manage, because + they require no synchronization or tracing garbage collection. + Linear objects can elegantly and efficiently solve otherwise + difficult problems of functional/mostly-functional systems -- + e.g., in-place updating and the efficient initialization of + functional objects. Use-once variables are ideal for directly + manipulating resources which are inherently linear such as + freelists and 'engine ticks' in reflective languages. + + A 'use-once' variable must be dynamically referenced exactly once + within its scope. Unreferenced use-once variables must be + explicitly killed, and multiply-referenced use-once variables must + be explicitly copied; this duplication and deletion is subject to + the constraint that some linear datatypes do not support + duplication and deletion methods. Use-once variables are bound + only to linear objects, which may reference other linear or + non-linear objects. Non-linear objects can reference other + non-linear objects, but can reference a linear object only in a + way that ensures mutual exclusion. + + Although implementations have long had implicit use-once variables + and linear objects, most languages do not provide the programmer + any help for their utilization. For example, use-once variables + allow for the safe/controlled use of reified language + implementation objects like single-use continuations. + + Linear objects and use-once variables map elegantly into dataflow + models of concurrent computation, and the graphical + representations of dataflow models make an appealing visual linear + programming language. + +* .. _BAKER95: + + Henry G. Baker. 1995. *Memory Management: International Workshop IWMM'95*. Springer-Verlag. ISBN 3-540-60368-9. + + .. admonition:: From the Preface + + The International Workshop on Memory Management 1995 (IWMM'95) is + a continuation of the excellent series started by Yves Bekkers and + Jacques Cohen with IWMM'92. The present volume assembles the + refereed and invited technical papers which were presented during + this year's workshop. + +* .. _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 `_". OOPSLA97 Workshop on Garbage Collection and Memory Management. + + .. admonition:: From the notes + + There is no well-defined memory-management library API which would + allow programmers to easily choose the best memory management + implementation for their application. + + Some languages allow replacement of their memory management + functions, but usually only the program API is specified, hence + replacement of the entire program interface is required. + + Few languages support multiple memory management policies within a + single program. Those that do use proprietary memory management + policies. + + We believe that the design of an abstract program API is a + prerequisite to the design of a “server” API and eventually an API + that would permit multiple cooperating memory “servers”. If the + interface is simple yet powerful enough to encompass most memory + management systems, it stands a good chance of being widely + adopted. + +* .. _ZORN93B: + + David A. Barrett, Benjamin Zorn. 1993. "`Using Lifetime Predictors to Improve Memory Allocation Performance `_". ACM. SIGPLAN'93 Conference on Programming Language Design and Implementation, pp. 187--196. + + .. admonition:: Abstract + + Dynamic storage allocation is used heavily in many application + areas including interpreters, simulators, optimizers, and + translators. We describe research that can improve all aspects of + the performance of dynamic storage allocation by predicting the + lifetimes of short-lived objects when they are allocated. Using + five significant, allocation-intensive C programs, we show that a + great fraction of all bytes allocated are short-lived (> 90% in + all cases). Furthermore, we describe an algorithm for lifetime + prediction that accurately predicts the lifetimes of 42--99% of all + objects allocated. We describe and simulate a storage allocator + that takes advantage of lifetime prediction of short-lived objects + and show that it can significantly improve a program's memory + overhead and reference locality, and even, at times, improve CPU + performance as well. + +* .. _BARRETT93: + + David A. Barrett, Benjamin Zorn. 1995. "`Garbage Collection using a Dynamic Threatening Boundary `_". ACM. SIGPLAN'95 Conference on Programming Language Design and Implementation, pp. 301--314. + + .. admonition:: Abstract + + Generational techniques have been very successful in reducing the + impact of garbage collection algorithms upon the performance of + programs. However, it is impossible for designers of collection + algorithms to anticipate the memory allocation behavior of all + applications in advance. Existing generational collectors rely + upon the applications programmer to tune the behavior of the + collector to achieve maximum performance for each application. + Unfortunately, because the many tuning parameters require detailed + knowledge of both the collection algorithm and the program + allocation behavior in order to be used effectively, such tuning + is difficult and error prone. We propose a new garbage collection + algorithm that uses just two easily understood tuning parameters + that directly reflect the maximum memory and pause time + constraints familiar to application programmers and users. + + Like generational collectors, ours divides memory into two spaces, + one for short-lived, and another for long-lived objects. Unlike + previous work, our collector dynamically adjusts the boundary + between these two spaces in order to directly meet the resource + constraints specified by the user. We describe two methods for + adjusting this boundary, compare them with several existing + algorithms, and show how effectively ours meets the specified + constraints. Our pause time collector saved memory by holding + median pause times closer to the constraint than the other pause + time constrained algorithm and, when not over-constrained, our + memory constrained collector exhibited the lowest CPU overhead of + the algorithms we measured yet was capable of maintaining a + maximum memory constraint. + +* .. _BARTLETT88: + + Joel F. Bartlett. 1988. "`Compacting Garbage Collection with Ambiguous Roots `_". Digital Equipment Corporation. + + .. admonition:: Abstract + + This paper introduces a copying garbage collection algorithm which + is able to compact most of the accessible storage in the heap + without having an explicitly defined set of pointers that contain + all the roots of all accessible storage. Using "hints" found in + the processor's registers and stack, the algorithm is able to + divide heap allocated objects into two groups: those that might be + referenced by a pointer in the stack or registers, and those that + are not. The objects which might be referenced are left in place, + and the other objects are copied into a more compact + representation. + + A Lisp compiler and runtime system which uses such a collector + need not have complete control of the processor in order to force + a certain discipline on the stack and registers. A Scheme + implementation has been done for the Digital WRL Titan processor + which uses a garbage collector based on this "mostly copying" + algorithm. Like other languages for the Titan, it uses the Mahler + intermediate language as its target. This simplifies the compiler + and allows it to take advantage of the significant machine + dependent optimizations provided by Mahler. The common + intermediate language also simplifies call-outs from Scheme + programs to functions written in other languages and call-backs + from functions in other languages. + + Measurements of the Scheme implementation show that the algorithm + is efficient, as little unneeded storage is retained and only a + very small fraction of the heap is left in place. + + Simple pointer manipulation protocols also mean that compiler + support is not needed in order to correctly handle pointers. Thus + it is reasonable to provide garbage collected storage in languages + such as C. A collector written in C which uses this algorithm is + included in the Appendix. + +* .. _BARTLETT89: + + Joel F. Bartlett. 1989. "`Mostly-Copying Garbage Collection Picks Up Generations and C++ `_". Digital Equipment Corporation. + + .. admonition:: Abstract + + The "mostly-copying" garbage collection algorithm provides a way + to perform compacting garbage collection in spite of the presence + of ambiguous pointers in the root set. As originally defined, each + collection required almost all accessible objects to be moved. + While adequate for many applications, programs that retained a + large amount of storage spent a significant amount of time garbage + collecting. To improve performance of these applications, a + generational version of the algorithm has been designed. This note + reports on this extension of the algorithm, and its application in + collectors for Scheme and C++. + +* .. _BC92: + + Yves Bekkers & Jacques Cohen. 1992. "`Memory Management, International Workshop IWMM 92 `_". 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 `_". University of Texas at Austin. UTCS TR99-22. + + .. admonition:: Abstract + + In this paper, we present Hoard, a memory allocator for + shared-memory multiprocessors. We prove that its worst-case memory + fragmentation is asymptotically equivalent to that of an optimal + uniprocessor allocator. We present experiments that demonstrate + its speed and scalability. + +* .. _BERGER01: + + Emery D. Berger, Benjamin G. Zorn, Kathryn S. McKinley. 2001. "`Composing high-performance memory allocators `_" ACM SIGPLAN Conference on Programming Language Design and Implementation 2001, pp. 114--124. + + .. admonition:: Abstract + + Current general-purpose memory allocators do not provide + sufficient speed or flexibility for modern high-performance + applications. Highly-tuned general purpose allocators have + per-operation costs around one hundred cycles, while the cost of + an operation in a custom memory allocator can be just a handful of + cycles. To achieve high performance, programmers often write + custom memory allocators from scratch -- a difficult and + error-prone process. + + In this paper, we present a flexible and efficient infrastructure + for building memory allocators that is based on C++ templates and + inheritance. This novel approach allows programmers to build + custom and general-purpose allocators as “heap layers” that can be + composed without incurring any additional runtime overhead or + additional programming cost. We show that this infrastructure + simplifies allocator construction and results in allocators that + either match or improve the performance of heavily-tuned + allocators written in C, including the Kingsley allocator and the + GNU obstack library. We further show this infrastructure can be + used to rapidly build a general-purpose allocator that has + performance comparable to the Lea allocator, one of the best + uniprocessor allocators available. We thus demonstrate a clean, + easy-to-use allocator interface that seamlessly combines the power + and efficiency of any number of general and custom allocators + within a single application. + +* .. _BW88: + + Hans-J. Boehm, Mark Weiser. 1988. "`Garbage collection in an uncooperative environment `_". Software -- Practice and Experience. 18(9):807--820. + + .. admonition:: Abstract + + We describe a technique for storage allocation and garbage + collection in the absence of significant co-operation from the + code using the allocator. This limits garbage collection overhead + to the time actually required for garbage collection. In + particular, application programs that rarely or never make use of + the collector no longer encounter a substantial performance + penalty. This approach greatly simplifies the implementation of + languages supporting garbage collection. It further allows + conventional compilers to be used with a garbage collector, either + as the primary means of storage reclamation, or as a debugging + tool. + +* .. _BDS91: + + Hans-J. Boehm, Alan J. Demers, Scott Shenker. 1991. "`Mostly Parallel Garbage Collection `_". Xerox PARC. ACM PLDI 91, SIGPLAN Notices 26, 6 (June 1991), pp. 157--164. + + .. admonition:: Abstract + + We present a method for adapting garbage collectors designed to + run sequentially with the client, so that they may run + concurrently with it. We rely on virtual memory hardware to + provide information about pages that have been updated or + "dirtied" during a given period of time. This method has been used + to construct a mostly parallel trace-and-sweep collector that + exhibits very short pause times. Performance measurements are + given. + +* .. _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. + + .. admonition:: Abstract + + Conservative garbage collectors are commonly used in combination + with conventional C programs. Empirically, this usually works + well. However, there are no guarantees that this is safe in the + presence of "improved" compiler optimization. We propose that C + compilers provide a facility to suppress optimizations that are + unsafe in the presence of conservative garbage collection. Such a + facility can be added to an existing compiler at very minimal + cost, provided the additional analysis is done in a + machine-independent source-to-source prepass. Such a prepass may + also check the source code for garbage-collector-safety. + +* .. _BOEHM93: + + Hans-J. Boehm. 1993. "`Space Efficient Conservative Garbage Collection `_". ACM, SIGPLAN. Proceedings of the ACM SIGPLAN '91 Conference on Programming Language Design and Implementation, SIGPLAN Notices 28, 6, pp 197--206. + + .. admonition:: Abstract + + We call a garbage collector conservative if it has only partial + information about the location of pointers, and is thus forced to + treat arbitrary bit patterns as though they might be pointers, in + at least some cases. We show that some very inexpensive, but + previously unused techniques can have dramatic impact on the + effectiveness of conservative garbage collectors in reclaiming + memory. Our most significant observation is that static data that + appears to point to the heap should not result in misidentified + reference to the heap. The garbage collector has enough + information to allocate around such references. We also observe + that programming style has a significantly impact on the amount of + spuriously retained storage, typically even if the collector is + not terribly conservative. Some fairly common C and C++ + programming styles significantly decrease the effectiveness of any + garbage collector. These observations suffice to explain some of + the different assessments of conservative collection that have + appeared in the literature. + +* .. _BOEHM00: + + Hans-J. Boehm. 2000. "`Reducing Garbage Collector Cache Misses `_". ACM. ISMM'00 pp. 59--64. + + .. admonition:: Abstract + + Cache misses are currently a major factor in the cost of garbage + collection, and we expect them to dominate in the future. + Traditional garbage collection algorithms exhibit relatively litle + temporal locality; each live object in the heap is likely to be + touched exactly once during each garbage collection. We measure + two techniques for dealing with this issue: prefetch-on-grey, and + lazy sweeping. The first of these is new in this context. Lazy + sweeping has been in common use for a decade. It was introduced as + a mechanism for reducing paging and pause times; we argue that it + is also crucial for eliminating cache misses during the sweep + phase. + + Our measurements are obtained in the context of a non-moving + garbage collector. Fully copying garbage collection inherently + requires more traffic through the cache, and thus probably also + stands to benefit substantially from something like the + prefetch-on-grey technique. Generational garbage collection may + reduce the benefit of these techniques for some applications, but + experiments with a non-moving generational collector suggest that + they remain quite useful. + +* .. _BOEHM02: + + Hans-J. Boehm. 2002. "`Destructors, Finalizers, and Synchronization `_". HP Labs technical report HPL-2002-335. + + .. admonition:: Abstract + + We compare two different facilities for running cleanup actions + for objects that are about to reach the end of their life. + Destructors, such as we find in C++, are invoked synchronously + when an object goes out of scope. They make it easier to implement + cleanup actions for objects of well-known lifetime, especially in + the presence of exceptions. Languages like Java, Modula-3, and C# + provide a different kind of "finalization" facility: Cleanup + methods may be run when the garbage collector discovers a heap + object to be otherwise inaccessible. Unlike C++ destructors, such + methods run in a separate thread at some much less well-defined + time. We argue that these are fundamentally different, and + potentially complementary, language facilities. We also try to + resolve some common misunderstandings about finalization in the + process. In particular: 1. The asynchronous nature of finalizers + is not just an accident of implementation or a shortcoming of + tracing collectors; it is necessary for correctness of client + code, fundamentally affects how finalizers must be written, and + how finalization facilities should be presented to the user. 2. An + object may legitimately be finalized while one of its methods are + still running. This should and can be addressed by the language + specification and client code. + +* .. _BM77: + + Robert S. Boyer and J. Strother Moore. 1977. "`A Fast String Searching Algorithm `_". *Communications of the ACM* 20(10):762--772. + + .. admonition:: Abstract + + An algorithm is presented that searches for the location, "*i*," + of the first occurrence of a character string, "*pat*," in another + string, "*string*." During the search operation, the characters of + *pat* are matched starting with the last character of *pat*. The + information gained by starting the match at the end of the pattern + often allows the algorithm to proceed in large jumps through the + text being searched. Thus the algorithm has the unusual property + that, in most cases, not all of the first *i* characters of + *string* are inspected. The number of characters actually + inspected (on the average) decreases as a function of the length + of *pat*. For a random English pattern of length 5, the algorithm + will typically inspect *i*/4 characters of string before finding a + match at *i*. Furthermore, the algorithm has been implemented so + that (on the average) fewer than *i* + *patlen* machine + instructions are executed. These conclusions are supported with + empirical evidence and a theoretical analysis of the average + behavior of the algorithm. The worst case behavior of the + algorithm is linear in *i* + *patlen*, assuming the availability + of array space for tables linear in *patlen* plus the size of the + alphabet. + +* .. _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 `_". ISMM'02. + + .. admonition:: Abstract + + The Memory Pool System (MPS) is a very general, adaptable, + flexible, reliable, and efficient memory management system. It + permits the flexible combination of memory management techniques, + supporting manual and automatic memory management, in-line + allocation, finalization, weakness, and multiple simultaneous + co-operating incremental generational garbage collections. It also + includes a library of memory pool classes implementing specialized + memory management policies. + + Between 1994 and 2001, Harlequin (now part of Global Graphics) + invested about thirty person-years of effort developing the MPS. + The system contained many innovative techniques and abstractions + which were kept secret. In 1997 Richard Brooksby, the manager and + chief architect of the project, and Nicholas Barnes, a senior + developer, left Harlequin to form their own consultancy company, + Ravenbrook, and in 2001, Ravenbrook acquired the MPS technology + from Global Graphics. We are happy to announce that we are + publishing the source code and documentation under an open source + licence. This paper gives an overview of the system. + +* .. _C1990: + + International Standard ISO/IEC 9899:1990. "Programming languages — C". + +* .. _C1999: + + International Standard ISO/IEC 9899:1999. "`Programming languages — C `_". + +* .. _CGZ94: + + Brad Calder, Dirk Grunwald, Benjamin Zorn. 1994. "`Quantifying Behavioral Differences Between C and C++ Programs `_". *Journal of Programming Languages.* 2(4):313--351. + + .. admonition:: Abstract + + Improving the performance of C programs has been a topic of great + interest for many years. Both hardware technology and compiler + optimization research has been applied in an effort to make C + programs execute faster. In many application domains, the C++ + language is replacing C as the programming language of choice. In + this paper, we measure the empirical behavior of a group of + significant C and C++ programs and attempt to identify and + quantify behavioral differences between them. Our goal is to + determine whether optimization technology that has been successful + for C programs will also be successful in C++ programs. We + furthermore identify behavioral characteristics of C++ programs + that suggest optimizations that should be applied in those + programs. Our results show that C++ programs exhibit behavior that + is significantly different than C programs. These results should + be of interest to compiler writers and architecture designers who + are designing systems to execute object-oriented programs. + +* .. _CPC00: + + Dante J. Cannarozzi, Michael P. Plezbert, Ron K. Cytron. 2000. "`Contaminated garbage collection `_". ACM. Proceedings of the ACM SIGPLAN '00 conference on on Programming language design and implementation, pp. 264--273. + + .. admonition:: Abstract + + We describe a new method for determining when an object can be + garbage collected. The method does not require marking live + objects. Instead, each object *X* is *dynamically* associated with + a stack frame *M*, such that *X* is collectable when *M* pops. + Because *X* could have been dead earlier, our method is + conservative. Our results demonstrate that the methos nonetheless + idenitifies a large percentage of collectable objects. The method + has been implemented in Sun's Java™ Virtual Machine interpreter, + and results are presented based on this implementation. + +* .. _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. + + .. admonition:: Abstract + + A new, high performance Smalltalk-80™ implementation is described + which builds directly upon two previous implementation efforts. + This implementation supports a large object space while retaining + compatibility with previous Smalltalk-80™ images. The + implementation utilizes a interpreter which incorporates a + generation based garbage collector and which does not have an + object table. This paper describes the design decisions which lead + to this implementation and reports preliminary performance + results. + +* .. _CHENEY70: + + C. J. Cheney. 1970. "`A non-recursive list compacting algorithm `_". CACM. 13-11 pp. 677--678. + + .. admonition:: Abstract + + A simple nonrecursive list structure compacting scheme or garbage + collector suitable for both compact and LISP-like list structures + is presented. The algorithm avoids the need for recursion by using + the partial structure as it is built up to keep track of those + lists that have been copied. + +* .. _CHL98: + + Perry Cheng, Robert Harper, Peter Lee. 1998. "`Generational stack collection and profile-driven pretenuring `_". ACM. Proceedings of SIGPLAN'98 Conference on Programming Language Design and Implementation, pp. 162--173. + + .. admonition:: Abstract + + This paper presents two techniques for improving garbage + collection performance: generational stack collection and + profile-driven pretenuring. The first is applicable to stack-based + implementations of functional languages while the second is useful + for any generational collector. We have implemented both + techniques in a generational collector used by the TIL compiler, + and have observed decreases in garbage collection times of as much + as 70% and 30%, respectively. + + Functional languages encourage the use of recursion which can lead + to a long chain of activation records. When a collection occurs, + these activation records must be scanned for roots. We show that + scanning many activation records can take so long as to become the + dominant cost of garbage collection. However, most deep stacks + unwind very infrequently, so most of the root information obtained + from the stack remains unchanged across successive garbage + collections. *Generational stack collection* greatly reduces the + stack scan cost by reusing information from previous scans. + + Generational techniques have been successful in reducing the cost + of garbage collection. Various complex heap arrangements and + tenuring policies have been proposed to increase the effectiveness + of generational techniques by reducing the cost and frequency of + scanning and copying. In contrast, we show that by using profile + information to make lifetime predictions, *pretenuring* can avoid + copying data altogether. In essence, this technique uses a + refinement of the generational hypothesis (most data die young) + with a locality principle concerning the age of data: most + allocations sites produce data that immediately dies, while a few + allocation sites consistently produce data that survives many + collections. + +* .. _CL98: + + Trishul M. Chilimbi, James R. Larus. 1998. "`Using Generational Garbage Collection To Implement Cache-Conscious Data Placement `_". ACM. ISMM'98 pp. 37--48. + + .. admonition:: Abstract + + Processor and memory technology trends show a continual increase + in the cost of accessing main memory. Machine designers have tried + to mitigate the effect of this trend through a variety of + techniques that attempt to reduce or tolerate memory latency. + These techniques, unfortunately, have only been partially + successful for pointer-manipulating programs. Recent research has + demonstrated that these programs can benefit greatly from the + complementary approach of reorganizing pointer data structures to + improve cache locality. This paper describes how a generational + garbage collector can be used to achieve a cache-conscious data + layout, in which objects with high temporal affinity are placed + next to each other, so they are likely to reside in the same cache + block. The paper demonstrates the feasibility of collecting low + overhead, real-time profiling information about data access + patterns for object-oriented languages, and describes a new + copying algorithm that utilizes this information to produce a + cache-conscious object layout. Preliminary results indicate that + this technique reduces cache miss rates by 21-42\%, and improves + program performance by 14-37\%. + +* .. _CH97: + + William D Clinger & Lars T Hansen. 1997. "`Generational Garbage Collection and the Radioactive Decay Model `_". ACM. Proceedings of PLDI 1997. + + .. admonition:: Abstract + + If a fixed exponentially decreasing probability distribution + function is used to model every object's lifetime, then the age of + an object gives no information about its future life expectancy. + This *radioactive decay model* implies that there can be no + rational basis for deciding which live objects should be promoted + to another generation. Yet there remains a rational basis for + deciding how many objects to promote, when to collect garbage, and + which generations to collect. + + Analysis of the model leads to a new kind of generational garbage + collector whose effectiveness does not depend upon heuristics that + predict which objects will live longer than others. + + This result provides insight into the computational advantages of + generational garbage collection, with implications for the + management of objects whose life expectancies are difficult to + predict. + +* .. _COHEN81: + + Jacques Cohen. 1981. "Garbage collection of linked data structures". Computing Surveys. Vol. 13, no. 3. + + .. admonition:: Abstract + + A concise and unified view of the numerous existing algorithms for + performing garbage collection of linked data structures is + presented. The emphasis is on garbage collection proper, rather + than on storage allocation. + + First, the classical garbage collection algorithms and their + marking and collecting phases, with and without compacting, are + discussed. + + Algorithms describing these phases are classified according to the + type of cells to be collected: those for collecting single-sized + cells are simpler than those for varisized cells. Recently + proposed algorithms are presented and compared with the classical + ones. Special topics in garbage collection are also covered. A + bibliography with topical annotations is included. + +* .. _CCZ98: + + Dominique Colnet, Philippe Coucaud, Olivier Zendra. 1998. "`Compiler Support to Customize the Mark and Sweep Algorithm `_". ACM. ISMM'98 pp. 154--165. + + .. admonition:: Abstract + + Mark and sweep garbage collectors (GC) are classical but still + very efficient automatic memory management systems. Although + challenged by other kinds of systems, such as copying collectors, + mark and sweep collectors remain among the best in terms of + performance. + + This paper describes our implementation of an efficient mark and + sweep garbage collector tailored to each program. Compiler support + provides the type information required to statically and + automatically generate this customized garbage collector. The + segregation of object by type allows the production of a more + efficient GC code. This technique, implemented in SmallEiffel, our + compiler for the object-oriented language Eiffel, is applicable to + other languages and other garbage collection algorithms, be they + distributed or not. + + We present the results obtained on programs featuring a variety of + programming styles and compare our results to a well-known and + high-quality garbage collector. + +* .. _CWZ93: + + Jonathan E. Cook, Alexander L. Wolf, Benjamin Zorn. 1994. "`Partition Selection Policies in Object Database Garbage Collection `_". ACM. SIGMOD. International Conference on the Management of Data (SIGMOD'94), pp. 371--382. + + .. admonition:: Abstract + + The automatic reclamation of storage for unreferenced objects is + very important in object databases. Existing language system + algorithms for automatic storage reclamation have been shown to be + inappropriate. In this paper, we investigate methods to improve + the performance of algorithms for automatic storage reclamation of + object databases. These algorithms are based on a technique called + partitioned garbage collection, in which a subset of the entire + database is collected independently of the rest. Specifically, we + investigate the policy that is used to select what partition in + the database should be collected. The new partition selection + policies that we propose and investigate are based on the + intuition that the values of overwritten pointers provide good + hints about where to find garbage. Using trace-driven simulation, + we show that one of our policies requires less I/O to collect more + garbage than any existing implementable policy and performs close + to an impractical-to-implement but near-optimal policy over a wide + range of database sizes and connectivities. + +* .. _CKWZ96: + + Jonathan E. Cook, Artur Klauser, Alexander L. Wolf, Benjamin Zorn. 1996. "`Semi-automatic, Self-adaptive Control of Garbage Collection Rates in Object Databases `_". ACM, SIGMOD. International Conference on the Management of Data (SIGMOD'96), pp. 377--388. + + .. admonition:: Abstract + + A fundamental problem in automating object database storage + reclamation is determining how often to perform garbage + collection. We show that the choice of collection rate can have a + significant impact on application performance and that the "best" + rate depends on the dynamic behavior of the application, tempered + by the particular performance goals of the user. We describe two + semi-automatic, self-adaptive policies for controlling collection + rate that we have developed to address the problem. Using + trace-driven simulations, we evaluate the performance of the + policies on a test database application that demonstrates two + distinct reclustering behaviors. Our results show that the + policies are effective at achieving user-specified levels of I/O + operations and database garbage percentage. We also investigate + the sensitivity of the policies over a range of object + connectivities. The evaluation demonstrates that semi-automatic, + self-adaptive policies are a practical means for flexibly + controlling garbage collection rate. + +* .. _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. + + .. admonition:: Abstract + + We improved the performance of garbage collection in the Standard ML of + New Jersey system by using the virtual memory facilities provided by + the Mach kernel. We took advantage of Mach's support for large sparse + address spaces and user-defined paging servers. We decreased the + elapsed time for realistic applications by as much as a factor of 4. + +* .. _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. + + .. admonition:: From the back cover + + Using techniques developed in the classroom at America Online's + Programmer's University, Michael Daconta deftly pilots programmers + through the intricacies of the two most difficult aspects of C++ + programming: pointers and dynamic memory management. Written by a + programmer for programmers, this no-nonsense, nuts-and-bolts guide + shows you how to fully exploit advanced C++ programming features, + such as creating class-specific allocators, understanding + references versus pointers, manipulating multidimensional arrays + with pointers, and how pointers and dynamic memory are the core of + object-oriented constructs like inheritance, name-mangling, and + virtual functions. + +* .. _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. + + .. admonition:: From the introduction + + A particularly troublesome phenomenon, thrashing, may seriously + interfere with the performance of paged memory systems, reducing + computing giants (Multics, IBM System 360, and others not + necessarily excepted) to computing dwarfs. The term thrashing + denotes excessive overhead and severe performance degradation or + collapse caused by too much paging. Thrashing inevitably turns a + shortage of memory space into a surplus of processor time. + +* .. _DENNING70: + + P. J. Denning. 1970. "`Virtual Memory `_". ACM. ACM Computing Surveys, vol. 2, no. 3, pp. 153--190, Sept. 1970. + + .. admonition:: Abstract + + The need for automatic storage allocation arises from desires for + program modularity, machine independence, and resource sharing. + Virtual memory is an elegant way of achieving these objectives. In + a virtual memory, the addresses a program may use to identify + information are distinguished from the addresses the memory system + uses to identify physical storage sites, and program-generated + addresses are translated automatically to the corresponding + machine addresses. Two principal methods for implementing virtual + memory, segmentation and paging, are compared and contrasted. Many + contemporary implementations have experienced one or more of these + problems: poor utilization of storage, thrashing, and high costs + associated with loading information into memory. These and + subsidiary problems are studied from a theoretic view, and are + shown to be controllable by a proper combination of hardware and + memory management policies. + +* .. _DS72: + + P. J. Denning, S. C. Schwartz. 1972. "`Properties of the Working-set Model `_". CACM. vol. 15, no. 3, pp. 191--198. + + .. admonition:: Abstract + + A program's working set *W*\ (*t*, *T*) at time *t* is the set of + distinct pages among the *T* most recently referenced pages. + Relations between the average working-set size, the missing-page + rate, and the interreference-interval distribution may be derived + both from time-average definitions and from ensemble-average + (statistical) definitions. An efficient algorithm for estimating + these quantities is given. The relation to LRU (least recently + used) paging is characterized. The independent-reference model, in + which page references are statistically independent, is used to + assess the effects of interpage dependencies on working-set size + observations. Under general assumptions, working-set size is shown + to be normally distributed. + +* .. _DETLEFS92: + + David L. Detlefs. 1992. "`Garbage collection and runtime typing as a C++ library `_". USENIX C++ Conference. + + .. admonition:: From the introduction + + Automatic storage management, or *garbage collection*, is a + feature that can ease program development and enhance program + reliability. Many high-level languages other than C++ provide + garbage collection. This paper proposes the use of "smart pointer" + template classes as an interface for the use of garbage collection + in C++. Template classes and operator overloading are techniques + allowing language extension at the level of user code; I claim + that using these techniques to create smart pointer classes + provdes a syntax for manipulating garbage-collected storage safely + and conveniently. Further, the use of a smart-pointer template + class offers the possibility of implementing the collector at the + user-level, without requiring support from the compiler. If such a + compiler-independent implementation is possible with adequate + performance, then programmers can start to write code using + garbage collection without waiting for language and compiler + modifications. If the use of such a garbage collection interface + becomes widespread, then C++ compilation systems can be built to + specially support tht garbage collection interface, thereby + allowing the use of collection algorithms with enhanced + performance. + +* .. _ZORN93: + + David L. Detlefs, Al Dosser, Benjamin Zorn. 1994. "`Memory Allocation Costs in Large C and C++ Programs `_". Software -- Practice and Experience. 24(6):527--542. + + .. admonition:: Abstract + + Dynamic storage allocation is an important part of a large class + of computer programs written in C and C++. High-performance + algorithms for dynamic storage allocation have been, and will + continue to be, of considerable interest. This paper presents + detailed measurements of the cost of dynamic storage allocation in + 11 diverse C and C++ programs using five very different dynamic + storage allocation implementations, including a conservative + garbage collection algorithm. Four of the allocator + implementations measured are publicly-available on the Internet. A + number of the programs used in these measurements are also + available on the Internet to facilitate further research in + dynamic storage allocation. Finally, the data presented in this + paper is an abbreviated version of more extensive statistics that + are also publicly-available on the Internet. + +* .. _DB76: + + L. Peter Deutsch, Daniel G. Bobrow. 1976. "`An Efficient, Incremental, Automatic Garbage Collector `_". CACM. vol. 19, no. 9, pp. 522--526. + + .. admonition:: Abstract + + This paper describes a new way of solving the storage reclamation + problem for a system such as Lisp that allocates storage + automatically from a heap, and does not require the programmer to + give any indication that particular items are no longer useful or + accessible. A reference count scheme for reclaiming + non-self-referential structures, and a linearizing, compacting, + copying scheme to reorganize all storage at the users discretion + are proposed. The algorithms are designed to work well in systems + which use multiple levels of storage, and large virtual address + space. They depend on the fact that most cells are referenced + exactly once, and that reference counts need only be accurate when + storage is about to be reclaimed. A transaction file stores + changes to reference counts, and a multiple reference table stores + the count for items which are referenced more than once. + +* .. _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 `_". Springer-Verlag. Lecture Notes in Computer Science, Vol. 46. + + .. admonition:: Abstract + + As an example of cooperation between sequential processes with + very little mutual interference despite frequent manipulations of + a large shared data space, a technique is developed which allows + nearly all of the activity needed for garbage detection and + collection to be performed by an additional processor operating + con- currently with the processor devoted to the computation + proper. Exclusion and synchronization constraints have been kept + as weak as could be achieved; the severe complexities engendered + by doing so are illustrated. + +* .. _DMH92: + + Amer Diwan, Richard L. Hudson, J. Eliot B. Moss. 1992. "`Compiler Support for Garbage Collection in a Statically Typed Language `_". ACM. Proceedings of the 5th ACM SIGPLAN conference on Programming language design and implementation, pp. 273--282. + + .. admonition:: Abstract + + We consider the problem of supporting compacting garbage + collection in the presence of modern compiler optimizations. Since + our collector may move any heap object, it must accurately locate, + follow, and update all pointers and values derived from pointers. + To assist the collector, we extend the compiler to emit tables + describing live pointers, and values derived from pointers, at + each program location where collection may occur. Significant + results include identification of a number of problems posed by + optimizations, solutions to those problems, a working compiler, + and experimental data concerning table sizes, table compression, + and time overhead of decoding tables during collection. While gc + support can affect the code produced, our sample programs show no + significant changes, the table sizes are a modest fraction of the + size of the optimized code, and stack tracing is a small fraction + of total gc time. Since the compiler enhancements are also modest, + we conclude that the approach is practical. + +* .. _DTM93: + + Amer Diwan, David Tarditi, J. Eliot B. Moss. 1993. "`Memory Subsystem Performance of Programs with Intensive Heap Allocation `_". Carnegie Mellon University. CMU-CS-93-227. + + .. admonition:: Abstract + + Heap allocation with copying garbage collection is a general + storage management technique for modern programming languages. It + is believed to have poor memory subsystem performance. To + investigate this, we conducted an in-depth study of the memory + subsystem performance of heap allocation for memory subsystems + found on many machines. We studied the performance of + mostly-functional Standard ML programs which made heavy use of + heap allocation. We found that most machines support heap + allocation poorly. However, with the appropriate memory subsystem + organization, heap allocation can have good performance. The + memory subsystem property crucial for achieving good performance + was the ability to allocate and initialize a new object into the + cache without a penalty. This can be achieved by having subblock + placement with a subblock size of one word with a write allocate + policy, along with fast page-mode writes or a write buffer. For + caches with subblock placement, the data cache overhead was under + 9% for a 64k or larger data cache; without subblock placement the + overhead was often higher than 50%. + +* .. _DTM93A: + + Amer Diwan, David Tarditi, J. Eliot B. Moss. 1994. "`Memory Subsystem Performance of Programs Using Copying Garbage Collection `_". ACM. CMU-CS-93-210, also in POPL '94. + + .. admonition:: Abstract + + Heap allocation with copying garbage collection is believed to + have poor memory subsystem performance. We conducted a study of + the memory subsystem performance of heap allocation for memory + subsystems found on many machines. We found that many machines + support heap allocation poorly. However, with the appropriate + memory subsystem organization, heap allocation can have good + memory subsystem performance. + +* .. _DOLIGEZ93: + + Damien Doligez & Xavier Leroy. 1993. "`A concurrent, generational garbage collector for a multithreaded implementation of ML `_". ACM. POPL '93, 113--123. + + .. admonition:: Abstract + + This paper presents the design and implementation of a "quasi + real-time" garbage collector for Concurrent Caml Light, an + implementation of ML with threads. This two-generation system + combines a fast, asynchronous copying collector on the young + generation with a non-disruptive concurrent marking collector on + the old generation. This design crucially relies on the ML + compile-time distinction between mutable and immutable objects. + +* .. _DOLIGEZ94: + + Damien Doligez & Georges Gonthier. 1994. "`Portable, unobtrusive garbage collection for multiprocessor systems `_". ACM. POPL '94, 70--83. + + .. admonition:: Abstract + + We describe and prove the correctness of a new concurrent + mark-and-sweep garbage collection algorithm. This algorithm + derives from the classical on-the-fly algorithm from Dijkstra et + al. A distinguishing feature of our algorithm is that it supports + multiprocessor environments where the registers of running + processes are not readily accessible, without imposing any + overhead on the elementary operations of loading a register or + reading or initializing a field. Furthermore our collector never + blocks running mutator processes except possibly on requests for + free memory; in particular, updating a field or creating or + marking or sweeping a heap object does not involve + system-dependent synchronization primitives such as locks. We also + provide support for process creation and deletion, and for + managing an extensible heap of variable-sized objects. + +* .. _DBE93: + + R. Kent Dybvig, Carl Bruggeman, David Eby. 1993. "`Guardians in a Generation-Based Garbage Collector `_". SIGPLAN. Proceedings of the ACM SIGPLAN '93 Conference on Programming Language Design and Implementation, June 1993. + + .. admonition:: Abstract + + This paper describes a new language feature that allows + dynamically allocated objects to be saved from deallocation by an + automatic storage management system so that clean-up or other + actions can be performed using the data stored within the objects. + The program has full control over the timing of clean-up actions, + which eliminates several potential problems and often eliminates + the need for critical sections in code that interacts with + clean-up actions. Our implementation is "generation-friendly" in + the sense that the additional overhead within the mutator is + proportional to the number of clean-up actions actually performed. + +* .. _EDELSON92A: + + Daniel R. Edelson. 1992. "`Smart pointers: They're smart, but they're not pointers `_". USENIX C++ Conference. + + .. admonition:: From the introduction + + This paper shows hhow the behaviour of smart pointers diverges + from that of pointers in certain common C++ constructs. Given + this, we conclude that the C++ programming language does not + support seamless smart pointers: smart pointers cannot + transparently replace raw pointers in all ways except declaration + syntax. We show that this conclusion also applies to *accessors*. + +* .. _EDELSON92: + + Daniel R. Edelson. 1992. "`Comparing Two Garbage Collectors for C++ `_". University of California at Santa Cruz. Technical Report UCSC-CRL-93-20. + + .. admonition:: Abstract + + Our research is concerned with compiler- independent, tag-free + garbage collection for the C++ programming language. This paper + presents a mark-and-sweep collector, and explains how it + ameliorates shortcomings of a previous copy collector. The new + collector, like the old, uses C++'s facilities for creating + abstract data types to define a *tracked reference* type, called + *roots*, at the level of the application program. A programmer + wishing to utilize the garbage collection service uses these roots + in place of normal, raw pointers. We present a detailed study of + the cost of using roots, as compared to both normal pointers and + reference counted pointers, in terms of instruction counts. We + examine the efficiency of a small C++ application using roots, + reference counting, manual reclamation, and conservative + collection. Coding the application to use garbage collection, and + analyzing the resulting efficiency, helped us identify a number of + memory leaks and inefficiencies in the original, manually + reclaimed version. We find that for this program, garbage + collection using roots is much more efficient than reference + counting, though less efficient than manual reclamation. It is + hard to directly compare our collector to the conservative + collector because of the differing efficiencies of their + respective memory allocators. + +* .. _EDWARDS: + + Daniel J. Edwards. n.d. "`Lisp II Garbage Collector `_". MIT. AI Memo 19 (AIM-19). + + .. admonition:: Our summary + + (This short memo doesn't have an abstract. Basically, it describes + the plan for the LISP II Relocating Garbage Collector. It has four + phases: marking, collection, relocation and moving. Marking is by + recursive descent using a bit table. The remaining phases are + linear sweeps through the bit table. The collection phase + calculates how much everything needs to move, storing this + information in the free blocks. The relocation phase updates all + relocatable addresses. The moving phase moves the surviving + objects into one contiguous block.) + +* .. _ELLIS93: + + John R. Ellis, David L. Detlefs. 1993. "`Safe, Efficient Garbage Collection for C++ `_". Xerox PARC. + + .. admonition:: Abstract + + We propose adding safe, efficient garbage collection to C++, + eliminating the possibility of storage-management bugs and making + the design of complex, object-oriented systems much easier. This + can be accomplished with almost no change to the language itself + and only small changes to existing implementations, while + retaining compatibility with existing class libraries. + +* .. _FERREIRA96: + + Paulo Ferreira. 1996. "`Larchant: garbage collection in a cached distributed shared store with persistence by reachability `_". Université Paris VI. Thése de doctorat. + + .. admonition:: Abstract + + The model of Larchant is that of a *Shared Address Space* + (spanning every site in a network including secondary storage) + with *Persistence By Reachability*. To provide the illusion of a + shared address space across the network, despite the fact that + site memories are disjoint, Larchant implements a *distributed + shared memory* mechanism. Reachability is accessed by tracing the + pointer graph, starting from the persistent root, and reclaiming + unreachable objects. This is the task of *Garbage Collection* + (GC). + + GC was until recently thought to be intractable in a large-scale + system, due to problems of scale, incoherence, asynchrony, and + performance. This thesis presents the solutions that Larchant + proposes to these problems. + + The GC algorithm in Larchant combines tracing and + reference-listing. It traces whenever economically feasible, i.e., + as long as the memory subset being collected remains local to a + site, and counts references that would cost I/O traffic to trace. + GC is orthogonal to coherence, i.e., makes progress even if only + incoherent replicas are locally available. The garbage collector + runs concurrently and asynchronously to applications. The + reference-listing boundary changes dynamically and seamlessly, and + independently at each site, in order to collect cycles of + unreachable objects. + + We prove formally that our GC algorithm is correct, i.e., it is + safe and live. The performance results from our Larchant prototype + show that our design goals (scalability, coherence orthogonality, + and good performance) are fulfilled. + +* .. _FS98: + + Paulo Ferreira & Marc Shapiro. 1998. "`Modelling a Distributed Cached Store for Garbage Collection `_". Springer-Verlag. Proceedings of 12th European Conference on Object-Oriented Programming, ECOOP98, LNCS 1445. + + .. admonition:: Abstract + + Caching and persistence support efficient, convenient and + transparent distributed data sharing. The most natural model of + persistence is persistence by reachability, managed automatically + by a garbage collector (GC). We propose a very general model of + such a system (based on distributed shared memory) and a scalable, + asynchronous distributed GC algorithm. Within this model, we show + sufficient and widely applicable correctness conditions for the + interactions between applications, store, memory, coherence, and + GC. + + The GC runs as a set of processes (local to each participating + machine) communicating by asynchronous messages. Collection does + not interfere with applications by setting locks, polluting + caches, or causing I/O; this requirement raised some novel and + interesting challenges which we address in this article. The + algorithm is safe and live; it is not complete, i.e. it collects + some distributed cycles of garbage but not necessarily all. + +* .. _FW76: + + Daniel P Friedman, David S. Wise. 1976. "`Garbage collecting a heap which includes a scatter table `_". *Information Processing Letters.* 5, 6 (December 1976): 161--164. + + .. admonition:: Abstract + + A new algorithm is introduced for garbage collecting a heap which + contains shared data structures accessed from a scatter table. The + scheme provides for the purging of useless entries from the + scatter table with no traverslas beyond the two required by + classic collection schemes. For languages which use scatter tables + to sustain unique existence of complex structures, like natural + variables of SNOBOL, it indirectly allows liberal use of a single + scatter table by ensuring efficient deletion of useless entries. + Since the scatter table is completely restructured during the + course of execution, the hashing scheme itself is easily altered + during garbage collection whenever skewed loading of the scatter + table warrants abandonment of the old hashing. This procedure is + applicable to the maintenance of dynamic structures such as those + in information retrieval schemes or in languages like LISP and + SNOBOL. + +* .. _FW77: + + Daniel P Friedman, David S. Wise. 1977. "`The One Bit Reference Count `_". *BIT.* (17)3: 351--359. + + .. admonition:: Abstract + + Deutsch and Bobrow propose a storage reclamation scheme for a heap + which is a hybrid of garbage collection and reference counting. + The point of the hybrid scheme is to keep track of very low + reference counts between necessary invocation of garbage + collection so that nodes which are allocated and rather quickly + abandoned can be returned to available space, delaying necessity + for garbage collection. We show how such a scheme may be + implemented using the mark bit already required in every node by + the garbage collector. Between garbage collections that bit is + used to distinguish nodes with a reference count known to be one. + A significant feature of our scheme is a small cache of references + to nodes whose implemented counts "ought to be higher" which + prevents the loss of logical count information in simple + manipulations of uniquely referenced structures. + +* .. _FW79: + + Daniel P Friedman, David S. Wise. 1979. "`Reference counting can manage the circular environments of mutual recursion `_". *Information Processing Letters.* 8, 1 (January 1979): 41--45. + + .. admonition:: From the introduction + + In this note we advance reference counting as a storage management + technique viable for implementing recursive languages like ISWIM + or pure LISP with the ``labels`` construct for implementing mutual + recursion from SCHEME. ``Labels`` is derived from ``letrec`` and + displaces the ``label`` operator, a version of the paradoxical + Y-combinator. The key observation is that the requisite circular + structure (which ordinarily cripples reference counts) occurs only + within the language--rather than the user--structure, and that the + references into this structure are well-controlled. + +* .. _GZH93: + + Dirk Grunwald, Benjamin Zorn, R. Henderson. 1993. "`Improving the Cache Locality of Memory Allocation `_". SIGPLAN. SIGPLAN '93, Conference on PLDI, June 1993, Albuquerque, New Mexico. + + .. admonition:: Abstract + + The allocation and disposal of memory is a ubiquitous operation in + most programs. Rarely do programmers concern themselves with + details of memory allocators; most assume that memory allocators + provided by the system perform well. This paper presents a + performance evaluation of the reference locality of dynamic + storage allocation algorithms based on trace-driven simulation of + five large allocation-intensive C programs. In this paper, we show + how the design of a memory allocator can significantly affect the + reference locality for various applications. Our measurements show + that poor locality in sequential-fit algorithms reduces program + performance, both by increasing paging and cache miss rates. While + increased paging can be debilitating on any architecture, cache + misses rates are also important for modern computer architectures. + We show that algorithms attempting to be space-efficient, by + coalescing adjacent free objects show poor reference locality, + possibly negating the benefits of space efficiency. At the other + extreme, algorithms can expend considerable effort to increase + reference locality yet gain little in total execution performance. + Our measurements suggest an allocator design that is both very + fast and has good locality of reference. + +* .. _GRUN92: + + Dirk Grunwald & Benjamin Zorn. 1993. "`CustoMalloc: Efficient Synthesized Memory Allocators `_". Software -- Practice and Experience. 23(8):851--869. + + .. admonition:: Abstract + + The allocation and disposal of memory is a ubiquitous operation in + most programs. Rarely do programmers concern themselves with + details of memory allocators; most assume that memory allocators + provided by the system perform well. Yet, in some applications, + programmers use domain-specific knowledge in an attempt to improve + the speed or memory utilization of memory allocators. In this + paper, we describe a program (CustoMalloc) that synthesizes a + memory allocator customized for a specific application. Our + experiments show that the synthesized allocators are uniformly + faster than the common binary-buddy (BSD) allocator, and are more + space efficient. Constructing a custom allocator requires little + programmer effort. The process can usually be accomplished in a + few minutes, and yields results superior even to domain-specific + allocators designed by programmers. Our measurements show the + synthesized allocators are from two to ten times faster than + widely used allocators. + +* .. _GUDEMAN93: + + David Gudeman. 1993. "`Representing Type Information in Dynamically Typed Languages `_". University of Arizona at Tucson. Technical Report TR 93-27. + + .. admonition:: Abstract + + This report is a discussion of various techniques for representing + type information in dynamically typed languages, as implemented on + general-purpose machines (and costs are discussed in terms of + modern RISC machines). It is intended to make readily available a + large body of knowledge that currently has to be absorbed + piecemeal from the literature or re-invented by each language + implementor. This discussion covers not only tagging schemes but + other forms of representation as well, although the discussion is + strictly limited to the representation of type information. It + should also be noted that this report does not purport to contain + a survey of the relevant literature. Instead, this report gathers + together a body of folklore, organizes it into a logical + structure, makes some generalizations, and then discusses the + results in terms of modern hardware. + +* .. _HARRIS99: + + Timothy Harris. 1999. "`Early storage reclamation in a tracing garbage collector `_". ACM. ACM SIG-PLAN Notices 34:4, pp. 46--53. + + .. admonition:: Abstract + + This article presents a technique for allowing the early recovery + of storage space occupied by garbage data. The idea is similar to + that of generational garbage collection, except that the heap is + partitioned based on a static analysis of data type definitions + rather than on the approximate age of allocated objects. A + prototype implementation is presented, along with initial results + and ideas for future work. + +* .. _HENRIK94: + + Roger Henriksson. 1994. "Scheduling Real Time Garbage Collection". Department of Computer Science at Lund University. LU-CS-TR:94-129. + + .. admonition:: Abstract + + This paper presents a new model for scheduling the work of an + incremental garbage collector in a system with hard real time + requirements. The method utilizes the fact that just some of the + processes in the system have to meet hard real time requirements + and that these processes typically run periodically, a fact that + we can make use of when scheduling the garbage collection. The + work of the collector is scheduled to be performed in the pauses + between the critical processes and is suspended when the processes + with hard real time requirements run. It is shown that this + approach is feasible for many real time systems and that it leaves + the time-critical parts of the system undisturbed from garbage + collection induced delays. + +* .. _HENRIK96: + + Roger Henriksson. 1996. "`Adaptive Scheduling of Incremental Copying Garbage Collection for Interactive Applications `_". NWPER96. + + .. admonition:: Abstract + + Incremental algorithms are often used to interleave the work of a + garbage collector with the execution of an application program, + the intention being to avoid long pauses. However, overestimating + the worst-case storage needs of the program often causes all the + garbage collection work to be performed in the beginning of the + garbage collection cycles, slowing down the application program to + an unwanted degree. This paper explores an approach to + distributing the work more evenly over the garbage collection + cycle. + +* .. _HENRIKSSON98: + + Roger Henriksson. 1998. "`Scheduling Garbage Collection in Embedded Systems `_". Department of Computer Science at Lund University. Ph.D. thesis. + + .. admonition:: Abstract + + The complexity of systems for automatic control and other + safety-critical applications grows rapidly. Computer software + represents an increasing part of the complexity. As larger systems + are developed, we need to find scalable techniques to manage the + complexity in order to guarantee high product quality. Memory + management is a key quality factor for these systems. Automatic + memory management, or garbage collection, is a technique that + significantly reduces the complex problem of correct memory + management. The risk of software errors decreases and development + time is reduced. + + Garbage collection techniques suitable for interactive and soft + real-time systems exist, but few approaches are suitable for + systems with hard real-time requirements, such as control systems + (embedded systems). One part of the problem is solved by + incremental garbage collection algorithms, which have been + presented before. We focus on the scheduling problem which forms + the second part of the problem, i.e. how the work of a garbage + collector should be scheduled in order to disturb the application + program as little as possible. It is studied how a priori + scheduling analysis of systems with automatic memory management + can be made. The field of garbage collection research is thus + joined with the field of scheduling analysis in order to produce a + practical synthesis of the two fields. + + A scheduling strategy is presented that employs the properties of + control systems to ensure that no garbage collection work is + performed during the execution of critical processes. The hard + real-time part of the system is thus never disturbed by garbage + collection work. Existing incremental garbage collection + algorithms are adapted to the presented strategy. Necessary + modifications of the algorithms and the real-time kernel are + discussed. A standard scheduling analysis technique, rate + monotonic analysis, is extended in order to make a priori analysis + of the schedulability of the garbage collector possible. + + The scheduling algorithm has been implemented in an industrially + relevant real-time environment in order to show that the strategy + is feasible in practice. The experimental evaluation shows that + predictable behaviour and sub-millisecond worst-case delays can be + achieved on standard hardware even by a non-optimized prototype + garbage collector. + +* .. _HOSKING91: + + Antony L. Hosking. 1991. "`Main memory management for persistence `_". ACM. Proceedings of the ACM OOPSLA'91 Workshop on Garbage Collection. + + .. admonition:: Abstract + + Reachability-based persistence imposes new requirements for main + memory management in general, and garbage collection in + particular. After a brief introduction to the characteristics and + requirements of reachability-based persistence, we present the + design of a run-time storage manager for Persistent Smalltalk and + Persistent Modula-3, which allows the reclamation of storage from + both temporary objects and buffered persistent objects. + +* .. _HMS92: + + Antony L. Hosking, J. Eliot B. Moss, Darko Stefanovic. 1992. "`A comparative performance evaluation of write barrier implementations `_". ACM. OOPSLA'92 Conference Proceedings, ACM SIGPLAN Notices 27(10), pp 92--109. + + .. admonition:: Abstract + + Generational garbage collectors are able to achieve very small + pause times by concentrating on the youngest (most recently + allocated) objects when collecting, since objects have been + observed to die young in many systems. Generational collectors + must keep track of all pointers from older to younger generations, + by “monitoring” all stores into the heap. This *write barrier* has + been implemented in a number of ways, varying essentially in the + granularity of the information observed and stored. Here we + examine a range of write barrier implementations and evaluate + their relative performance within a generation scavenging garbage + collector for Smalltalk. + +* .. _HH93: + + Antony L. Hosking, Richard L. Hudson. 1993. "`Remembered sets can also play cards `_". ACM. Proceedings of the ACM OOPSLA'93 Workshop on Memory Management and Garbage Collection. + + .. admonition:: Abstract + + Remembered sets and dirty bits have been proposed as alternative + implementations of the write barrier for garbage collection. There + are advantages to both approaches. Dirty bits can be efficiently + maintained with minimal, bounded overhead per store operation, + while remembered sets concisely, and accurately record the + necessary information. Here we present evidence to show that + hybrids can combine the virtues of both schemes and offer + competitive performance. Moreover, we argue that a hybrid can + better avoid the devils that are the downfall of the separate + alternatives. + +* .. _HM93: + + Antony L. Hosking, J. Eliot B. Moss. 1993. "`Protection traps and alternatives for memory management of an object-oriented language `_". ACM. Proceedings of the Fourteenth ACM Symposium on Operating Systems Principles, ACM Operating Systems Review 27(5), pp 106--119. + + .. admonition:: Abstract + + Many operating systems allow user programs to specify the + protection level (inaccessible, read-only, read-write) of pages in + their virtual memory address space, and to handle any protection + violations that may occur. Such page-protection techniques have + been exploited by several user-level algorithms for applications + including generational garbage collection and persistent stores. + Unfortunately, modern hardware has made efficient handling of page + protection faults more difficult. Moreover, page-sized granularity + may not match the natural granularity of a given application. In + light of these problems, we reevaluate the usefulness of + page-protection primitives in such applications, by comparing the + performance of implementations that make use of the primitives + with others that do not. Our results show that for certain + applications software solutions outperform solutions that rely on + page-protection or other related virtual memory primitives. + +* .. _HMDW91: + + Richard L. Hudson, J. Eliot B. Moss, Amer Diwan, Christopher F. Weight. 1991. "`A Language-Independent Garbage Collector Toolkit `_". University of Massachusetts at Amherst. COINS Technical Report 91--47. + + .. admonition:: Abstract + + We describe a memory management toolkit for language implementors. + It offers efficient and flexible generation scavenging garbage + collection. In addition to providing a core of + language-independent algorithms and data structures, the toolkit + includes auxiliary components that ease implementation of garbage + collection for programming languages. We have detailed designs for + Smalltalk and Modula-3 and are confident the toolkit can be used + with a wide variety of languages. The toolkit approach is itself + novel, and our design includes a number of additional innovations + in flexibility, efficiency, accuracy, and cooperation between the + compiler and the collector. + +* .. _HM92: + + Richard L. Hudson, J. Eliot B. Moss. 1992. "`Incremental Collection of Mature Objects `_". Springer-Verlag. LNCS #637 International Workshop on Memory Management, St. Malo, France, Sept. 1992, pp. 388--403. + + .. admonition:: Abstract + + We present a garbage collection algorithm that extends + generational scavenging to collect large older generations (mature + objects) non-disruptively. The algorithm's approach is to process + bounded-size pieces of mature object space at each collection; the + subtleties lie in guaranteeing that it eventually collects any and + all garbage. The algorithm does not assume any special hardware or + operating system support, e.g., for forwarding pointers or + protection traps. The algorithm copies objects, so it naturally + supports compaction and reclustering. + +* .. _HMMM97: + + Richard L. Hudson, Ron Morrison, J. Eliot B. Moss, David S. Munro. 1997. "`Garbage Collecting the World: One Car at a Time `_". ACM. Proc. OOPSLA 97, pp. 162--175. + + .. admonition:: Abstract + + A new garbage collection algorithm for distributed object systems, + called DMOS (Distributed Mature Object Space), is presented. It is + derived from two previous algorithms, MOS (Mature Object Space), + sometimes called the train algorithm, and PMOS (Persistent Mature + Object Space). The contribution of DMOS is that it provides the + following unique combination of properties for a distributed + collector: safety, completeness, non-disruptiveness, + incrementality, and scalability. Furthermore, the DMOS collector + is non-blocking and does not use global tracing. + +* .. _JOHNSTONE97: + + Mark S. Johnstone. 1997. "`Non-Compacting Memory Allocation and Real-Time Garbage Collection `_". University of Texas at Austin. + + .. admonition:: Abstract + + Dynamic memory use has been widely recognized to have profound + effects on program performance, and has been the topic of many + research studies over the last forty years. In spite of years of + research, there is considerable confusion about the effects of + dynamic memory allocation. Worse, this confusion is often + unrecognized, and memory allocators are widely thought to be + fairly well understood. + + In this research, we attempt to clarify many issues for both + manual and automatic non-moving memory management. We show that + the traditional approaches to studying dynamic memory allocation + are unsound, and develop a sound methodology for studying this + problem. We present experimental evidence that fragmentation costs + are much lower than previously recognized for most programs, and + develop a framework for understanding these results and enabling + further research in this area. For a large class of programs using + well-known allocation policies, we show that fragmentation costs + are near zero. We also study the locality effects of memory + allocation on programs, a research area that has been almost + completely ignored. We show that these effects can be quite + dramatic, and that the best allocation policies in terms of + fragmentation are also among the best in terms of locality at both + the cache and virtual memory levels of the memory hierarchy. + + We extend these fragmentation and locality results to real-time + garbage collection. We have developed a hard real-time, + non-copying generational garbage collector which uses a + write-barrier to coordinate collection work only with + modifications of pointers, therefore making coordination costs + cheaper and more predictable than previous approaches. We combine + this write-barrier approach with implicit non-copying reclamation, + which has most of the advantages of copying collection (notably + avoiding both the sweep phase required by mark-sweep collectors, + and the referencing of garbage objects when reclaiming their + space), without the disadvantage of having to actually copy the + objects. In addition, we present a model for non-copying + implicit-reclamation garbage collection. We use this model to + compare and contrast our work with that of others, and to discuss + the tradeoffs that must be made when developing such a garbage + collector. + +* .. _JW98: + + Mark S. Johnstone, Paul R. Wilson. 1998. "`The Memory Fragmentation Problem: Solved? `_". ACM. ISMM'98 pp. 26--36. + + .. admonition:: Abstract + + We show that for 8 real and varied C and C++ programs, several + conventional dynamic storage allocators provide near-zero + fragmentation, once overheads due to implementation details + (headers, alignment, etc.) are properly accounted for. This + substantially strengthens our previous results showing that the + memory fragmentation problem has generally been misunderstood, and + that good allocator policies can provide good memory usage for + most programs. The new results indicate that for most programs, + excellent allocator policies are readily available, and efficiency + of implementation is the major challenge. While we believe that + our experimental results are state-of-the-art and our methodology + is superior to most previous work, more work should be done to + identify and study unusual problematic program behaviors not + represented in our sample. + +* .. _JONES92: + + Richard E. Jones. 1992. "`Tail recursion without space leaks `_". *Journal of Functional Programming.* 2(1):73--79. + + .. admonition:: Abstract + + The G-machine is a compiled graph reduction machine for lazy + functional languages. The G-machine compiler contains many + optimisations to improve performance. One set of such + optimisations is designed to improve the performance of tail + recursive functions. Unfortunately the abstract machine is subject + to a space leak--objects are unnecessarily preserved by the + garbage collector. + + This paper analyses why a particular form of space leak occurs in + the G-machine, and presents some ideas for fixing this problem. + This phenomena in other abstract machines is also examined + briefly. + +* .. _JL92: + + Richard E. Jones, Rafael Lins. 1992. "`Cyclic weighted reference counting without delay `_". Computing Laboratory, The University of Kent at Canterbury. Technical Report 28-92. + + .. admonition:: Abstract + + Weighted Reference Counting is a low-communication distributed + storage reclamation scheme for loosely-coupled multiprocessors. + The algorithm we present herein extends weighted reference + counting to allow the collection of cyclic data structures. To do + so, the algorithm identifies candidate objects that may be part of + cycles and performs a tricolour mark-scan on their subgraph in a + lazy manner to discover whether the subgraph is still in use. The + algorithm is concurrent in the sense that multiple useful + computation processes and garbage collection processes can be + performed simultaneously. + +* .. _JONES96: + + Richard E. Jones, Rafael Lins. 1996. "`Garbage Collection: Algorithms for Automatic Dynamic Memory Management `_". Wiley. ISBN 0-471-94148-4. + + .. admonition:: From the back cover + + The memory storage requirements of complex programs are extremely + difficult to manage correctly by hand. A single error may lead to + indeterminate and inexplicable program crashes. Worse still, + failures are often unrepeatable and may surface only long after + the program has been delivered to the customer. The eradication of + memory errors typically consumes a substantial amount of + development time. And yet the answer is relatively easy -- garbage + collection; removing the clutter of memory management from module + interfaces, which then frees the programmer to concentrate on the + problem at hand rather than low-level book-keeping details. For + this reason, most modern object-oriented languages such as + Smalltalk, Eiffel, Java and Dylan, are supported by garbage + collection. Garbage collecting libraries are even available for + such uncooperative languages as C and C++. + + This book considers how dynamic memory can be recycled + automatically to guarantee error-free memory management. There is + an abundant but disparate literature on the subject, largely + confined to research papers. This book sets out to pool this + experience in a single accessible and unified framework. + + Each of the important algorithms is explained in detail, often + with illustrations of its characteristic features and animations + of its use. Techniques are described and compared for declarative + and imperative programming styles, for sequential, concurrent and + distributed architectures. + + For professionals developing programs from simple software tools + to complex systems, as well as for researchers and students + working in compiler construction, functional, logic and + object-oriented programming design, this book will provide not + only a clear introduction but also a convenient reference source + for modern garbage collection techniques. + +* .. _ACM98: + + Richard E. Jones. 1998. "`ISMM'98 International Symposium on Memory Management `_". ACM. ISBN 1-58113-114-3. + + .. admonition:: From the Preface + + The International Symposium on Memory Management is a forum for + research in several related areas of memory management, especially + garbage collectors and dynamic storage allocators. [...] The + nineteen papers selected for publication in this volume cover a + remarkably broad range of memory management topics from explicit + malloc-style allocation to automatic memory management, from + cache-conscious data layout to efficient management of distributed + references, from conservative to type-accurate garbage collection, + for applications ranging from user application to long-running + servers, supporting languages as different as C, C++, Modula-3, + Java, Eiffel, Erlang, Scheme, ML, Haskell and Prolog. + +* .. _JONES12: + + Richard E. Jones, Antony Hosking, and Eliot Moss. 2012. "`The Garbage Collection Handbook `_". Chapman & Hall. + +* .. _JOYNER96: + + Ian Joyner. 1996. "`C++??: A Critique of C++ `_.". + + .. admonition:: Abstract + + The C++?? Critique is an analysis of some of the flaws of C++. It + is by no means exhaustive, nor does it attempt to document every + little niggle with C++, rather concentrating on main themes. The + critique uses Java and Eiffel as comparisons to C++ to give a more + concrete feel to the criticisms, viewing conceptual differences + rather than syntactic ones as being more important. Some C++ + authors realising there are glaring deficiencies in C++ have + chosen to defend C++ by also being critical within their own work. + Most notable are Bjarne Stroustup's "Design and Evolution of C++," + and Scott Meyers' "Effective" and "More Effective C++." These warn + of many traps and pitfalls, but reach the curious conclusion that + since "good" C++ programmers are aware of these problems and know + how to avoid them, C++ is alright. + + The C++ critique makes many of the same criticisms, but comes to + the different conclusion that these pitfalls are not acceptable, + and should not be in a language used for modern large scale + software engineering. Clean design is more important than after + the fact warnings, and it is inconceivable that purchasers of end + user software would tolerate this tactic on the part of vendors. + The critique also takes a look at C, and concludes that many of + the features of C should be left out of modern languages, and that + C is a flawed base for a language. + +* .. _KANEFSKY89: + + Bob Kanefsky. 1989. "`Recursive Memory Allocation `_". Bob Kanefsky. Songworm 3, p.?. + +* .. _KQH98: + + Jin-Soo Kim, Xiaohan Qin, Yarsun Hsu. 1998. "`Memory Characterization of a Parallel Data Mining Workload `_". IEEE. Proc. Workload Characterization: Methodology and Case Studies, pp. . + + .. admonition:: Abstract + + This paper studies a representative of an important class of + emerging applications, a parallel data mining workload. The + application, extracted from the IBM Intelligent Miner, identifies + groups of records that are mathematically similar based on a + neural network model called self-organizing map. We examine and + compare in details two implementations of the application: + (1) temporal locality or working set sizes; (2) spatial locality + and memory block utilization; (3) communication characteristics + and scalability; and (4) TLB performance. + + First, we find that the working set hierarchy of the application + is governed by two parameters, namely the size of an input record + and the size of prototype array; it is independent of the number + of input records. Second, the application shows good spatial + locality, with the implementation optimized for sparse data sets + having slightly worse spatial locality. Third, due to the batch + update scheme, the application bears very low communication. + Finally, a 2-way set associative TLB may result in severely skewed + TLB performance in a multiprocessor environment caused by the + large discrepancy in the amount of conflict misses. Increasing the + set associativity is more effective in mitigating the problem than + increasing the TLB size. + +* .. _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. + + .. admonition:: Abstract + + This paper studies the memory system behavior of Java programs by + analyzing memory reference traces of several SPECjvm98 + applications running with a Just-In-Time (JIT) compiler. Trace + information is collected by an exception-based tracing tool called + JTRACE, without any instrumentation to the Java programs or the + JIT compiler.First, we find that the overall cache miss ratio is + increased due to garbage collection, which suffers from higher + cache misses compared to the application. We also note that going + beyond 2-way cache associativity improves the cache miss ratio + marginally. Second, we observe that Java programs generate a + substantial amount of short-lived objects. However, the size of + frequently-referenced long-lived objects is more important to the + cache performance, because it tends to determine the application's + working set size. Finally, we note that the default heap + configuration which starts from a small initial heap size is very + inefficient since it invokes a garbage collector frequently. + Although the direct costs of garbage collection decrease as we + increase the available heap size, there exists an optimal heap + size which minimizes the total execution time due to the + interaction with the virtual memory performance. + +* .. _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. + + .. admonition:: Abstract + + A stable heap is a storage that is managed automatically using + garbage collection, manipulated using atomic transactions, and + accessed using a uniform storage model. These features enhance + reliability and simplify programming by preventing errors due to + explicit deallocation, by masking failures and concurrency using + transactions, and by eliminating the distinction between accessing + temporary storage and permanent storage. Stable heap management is + useful for programming language for reliable distributed + computing, programming languages with persistent storage, and + object-oriented database systems. Many applications that could + benefit from a stable heap (e.g., computer-aided design, + computer-aided software engineering, and office information + systems) require large amounts of storage, timely responses for + transactions, and high availability. We present garbage collection + and recovery algorithms for a stable heap implementation that meet + these goals and are appropriate for stock hardware. The collector + is incremental: it does not attempt to collect the whole heap at + once. The collector is also atomic: it is coordinated with the + recovery system to prevent problems when it moves and modifies + objects . The time for recovery is independent of heap size, and + can be shortened using checkpoints. + +* .. _LK98: + + Per-Åke Larson & Murali Krishnan. 1998. "`Memory Allocation for Long-Running Server Applications `_". ACM. ISMM'98 pp. 176--185. + + .. admonition:: Abstract + + Prior work on dynamic memory allocation has largely neglected + long-running server applications, for example, web servers and + mail servers. Their requirements differ from those of one-shot + applications like compilers or text editors. We investigated how + to build an allocator that is not only fast and memory efficient + but also scales well on SMP machines. We found that it is not + sufficient to focus on reducing lock contention. Only limited + improvement can be achieved this way; higher speedups require a + reduction in cache misses and cache invalidation traffic. We then + designed and prototyped a new allocator, called Lkmalloc, targeted + for both traditional applications and server applications. + LKmalloc uses several subheaps, each one with a separate set of + free lists and memory arena. A thread always allocates from the + same subheap but can free a block belonging to any subheap. A + thread is assigned to a subheap by hashing on its thread ID. We + compared its performance with several other allocators on a + server-like, simulated workload and found that it indeed scales + well and is quite fast but could use memory more efficiently. + +* .. _LH83: + + Henry Lieberman & Carl Hewitt. 1983. "`A real-time garbage collector based on the lifetimes of objects `_". ACM. 26(6):419--429. + + .. admonition:: Abstract + + In previous heap storage systems, the cost of creating objects and + garbage collection is independent of the lifetime of the object. + Since objects with short lifetimes account for a large portion of + storage use, it is worth optimizing a garbage collector to reclaim + storage for these objects more quickly. The garbage collector + should spend proportionately less effort reclaiming objects with + longer lifetimes. We present a garbage collection algorithm that + (1) makes storage for short-lived objects cheaper than storage for + long-lived objects, (2) that operates in real-time--object + creation and access times are bounded, (3) increases locality of + reference, for better virtual memory performance, (4) works well + with multiple processors and a large address space. + +* .. _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 `_". CACM. + + .. admonition:: Abstract + + A programming system called LISP (for LISt Processor) has been + developed for the IBM 704 computer by the Artificial Intelligence + group at M.I.T. The system was designed to facilitate experiments + with a proposed system called the Advice Taker, whereby a machine + could be instructed to handle declarative as well as imperative + sentences and could exhibit "common sense" in carrying out its + instructions. The original proposal for the Advice Taker was made + in November 1958. The main requirement was a programming system + for manipulating expressions representing formalized declarative + and imperative sentences so that the Advice Taker could make + deductions. + + In the course of its development the LISP system went through + several stages of simplification and eventually came to be based + on a scheme for representing the partial recursive functions of a + certain class of symbolic expressions. This representation is + independent of the IBM 704 computer, or of any other electronic + computer, and it now seems expedient to expound the system by + starting with the class of expressions called S-expressions and + the functions called S-functions. + +* .. _MCCARTHY79: + + John McCarthy. 1979. "`History of Lisp `_". In *History of programming languages I*, pp. 173--185. ACM. + +* .. _PTM98: + + Veljko Milutinovic, Jelica Protic, Milo Tomasevic. 1997. "`Distributed shared memory: concepts and systems `_". IEEE Computer Society Press. ISBN 0-8186-7737-6. + + .. admonition:: From the publisher's catalog + + Presents a survey of both distributed shared memory (DSM) efforts + and commercial DSM systems. The book discusses relevant issues + that make the concept of DSM one of the most attractive approaches + for building large-scale, high-performance multiprocessor systems. + Its text provides a general introduction to the DSM field as well + as a broad survey of the basic DSM concepts, mechanisms, design + issues, and systems. + + Distributed Shared Memory concentrates on basic DSM algorithms, + their enhancements, and their performance evaluation. In addition, + it details implementations that employ DSM solutions at the + software and the hardware level. The book is a research and + development reference that provides state-of-the art information + that will be useful to architects, designers, and programmers of + DSM systems. + +* .. _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). + + .. admonition:: Abstract + + This paper presents an algorithm for reclaiming unused free + storage memory cells is LISP. It depends on availability of a fast + secondary storage device, or a large block of available temporary + storage. For this price, we get 1. Packing of free-storage into a + solidly packed block. 2. Smooth packing of arbitrary linear blocks + and arrays. 3. The collector will handle arbitrarily complex + re-entrant list structure with no introduction of spurious copies. + 4. The algorithm is quite efficient; the marking pass visits words + at most twice and usually once, and the loading pass is linear. + 5. The system is easily modified to allow for increase in size of + already fixed consecutive blocks, provide one can afford to + initiate a collection pass or use a modified array while waiting + for such a pass to occur. + +* .. _MOON84: + + David Moon. 1984. "`Garbage Collection in a Large Lisp System `_". ACM. Symposium on Lisp and Functional Programming, August 1984. + + .. admonition:: Abstract + + This paper discusses garbage collection techniques used in a + high-performance Lisp implementation with a large virtual memory, + the Symbolics 3600. Particular attention is paid to practical + issues and experience. In a large system problems of scale appear + and the most straightforward garbage-collection techniques do not + work well. Many of these problems involve the interaction of the + garbage collector with demand-paged virtual memory. Some of the + solutions adopted in the 3600 are presented, including incremental + copying garbage collection, approximately depth-first copying, + ephemeral objects, tagged architecture, and hardware assists. We + discuss techniques for improving the efficiency of garbage + collection by recognizing that objects in the Lisp world have a + variety of lifetimes. The importance of designing the architecture + and the hardware to facilitate garbage collection is stressed. + +* .. _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 `_". ACM. ISMM'98 pp. 57--67. + + .. admonition:: Abstract + + Massively distributed computing is a challenging problem for + garbage collection algorithm designers as it raises the issue of + scalability. The high number of hosts involved in a computation + can require large tables for reference listing, whereas the lack + of information sharing between hosts in a same locality can entail + redundant GC traffic. In this paper, we argue that a conceptual + hierarchical organisation of massive distributed computations can + solve this problem. By conceptual hierarchical organisation, we + mean that processors are still able to communicate in a peer to + peer manner using their usual communication mechanism, but GC + messages will be routed as if processors were organised in + hierarchy. We present an extension of a distributed reference + counting algorithm that uses such a hierarchical organisation. It + allows us to bound table sizes by the number of hosts in a domain, + and it allows us to share GC information between hosts in a same + locality in order to reduce cross-network GC traffic. + +* .. _MFH95: + + Greg Morrisett, Matthias Felleisen, Robert Harper. 1995. "`Abstract Models of Memory Management `_". Carnegie Mellon University. CMU-CS-FOX-95-01. + + .. admonition:: Abstract + + Most specifications of garbage collectors concentrate on the + low-level algorithmic details of how to find and preserve + accessible objects. Often, they focus on bit-level manipulations + such as "scanning stack frames," "marking objects," "tagging + data," etc. While these details are important in some contexts, + they often obscure the more fundamental aspects of memory + management: what objects are garbage and why? + + We develop a series of calculi that are just low-level enough that + we can express allocation and garbage collection, yet are + sufficiently abstract that we may formally prove the correctness + of various memory management strategies. By making the heap of a + program syntactically apparent, we can specify memory actions as + rewriting rules that allocate values on the heap and automatically + dereference pointers to such objects when needed. This formulation + permits the specification of garbage collection as a relation that + removes portions of the heap without affecting the outcome of + evaluation. + + Our high-level approach allows us to specify in a compact manner a + wide variety of memory management techniques, including standard + trace-based garbage collection (i.e., the family of copying and + mark/sweep collection algorithms), generational collection, and + type-based, tag-free collection. Furthermore, since the definition + of garbage is based on the semantics of the underlying language + instead of the conservative approximation of inaccessibility, we + are able to specify and prove the idea that type inference can be + used to collect some objects that are accessible but never used. + +* .. _MBMM99: + + David S. Munro, Alfred Brown, Ron Morrison, J. Eliot B. Moss. 1999. "`Incremental Garbage Collection of a Persistent Object Store using PMOS `_". Morgan Kaufmann. in Advances in Persistent Object Systems, pp. 78--91. + + .. admonition:: Abstract + + PMOS is an incremental garbage collector designed specifically to + reclaim space in a persistent object store. It is complete in that + it will, after a finite number of invocations, reclaim all + unreachable storage. PMOS imposes minimum constraints on the order + of collection and offers techniques to reduce the I/O traffic + induced by the collector. Here we present the first implementation + of the PMOS collector called PMOS#1. The collector has been + incorporated into the stable heap layer of the generic persistent + object store used to support a number of languages including + Napier88. Our main design goals are to maintain the independence + of the language from the store and to retain the existing store + interface. The implementation has been completed and tested using + a Napier88 system. The main results of this work show that the + PMOS collector is implementable in a persistent store and that it + can be built without requiring changes to the language + interpreter. Initial performance measurements are reported. These + results suggest however, that effective use of PMOS requires + greater co-operation between language and store. + +* .. _NOPH92: + + Scott Nettles, James O'Toole, David Pierce, Nickolas Haines. 1992. "`Replication-Based Incremental Copying Collection `_". IWMM'92. + + .. admonition:: Abstract + + We introduce a new replication-based copying garbage collection + technique. We have implemented one simple variation of this method + to provide incremental garbage collection on stock hardware with + no special operating system or virtual memory support. The + performance of the prototype implementation is excellent: major + garbage collection pauses are completely eliminated with only a + slight increase in minor collection pause times. + + Unlike the standard copying algorithm, the replication-based + method does not destroy the original replica when a copy is + created. Instead, multiple copies may exist, and various standard + strategies for maintaining consistency may be applied. In our + implementation for Standard ML of New Jersey, the mutator + continues to use the from-space replicas until the collector has + achieved a consistent replica of all live data in to-space. + + We present a design for a concurrent garbage collector using the + replication-based technique. We also expect replication-based GC + methods to be useful in providing services for persistence and + distribution, and briefly discuss these possibilities. + +* .. _NETTLES92: + + Scott Nettles. 1992. "`A Larch Specification of Copying Garbage Collection `_". Carnegie Mellon University. CMU-CS-92-219. + + .. admonition:: Abstract + + Garbage collection (GC) is an important part of many language + implementations. One of the most important garbage collection + techniques is copying GC. This paper consists of an informal but + abstract description of copying collection, a formal specification + of copying collection written in the Larch Shared Language and the + Larch/C Interface Language, a simple implementation of a copying + collector written in C, an informal proof that the implementation + satisfies the specification, and a discussion of how the + specification applies to other types of copying GC such as + generational copying collectors. Limited familiarity with copying + GC or Larch is needed to read the specification. + +* .. _NO93A: + + Scott Nettles & James O'Toole. 1993. "Implementing Orthogonal Persistence: A Simple Optimization Using Replicating Collection". USENIX. IWOOOS'93. + + .. admonition:: Abstract + + Orthogonal persistence provides a safe and convenient model of + object persistence. We have implemented a transaction system which + supports orthogonal persistence in a garbage-collected heap. In + our system, replicating collection provides efficient concurrent + garbage collection of the heap. In this paper, we show how + replicating garbage collection can also be used to reduce commit + operation latencies in our implementation. + + We describe how our system implements transaction commit. We + explain why the presence of non-persistent objects can add to the + cost of this operation. We show how to eliminate these additional + costs by using replicating garbage collection. The resulting + implementation of orthogonal persistence should provide + transaction performance that is independent of the quantity of + non-persistent data in use. We expect efficient support for + orthogonal persistence to be valuable in operating systems + applications which use persistent data. + +* .. _NO93: + + Scott Nettles & James O'Toole. 1993. "`Real-Time Replication Garbage Collection `_". ACM. PLDI'93. + + .. admonition:: Abstract + + We have implemented the first copying garbage collector that + permits continuous unimpeded mutator access to the original + objects during copying. The garbage collector incrementally + replicates all accessible objects and uses a mutation log to bring + the replicas up-to-date with changes made by the mutator. An + experimental implementation demonstrates that the costs of using + our algorithm are small and that bounded pause times of 50 + milliseconds can be readily achieved. + +* .. _NIELSEN77: + + Norman R. Nielsen. 1977. "Dynamic Memory Allocation in Computer Simulation". ACM. CACM 20:11. + + .. admonition:: Abstract + + This paper investigates the performance of 35 dynamic memory + allocation algorithms when used to service simulation programs as + represented by 18 test cases. Algorithm performance was measured + in terms of processing time, memory usage, and external memory + fragmentation. Algorithms maintaining separate free space lists + for each size of memory block used tended to perform quite well + compared with other algorithms. Simple algorithms operating on + memory ordered lists (without any free list) performed + surprisingly well. Algorithms employing power-of-two block sizes + had favorable processing requirements but generally unfavorable + memory usage. Algorithms employing LIFO, FIFO, or memory ordered + free lists generally performed poorly compared with others. + +* .. _OTOOLE90: + + James O'Toole. 1990. "Garbage Collecting Locally". + + .. admonition:: Abstract + + Generational garbage collection is a simple technique for + automatic partial memory reclamation. In this paper, I present the + basic mechanics of generational collection and discuss its + characteristics. I compare several published algorithms and argue + that fundamental considerations of locality, as reflected in the + changing relative speeds of processors, memories, and disks, + strongly favor a focus on explicit optimization of I/O + requirements during garbage collection. I show that this focus on + I/O costs due to memory hierarchy debunks a well-known claim about + the relative costs of garbage collection and stack allocation. I + suggest two directions for future research in this area and + discuss some simple architectural changes in virtual memory + interfaces which may enable efficient garbage collector + utilization of standard virtual memory hardware. + +* .. _ON94: + + James O'Toole & Scott Nettles. 1994. "`Concurrent Replicating Garbage Collection `_". ACM. LFP'94. + + .. admonition:: Abstract + + We have implemented a concurrent copying garbage collector that + uses replicating garbage collection. In our design, the client can + continuously access the heap during garbage collection. No + low-level synchronization between the client and the garbage + collector is required on individual object operations. The garbage + collector replicates live heap objects and periodically + synchronizes with the client to obtain the client's current root + set and mutation log. An experimental implementation using the + Standard ML of New Jersey system on a shared-memory multiprocessor + demonstrates excellent pause time performance and moderate + execution time speedups. + +* .. _JRR99: + + Simon Peyton Jones, Norman Ramsey, Fermin Reig. 1999. "`C--: a portable assembly language that supports garbage collection `_". Springer-Verlag. International Conference on Principles and Practice of Declarative Programming 1999, LNCS 1702, pp. 1--28. + + .. admonition:: Abstract + + For a compiler writer, generating good machine code for a variety + of platforms is hard work. One might try to reuse a retargetable + code generator, but code generators are complex and difficult to + use, and they limit one's choice of implementation language. One + might try to use C as a portable assembly language, but C limits + the compiler writer's flexibility and the performance of the + resulting code. The wide use of C, despite these drawbacks, argues + for a portable assembly language. C-- is a new language designed + expressly for this purpose. The use of a portable assembly + language introduces new problems in the support of such high-level + run-time services as garbage collection, exception handling, + concurrency, profiling, and debugging. We address these problems + by combining the C-- language with a C-- run-time interface. The + combination is designed to allow the compiler writer a choice of + source-language semantics and implementation techniques, while + still providing good performance. + +* .. _PIEPER93: + + John S. Pieper. 1993. "Compiler Techniques for Managing Data Motion". Carnegie Mellon University. Technical report number CMU-CS-93-217. + + .. admonition:: Abstract + + Software caching, automatic algorithm blocking, and data overlays + are different names for the same problem: compiler management of + data movement throughout the memory hierarchy. Modern + high-performance architectures often omit hardware support for + moving data between levels of the memory hierarchy: iWarp does not + include a data cache, and Cray supercomputers do not have virtual + memory. These systems have effectively traded a more complicated + programming model for performance by replacing a + hardware-controlled memory hierarchy with a simple fast memory. + The simpler memories have less logic in the critical path, so the + cycle time of the memories is improved. + + For programs which fit in the resulting memory, the extra + performance is great. Unfortunately, the driving force behind + supercomputing today is a class of very large scientific problems, + both in terms of computation time and in terms of the amount of + data used. Many of these programs do not fit in the memory of the + machines available. When architects trade hardware support for + data migration to gain performance, control of the memory + hierarchy is left to the programmer. Either the program size must + be cut down to fit into the machine, or every loop which accesses + more data than will fit into memory must be restructured by hand. + This thesis describes how a compiler can relieve the programmer of + this burden, and automate data motion throughout the memory + hierarchy without direct hardware support. + + This works develops a model of how data is accessed within a + nested loop by typical scientific programs. It describes + techniques which can be used by compilers faced with the task of + managing data motion. The concentration is on nested loops which + process large data arrays using linear array subscripts. Because + the array subscripts are linear functions of the loop indices and + the loop indices form an integer lattice, linear algebra can be + applied to solve many compilation problems. + + The approach it to tile the iteration space of the loop nest. + Tiling allows the compiler to improve locality of reference. The + tiling basis matrix is chosen from a set of candidate vectors + which neatly divide the data set. The execution order of the tiles + is selected to maximize locality between tiles. Finally, the tile + sizes are chosen to minimize execution time. + + The approach has been applied to several common scientific loop + nests: matrix-matrix multiplication, QR-decomposition, and + LU-decomposition. In addition, an illustrative example from the + Livermore Loop benchmark set is examined. Although more compiler + time can be required in some cases, this technique produces better + code at no cost for most programs. + +* .. _PIRINEN98: + + Pekka P. Pirinen. 1998. "Barrier techniques for incremental tracing". ACM. ISMM'98 pp. 20--25. + + .. admonition:: Abstract + + This paper presents a classification of barrier techniques for + interleaving tracing with mutator operation during an incremental + garbage collection. The two useful tricolour invariants are + derived from more elementary considerations of graph traversal. + Barrier techniques for maintaining these invariants are classified + according to the action taken at the barrier (such as scanning an + object or changing its colour), and it is shown that the + algorithms described in the literature cover all the possibilities + except one. Unfortunately, the new technique is impractical. Ways + of combining barrier techniques are also discussed. + +* .. _PRINTEZIS96: + + Tony Printezis. 1996. "Disk Garbage Collection Strategies for Persistent Java". Proceedings of the First International Workshop on Persistence and Java. + + .. admonition:: Abstract + + This paper presents work currently in progress on Disk Garbage + Collection issues for PJava, an orthogonally persistent version of + Java. In particular, it concentrates on the initial Prototype of + the Disk Garbage Collector of PJava0 which has already been + implemented. This Prototype was designed to be very simple and + modular in order to be easily changed, evolved, improved, and + allow experimentation. Several experiments were performed in order + to test possible optimisations; these experiments concentrated on + the following four areas: a) efficient access to the store; b) + page-replacement algorithms; c) efficient discovery of live + objects during compaction; and d) dealing with forward references. + The paper presents a description of the Prototype's architecture, + the results of these experiments and related discussion, and some + future directions based on the experience gained from this work. + +* .. _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 `_". Laboratory for Computer Science at MIT. MIT/LCS/TR-581. + + .. admonition:: Abstract + + As processor speeds continue to improve relative to main-memory + access times, cache performance is becoming an increasingly + important component of program performance. Prior work on the + cache performance of garbage-collected programming languages has + either assumed or argued that conventional garbage-collection + methods will yield poor performance, and has therefore + concentrated on new collection algorithms designed specifically to + improve cache-level reference locality. This dissertation argues + to the contrary: Many programs written in garbage-collected + languages are naturally well-suited to the direct-mapped caches + typically found in modern computer systems. + + Using a trace-driven cache simulator and other analysis tools, + five nontrivial, long-running Scheme programs are studied. A + control experiment shows that the programs have excellent cache + performance without any garbage collection at all. A second + experiment indicates that the programs will perform well with a + simple and infrequently-run generational compacting collector. + + An analysis of the test programs' memory usage patterns reveals + that the mostly-functional programming style typically used in + Scheme programs, in combination with simple linear storage + allocation, causes most data objects to be dispersed in time and + space so that references to them cause little cache interference. + From this it follows that other Scheme programs, and programs + written in similar styles in different languages, should perform + well with a simple generational compacting collector; + sophisticated collectors intended to improve cache performance are + unlikely to be effective. The analysis also suggests that, as + locality becomes ever more important to program performance, + programs written in garbage-collected languages may turn out to + have significant performance advantage over programs written in + more conventional languages. + +* .. _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. + + .. admonition:: Abstract + + It is well accepted that automatic garbage collection simplifies + programming, promotes modularity, and reduces development effort. + However it is commonly believed that these advantages do not + counteract the perceived price: excessive overheads, possible long + pause times while garbage collections occur, and the need to + modify existing code. Even though there are publically available + garbage collector implementations that can be used in existing + programs, they do not guarantee short pauses, and some + modification of the application using them is still required. In + this paper we describe a snapshot-at-beginning concurrent garbage + collector algorithm and its implementation. This algorithm + guarantees short pauses, and can be easily implemented on stock + UNIX-like operating systems. Our results show that our collector + performs comparable to other garbage collection implementations on + uniprocessor machines and outperforms similar collectors on + multiprocessor machines. We also show our collector to be + competitive in performance with explicit deallocation. Our + collector has the added advantage of being non-intrusive. Using a + dynamic linking technique and effective root set inferencing, we + have been able to successfully run our collector even in + commercial programs where only the binary executable and no source + code is available. In this paper we describe our algorithm, its + implementation, and provide both an algorithmic and a performance + comparison between our collector and other similar garbage + collectors. + +* .. _ROJEMO95: + + Niklas Röjemo. 1995. "Highlights from nhc -- a space-efficient Haskell compiler". Chalmers University of Technology. + + .. admonition:: Abstract + + Self-compiling implementations of Haskell, i.e., those written in + Haskell, have been and, except one, are still space consuming + monsters. Object code size for the compilers themselves are 3-8Mb, + and they need 12-20Mb to recompile themselves. One reason for the + huge demands for memory is that the main goal for these compilers + is to produce fast code. However, the compiler described in this + paper, called "nhc" for "Nearly a Haskell Compiler", is the one + above mentioned exception. This compiler concentrates on keeping + memory usage down, even at a cost in time. The code produced is + not fast, but nhc is usable, and the resulting programs can be run + on computers with small memory. + + This paper describes some of the implementation choices done, in + the Haskell part of the source code, to reduce memory consumption + in nhc. It is possible to use these also in other Haskell + compilers with no, or very small, changes to their run-time + systems. + + Time is neither the main focus of nhc nor of this paper, but there + is nevertheless a small section about the speed of nhc. The most + notable observation concerning speed is that nhc spends + approximately half the time processing interface files, which is + much more than needed in the type checker. Processing interface + files is also the most space consuming part of nhc in most cases. + It is only when compiling source files with large sets of mutually + recursive functions that more memory is needed to type check than + to process interface files. + +* .. _ROJEMO95A: + + Niklas Röjemo. 1995. "Generational garbage collection for lazy functional languages without temporary space leaks". Chalmers University of Technology. + + .. admonition:: Abstract + + Generational garbage collection is an established method for + creating efficient garbage collectors. Even a simple + implementation where all nodes that survive one garbage collection + are *tenured*, i.e., moved to an old generation, works well in + strict languages. In lazy languages, however, such an + implementation can create severe *temporary space leaks*. The + temporary space leaks appear in programs that traverse large + lazily built data structures, e.g., a lazy list representing a + large file, where only a small part is needed at any time. A + simple generational garbage collector cannot reclaim the memory, + used by the lazily built list, at minor collections. The reason is + that at least one of the nodes in the list belongs to the old + generation, after the first minor collection, and will hold on to + the rest of the nodes in the list until the next major collection. + +* .. _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. + + .. admonition:: Abstract + + The context for this paper is functional computation by graph + reduction. Our overall aim is more efficient use of memory. The + specific topic is the detection of dormant cells in the live graph + -- those retained in heap memory though not actually playing a + useful role in computation. We describe a profiler that can + identify heap consumption by such 'useless' cells. Unlike heap + profilers based on traversals of the live heap, this profiler + works by examining cells post-mortem. The new profiler has + revealed a surprisingly large proportion of 'useless' cells, even + in some programs that previously seemed space-efficient such as + the bootstrapping Haskell compiler "nhc". + +* .. _RW99: + + David J. Roth, David S. Wise. 1999. "`One-bit counts between unique and sticky `_". ACM. ISMM'98, pp. 49--56. + + .. admonition:: Abstract + + Stoye's one-bit reference tagging scheme can be extended to local + counts of two or more via two strategies. The first, suited to + pure register transactions, is a cache of referents to two shared + references. The analog of Deutch's and Bobrow's multiple-reference + table, this cache is sufficient to manage small counts across + successive assignment statements. Thus, accurate reference counts + above one can be tracked for short intervals, like that bridging + one function's environment to its successor's. + + The second, motivated by runtime stacks that duplicate references, + avoids counting any references from the stack. It requires a local + pointer-inversion protocol in the mutator, but one still local to + the referent and the stack frame. Thus, an accurate reference + count of one can be maintained regardless of references from the + recursion stack. + +* .. _ROVNER85: + + Paul Rovner. 1985. "`On Adding Garbage Collection and Runtime Types to a Strongly-Typed, Statically-Checked, Concurrent Language `_". Xerox PARC. TR CSL-84-7. + + .. admonition:: Abstract + + Enough is known now about garbage collection, runtime types, + strong-typing, static-checking and concurrency that it is possible + to explore what happens when they are combined in a real + programming system. + + Storage management is one of a few central issues through which + one can get a good view of the design of an entire system. + Tensions between ease of integration and the need for protection; + between generality, simplicity, flexibility, extensibility and + efficiency are all manifest when assumptions and attitudes about + managing storage are studied. And deep understanding follows best + from the analysis of systems that people use to get real work + done. + + This paper is not for those who seek arguments pro or con about + the need for these features in programming systems; such issues + are for other papers. This one assumes these features to be good + and describes how they combine and interact in Cedar, a + programming language and environment designed to help programmers + build moderate-sized experimental systems for moderate numbers of + people to test and use. + +* .. _RUNCIMAN92: + + Colin Runciman & David Wakeling. 1992. "`Heap Profiling of Lazy Functional Programs `_". University of York. + + .. admonition:: Abstract + + We describe the design, implementation, and use of a new kind of + profiling tool that yields valuable information about the memory + use of lazy functional programs. The tool has two parts: a + modified functional language implementation which generated + profiling implementation during the execution of programs, and a + separate program which converts this information to graphical + form. With the aid of profile graphs, one can make alterations to + a functional program which dramatically reduce its space + consumption. We demonstrate that this is the case of a genuine + example -- the first to which the tool has been applied -- for + which the results are strikingly successful. + +* .. _RR94: + + Colin Runciman & Niklas Röjemo. 1994. "`New dimensions in heap profiling `_". University of York. + + .. admonition:: Abstract + + First-generation heap profilers for lazy functional languages have + proved to be effective tools for locating some kinds of space + faults, but in other cases they cannot provide sufficient + information to solve the problem. This paper describes the design, + implementation and use of a new profiler that goes beyond the + two-dimensional "who produces what" view of heap cells to provide + information about their more dynamic and structural attributes. + Specifically, the new profiler can distinguish between cells + according to their *eventual lifetime*, or on the basis of the + *closure retainers* by virtue of which they remain part of the + live heap. A bootstrapping Haskell compiler (nhc) hosts the + implementation: among examples of the profiler's use we include + self-application to nhc. Another example is the original + heap-profiling case study "clausify", which now consumes even less + memory and is much faster. + +* .. _RR96A: + + Colin Runciman & Niklas Röjemo. 1996. "Two-pass heap profiling: a matter of life and death". Department of Computer Science, University of York. + + .. admonition:: Abstract + + A heap profile is a chart showing the contents of heap memory + throughout a computation. Contents are depicted abstractly by + showing how much space is occupied by memory cells in each of + several classes. A good heap profiler can use a variety of + attributes of memory cells to de-fine a classification. Effective + profiling usually involves a combination of attributes. The ideal + profiler gives full support for combination in two ways. First, a + section of the heap of interest to the programmer can be specified + by constraining the values of any combination of cell attributes. + Secondly, no matter what attributes are used to specify such a + section, a heap profile can be obtained for that section only, and + any other attribute can be used to define the classification. + + Achieving this ideal is not simple For some combinations of + attributes. A heap profile is derived by interpolation of a series + of censuses of heap contents at different stages. The obvious way + to obtain census data is to traverse the live heap at intervals + throughout the computation. This is fine for static attributes + (e.g. What type of value does this memory cell represent?), and + for dynamic attributes that can be determined for each cell by + examining the heap at any given moment (e.g. From which function + closures can this cell be reached?). But some attributes of cells + can only be determined retrospectively by post-mortem inspection + asa cell is overwritten or garbage-collected (e.g. Is this cell + ever used again?). Now we see the problem: if a profiler supports + both live and pose-mortem attributes, how can we implement the + ideal of unrestricted combinations? That is the problem me solve + in this paper. We give techniques for profiling a. heap section + specified in terms of both live and post-mortem attributes. We + show how to generate live-attribute profiles of a section of the + heal, specified using post-mortem attributes, and vice versa. + +* .. _SG95: + + Jacob Seligmann & Steffen Grarup. 1995. "`Incremental Mature Garbage Collection Using the Train Algorithm `_". Springer-Verlag. ECOOP'95, Lecture Notes in Computer Science, Vol. 952, pp. 235--252, ISBN 3-540-60160-0. + + .. admonition:: Abstract + + We present an implementation of the Train Algorithm, an + incremental collection scheme for reclamation of mature garbage in + generation-based memory management systems. To the best of our + knowledge, this is the first Train Algorithm implementation ever. + Using the algorithm, the traditional mark-sweep garbage collector + employed by the Mjølner run-time system for the + object-oriented BETA programming language was replaced by a + non-disruptive one, with only negligible time and storage + overheads. + +* .. _SB00: + + Manuel Serrano, Hans-J. Boehm. 2000. "`Understanding memory allocation of Scheme programs `_". ACM. Proceedings of International Conference on Functional Programming 2000. + + .. admonition:: Abstract + + Memory is the performance bottleneck of modern architectures. + Keeping memory consumption as low as possible enables fast and + unobtrusive applications. But it is not easy to estimate the + memory use of programs implemented in functional languages, due to + both the complex translations of some high level constructs, and + the use of automatic memory managers. To help understand memory + allocation behavior of Scheme programs, we have designed two + complementary tools. The first one reports on frequency of + allocation, heap configurations and on memory reclamation. The + second tracks down memory leaks. We have applied these tools to + our Scheme compiler, the largest Scheme program we have been + developing. This has allowed us to drastically reduce the amount + of memory consumed during its bootstrap process, without requiring + much development time. Development tools will be neglected unless + they are both conveniently accessible and easy to use. In order to + avoid this pitfall, we have carefully designed the user interface + of these two tools. Their integration into a real programming + environment for Scheme is detailed in the paper. + +* .. _SHAPIRO94: + + Marc Shapiro & Paulo Ferreira. 1994. "`Larchant-RDOSS: a distributed shared persistent memory and its garbage collector `_". INRIA. INRIA Rapport de Recherche no. 2399; Cornell Computer Science TR94-1466. + + .. admonition:: Abstract + + Larchant-RDOSS is a distributed shared memory that persists on + reliable storage across process lifetimes. Memory management is + automatic: including consistent caching of data and of locks, + collecting objects unreachable from the persistent root, writing + reachable objects to disk, and reducing store fragmentation. + Memory management is based on a novel garbage collection + algorithm, that approximates a global trace by a series of local + traces, with no induced I/O or locking traffic, and no + synchronization between the collector and the application + processes. This results in a simple programming model, and + expected minimal added application latency. The algorithm is + designed for the most unfavorable environment (uncontrolled + programming language, reference by pointers, distributed system, + non-coherent shared memory) and should work well also in more + favorable settings. + +* .. _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 `_". University of Texas at Austin. + + .. admonition:: Abstract + + Texas is a persistent storage system for C++, providing high + performance while emphasizing simplicity, modularity and + portability. A key component of the design is the use of pointer + swizzling at page fault time, which exploits existing virtual + memory features to implement large address spaces efficiently on + stock hardware, with little or no change to existing compilers. + Long pointers are used to implement an enormous address space, but + are transparently converted to the hardware-supported pointer + format when pages are loaded into virtual memory. + + Runtime type descriptors and slightly modified heap allocation + routines support pagewise pointer swizzling by allowing objects + and their pointer fields to be identified within pages. If + compiler support for runtime type identification is not available, + a simple preprocessor can be used to generate type descriptors. + + This address translation is largely independent of issues of data + caching, sharing, and checkpointing; it employs operating systems' + existing virtual memories for caching, and a simple and flexible + log-structured storage manager to improve checkpointing + performance. + + Pagewise virtual memory protections are also used to detect writes + for logging purposes, without requiring any changes to compiled + code. This may degrade checkpointing performance for small + transactions with poor locality of writes, but page diffing and + sub-page logging promise to keep performance competitive with + finer-grained checkpointing schemes. + + Texas presents a simple programming interface; an application + creates persistent objects by simply allocating them on the + persistent heap. In addition, the implementation is relatively + small, and is easy to incorporate into existing applications. The + log-structured storage module easily supports advanced extensions + such as compressed storage, versioning, and adaptive + reorganization. + +* .. _SOBALVARRO88: + + P. G. Sobalvarro. 1988. "`A Lifetime-based Garbage Collector for LISP Systems on General-Purpose Computers `_". MIT. AITR-1417. + + .. admonition:: Abstract + + Garbage collector performance in LISP systems on custom hardware has been substantially improved by the adoption of lifetime-based garbage collection techniques. To date, however, successful lifetime-based garbage collectors have required special-purpose hardware, or at least privileged access to data structures maintained by the virtual memory system. I present here a lifetime-based garbage collector requiring no special-purpose hardware or virtual memory system support, and discuss its performance. + +* .. _STEELE75: + + Guy L. Steele. 1975. "Multiprocessing Compactifying Garbage Collection". CACM. 18:9 pp. 495--508. + + .. admonition:: Abstract + + Algorithms for a multiprocessing compactifying garbage collector + are presented and discussed. The simple case of two processors, + one performing LISP-like list operations and the other performing + garbage collection continuously, is thoroughly examined. The + necessary capabilities of each processor are defined, as well as + interprocessor communication and interlocks. Complete procedures + for garbage collection and for standard list processing primitives + are presented and thoroughly explained. Particular attention is + given to the problems of marking and relocating list cells while + another processor may be operating on them. The primary aim + throughout is to allow the list processor to run unimpeded while + the other processor reclaims list storage The more complex case + involving several list processors and one or more garbage + collection processors are also briefly discussed. + +* .. _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 420. + + .. admonition:: Abstract + + The internal representations of the various MacLISP data types are + presented and discussed. Certain implementation tradeoffs are + considered. The ultimate decisions on these tradeoffs are + discussed in the light of MacLISP's prime objective of being an + efficient high-level language for the implementation of large + systems such as MACSYMA. The basic strategy of garbage collection + is outlined, with reference to the specific representations + involved. Certain "clever tricks" are explained and justified. The + "address space crunch" is explained and some alternative solutions + explored. + +* .. _SLC99: + + James M. Stichnoth, Guei-Yuan Lueh, Michal Cierniak. 1999. "`Support for Garbage Collection at Every Instruction in a Java Compiler `_". SIGPLAN. Proceedings of the 1999 ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI). SIGPLAN Notices 34(5). pp. 118--127. + + .. admonition:: Abstract + + A high-performance implementation of a Java Virtual Machine + requires a compiler to translate Java bytecodes into native + instructions, as well as an advanced garbage collector (e.g., + copying or generational). When the Java heap is exhausted and the + garbage collector executes, the compiler must report to the + garbage collector all live object references contained in physical + registers and stack locations. Typical compilers only allow + certain instructions (e.g., call instructions and backward + branches) to be GC-safe; if GC happens at some other instruction, + the compiler may need to advance execution to the next GC-safe + point. Until now, no one has ever attempted to make every + compiler-generated instruction GC-safe, due to the perception that + recording this information would require too much space. This kind + of support could improve the GC performance in multithreaded + applications. We show how to use simple compression techniques to + reduce the size of the GC map to about 20% of the generated code + size, a result that is competitive with the best previously + published results. In addition, we extend the work of Agesen, + Detlefs, and Moss, regarding the so-called “JSR Problem” (the + single exception to Java’s type safety property), in a way that + eliminates the need for extra runtime overhead in the generated + code. + +* .. _SCN84: + + Will R Stoye, T J W Clarke, Arthur C Norman. 1984. "Some Practical Methods for Rapid Combinator Reduction". In LFP 1984, 159--166. + + .. admonition:: Abstract + + The SKIM II processor is a microcoded hardware machine for the + rapid evaluation of functional languages. This paper gives details + of some of the more novel methods employed by SKIM II, and + resulting performance measurements. The authors conclude that + combinator reduction can still form the basis for the efficient + implementation of a functional language. + +* .. _TD95: + + David Tarditi & Amer Diwan. 1995. "`Measuring the Cost of Storage Management `_". Carnegie Mellon University. CMU-CS-94-201. + + .. admonition:: Abstract + + We study the cost of storage management for garbage-collected + programs compiled with the Standard ML of New Jersey compiler. We + show that the cost of storage management is not the same as the + time spent garbage collecting. For many of the programs, the time + spent garbage collecting is less than the time spent doing other + storage-management tasks. + +* .. _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. + + .. admonition:: Abstract + + Shared environment closure reducers such as Fairbairn and Wray's + TIM incur a comparatively low cost when creating a suspension, and + so provide an elegant method for implementing lazy functional + evaluation. However, comparatively little attention has been given + to the problems involved in identifying which portions of a shared + environment are needed (and ignoring those which are not) during a + garbage collection. Proper consideration of this issue has subtle + consequences when implementing a storage manager in a TIM-like + system. We describe the problem and illustrate the negative + consequences of ignoring it. + + We go on to describe a solution in which the compiler determines + statically which portions of that code's environment are required + for each piece of code it generates, and emits information to + assist the run-time storage manager to scavenge environments + selectively. We also describe a technique for expressing this + information directly as executable code, and demonstrate that a + garbage collector implemented in this way can perform + significantly better than an equivalent, table-driven interpretive + collector. + +* .. _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. + + .. admonition:: Abstract + + Implementations of abstract machines such as the OP-TIM and the + PG-TIM need to use a tailored garbage collector which seems to + require an auxiliary stack,with a potential maximum size that is + directly proportional to the amount of live data in the heap. + However, it turns out that it is possible to build a recursive + copying collector that does not require additional space by + reusing already-scavenged space. This paper is a description of + this technique. + +* .. _TT97: + + Mads Tofte & Jean-Pierre Talpin. 1997. "`Region-Based Memory Management `_". Information and Computation 132(2), pp. 109--176. + + .. admonition:: Abstract + + This paper describes a memory management discipline for programs + that perform dynamic memory allocation and de-allocation. At + runtime, all values are put into regions. The store consists of a + stack of regions. All points of region allocation and + de-allocation are inferred automatically, using a type and effect + based program analysis. The scheme does not assume the presence of + a garbage collector. The scheme was first presented in 1994 (M. + Tofte and J.-P. Talpin, in *Proceedings of the 21st ACM + SIGPLAN-SIGACT Symposium on Principles of Programming Languages,* + pp. 188--201); subsequently, it has been tested in the ML Kit with + Regions, a region-based, garbage-collection free implementation of + the Standard ML Core Language, which includes recursive datatypes, + higher-order functions and updatable references (L. Birkedal, M. + Tofte, and M. Vejlstrup, (1996), in *Proceedings of the 23rd ACM + SIGPLAN-SIGACT Symposium on Principles of Programming Languages,* + pp. 171--183). This paper defines a region-based dynamic semantics + for a skeletal programming language extracted from Standard ML. We + present the inference system which specifies where regions can be + allocated and de-allocated and a detailed proof that the system is + sound with respect to a standard semantics. We conclude by giving + some advice on how to write programs that run well on a stack of + regions, based on practical experience with the ML Kit. + +* .. _UNGAR84: + + Dave Ungar. 1984. "`Generation Scavenging: A Non-disruptive High Performance Storage Reclamation Algorithm `_". ACM, SIGSOFT, SIGPLAN. Practical Programming Environments Conference. + + .. admonition:: Abstract + + Many interactive computing environments provide automatic storage + reclamation and virtual memory to ease the burden of managing + storage. Unfortunately, many storage reclamation algorithms impede + interaction with distracting pauses. *Generation Scavenging* is a + reclamation algorithm that has no noticeable pauses, eliminates + page faults for transient objects, compacts objects without + resorting to indirection, and reclaims circular structures, in one + third the time of traditional approaches. + +* .. _UNGAR88: + + Dave Ungar & Frank Jackson. 1988. "`Tenuring Policies for Generation-Based Storage Reclamation `_". SIGPLAN. OOPSLA '88 Conference Proceedings, ACM SIGPLAN Notices, Vol. 23, No. 11, pp. 1--17. + + .. admonition:: Abstract + + One of the most promising automatic storage reclamation + techniques, generation-based storage reclamation, suffers poor + performance if many objects live for a fairly long time and then + die. We have investigated the severity of the problem by + simulating Generation Scavenging automatic storage reclamation + from traces of actual four-hour sessions. There was a wide + variation in the sample runs, with garbage-collection overhead + ranging from insignificant, during interactive runs, to sever, + during a single non-interactive run. All runs demonstrated that + performance could be improved with two techniques: segregating + large bitmaps and strings, and mediating tenuring with demographic + feedback. These two improvements deserve consideration for any + generation-based storage reclamation strategy. + +* .. _VO96: + + Kiem-Phong Vo. 1996. "Vmalloc: A General and Efficient Memory Allocator". Software -- Practice and Experience. 26(3): 357--374 (1996). + + .. admonition:: Abstract + + On C/Unix systems, the malloc interface is standard for dynamic + memory allocation. Despite its popularity, malloc's shortcomings + frequently cause programmers to code around it. The new library + Vmalloc generalizes malloc to give programmers more control over + memory allocation. Vmalloc introduces the idea of organizing + memory into separate regions, each with a discipline to get raw + memory and a method to manage allocation. Applications can write + their own disciplines to manipulate arbitrary type of memory or + just to better organize memory in a region by creating new regions + out of its memory. The provided set of allocation methods include + general purpose allocations, fast special cases and aids for + memory debugging or profiling. A compatible malloc interface + enables current applications to select allocation methods using + environment variables so they can tune for performance or perform + other tasks such as profiling memory usage, generating traces of + allocation calls or debugging memory errors. A performance study + comparing Vmalloc and currently popular malloc implementations + shows that Vmalloc is competitive to the best of these allocators. + Applications can gain further performance improvement by using the + right mixture of regions with different Vmalloc methods. + +* .. _WW76: + + Daniel C. Watson, David S. Wise. 1976. "Tuning Garwick's algorithm for repacking sequential storage". *BIT.* 16, 4 (December 1976): 442--450. + + .. admonition:: Abstract + + Garwick's algorithm, for repacking LIFO lists stored in a + contiguous block of memory, bases the allocation of remaining + space upon both sharing and previous stack growth. A system + whereby the weight applied to each method can be adjusted + according to the current behaviour of the stacks is discussed. + + We also investigate the problem of determining during memory + repacking that the memory is used to saturation and the driving + program should therefore be aborted. The tuning parameters studied + here seem to offer no new grasp on this problem. + +* .. _WLM92: + + Paul R. Wilson, Michael S. Lam, Thomas G. Moher. 1992. "Caching Considerations for Generational Garbage Collection". ACM. L&FP 92. + + .. admonition:: Abstract + + GC systems allocate and reuse memory cyclically; this imposes a + cyclic pattern on memory accesses that has its own distinctive + locality characteristics. The cyclic reuse of memory tends to + defeat caching strategies if the reuse cycle is too large to fit + in fast memory. Generational GCs allow a smaller amount of memory + to be reused more often. This improves VM performance, because the + frequently-reused area stays in main memory. The same principle + can be applied at the level of high-speed cache memories, if the + cache is larger than the youngest generation. Because of the + repeated cycling through a fixed amount of memory, however, + generational GC interacts with cache design in unusual ways, and + modestly set-associative caches can significantly outperform + direct-mapped caches. + + While our measurements do not show very high miss rates for GCed + systems, they indicate that performance problems are likely in + faster next-generation systems, where second-level cache misses + may cost scores of cycles. Software techniques can improve cache + performance of garbage-collected systems, by decreasing the cache + "footprint" of the youngest generation; compiler techniques that + reduce the amount of heap allocation also improve locality. Still, + garbage-collected systems with a high rate of heap allocation + require somewhat more cache capacity and/or main memory bandwidth + than conventional systems. + +* .. _WIL92A: + + Paul R. Wilson, Sheetal V. Kakkad. 1992. "`Pointer Swizzling at Page Fault Time `_". University of Texas at Austin. + + .. admonition:: Abstract + + Pointer swizzling at page fault time is a novel address + translation mechanism that exploits conventional address + translation hardware. It can support huge address spaces + efficiently without long hardware addresses; such large address + spaces are attractive for persistent object stores, distributed + shared memories, and shared address space operating systems. This + swizzling scheme can be used to provide data compatibility across + machines with different word sizes, and even to provide binary + code compatibility across machines with different hardware address + sizes. + + Pointers are translated ("swizzled") from a long format to a + shorter hardware-supported format at page fault time. No extra + hardware is required, and no continual software overhead is + incurred by presence checks of indirection of pointers. This + pagewise technique exploits temporal and spatial locality in much + the same way as normal virtual memory; this gives it many + desirable performance characteristics, especially given the trend + toward larger main memories. It is easy to implement using common + compilers and operating systems. + +* .. _WIL94: + + Paul R. Wilson. 1994. "`Uniprocessor Garbage Collection Techniques `_". University of Texas. + + .. admonition:: Abstract + + We survey basic garbage collection algorithms, and variations such + as incremental and generational collection; we then discuss + low-level implementation considerations and the relationships + between storage management systems, languages, and compilers. + Throughout, we attempt to present a unified view based on abstract + traversal strategies, addressing issues of conservatism, + opportunism, and immediacy of reclamation; we also point out a + variety of implementation details that are likely to have a + significant impact on performance. + +* .. _WIL95: + + Paul R. Wilson, Mark S. Johnstone, Michael Neely, David Boles. 1995. "`Dynamic Storage Allocation: A Survey and Critical Review `_". University of Texas at Austin. + + .. admonition:: Abstract + + Dynamic memory allocation has been a fundamental part of most + computer systems since roughly 1960, and memory allocation is + widely considered to be either a solved problem or an insoluble + one. In this survey, we describe a variety of memory allocator + designs and point out issues relevant to their design and + evaluation. We then chronologically survey most of the literature + on allocators between 1961 and 1995. (Scores of papers are + discussed, in varying detail, and over 150 references are given.) + + We argue that allocator designs have been unduly restricted by an + emphasis on mechanism, rather than policy, while the latter is + more important; higher-level strategic issues are still more + important, but have not been given much attention. + + Most theoretical analyses and empirical allocator evaluations to + date have relied on very strong assumptions of randomness and + independence, but real program behavior exhibits important + regularities that must be exploited if allocators are to perform + well in practice. + +* .. _WISE78: + + David S. Wise. 1978. "`The double buddy system `_". Department of Computer Science at Indiana University. Technical Report 79. + + .. admonition:: Abstract + + A new buddy system is described in which the region of storage + being managed is partitioned into two sub-regions, each managed by + a fairly standard "binary" buddy system. Like the weighted buddy + systems of Shen and Peterson, the block sizes are of sizes 2\ + :superscript:`n+1` or 3·2\ :superscript:`n`, but unlike theirs + there is no extra overhead for typing information or for buddy + calculation, and an allocation which requires splitting an extant + available block only rarely creates a block smaller than the one + being allocated. Such smaller blocks are carved out only when the + boundary between the two subregions floats; the most interesting + property of this system is that the procedures for allocation and + deallocation are designed to keep blocks immediately adjacent to + the subregion boundary free, so that the boundary may be moved + within a range of unused space without disturbing blocks in use. + This option is attained with a minimum of extra computation beyond + that of a binary buddy system, and provides this scheme with a new + approach to the problem of external fragmentation. + +* .. _WISE79: + + David S. Wise. 1979. "`Morris's garbage compaction algorithm restores reference counts `_". TOPLAS. 1, 1 (July 1979): 115--120. + + .. admonition:: Abstract + + The two-pass compaction algorithm of F.L. Morris, which follows + upon the mark phase in a garbage collector, may be modified to + recover reference counts for a hybrid storage management system. + By counting the executions of two loops in that algorithm where + upward and downward references, respectively, are forwarded to the + relocation address of one node, we can initialize a count of + active references and then update it but once. The reference count + may share space with the mark bit in each node, but it may not + share the additional space required in each pointer by Morris's + algorithm, space which remains unused outside the garbage + collector. + +* .. _WISE85: + + David S. Wise. 1985. "`Design for a multiprocessing heap with on-board reference counting `_". Springer-Verlag. In J.-P. Jouannaud (ed.), Functional Programming Languages and Computer Architecture, Lecture Notes in Computer Science 201: 289--304. + + .. admonition:: Abstract + + A project to design a pair of memory chips with a modicum of + intelligence is described. Together, the two allow simple + fabrication of a small memory bank, a heap of binary (LISP-like) + nodes that offers the following features: 64-bit nodes; two + pointer fields per node up to 29 bits each; reference counts + implicitly maintained on writes; 2 bits per node for marking + (uncounted) circular references; 4 bits per node for + conditional-store testing at the memory; provision for + processor-driven, recounting garbage collection. + +* .. _WISE92: + + .. _WISE93: + + David S. Wise. 1993. "`Stop-and-copy and one-bit reference counting `_". *Information Processing Letters.* 46, 5 (July 1993): 243--249. + + .. admonition:: Abstract + + A stop-and-copy garbage collector updates one-bit reference + counting with essentially no extra space and minimal memory cycles + beyond the conventional collection algorithm. Any object that is + uniquely referenced during a collection becomes a candidate for + cheap recovery before the next one, or faster recopying then if it + remains uniquely referenced. Since most objects stay uniquely + referenced, subsequent collections run faster even if none are + recycled between garbage collections. This algorithm extends to + generation scavenging, it admits uncounted references from roots, + and it corrects conservatively stuck counters, that result from + earlier uncertainty whether references were unique. + +* .. _WW95: + + David S. Wise, Joshua Walgenbach. 1996. "`Static and Dynamic Partitioning of Pointers as Links and Threads `_". SIGPLAN. Proc. 1996 ACM SIGPLAN Intl. Conf. on Functional Programming, SIGPLAN Not. 31, 6 (June 1996), pp. 42--49. + + .. admonition:: Abstract + + Identifying some pointers as invisible threads, for the purposes + of storage management, is a generalization from several widely + used programming conventions, like threaded trees. The necessary + invariant is that nodes that are accessible (without threads) emit + threads only to other accessible nodes. Dynamic tagging or static + typing of threads ameliorates storage recycling both in functional + and imperative languages. + + We have seen the distinction between threads and links sharpen + both hardware- and software-supported storage management in + SCHEME, and also in C. Certainly, therefore, implementations of + languages that already have abstract management and concrete + typing, should detect and use this as a new static type. + +* .. _WHHHO94: + + David S. Wise, Brian Heck, Caleb Hess, Willie Hunt, Eric Ost. 1997. "`Uniprocessor Performance of a Reference-Counting Hardware Heap `_". *LISP and Symbolic Computation.* 10, 2 (July 1997), pp. 159--181. + + .. admonition:: Abstract + + A hardware self-managing heap memory (RCM) for languages like + LISP, SMALLTALK, and JAVA has been designed, built, tested and + benchmarked. On every pointer write from the processor, + reference-counting transactions are performed in real time within + this memory, and garbage cells are reused without processor + cycles. A processor allocates new nodes simply by reading from a + distinguished location in its address space. The memory hardware + also incorporates support for off-line, multiprocessing, + mark-sweep garbage collection. + + Performance statistics are presented from a partial implementation + of SCHEME over five different memory models and two garbage + collection strategies, from main memory (no access to RCM) to a + fully operational RCM installed on an external bus. The + performance of the RCM memory is more than competitive with main + memory. + +* .. _WITHINGTON91: + + P. Tucker Withington. 1991. "`How Real is 'Real-Time' Garbage Collection? `_". ACM. OOPSLA/ECOOP '91 Workshop on Garbage Collection in Object-Oriented Systems. + + .. admonition:: Abstract + + A group at Symbolics is developing a Lisp runtime kernel, derived + from its Genera operating system, to support real-time control + applications. The first candidate application has strict + response-time requirements (so strict that it does not permit the + use of paged virtual memory). Traditionally, Lisp's automatic + storage-management mechanism has made it unsuitable to real-time + systems of this nature. A number of garbage collector designs and + implementations exist (including the Genera garbage collector) + that purport to be "real-time", but which actually have only + mitigated the impact of garbage collection sufficiently that it + usually goes unnoticed by humans. Unfortunately, + electro-mechanical systems are not so forgiving. This paper + examines the limitations of existing real-time garbage collectors + and describes the avenues that we are exploring in our work to + develop a CLOS-based garbage collector that can meet the real-time + requirements of real real-time systems. + +* .. _YIP91: + + G. May Yip. 1991. "`Incremental, Generational Mostly-Copying Garbage Collection in Uncooperative Environments `_". Digital Equipment Corporation. + + .. admonition:: Abstract + + The thesis of this project is that incremental collection can be + done feasibly and efficiently in an architecture and compiler + independent manner. The design and implementation of an + incremental, generational mostly-copying garbage collector for C++ + is presented. The collector achieves, simultaneously, real-time + performance (from incremental collection), low total garbage + collection delay (from generational collection), and the ability + to function without hardware and compiler support (from + mostly-copying collection). + + The incremental collector runs on commercially-available + uniprocessors, such as the DECStation 3100, without any special + hardware support. It uses UNIX's user controllable page protection + facility (mprotect) to synchronize between the scanner (of the + collector) and the mutator (of the application program). Its + implementation does not require any modification to the C++ + compiler. The maximum garbage collection pause is well within the + 100-millisecond limit imposed by real-time applications executing + on interactive workstations. Compared to its non-incremental + version, the total execution time of the incremental collector is + not adversely affected. + +* .. _YUASA90: + + Taiichi Yuasa. 1990. "Real-Time Garbage Collection on General-Purpose Machines". Journal of Software and Systems. 11:3 pp. 181--198. + + .. admonition:: Abstract + + An algorithm for real-time garbage collection is presented, proved + correct, and evaluated. This algorithm is intended for + list-processing systems on general-purpose machines, i.e., Von + Neumann style serial computers with a single processor. On these + machines, real-time garbage collection inevitably causes some + overhead on the overall execution of the list-processing system, + because some of the primitive list-processing operations must + check the status of garbage collection. By removing such overhead + from frequently used primitives such as pointer references (e.g., + Lisp car and cdr) and stack manipulations, the presented algorithm + reduces the execution overhead to a great extent. Although the + algorithm does not support compaction of the whole data space, it + efficiently supports partial compaction such as array relocation. + +* .. _ZORN88: + + Benjamin Zorn & Paul Hilfinger. 1988. "`A Memory Allocation Profiler for C and Lisp Programs `_". USENIX. Proceedings for the Summer 1988 USENIX Conference, pp. 223--237. + + .. admonition:: Abstract + + This paper describes inprof, a tool used to study the memory + allocation behavior of programs. mprof records the amount of + memory each function allocates, breaks down allocation information + by type and size, and displays a program's dynamic cal graph so + that functions indirectly responsible for memory allocation are + easy to identify. mprof is a two-phase tool. The monitor phase is + linked into executing programs and records information each time + memory is allocated. The display phase reduces the data generated + by the monitor and displays the information to the user in several + tables. mprof has been implemented for C and Kyoto Common Lisp. + Measurements of these implementations are presented. + +* .. _ZORN89: + + Benjamin Zorn. 1989. "`Comparative Performance Evaluation of Garbage Collection Algorithms `_". Computer Science Division (EECS) of University of California at Berkeley. Technical Report UCB/CSD 89/544 and PhD thesis. + + .. admonition:: Abstract + + This thesis shows that object-level, trace-driven simulation can + facilitate evaluation of language runtime systems and reaches new + conclusions about the relative performance of important garbage + collection algorithms. In particular, I reach the unexpected + conclusion that mark-and-sweep garbage collection, when augmented + with generations, shows comparable CPU performance and much better + reference locality than the more widely used copying algorithms. + In the past, evaluation of garbage collection algorithms has been + limited by the high cost of implementing the algorithms. + Substantially different algorithms have rarely been compared in a + systematic way. + + With the availability of high-performance, low-cost workstations, + trace-driven performance evaluation of these algorithms is now + economical. This thesis describes MARS, a runtime system simulator + that is driven by operations on program objects, and not memory + addresses. MARS has been attached to a commercial Common Lisp + system and eight large Lisp applications are used in the thesis as + test programs. To illustrate the advantages of the object-level + tracing technique used by MARS, this thesis compares the relative + performance of stop-and-copy, incremental, and mark-and-sweep + collection algorithms, all organized with multiple generations. + The comparative evaluation is based on several metrics: CPU + overhead, reference locality, and interactive availability. + + Mark-and-sweep collection shows slightly higher CPU overhead than + stop-and-copy ability (5 percent), but requires significantly less + physical memory to achieve the same page fault rate (30-40 + percent). Incremental collection has very good interactive + availability, but implementing the read barrier on stock hardware + incurs a substantial CPU overhead (30-60 percent). In the future, + I will use MARS to investigate other performance aspects of + sophisticated runtime systems. + +* .. _ZORN90B: + + Benjamin Zorn. 1990. "Comparing Mark-and-sweep and Stop-and-copy Garbage Collection". ACM. Conference on Lisp and Functional Programming, pp. 87--98. + + .. admonition:: Abstract + + Stop-and-copy garbage collection has been preferred to + mark-and-sweep collection in the last decade because its + collection time is proportional to the size of reachable data and + not to the memory size. This paper compares the CPU overhead and + the memory requirements of the two collection algorithms extended + with generations, and finds that mark-and-sweep collection + requires at most a small amount of additional CPU overhead (3-6%) + but requires an average of 20% (and up to 40%) less memory to + achieve the same page fault rate. The comparison is based on + results obtained using trace-driven simulation with large Common + Lisp programs. + +* .. _ZORN90: + + Benjamin Zorn. 1990. "`Barrier Methods for Garbage Collection `_". University of Colorado at Boulder. Technical Report CU-CS-494-90. + + .. admonition:: Abstract + + Garbage collection algorithms have been enhanced in recent years + with two methods: generation-based collection and Baker + incremental copying collection. Generation-based collection + requires special actions during certain store operations to + implement the "write barrier". Incremental collection requires + special actions on certain load operations to implement the "read + barrier". This paper evaluates the performance of different + implementations of the read and write barriers and reaches several + important conclusions. First, the inlining of barrier checks + results in surprisingly low overheads, both for the write barrier + (2%-6%) and the read barrier (< 20%). Contrary to previous + belief, these results suggest that a Baker-style read barrier can + be implemented efficiently without hardware support. Second, the + use of operating system traps to implement garbage collection + methods results in extremely high overheads because the cost of + trap handling is so high. Since this large overhead is completely + unnecessary, operating system memory protection traps should be + reimplemented to be as fast as possible. Finally, the performance + of these approaches on several machine architectures is compared + to show that the results are generally applicable. + +* .. _ZORN91: + + Benjamin Zorn. 1991. "`The Effect of Garbage Collection on Cache Performance `_". University of Colorado at Boulder. Technical Report CU-CS-528-91. + + .. admonition:: Abstract + + Cache performance is an important part of total performance in + modern computer systems. This paper describes the use of + trace-driven simulation to estimate the effect of garbage + collection algorithms on cache performance. Traces from four large + Common Lisp programs have been collected and analyzed with an + all-associativity cache simulator. While previous work has focused + on the effect of garbage collection on page reference locality, + this evaluation unambiguously shows that garbage collection + algorithms can have a profound effect on cache performance as + well. On processors with a direct-mapped cache, a generation + stop-and-copy algorithm exhibits a miss rate up to four times + higher than a comparable generation mark-and-sweep algorithm. + Furthermore, two-way set-associative caches are shown to reduce + the miss rate in stop-and-copy algorithms often by a factor of two + and sometimes by a factor of almost five over direct-mapped + caches. As processor speeds increase, cache performance will play + an increasing role in total performance. These results suggest + that garbage collection algorithms will play an important part in + improving that performance. + +* .. _ZORN92B: + + Benjamin Zorn & Dirk Grunwald. 1992. "`Empirical Measurements of Six Allocation-intensive C Programs `_". ACM, SIGPLAN. SIGPLAN notices, 27(12):71--80. + + .. admonition:: Abstract + + Dynamic memory management is an important part of a large class of + computer programs and high-performance algorithms for dynamic + memory management have been, and will continue to be, of + considerable interest. This paper presents empirical data from a + collection of six allocation-intensive C programs. Extensive + statistics about the allocation behavior of the programs measured, + including the distributions of object sizes, lifetimes, and + interarrival times, are presented. This data is valuable for the + following reasons: first, the data from these programs can be used + to design high-performance algorithms for dynamic memory + management. Second, these programs can be used as a benchmark test + suite for evaluating and comparing the performance of different + dynamic memory management algorithms. Finally, the data presented + gives readers greater insight into the storage allocation patterns + of a broad range of programs. The data presented in this paper is + an abbreviated version of more extensive statistics that are + publicly available on the internet. + +* .. _ZORN92: + + Benjamin Zorn. 1993. "`The Measured Cost of Conservative Garbage Collection `_". Software -- Practice and Experience. 23(7):733--756. + + .. admonition:: Abstract + + Because dynamic memory management is an important part of a large + class of computer programs, high-performance algorithms for + dynamic memory management have been, and will continue to be, of + considerable interest. Experience indicates that for many + programs, dynamic storage allocation is so important that + programmers feel compelled to write and use their own + domain-specific allocators to avoid the overhead of system + libraries. Conservative garbage collection has been suggested as + an important algorithm for dynamic storage management in C + programs. In this paper, I evaluate the costs of different dynamic + storage management algorithms, including domain-specific + allocators; widely-used general-purpose allocators; and a publicly + available conservative garbage collection algorithm. Surprisingly, + I find that programmer enhancements often have little effect on + program performance. I also find that the true cost of + conservative garbage collection is not the CPU overhead, but the + memory system overhead of the algorithm. I conclude that + conservative garbage collection is a promising alternative to + explicit storage management and that the performance of + conservative collection is likely to be improved in the future. C + programmers should now seriously consider using conservative + garbage collection instead of malloc/free in programs they write. + +* .. _ZORN92A: + + Benjamin Zorn & Dirk Grunwald. 1994. "`Evaluating Models of Memory Allocation `_". ACM. Transactions on Modeling and Computer Simulation 4(1):107--131. + + .. admonition:: Abstract + + Because dynamic memory management is an important part of a large + class of computer programs, high-performance algorithms for + dynamic memory management have been, and will continue to be, of + considerable interest. We evaluate and compare models of the + memory allocation behavior in actual programs and investigate how + these models can be used to explore the performance of memory + management algorithms. These models, if accurate enough, provide + an attractive alternative to algorithm evaluation based on + trace-driven simulation using actual traces. We explore a range of + models of increasing complexity including models that have been + used by other researchers. Based on our analysis, we draw three + important conclusions. First, a very simple model, which generates + a uniform distribution around the mean of observed values, is + often quite accurate. Second, two new models we propose show + greater accuracy than those previously described in the + literature. Finally, none of the models investigated appear + adequate for generating an operating system workload. + diff --git a/mps/manual/source/conf.py b/mps/manual/source/conf.py index b3c561d615f..733438fc253 100644 --- a/mps/manual/source/conf.py +++ b/mps/manual/source/conf.py @@ -22,6 +22,34 @@ import sys # documentation root, use os.path.abspath to make it absolute, like shown here. 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 ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. @@ -40,24 +68,9 @@ source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' -# The master toctree document. -master_doc = 'index' - # General information about the project. -project = u'Memory Pool System' 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 # for a list of supported languages. #language = None @@ -98,10 +111,6 @@ pygments_style = 'sphinx' # -- 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 # further. For a list of options available for each theme, see the # documentation. @@ -119,7 +128,7 @@ html_theme_path = ['themes'] # The name of an image file (relative to this directory) to place at the top # 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 # 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, # relative to this directory. They are copied after the builtin static files, # 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, # using the given strftime format. @@ -139,11 +148,6 @@ html_static_path = [] # typographically correct entities. 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 # template names. #html_additional_pages = {} diff --git a/mps/manual/source/copyright.rst b/mps/manual/source/copyright.rst index 98b2dea1b42..234ae604da6 100644 --- a/mps/manual/source/copyright.rst +++ b/mps/manual/source/copyright.rst @@ -1,7 +1,7 @@ -.. _license: - .. index:: single: copyright single: license +.. _license: + .. include:: ../../license.txt diff --git a/mps/manual/source/extensions/mps/designs.py b/mps/manual/source/extensions/mps/designs.py index 230594e9392..ceaee15a256 100644 --- a/mps/manual/source/extensions/mps/designs.py +++ b/mps/manual/source/extensions/mps/designs.py @@ -20,12 +20,12 @@ TYPES = ''' AccessSet Accumulation Addr Align AllocFrame AllocPattern AP Arg Arena Attr Bool BootBlock BT Buffer BufferMode Byte Chain Chunk - Clock Compare Count Epoch FindDelete Format FrameState Fun Globals - Index Land LD Lock Message MessageType MutatorFaultContext Page - Pointer Pool PThreadext Range Rank RankSet Ref RefSet Res - Reservoir Ring Root RootMode RootVar ScanState Seg SegBuf SegPref - SegPrefKind Serial Shift Sig Size Space SplayNode SplayTree - StackContext Thread Trace TraceId TraceSet TraceStartWhy + Clock Compare Count Epoch FindDelete Format FrameState Fun GenDesc + Globals Index Land LD Lock Message MessageType MutatorFaultContext + Page Pointer Pool PoolGen PThreadext Range Rank RankSet Ref RefSet + Res Reservoir Ring Root RootMode RootVar ScanState Seg SegBuf + SegPref SegPrefKind Serial Shift Sig Size Space SplayNode + SplayTree StackContext Thread Trace TraceId TraceSet TraceStartWhy TraceState ULongest VM Word ZoneSet ''' @@ -124,6 +124,15 @@ def convert_file(name, source, dest): with open(dest, 'wb') as out: 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 def convert_updated(app): app.info(bold('converting MPS design documents')) @@ -131,11 +140,11 @@ def convert_updated(app): name = os.path.splitext(os.path.basename(design))[0] if name == 'index': continue converted = 'source/design/%s.rst' % name - if (not os.path.isfile(converted) - or os.path.getmtime(converted) < os.path.getmtime(design) - or os.path.getmtime(converted) < os.path.getmtime(__file__)): + if newer(design, converted): app.info('converting design %s' % name) convert_file(name, design, converted) 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) + diff --git a/mps/manual/source/glossary/a.rst b/mps/manual/source/glossary/a.rst index a7ab2de1bda..ec4da5f86d2 100644 --- a/mps/manual/source/glossary/a.rst +++ b/mps/manual/source/glossary/a.rst @@ -103,6 +103,26 @@ Memory Management Glossary: A .. 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 .. see:: :term:`translation lookaside buffer`. @@ -182,7 +202,11 @@ Memory Management Glossary: A .. mps:specific:: 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 @@ -389,6 +413,10 @@ Memory Management Glossary: A class of :term:`arenas`. Arena classes include :term:`client arenas` and :term:`virtual memory arenas`. + ASLR + + .. see:: :term:`address space layout randomization`. + assertion A declaration in a program of a condition that is expected @@ -452,6 +480,12 @@ Memory Management Glossary: A .. 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 In :term:`C`, :term:`objects` that are declared with diff --git a/mps/manual/source/glossary/c.rst b/mps/manual/source/glossary/c.rst index b2d8f2b1400..2449ce9f82a 100644 --- a/mps/manual/source/glossary/c.rst +++ b/mps/manual/source/glossary/c.rst @@ -131,7 +131,7 @@ Memory Management Glossary: C A cactus stack is a :term:`stack` with branches. When diagrammed, its shape resembles that of a `saguaro cactus - `_. + `_. In languages that support :term:`continuations`, :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`. + .. mps:specific:: + + The :ref:`pool-amc` pool class implements copying garbage + collection (more precisely, :term:`mostly-copying garbage + collection`). + core A historical synonym for :term:`main memory`, deriving from diff --git a/mps/manual/source/glossary/f.rst b/mps/manual/source/glossary/f.rst index 540cc048d46..eedbd00a9da 100644 --- a/mps/manual/source/glossary/f.rst +++ b/mps/manual/source/glossary/f.rst @@ -26,6 +26,11 @@ Memory Management Glossary: F .. similar:: :term:`in-band header`. + .. mps:specific:: + + :term:`Debugging pools` use fenceposts. See + :ref:`topic-debugging`. + fencepost error fence post error diff --git a/mps/manual/source/glossary/g.rst b/mps/manual/source/glossary/g.rst index 25feb894906..4dc74e66221 100644 --- a/mps/manual/source/glossary/g.rst +++ b/mps/manual/source/glossary/g.rst @@ -89,7 +89,7 @@ Memory Management Glossary: G This term is often used when referring to particular implementations or algorithms, for example, "the - Boehm-Demers-Weiser *collector*". + Boehm--Demers--Weiser *collector*". GB @@ -132,16 +132,16 @@ Memory Management Glossary: G .. mps:specific:: The :term:`client program` specifies the generational - structure of a :term:`pool` using a :term:`generation - chain`. See :ref:`topic-collection`. + structure of a :term:`pool` (or group of pools) using a + :term:`generation chain`. See :ref:`topic-collection`. generation chain .. mps:specific:: A data structure that specifies the structure of the - :term:`generations` in a :term:`pool`. See - :ref:`topic-collection`. + :term:`generations` in a :term:`pool` (or group of pools). + See :ref:`topic-collection`. generation scavenging @@ -174,6 +174,11 @@ Memory Management Glossary: G .. seealso:: :term:`remembered set`. + .. mps:specific:: + + The :ref:`pool-amc` and :ref:`pool-amcz` pool classes + support generational garbage collection. + generational hypothesis .. aka:: *infant mortality*. diff --git a/mps/manual/source/glossary/i.rst b/mps/manual/source/glossary/i.rst index 9ce2a3f9cea..b174241959c 100644 --- a/mps/manual/source/glossary/i.rst +++ b/mps/manual/source/glossary/i.rst @@ -133,6 +133,12 @@ Memory Management Glossary: I .. bibref:: :ref:`Appel et al. (1988) `, :ref:`Boehm et al. (1991) `. + .. mps:specific:: + + The MPS uses incremental collection, except for + collections started by calling + :c:func:`mps_arena_collect`. + incremental update Incremental-update algorithms for :term:`tracing `, diff --git a/mps/manual/source/glossary/index.rst b/mps/manual/source/glossary/index.rst index bb55975bf97..40656261350 100644 --- a/mps/manual/source/glossary/index.rst +++ b/mps/manual/source/glossary/index.rst @@ -7,6 +7,7 @@ Memory Management Glossary .. toctree:: :maxdepth: 1 + :hidden: a b @@ -31,3 +32,594 @@ Memory Management Glossary v w z + +All +=== + +:term:`absolute address ` +:term:`activation frame ` +:term:`activation record` +:term:`activation stack ` +:term:`active ` +:term:`address` +:term:`address space` +:term:`address space layout randomization` +:term:`address translation cache ` +:term:`address-ordered first fit` +:term:`aging space` +:term:`algebraic data type` +:term:`alignment` +:term:`alive ` +: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
` +:term:`assertion` +:term:`asynchronous garbage collector` +:term:`ATC ` +:term:`atomic object ` +:term:`automatic memory management` +:term:`automatic storage duration` + +:term:`backing store` +:term:`barrier (1)` +:term:`barrier (2)` +:term:`barrier hit ` +:term:`base pointer` +:term:`best fit` +:term:`BIBOP` +:term:`big bag of pages ` +:term:`binary buddies` +:term:`bit array ` +:term:`bit table ` +:term:`bit vector ` +:term:`bitmap` +:term:`bitmapped fit` +:term:`bitmask` +:term:`bitset ` +:term:`black` +:term:`blacklisting` +:term:`black-listing` +:term:`block` +:term:`bounds 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 ` +:term:`C90` +:term:`C99` +:term:`cache (1)` +:term:`cache (2)` +:term:`cache memory ` +:term:`cache policy` +:term:`caching (3)` +:term:`cactus stack` +:term:`card` +:term:`card marking` +:term:`cell ` +:term:`Cheney collector` +:term:`Cheney scan ` +:term:`clamped state` +:term:`client arena` +:term:`client object` +:term:`client pointer` +:term:`client program ` +:term:`closure` +:term:`coalesce` +:term:`collect` +:term:`collection ` +:term:`collection cycle` +:term:`collector (1) ` +:term:`collector (2)` +:term:`color` +:term:`colour` +:term:`commit limit` +:term:`committed (1) ` +:term:`committed (2)` +:term:`compactifying ` +:term:`compaction` +:term:`composite object` +:term:`comprehensive` +:term:`concurrent garbage collection ` +:term:`condemned set` +:term:`connected` +:term:`cons (1)` +:term:`cons (2) ` +: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 ` +:term:`debugging pool` +:term:`deferred coalescing` +:term:`deferred reference counting` +:term:`dependent object` +:term:`derived pointer ` +:term:`derived type` +:term:`destructor (1)` +:term:`destructor (2)` +:term:`DGC ` +: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 ` +:term:`dynamic allocation ` +:term:`dynamic extent` +:term:`dynamic memory` +:term:`dynamic RAM ` + +:term:`ecru ` +: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 ` +:term:`exit table` +:term:`extent ` +: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 ` +: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 ` +:term:`free (1)` +:term:`free (2)` +:term:`free (3)` +:term:`free (4) ` +:term:`free block` +:term:`free block chain` +:term:`free list` +:term:`free store ` +:term:`freestore ` +:term:`from space` +:term:`fromspace` +:term:`function pointer` +:term:`function record ` + +:term:`garbage` +:term:`garbage collection` +:term:`garbage collector` +:term:`GB ` +:term:`GC ` +:term:`General Protection Fault` +:term:`generation` +:term:`generation chain` +:term:`generation scavenging ` +:term:`generational garbage collection` +:term:`generational hypothesis` +:term:`gigabyte` +:term:`good fit` +:term:`GPF ` +:term:`grain` +:term:`graph` +:term:`gray` +:term:`grey` +:term:`gray list` +:term:`grey list` + +:term:`handle` +:term:`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 ` +: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 ` +: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 ` +:term:`keyword argument` +:term:`kilobyte` + +:term:`large object area` +:term:`large page ` +:term:`leaf object` +:term:`leak ` +:term:`life ` +: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 ` +:term:`location dependency` +:term:`lock free` +:term:`logical address ` +:term:`longword ` + +:term:`machine 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 ` +:term:`megabyte` +:term:`memoization ` +:term:`memory (1)` +:term:`memory (2)` +:term:`memory (3)
` +:term:`memory (4)` +:term:`memory bandwidth` +:term:`memory cache ` +:term:`memory hierarchy ` +:term:`memory leak` +:term:`memory location` +:term:`memory management` +:term:`Memory Management Unit ` +:term:`memory manager` +:term:`memory mapping` +:term:`memory protection ` +:term:`message` +:term:`message queue` +:term:`message type` +:term:`misaligned ` +:term:`miss` +:term:`miss rate` +:term:`mmap` +:term:`MMU` +:term:`mostly-copying garbage collection` +:term:`mostly-exact garbage collection ` +:term:`mostly-precise garbage collection ` +:term:`moving garbage collector` +:term:`moving memory manager` +:term:`mutable` +:term:`mutator` + +:term:`nailing ` +:term:`natural alignment` +:term:`nepotism` +:term:`next fit` +:term:`new space` +:term:`newspace ` +:term:`node` +:term:`non-moving garbage collector` +:term:`non-moving memory manager` +:term:`nursery generation ` +:term:`nursery space` + +:term:`object` +:term:`object format` +:term:`object pointer` +:term:`off-white` +:term:`old space ` +:term:`oldspace ` +: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 ` +: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 ` +:term:`pig in the python` +:term:`pig in the snake ` +:term:`pinning` +:term:`placement policy ` +:term:`platform` +:term:`plinth` +:term:`pointer` +:term:`pool` +:term:`pool class` +:term:`precise garbage collection ` +:term:`precise reference ` +:term:`precise root ` +:term:`premature free` +:term:`premature promotion ` +:term:`premature tenuring` +:term:`primary storage
` +:term:`promotion` +:term:`protectable root` +:term:`protection` +:term:`protection exception ` +:term:`protection fault` +:term:`protection violation ` + +:term:`quadword` + +:term:`RAM` +:term:`random access memory ` +:term:`ramp allocation` +:term:`rank` +:term:`rash` +:term:`raw ` +:term:`reachable` +:term:`read barrier` +:term:`read fault` +:term:`read-only memory ` +:term:`real memory (1)` +:term:`real memory (2) ` +: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 ` +: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 ` +: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 ` +:term:`spare commit limit` +:term:`spare committed memory` +:term:`spaghetti stack ` +:term:`splat` +:term:`split` +:term:`SRAM ` +:term:`SSB ` +:term:`stack` +:term:`stack allocation` +:term:`stack frame` +:term:`stack record ` +:term:`static allocation` +:term:`static memory (1)` +:term:`static memory (2)` +:term:`static object` +:term:`static RAM ` +:term:`static storage duration` +:term:`stepper function` +:term:`sticky reference count ` +:term:`stop-and-copy collection` +:term:`storage ` +:term:`storage hierarchy` +:term:`storage level` +:term:`storage management ` +:term:`store (1)` +:term:`store (2) ` +: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 ` +:term:`sure reference ` +:term:`swap space` +:term:`swapped in` +:term:`swapped out` +:term:`swapping` +:term:`sweeping` +:term:`synchronous garbage collector` + +:term:`tabling ` +:term:`tag` +:term:`tagged architecture` +:term:`tagged reference` +:term:`TB (1) ` +:term:`TB (2) ` +:term:`telemetry filter` +:term:`telemetry label` +:term:`telemetry stream` +:term:`tenuring ` +:term:`terabyte` +:term:`termination ` +:term:`thrash` +:term:`thread` +:term:`threatened set ` +:term:`TLB ` +: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 ` +: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 ` +:term:`type punning` + +:term:`unaligned` +:term:`unboxed` +:term:`unclamped state` +:term:`undead` +:term:`unmapped` +:term:`unreachable` +:term:`unsure reference ` +:term:`unwrapped` +:term:`use after 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 ` +:term:`VM (1) ` +: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 ` +:term:`zero count table` diff --git a/mps/manual/source/glossary/l.rst b/mps/manual/source/glossary/l.rst index 5a143e55f69..3e4f0db4270 100644 --- a/mps/manual/source/glossary/l.rst +++ b/mps/manual/source/glossary/l.rst @@ -81,9 +81,14 @@ Memory Management Glossary: L If leaf objects can be identified, a :term:`garbage collector` can make certain optimizations: leaf objects do not have to be :term:`scanned ` for references nor - are :term:`barrier (1)` needed to detect + are :term:`barriers (1)` needed to detect 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 .. see:: :term:`memory leak`. diff --git a/mps/manual/source/glossary/m.rst b/mps/manual/source/glossary/m.rst index 4562d30d7b6..db4d8b88a59 100644 --- a/mps/manual/source/glossary/m.rst +++ b/mps/manual/source/glossary/m.rst @@ -535,6 +535,11 @@ Memory Management Glossary: M .. bibref:: :ref:`Bartlett (1989) `, :ref:`Yip (1991) `. + .. mps:specific:: + + The :ref:`pool-amc` pool class implements mostly-copying + garbage collection. + mostly-exact garbage collection .. see:: :term:`semi-conservative garbage collection`. diff --git a/mps/manual/source/glossary/n.rst b/mps/manual/source/glossary/n.rst index 24ddcf66cea..67fbd65a371 100644 --- a/mps/manual/source/glossary/n.rst +++ b/mps/manual/source/glossary/n.rst @@ -117,4 +117,10 @@ Memory Management Glossary: N The size of the nursery space must be chosen carefully. Often 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`. diff --git a/mps/manual/source/glossary/p.rst b/mps/manual/source/glossary/p.rst index fc08d9c2abb..5fdba129d77 100644 --- a/mps/manual/source/glossary/p.rst +++ b/mps/manual/source/glossary/p.rst @@ -167,7 +167,7 @@ Memory Management Glossary: P mutator changing :term:`objects` while collection occurs. The problem is similar to that of :term:`incremental GC `, but harder. The solution - typically involves :term:`barrier (1)`. + typically involves :term:`barriers (1)`. .. similar:: :term:`incremental `. @@ -222,7 +222,7 @@ Memory Management Glossary: P .. link:: - `Class java.lang.ref.PhantomReference `_, `Reference Objects and Garbage Collection `_. + `Class java.lang.ref.PhantomReference `_, `Reference Objects and Garbage Collection `_. phantom reference @@ -239,7 +239,7 @@ Memory Management Glossary: P .. link:: - `Class java.lang.ref.PhantomReference `_, `Reference Objects and Garbage Collection `_. + `Class java.lang.ref.PhantomReference `_, `Reference Objects and Garbage Collection `_. physical address @@ -321,6 +321,14 @@ Memory Management Glossary: P .. 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 .. see:: :term:`pig in the python`. diff --git a/mps/manual/source/glossary/r.rst b/mps/manual/source/glossary/r.rst index a521c1d7bd4..2c8a9ef70ad 100644 --- a/mps/manual/source/glossary/r.rst +++ b/mps/manual/source/glossary/r.rst @@ -93,7 +93,7 @@ Memory Management Glossary: R .. link:: - `Package java.lang.ref `_, `Reference Objects and Garbage Collection `_. + `Package java.lang.ref `_, `Reference Objects and Garbage Collection `_. read barrier @@ -317,7 +317,7 @@ Memory Management Glossary: R .. link:: - `Package java.lang.ref `_, `Reference Objects and Garbage Collection `_. + `Package java.lang.ref `_, `Reference Objects and Garbage Collection `_. .. bibref:: :ref:`Dybvig et al. (1993) `. @@ -471,6 +471,11 @@ Memory Management Glossary: R .. seealso:: :term:`mapping`, :term:`mmap`. + .. mps:specific:: + + The function :c:func:`mps_arena_reserved` returns the + total address space reserved by an arena. + resident In a :term:`cache (2)` system, that part of the cached storage diff --git a/mps/manual/source/glossary/s.rst b/mps/manual/source/glossary/s.rst index 41389cb2103..dc9355f2a0f 100644 --- a/mps/manual/source/glossary/s.rst +++ b/mps/manual/source/glossary/s.rst @@ -333,7 +333,7 @@ Memory Management Glossary: S By overloading certain operators it is possible for the class 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 using the smart pointer class to have their :term:`memory (1)` automatically :term:`reclaimed` when they are no longer @@ -429,7 +429,7 @@ Memory Management Glossary: S .. link:: - `Class java.lang.ref.SoftReference `_, `Reference Objects and Garbage Collection `_. + `Class java.lang.ref.SoftReference `_, `Reference Objects and Garbage Collection `_. softly reachable @@ -453,7 +453,7 @@ Memory Management Glossary: S .. link:: - `Class java.lang.ref.SoftReference `_, `Reference Objects and Garbage Collection `_. + `Class java.lang.ref.SoftReference `_, `Reference Objects and Garbage Collection `_. space leak @@ -785,6 +785,26 @@ Memory Management Glossary: S .. see:: :term:`memory (1)`. + stretchy vector + + A :term:`vector ` that may grow or shrink to + accommodate adding or removing elements. Named after the + ```` 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 `_. + + .. mps:specific:: + + See :ref:`guide-stretchy-vector`. + strict segregated fit 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 keeps the :term:`object` it refers to :term:`alive `. - 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 (1)`. @@ -819,7 +839,7 @@ Memory Management Glossary: S A strong root is a :term:`root` such that all :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`. .. opposite:: :term:`weak root`. diff --git a/mps/manual/source/glossary/w.rst b/mps/manual/source/glossary/w.rst index 7d061294ce6..46d8d9edd06 100644 --- a/mps/manual/source/glossary/w.rst +++ b/mps/manual/source/glossary/w.rst @@ -70,7 +70,7 @@ Memory Management Glossary: W .. link:: - `Class java.lang.ref.WeakReference `_, `Reference Objects and Garbage Collection `_. + `Class java.lang.ref.WeakReference `_, `Reference Objects and Garbage Collection `_. weak root @@ -134,7 +134,7 @@ Memory Management Glossary: W .. link:: - `Class java.lang.ref.WeakReference `_, `Reference Objects and Garbage Collection `_. + `Class java.lang.ref.WeakReference `_, `Reference Objects and Garbage Collection `_. weighted buddies diff --git a/mps/manual/source/guide/debug.rst b/mps/manual/source/guide/debug.rst index daf3fb63ae5..060928c2ba6 100644 --- a/mps/manual/source/guide/debug.rst +++ b/mps/manual/source/guide/debug.rst @@ -42,21 +42,20 @@ General debugging advice in production), and can generate profiling output in the form of the :term:`telemetry stream`. -#. .. index:: - single: ASLR - single: address space layout randomization +#. If your program triggers an assertion failure in the MPS, consult + :ref:`topic-error-cause` for suggestions as to the possible cause. - Prepare a reproducible test case if possible. The MPS may be +#. Prepare a reproducible test case if possible. The MPS may be :term:`asynchronous `, but it is deterministic, so in single-threaded applications you should be - able to get consistent results. (But you need to beware of `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.) + able to get consistent results. - .. _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 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 collections (by calling :c:func:`mps_arena_collect` followed by :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:: single: debugger @@ -86,13 +88,111 @@ General debugging advice handle SIGSEGV pass nostop noprint - On these operating systems, you can add this commands to your - ``.gdbinit`` if you always want them to be run. + On these operating systems, you can add this command to your + ``.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. +.. 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 + #include + + 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 + + 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 `.) + + .. index:: single: underscanning single: bug; underscanning diff --git a/mps/manual/source/guide/index.rst b/mps/manual/source/guide/index.rst index abd9ef242ca..a7218dd2ba5 100644 --- a/mps/manual/source/guide/index.rst +++ b/mps/manual/source/guide/index.rst @@ -9,6 +9,7 @@ Guide overview build lang + vector debug perf advanced diff --git a/mps/manual/source/guide/vector.rst b/mps/manual/source/guide/vector.rst new file mode 100644 index 00000000000..8b9452ac1f6 --- /dev/null +++ b/mps/manual/source/guide/vector.rst @@ -0,0 +1,152 @@ +.. index:: + single: stretchy vectors + single: atomic updates + +.. _guide-stretchy-vector: + +The stretchy vector problem +============================ + +The :ref:`previous chapter ` pointed out that: + + Because the MPS is :term:`asynchronous `, 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: 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 `. (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; iarray[i]); + t->sizearray = size; + } + +Lua's garbage collector is :term:`synchronous `, 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 diff --git a/mps/manual/source/diagrams/logo.png b/mps/manual/source/images/logo.png similarity index 100% rename from mps/manual/source/diagrams/logo.png rename to mps/manual/source/images/logo.png diff --git a/mps/manual/source/index.rst b/mps/manual/source/index.rst index 161a13ad3b3..4edc69bbf60 100644 --- a/mps/manual/source/index.rst +++ b/mps/manual/source/index.rst @@ -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 ################## @@ -15,26 +11,26 @@ Memory Pool System design/old -Memory Management Reference -########################### - -.. toctree:: - :maxdepth: 2 - - mmref/index - mmref/bib - mmref/credit - - Appendices ########## .. toctree:: :maxdepth: 1 + bib glossary/index copyright contact release * :ref:`genindex` + + +.. toctree:: + :hidden: + + mmref/index + mmref-index + mmref/faq + mmref-copyright + mmref/credit diff --git a/mps/manual/source/mmref-copyright.rst b/mps/manual/source/mmref-copyright.rst new file mode 100644 index 00000000000..b2e95ecd3a7 --- /dev/null +++ b/mps/manual/source/mmref-copyright.rst @@ -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. diff --git a/mps/manual/source/mmref-index.rst b/mps/manual/source/mmref-index.rst new file mode 100644 index 00000000000..c645899bb49 --- /dev/null +++ b/mps/manual/source/mmref-index.rst @@ -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 ` +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/ diff --git a/mps/manual/source/mmref/bib.rst b/mps/manual/source/mmref/bib.rst deleted file mode 100644 index aba18413d6e..00000000000 --- a/mps/manual/source/mmref/bib.rst +++ /dev/null @@ -1,965 +0,0 @@ -.. _bibliography: - -Bibliography -************ - -* .. _AD97: - - Ole Agesen, David L. Detlefs. 1997. "`Finding References in Java Stacks `_". 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 `_". 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 `_". 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 `_". TR-94-010. - - .. abstract: attardi94.html - -* .. _AFI98: - - Giuseppe Attardi, Tito Flagella, Pietro Iglio. 1998. "`A customisable memory management framework for C++ `_". 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 `_". ACM. ISMM'98 pp. 10--19. - - .. abstract: akpy98.html - -* .. _BAKER77: - - Henry G. Baker, Carl Hewitt. 1977. "`The Incremental Garbage Collection of Processes `_". 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 `_". 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 `_". In Winston and Brown, eds. *Artificial Intelligence: An MIT Perspective.* MIT Press. - - .. abstract: baker79.html - -* .. _BAKER91: - - Henry G. Baker. 1991. "`Cache-Conscious Copying Collectors `_". OOPSLA'91/GC'91 Workshop on Garbage Collection. - - .. abstract: baker91.html - -* .. _BAKER92A: - - Henry G. Baker. 1992. "`Lively Linear Lisp -- 'Look Ma, No Garbage!' `_". 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 `_". 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 `_". 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 `_". Springer-Verlag. LNCS Vol. 637. - - .. abstract: baker92b.html - -* .. _BAKER93: - - Henry G. Baker. 1993. "`'Infant Mortality' and Generational Garbage Collection `_". 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 `_". 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 `_". ACM. SIGPLAN Notices 29, 9 (September 1994), pp. 38--43. - - .. abstract: baker94.html - -* .. _BAKER94A: - - Henry G. Baker. 1994. "`Thermodynamics and Garbage Collection `_". 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 `_". 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 `_". OOPSLA97 Workshop on Garbage Collection and Memory Management. - -* .. _ZORN93B: - - David A. Barrett, Benjamin Zorn. 1993. "`Using Lifetime Predictors to Improve Memory Allocation Performance `_". 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 `_". 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 `_". Digital Equipment Corporation. - - .. abstract: bartlett88.html - -* .. _BARTLETT89: - - Joel F. Bartlett. 1989. "`Mostly-Copying Garbage Collection Picks Up Generations and C++ `_". Digital Equipment Corporation. - - .. abstract: bartlett89.html - -* .. _BC92: - - Yves Bekkers & Jacques Cohen. 1992. "`Memory Management, International Workshop IWMM 92 `_". 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 `_". 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 `_" 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 `_". 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 `_". 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 `_". 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 `_". ACM. ISMM'00 pp. 59--64. - - .. abstract: boehm00.html - -* .. _BOEHM02: - - Hans-J. Boehm. 2002. "`Destructors, Finalizers, and Synchronization `_". HP Labs technical report HPL-2002-335. - -* .. _BM77: - - Robert S. Boyer and J. Strother Moore. 1977. "`A Fast String Searching Algorithm `_". *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 `_". ISMM'02. - -* .. _C1990: - - International Standard ISO/IEC 9899:1990. "Programming languages — C". - -* .. _C1999: - - International Standard ISO/IEC 9899:1999. "`Programming languages — C `_". - -* .. _CGZ94: - - Brad Calder, Dirk Grunwald, Benjamin Zorn. 1994. "`Quantifying Behavioral Differences Between C and C++ Programs `_". *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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". CACM. vol. 15, no. 3, pp. 191--198. - -* .. _DETLEFS92: - - David L. Detlefs. 1992. "`Garbage collection and runtime typing as a C++ library `_". USENIX C++ Conference. - -* .. _ZORN93: - - David L. Detlefs, Al Dosser, Benjamin Zorn. 1994. "`Memory Allocation Costs in Large C and C++ Programs `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". ACM. POPL '93, 113--123. - - .. abstract: doligez93.html - -* .. _DOLIGEZ94: - - Damien Doligez & Georges Gonthier. 1994. "`Portable, unobtrusive garbage collection for multiprocessor systems `_". ACM. POPL '94, 70--83. - - .. abstract: doligez94.html - -* .. _DBE93: - - R. Kent Dybvig, Carl Bruggeman, David Eby. 1993. "`Guardians in a Generation-Based Garbage Collector `_". 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 `_". 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 `_". MIT. AI Memo 19 (AIM-19). - - .. abstract: edwards.html - -* .. _ELLIS93: - - John R. Ellis, David L. Detlefs. 1993. "`Safe, Efficient Garbage Collection for C++ `_". Xerox PARC. - - .. abstract: ellis93.html - -* .. _FERREIRA96: - - Paulo Ferreira. 1996. "`Larchant: garbage collection in a cached distributed shared store with persistence by reachability `_". Université Paris VI. Thése de doctorat. - - .. abstract: ferreira96.html - -* .. _FS98: - - Paulo Ferreira & Marc Shapiro. 1998. "`Modelling a Distributed Cached Store for Garbage Collection `_". 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 `_". *Information Processing Letters.* 5, 6 (December 1976): 161--164. - -* .. _FW77: - - Daniel P Friedman, David S. Wise. 1977. "`The One Bit Reference Count `_". *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 `_". *Information Processing Letters.* 8, 1 (January 1979): 41--45. - -* .. _GZH93: - - Dirk Grunwald, Benjamin Zorn, R. Henderson. 1993. "`Improving the Cache Locality of Memory Allocation `_". 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 `_". Software -- Practice and Experience. 23(8):851--869. - - .. abstract: grun92.html - -* .. _GUDEMAN93: - - David Gudeman. 1993. "`Representing Type Information in Dynamically Typed Languages `_". 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 `_". 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 `_". NWPER96. - - .. abstract: henrik96.html - -* .. _HENRIKSSON98: - - Roger Henriksson. 1998. "`Scheduling Garbage Collection in Embedded Systems `_". Department of Computer Science at Lund University. Ph.D. thesis. - - .. abstract: henriksson98.html - -* .. _HOSKING91: - - Antony L. Hosking. 1991. "`Main memory management for persistence `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". University of Texas at Austin. - - .. abstract: johnstone97.html - -* .. _JW98: - - Mark S. Johnstone, Paul R. Wilson. 1998. "`The Memory Fragmentation Problem: Solved? `_". ACM. ISMM'98 pp. 26--36. - - .. abstract: jw98.html - -* .. _JONES92: - - Richard E. Jones. 1992. "`Tail recursion without space leaks `_". *Journal of Functional Programming.* 2(1):73--79. - -* .. _JL92: - - Richard E. Jones, Rafael Lins. 1992. "`Cyclic weighted reference counting without delay `_". 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 `_". Wiley. ISBN 0-471-94148-4. - - .. abstract: jones96.html - -* .. _ACM98: - - Richard E. Jones. 1998. "`ISMM'98 International Symposium on Memory Management `_". ACM. ISBN 1-58113-114-3. - - .. abstract: acm98.html - -* .. _JONES12: - - Richard E. Jones, Antony Hosking, and Eliot Moss. 2012. "`The Garbage Collection Handbook `_". Chapman & Hall. - -* .. _JOYNER96: - - Ian Joyner. 1996. "`C++??: A Critique of C++ `_.". - -* .. _KANEFSKY89: - - Bob Kanefsky. 1989. "`Recursive Memory Allocation `_". Bob Kanefsky. Songworm 3, p.?. - -* .. _KQH98: - - Jin-Soo Kim, Xiaohan Qin, Yarsun Hsu. 1998. "`Memory Characterization of a Parallel Data Mining Workload `_". 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 `_". 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 `_". 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 `_". CACM. - - .. abstract: mccarthy60.html - -* .. _MCCARTHY79: - - John McCarthy. 1979. "`History of Lisp `_". In *History of programming languages I*, pp. 173–185. ACM. - -* .. _PTM98: - - Veljko Milutinovic, Jelica Protic, Milo Tomasevic. 1997. "`Distributed shared memory: concepts and systems `_". 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 `_". 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 `_". ACM. ISMM'98 pp. 57--67. - -* .. _MFH95: - - Greg Morrisett, Matthias Felleisen, Robert Harper. 1995. "`Abstract Models of Memory Management `_". 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 `_". 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 `_". IWMM'92. - - .. abstract: noph92.html - -* .. _NETTLES92: - - Scott Nettles. 1992. "`A Larch Specification of Copying Garbage Collection `_". 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 `_". 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 `_". ACM. LFP'94. - - .. abstract: on94.html - -* .. _JRR99: - - Simon Peyton Jones, Norman Ramsey, Fermin Reig. 1999. "`C--: a portable assembly language that supports garbage collection `_". 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 `_". 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 `_". 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 `_". Xerox PARC. TR CSL-84-7. - -* .. _RUNCIMAN92: - - Colin Runciman & David Wakeling. 1992. "`Heap Profiling of Lazy Functional Programs `_". University of York. - - .. abstract: runciman92.html - -* .. _RR94: - - Colin Runciman & Niklas Röjemo. 1994. "`New dimensions in heap profiling `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". MIT. AITR-1417. - - .. abstract: sobalvarro88.html - -* .. _STEELE75: - - Guy L. Steele. 1975. "`Multiprocessing Compactifying Garbage Collection `_". 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 `_". 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 `_". 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 `_". 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 `_". ACM, SIGSOFT, SIGPLAN. Practical Programming Environments Conference. - -* .. _UNGAR88: - - Dave Ungar & Frank Jackson. 1988. "`Tenuring Policies for Generation-Based Storage Reclamation `_". 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 `_". University of Texas at Austin. - - .. abstract: wil92a.html - -* .. _WIL94: - - Paul R. Wilson. 1994. "`Uniprocessor Garbage Collection Techniques `_". 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 `_". University of Texas at Austin. - - .. abstract: wil95.html - -* .. _WISE78: - - David S. Wise. 1978. "`The double buddy system `_". Department of Computer Science at Indiana University. Technical Report 79. - -* .. _WISE79: - - David S. Wise. 1979. "`Morris's garbage compaction algorithm restores reference counts `_". TOPLAS. 1, 1 (July l979): 115--120. - -* .. _WISE85: - - David S. Wise. 1985. "`Design for a multiprocessing heap with on-board reference counting `_". 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 `_". *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 `_". 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 `_". *LISP and Symbolic Computation.* 10, 2 (July 1997), pp. 159--181. - -* .. _WITHINGTON91: - - P. Tucker Withington. 1991. "`How Real is 'Real-Time' Garbage Collection? `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". 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 `_". ACM, SIGPLAN. SIGPLAN notices, 27(12):71--80. - - .. abstract: zorn92b.html - -* .. _ZORN92: - - Benjamin Zorn. 1993. "`The Measured Cost of Conservative Garbage Collection `_". Software -- Practice and Experience. 23(7):733--756. - - .. abstract: zorn92.html - -* .. _ZORN92A: - - Benjamin Zorn & Dirk Grunwald. 1994. "`Evaluating Models of Memory Allocation `_". ACM. Transactions on Modeling and Computer Simulation 4(1):107--131. - - .. abstract: zorn92a.html - diff --git a/mps/manual/source/mmref/credit.rst b/mps/manual/source/mmref/credit.rst index 816cfb0c870..0ce0bd0c8b3 100644 --- a/mps/manual/source/mmref/credit.rst +++ b/mps/manual/source/mmref/credit.rst @@ -27,7 +27,7 @@ Reference. The Adaptive Memory Management Group no longer exists, and Harlequin has become a part of `Global Graphics `_. 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 senior group member. diff --git a/mps/manual/source/mmref/faq.rst b/mps/manual/source/mmref/faq.rst index 190ecaecdb4..594f1656b97 100644 --- a/mps/manual/source/mmref/faq.rst +++ b/mps/manual/source/mmref/faq.rst @@ -22,11 +22,12 @@ garbage collection>` for :term:`C` exist as add-on libraries. .. link:: - `Boehm–Weiser collector `_. + `Memory Pool System `_, + `Boehm–Demers–Weiser collector `_. -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 :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. -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:`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` -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` -service. However, it does not provide the following things, which may -be desirable in your memory manager: +The :term:`malloc` function provides a very basic :term:`manual memory +management` service. However, it does not provide the following +things, which may be desirable in your memory manager: * high performance for specified block sizes; * :term:`tagged references`; @@ -130,11 +131,12 @@ semi-conservative garbage collectors for C++. .. link:: - `Boehm–Weiser collector `_. + `Memory Pool System `_, + `Boehm–Demers–Weiser collector `_. -Why is ``delete`` so slow? -^^^^^^^^^^^^^^^^^^^^^^^^^^ +Why is delete so slow? +^^^^^^^^^^^^^^^^^^^^^^ Often ``delete`` must perform a more complex task than simply freeing 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 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 -collector will work with C++. +can try is to add a :term:`garbage collector`. .. link:: - `Boehm–Weiser collector `_. + `Memory Pool System `_, + `Boehm–Demers–Weiser collector `_. 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 the language documentation should give details. For some other 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` @@ -408,22 +410,25 @@ Boehm–Weiser collector. .. link:: - `Boehm–Weiser collector `_, + `Memory Pool System `_, + `Boehm–Demers–Weiser collector `_, `GC-LIST FAQ `_. Where can I get a garbage collector? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The Boehm–Weiser collector is suitable for C or C++. The best way to -get a garbage collector, however, is to program in a language that -provides garbage collection. +The Memory Pool System and the Boehm–Demers–Weiser collector are +suitable for C or C++. The best way to get a garbage collector, +however, is to program in a language that provides garbage collection +natively. .. seealso:: :term:`garbage collection` .. link:: - `Boehm–Weiser collector `_. + `Memory Pool System `_, + `Boehm–Demers–Weiser collector `_. Why does my program use so much memory? diff --git a/mps/manual/source/mmref/index.rst b/mps/manual/source/mmref/index.rst index eb6ef48257e..d87db74339d 100644 --- a/mps/manual/source/mmref/index.rst +++ b/mps/manual/source/mmref/index.rst @@ -1,3 +1,5 @@ +.. _mmref-intro: + Introduction to memory management ################################# @@ -9,5 +11,3 @@ Introduction to memory management alloc recycle lang - faq - diff --git a/mps/manual/source/mmref/lang.rst b/mps/manual/source/mmref/lang.rst index 0d081b82a30..247eb7c6c25 100644 --- a/mps/manual/source/mmref/lang.rst +++ b/mps/manual/source/mmref/lang.rst @@ -53,8 +53,9 @@ Memory management in various languages library functions for :term:`memory (2)` management in C, :term:`malloc` and :term:`free (2)`, have become almost synonymous with :term:`manual memory management`), although - with the Boehm-Weiser :term:`collector (1)`, it is now - possible to use :term:`garbage collection`. + with the Memory Pool System, or the Boehm–Demers–Weiser + collector, it is now possible to use :term:`garbage + collection`. The language is notorious for fostering memory management bugs, including: @@ -86,7 +87,8 @@ Memory management in various languages .. link:: - `Boehm-Weiser collector `_, + `Memory Pool System `_, + `Boehm–Demers–Weiser collector `_, `C standardization `_, `comp.lang.c Frequently Asked Questions `_. @@ -148,11 +150,11 @@ Memory management in various languages The :term:`garbage collector` in the .NET Framework is configurable to run in soft real time, or in batch mode. - The Mono runtime comes with two collectors: the Boehm–Weiser - :term:`conservative collector `, and a :term:`generational ` :term:`copying collector `. + The Mono runtime comes with two collectors: the + Boehm–Demers–Weiser :term:`conservative collector + `, and a :term:`generational + ` :term:`copying collector + `. .. link:: @@ -173,9 +175,9 @@ Memory management in various languages abstraction level of C++ makes the bookkeeping required for :term:`manual memory management` even harder. Although the standard library provides only manual memory management, with - the Boehm-Weiser :term:`collector (1)`, it is now possible to - use :term:`garbage collection`. :term:`Smart pointers` are - another popular solution. + the Memory Pool System, or the Boehm–Demers–Weiser collector, + it is now possible to use :term:`garbage collection`. + :term:`Smart pointers` are another popular solution. The language is notorious for fostering memory management bugs, including: @@ -222,6 +224,8 @@ Memory management in various languages .. link:: + `Memory Pool System `_, + `Boehm–Demers–Weiser collector `_, `comp.lang.c++ FAQ `_, `C++ standardization `_. diff --git a/mps/manual/source/pool/ams.rst b/mps/manual/source/pool/ams.rst index ae1d43f8bed..9fb1f9a9103 100644 --- a/mps/manual/source/pool/ams.rst +++ b/mps/manual/source/pool/ams.rst @@ -183,16 +183,16 @@ AMS interface takes three keyword arguments: :c:macro:`MPS_KEY_FORMAT` and :c:macro:`MPS_KEY_CHAIN` are as described above, and :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. - When using :c:func:`mps_pool_create`, pass the format, - chain, and debugging options like this:: + When using :c:func:`mps_pool_create`, pass the arguments like + this:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, 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_chain_t chain, mps_bool_t support_ambiguous) diff --git a/mps/manual/source/pool/intro.rst b/mps/manual/source/pool/intro.rst index ed8f83b8d4a..7abe7480e9b 100644 --- a/mps/manual/source/pool/intro.rst +++ b/mps/manual/source/pool/intro.rst @@ -100,35 +100,35 @@ it makes no sense to ask whether they may contain :term:`weak references (1)`. -============================================= ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== -Property AMC AMCZ AMS AWL LO MFS MV MVFF MVT SNC -============================================= ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== -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 allocation points? yes yes yes yes yes no yes yes yes yes -Supports allocation frames? yes yes yes yes yes no no yes yes yes -Supports segregated allocation caches? no no no no no yes yes yes no no -Timing of collections? [2]_ auto auto auto auto auto --- --- --- --- --- -May contain references? [3]_ yes no yes yes no no no no no yes -May contain exact references? [4]_ yes --- yes yes --- --- --- --- --- yes -May contain ambiguous references? [4]_ no --- no no --- --- --- --- --- no -May contain weak references? [4]_ no --- no yes --- --- --- --- --- no -Allocations fixed or variable in size? var var var var var fixed var var var var -Alignment? [5]_ conf conf conf conf conf [6]_ [6]_ [7]_ [7]_ conf -Dependent objects? [8]_ no --- no yes --- --- --- --- --- no -May use remote references? [9]_ no --- no no --- --- --- --- --- no -Blocks are automatically managed? [10]_ yes yes yes yes yes no no no no no -Blocks are promoted between generations yes yes no no no --- --- --- --- --- -Blocks are manually managed? [10]_ no no no no no yes yes yes yes yes -Blocks are scanned? [11]_ yes no yes yes no no no no no yes -Blocks support base pointers only? [12]_ no no yes yes yes --- --- --- --- yes -Blocks support internal pointers? [12]_ yes yes no no no --- --- --- --- no -Blocks may be protected by barriers? yes no yes yes yes no no no no yes -Blocks may move? yes yes no no no no no no no no -Blocks may be finalized? yes yes yes yes yes no no no no 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 -============================================= ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== +.. csv-table:: + :header: "Property", ":ref:`AMC `", ":ref:`AMCZ `", ":ref:`AMS `", ":ref:`AWL `", ":ref:`LO `", ":ref:`MFS `", ":ref:`MV `", ":ref:`MVFF `", ":ref:`MVT `", ":ref:`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 allocation points?, yes, yes, yes, yes, yes, no, yes, yes, yes, yes + Supports allocation frames?, yes, yes, yes, yes, yes, no, no, yes, yes, yes + Supports segregated allocation caches?, no, no, no, no, no, yes, yes, yes, no, no + Timing of collections? [2]_, auto, auto, auto, auto, auto, ---, ---, ---, ---, --- + May contain references? [3]_, yes, no, yes, yes, no, no, no, no, no, yes + May contain exact references? [4]_, yes, ---, yes, yes, ---, ---, ---, ---, ---, yes + May contain ambiguous references? [4]_, no, ---, no, no, ---, ---, ---, ---, ---, no + May contain weak references? [4]_, no, ---, no, yes, ---, ---, ---, ---, ---, no + Allocations fixed or variable in size?, var, var, var, var, var, fixed, var, var, var, var + Alignment? [5]_, conf, conf, conf, conf, conf, [6]_, [6]_, [7]_, [7]_, conf + Dependent objects? [8]_, no, ---, no, yes, ---, ---, ---, ---, ---, no + May use remote references? [9]_, no, ---, no, no, ---, ---, ---, ---, ---, no + Blocks are automatically managed? [10]_, yes, yes, yes, yes, yes, no, no, no, no, no + Blocks are promoted between generations, yes, yes, no, no, no, ---, ---, ---, ---, --- + Blocks are manually managed? [10]_, no, no, no, no, no, yes, yes, yes, yes, yes + Blocks are scanned? [11]_, yes, no, yes, yes, no, no, no, no, no, yes + Blocks support base pointers only? [12]_, no, no, yes, yes, yes, ---, ---, ---, ---, yes + Blocks support internal pointers? [12]_, yes, yes, no, no, no, ---, ---, ---, ---, no + Blocks may be protected by barriers?, yes, no, yes, yes, yes, no, no, no, no, yes + Blocks may move?, yes, yes, no, no, no, no, no, no, no, no + Blocks may be finalized?, yes, yes, yes, yes, yes, no, no, no, no, 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:: diff --git a/mps/manual/source/pool/mv.rst b/mps/manual/source/pool/mv.rst index 361cd41c0b5..d24ce3f273f 100644 --- a/mps/manual/source/pool/mv.rst +++ b/mps/manual/source/pool/mv.rst @@ -122,16 +122,17 @@ MV interface takes four keyword arguments: :c:macro:`MPS_KEY_EXTEND_SIZE`, :c:macro:`MPS_KEY_MEAN_SIZE`, :c:macro:`MPS_KEY_MAX_SIZE` are as 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. - When using :c:func:`mps_pool_create`, pass the debugging - options, segment size, mean size, and maximum size like this:: + When using :c:func:`mps_pool_create`, pass the arguments like + this:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, 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 average_size, mps_size_t maximum_size) diff --git a/mps/manual/source/pool/mvff.rst b/mps/manual/source/pool/mvff.rst index 64c220e9506..b05752a70de 100644 --- a/mps/manual/source/pool/mvff.rst +++ b/mps/manual/source/pool/mvff.rst @@ -207,16 +207,16 @@ MVFF interface :c:macro:`MPS_KEY_MVFF_SLOT_HIGH`, and :c:macro:`MPS_KEY_MVFF_FIRST_FIT` are as described above, and :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. - When using :c:func:`mps_pool_create`, pass the debugging - options, and other arguments like this:: + When using :c:func:`mps_pool_create`, pass the arguments like + this:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, 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 average_size, mps_align_t alignment, diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index 21d6ca6c13e..16bd2f16382 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -44,8 +44,8 @@ New features Interface changes ................. -#. There is now a default value (currently 1 \ :term:`megabyte`) for - the :c:macro:`MPS_KEY_ARENA_SIZE` keyword argument to +#. There is now a default value (currently 256 \ :term:`megabytes`) + for the :c:macro:`MPS_KEY_ARENA_SIZE` keyword argument to :c:func:`mps_arena_create_k` when creating a virtual memory arena. See :c:func:`mps_arena_class_vm`. @@ -87,10 +87,9 @@ Other changes .. _job003756: https://www.ravenbrook.com/project/mps/issue/job003756/ -#. :ref:`pool-ams` pools get reliably collected, even in the case - where an AMS pool is the only pool on its generation chain and is - allocating into some generation other than the nursery. See - job003771_. +#. An :ref:`pool-ams` pool gets collected even if it is the only pool + on its generation chain and is allocating into a generation other + than the nursery. See job003771_. .. _job003771: https://www.ravenbrook.com/project/mps/issue/job003771/ @@ -104,6 +103,44 @@ Other changes 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 ................. @@ -176,17 +213,23 @@ Interface changes #. Functions that take a variable number of arguments (:c:func:`mps_arena_create`, :c:func:`mps_pool_create`, - :c:func:`mps_ap_create`, :c:func:`mps_fmt_create_A`) and their - ``va_list`` alternatives (:c:func:`mps_arena_create_v` etc.) are - now deprecated in favour of functions that use a :term:`keyword - argument` interface (:c:func:`mps_arena_create_k`, - :c:func:`mps_pool_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`. + :c:func:`mps_ap_create`) and their ``va_list`` alternatives + (:c:func:`mps_arena_create_v` etc.) are now deprecated in favour of + functions that use a :term:`keyword argument` interface + (:c:func:`mps_arena_create_k`, :c:func:`mps_pool_create_k`, + :c:func:`mps_ap_create_k`). - The old interface continues to be supported, but new features will - become available through the keyword interface only. + Similarly, the object format variant structures + (: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 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/ -#. :ref:`pool-mvt` no longer triggers an assertion failure when it - runs out of space on its reserved block queue. See job003486_. +#. An :ref:`pool-mvt` pool no longer triggers an assertion failure + when it runs out of space on its reserved block queue. See + job003486_. .. _job003486: https://www.ravenbrook.com/project/mps/issue/job003486/ @@ -258,13 +302,13 @@ New features ` loads an event stream into a SQLite database for further analysis. See :ref:`topic-telemetry`. -#. The new pool class MFS provide manually managed allocation of - fixed-size objects. See :ref:`pool-mfs`. +#. The new pool class :ref:`pool-mfs` provides manually managed + allocation of fixed-size objects. -#. The new pool class MVT provide manually managed allocation of - variable-size objects using a *temporal fit* allocation policy - (that is, objects that are allocated togther are expected to be - freed together). See :ref:`pool-mvt`. +#. The new pool class :ref:`pool-mvt` provides manually managed + allocation of variable-size objects using a *temporal fit* + allocation policy (that is, objects that are allocated togther are + expected to be freed together). Interface changes diff --git a/mps/manual/source/themes/mmref/layout.html b/mps/manual/source/themes/mmref/layout.html new file mode 100644 index 00000000000..961baeda428 --- /dev/null +++ b/mps/manual/source/themes/mmref/layout.html @@ -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 %} +
+ +
+ {%- if prev and '/' not in prev.link and 'mmref-' not in prev.link %} + « {{ prev.title }} | + {%- endif %} + {{ title }} + {%- if next and '/' not in next.link and 'mmref-' not in next.link %} + | {{ next.title }} » + {%- endif %} +
+
+ {%- if display_toc %} +
+

{{ _('Table Of Contents') }}

+ {{ toc }} +
+ {%- endif %} + {% block body %}{% endblock %} +
+
+{% endblock %} diff --git a/mps/manual/source/themes/mmref/static/metal.png b/mps/manual/source/themes/mmref/static/metal.png new file mode 100644 index 00000000000..2f9f1ad0847 Binary files /dev/null and b/mps/manual/source/themes/mmref/static/metal.png differ diff --git a/mps/manual/source/themes/mmref/static/mmref.css_t b/mps/manual/source/themes/mmref/static/mmref.css_t new file mode 100644 index 00000000000..f16758a7391 --- /dev/null +++ b/mps/manual/source/themes/mmref/static/mmref.css_t @@ -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; +} diff --git a/mps/manual/source/themes/mmref/static/watermark.png b/mps/manual/source/themes/mmref/static/watermark.png new file mode 100644 index 00000000000..5bca5d2008b Binary files /dev/null and b/mps/manual/source/themes/mmref/static/watermark.png differ diff --git a/mps/manual/source/themes/mmref/static/watermark.svg b/mps/manual/source/themes/mmref/static/watermark.svg new file mode 100644 index 00000000000..ca9159234e1 --- /dev/null +++ b/mps/manual/source/themes/mmref/static/watermark.svg @@ -0,0 +1,237 @@ + + + + + + + + + + image/svg+xml + + + + + + + + 2e2f 6d70 7369 2e63 0073 697a 6520 3e203000 6d70 735f 6172 656e 615f 6f20 213d204e 554c 4c00 6d70 735f 706f 6f6c 5f6f2021 3d20 4e55 4c4c 006d 7073 5f66 6d745f6f 2021 3d20 4e55 4c4c 006d 7073 5f666d74 5f41 2021 3d20 4e55 4c4c 006d 70735f66 6d74 5f42 2021 3d20 4e55 4c4c 006d7073 5f66 6d74 2021 3d20 4e55 4c4c 006d7073 5f66 6d74 5f66 6978 6564 2021 3d204e55 4c4c 0054 4553 5454 2846 6f72 6d61742c 2066 6f72 6d61 7429 0054 4553 54542850 6f6f 6c2c 2070 6f6f 6c29 0070 5f6f2021 3d20 4e55 4c4c 006d 7073 5f61 705f6f20 213d 204e 554c 4c00 6d70 735f 61702021 3d20 4e55 4c4c 0054 4553 5454 28427566 6665 722c 2062 7566 2900 5445 53545428 4275 6666 6572 2c20 4275 6666 65724f66 4150 286d 7073 5f61 7029 2900 6d70735f 6170 2d3e 696e 6974 203d 3d20 6d70735f 6170 2d3e 616c 6c6f 6300 7020 213d204e 554c 4c00 7020 3d3d 206d 7073 5f61702d 3e69 6e69 7400 2876 6f69 6420 2a292828 6368 6172 202a 296d 7073 5f61 702d3e69 6e69 7420 2b20 7369 7a65 2920 3d3d206d 7073 5f61 702d 3e61 6c6c 6f63 00667261 6d65 5f6f 2021 3d20 4e55 4c4c 0053697a 6549 7341 6c69 676e 6564 2873 697a652c 2042 7566 6665 7250 6f6f 6c28 62756629 2d3e 616c 6967 6e6d 656e 7429 006d7073 5f73 6163 5f6f 2021 3d20 4e55 4c4c0054 4553 5454 2853 4143 2c20 7361 63290054 4553 5454 2853 4143 2c20 5341 434f6645 7874 6572 6e61 6c53 4143 286d 7073 + + diff --git a/mps/manual/source/themes/mmref/theme.conf b/mps/manual/source/themes/mmref/theme.conf new file mode 100644 index 00000000000..e0ef30ece1b --- /dev/null +++ b/mps/manual/source/themes/mmref/theme.conf @@ -0,0 +1,18 @@ +# Colour scheme: + +[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 diff --git a/mps/manual/source/themes/mps/static/mps.css_t b/mps/manual/source/themes/mps/static/mps.css_t index b21939b7af6..5904c165580 100644 --- a/mps/manual/source/themes/mps/static/mps.css_t +++ b/mps/manual/source/themes/mps/static/mps.css_t @@ -139,6 +139,9 @@ dl.glossary dt, dl.type dt, dl.function dt, dl.macro dt { margin-top: 2em; margin-bottom: 1em; 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. */ padding-left: 4em; text-indent: -4em; @@ -185,7 +188,7 @@ p.glossary-alphabet { } sup { - vertical-align: 20%; + vertical-align: top; font-size: 80%; } @@ -217,3 +220,22 @@ li.toctree-l1, li.toctree-l2, li.toctree-l3 { 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; +} diff --git a/mps/manual/source/topic/arena.rst b/mps/manual/source/topic/arena.rst index 86e0a39550f..8fd61fed6bf 100644 --- a/mps/manual/source/topic/arena.rst +++ b/mps/manual/source/topic/arena.rst @@ -236,7 +236,7 @@ Virtual memory arenas accepts one :term:`keyword argument` on all platforms: * :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 is initially reserved so that the arena can subsequently use it without interference from other parts of the program, but diff --git a/mps/manual/source/topic/error.rst b/mps/manual/source/topic/error.rst index 200c20af8bb..e65f6eafebd 100644 --- a/mps/manual/source/topic/error.rst +++ b/mps/manual/source/topic/error.rst @@ -233,6 +233,13 @@ cause), please :ref:`let us know ` so that we can improve 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`` The client program wrote to a location after the end, or before diff --git a/mps/manual/source/topic/finalization.rst b/mps/manual/source/topic/finalization.rst index 745feefed16..5b65d9945dd 100644 --- a/mps/manual/source/topic/finalization.rst +++ b/mps/manual/source/topic/finalization.rst @@ -51,7 +51,7 @@ the block was allocated. to do the finalization. In such an implementation, the client program's finalization code may end up running concurrently with 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 (2002) ` for a detailed discussion of this issue. @@ -170,8 +170,9 @@ Cautions #. The MPS does not finalize objects in the context of :c:func:`mps_arena_destroy` or :c:func:`mps_pool_destroy`. - :c:func:`mps_pool_destroy` should therefore not be invoked on pools - containing objects registered for finalization. + Moreover, if you have pools containing objects registered for + finalization, you must destroy these pools by following the “safe + tear-down” procedure described under :c:func:`mps_pool_destroy`. .. note:: @@ -189,11 +190,6 @@ Cautions .. 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 are finalized is to maintain a table of :term:`weak references (1)` to all such objects. The weak references don't diff --git a/mps/manual/source/topic/interface.rst b/mps/manual/source/topic/interface.rst index a939ddf302b..54637557f60 100644 --- a/mps/manual/source/topic/interface.rst +++ b/mps/manual/source/topic/interface.rst @@ -194,7 +194,7 @@ out parameter, like this:: res = mps_alloc((mps_addr_t *)&fp, pool, sizeof(struct foo)); This is known as :term:`type punning`, and its behaviour is not -defined in ANSI/ISO Standard C. See :ref:`ISO/IEC 9899:1990 ` +defined in ANSI/ISO Standard C. See :ref:`ISO/IEC 9899:1990 ` §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 in the standard. @@ -209,7 +209,7 @@ Instead, we recommend this approach:: This has defined behaviour because conversion from ``void *`` to any other :term:`object pointer` type is defined by :ref:`ISO/IEC -9899:1990 ` §6.3.2.3.1. +9899:1990 ` §6.3.2.3.1. .. index:: @@ -219,7 +219,7 @@ Macros ------ #. For function-like macros, the MPS follows the same convention as - the Standard C library. To quote :ref:`ISO/IEC 9899:1990 ` + the Standard C library. To quote :ref:`ISO/IEC 9899:1990 ` §7.1.7: Any function declared in a header may additionally be diff --git a/mps/manual/source/topic/plinth.rst b/mps/manual/source/topic/plinth.rst index a7e94d21a0b..daba2ad62de 100644 --- a/mps/manual/source/topic/plinth.rst +++ b/mps/manual/source/topic/plinth.rst @@ -296,7 +296,7 @@ Library module This function is intended to have the same semantics as the :c:func:`fputc` function of the ANSI C Standard (:ref:`ISO/IEC - 9899:1990 ` §7.11.7.3). + 9899:1990 ` §7.11.7.3). .. note:: @@ -314,7 +314,7 @@ Library module This function is intended to have the same semantics as the :c:func:`fputs` function of the ANSI C Standard (:ref:`ISO/IEC - 9899:1990 ` §7.11.7.4). + 9899:1990 ` §7.11.7.4). Return a non-negative integer if successful, or :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 :c:func:`memcmp` function of the ANSI C Standard (:ref:`ISO/IEC - 9899:1990 ` §7.11.4.1). + 9899:1990 ` §7.11.4.1). .. note:: @@ -406,7 +406,7 @@ Library module This function is intended to have the same semantics as the :c:func:`memcpy` function of the ANSI C Standard (:ref:`ISO/IEC - 9899:1990 ` §7.11.2.1). + 9899:1990 ` §7.11.2.1). The MPS never passes overlapping blocks to :c:func:`mps_lib_memcpy`. @@ -432,7 +432,7 @@ Library module This function is intended to have the same semantics as the :c:func:`memset` function of the ANSI C Standard (:ref:`ISO/IEC - 9899:1990 ` §7.11.6.1). + 9899:1990 ` §7.11.6.1). .. note:: diff --git a/mps/manual/source/topic/scanning.rst b/mps/manual/source/topic/scanning.rst index 474ec637dd8..a36da60bf0c 100644 --- a/mps/manual/source/topic/scanning.rst +++ b/mps/manual/source/topic/scanning.rst @@ -60,8 +60,8 @@ region to be scanned. They must carry out the following steps: function as soon as practicable. #. If :c:func:`MPS_FIX2` returns :c:macro:`MPS_RES_OK`, it may have - updated the reference. If necessary, make sure that the updated - reference is stored back to the region being scanned. + updated the reference. Make sure that the updated reference is + stored back into the region being scanned. #. Call the macro :c:func:`MPS_SCAN_END` on the scan state. @@ -463,15 +463,18 @@ Fixing interface :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. - Returns :c:macro:`MPS_RES_OK` if successful: in this case the - reference may have been updated, and the scan method must continue - to scan the :term:`block`. If it returns any other result, the - :term:`scan method` must return that result as soon as possible, - without fixing any further references. + Returns :c:macro:`MPS_RES_OK` if successful. In this case the + reference may have been updated, and so the scan method must store + the updated reference back to the region being scanned. The scan + method must continue to scan the :term:`block`. + + 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 :c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`. diff --git a/mps/procedure/release-build.rst b/mps/procedure/release-build.rst index ee65b5f645d..6624e0b8341 100644 --- a/mps/procedure/release-build.rst +++ b/mps/procedure/release-build.rst @@ -102,6 +102,10 @@ All relative paths are relative to 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) ------------------------------------------- diff --git a/mps/tool/branch b/mps/tool/branch index bb54f0d4527..981735d4360 100755 --- a/mps/tool/branch +++ b/mps/tool/branch @@ -1,11 +1,10 @@ #!/usr/bin/env python # -# Ravenbrook -# -# # BRANCH -- CREATE VERSION OR TASK BRANCH -# # Gareth Rees, Ravenbrook Limited, 2014-03-18 +# +# $Id$ +# Copyright (c) 2014 Ravenbrook Limited. See end of file for license. # # # 1. INTRODUCTION diff --git a/mps/tool/noaslr.c b/mps/tool/noaslr.c new file mode 100644 index 00000000000..3ae73dc9362 --- /dev/null +++ b/mps/tool/noaslr.c @@ -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" + * + * + * 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. + * + */ + +#include +#include +#include +#include + +#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 . + * All rights reserved. This is an open source license. Contact + * Ravenbrook for commercial licensing options. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Redistributions in any form must be accompanied by information on how + * to obtain complete source code for this software and any accompanying + * software that uses this software. The source code must either be + * included in the distribution or be available for no more than the cost + * of distribution plus a nominal fee, and must be freely redistributable + * under reasonable conditions. For an executable file, complete source + * code means the source code for all modules it contains. It does not + * include source code for modules or files that typically accompany the + * major components of the operating system on which the executable file + * runs. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/mps/tool/release b/mps/tool/release index 6daf82bed1c..d47fc36e788 100755 --- a/mps/tool/release +++ b/mps/tool/release @@ -1,11 +1,10 @@ #!/usr/bin/env python # -# Ravenbrook -# -# # RELEASE -- MAKE A RELEASE -# # Gareth Rees, Ravenbrook Limited, 2014-03-18 +# +# $Id$ +# Copyright (c) 2014 Ravenbrook Limited. See end of file for license. # # # 1. INTRODUCTION diff --git a/mps/tool/testaslr.c b/mps/tool/testaslr.c new file mode 100644 index 00000000000..f421565b7be --- /dev/null +++ b/mps/tool/testaslr.c @@ -0,0 +1,62 @@ +/* testaslr.c: Simple test for ASLR + * + * $Id: //info.ravenbrook.com/project/mps/master/code/eventcnv.c#26 $ + * Copyright (c) 2014 Ravenbrook Limited. See end of file for license. + * + * Run this program multiple times and see if gets different addresses. + */ + +#include +#include + +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; +} + + +/* C. COPYRIGHT AND LICENSE + * + * Copyright (C) 2014 Ravenbrook Limited . + * All rights reserved. This is an open source license. Contact + * Ravenbrook for commercial licensing options. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Redistributions in any form must be accompanied by information on how + * to obtain complete source code for this software and any accompanying + * software that uses this software. The source code must either be + * included in the distribution or be available for no more than the cost + * of distribution plus a nominal fee, and must be freely redistributable + * under reasonable conditions. For an executable file, complete source + * code means the source code for all modules it contains. It does not + * include source code for modules or files that typically accompany the + * major components of the operating system on which the executable file + * runs. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/mps/tool/testcoverage b/mps/tool/testcoverage index cf4c62ae703..56ee5789bbf 100755 --- a/mps/tool/testcoverage +++ b/mps/tool/testcoverage @@ -1,11 +1,10 @@ #!/bin/sh # -# Ravenbrook -# -# # TESTCOVERAGE -- TEST COVERAGE REPORT FOR THE MPS -# # Gareth Rees, Ravenbrook Limited, 2014-03-21 +# +# $Id$ +# Copyright (c) 2014 Ravenbrook Limited. See end of file for license. # # # 1. INTRODUCTION diff --git a/mps/tool/testemscripten b/mps/tool/testemscripten index 4639e9e69a4..b4c565440db 100755 --- a/mps/tool/testemscripten +++ b/mps/tool/testemscripten @@ -1,11 +1,10 @@ #!/bin/sh # -# Ravenbrook -# -# # TESTEMSCRIPTEN -- TEST THE MPS WITH EMSCRIPTEN -# # Gareth Rees, Ravenbrook Limited, 2014-04-17 +# +# $Id$ +# Copyright (c) 2014 Ravenbrook Limited. See end of file for license. # # # 1. INTRODUCTION diff --git a/mps/tool/testopendylan b/mps/tool/testopendylan index 0c185ff2fd0..4bd1488261c 100755 --- a/mps/tool/testopendylan +++ b/mps/tool/testopendylan @@ -1,11 +1,10 @@ #!/bin/sh # -# Ravenbrook -# -# # TESTOPENDYLAN -- TEST THE MPS WITH OPENDYLAN -# # Gareth Rees, Ravenbrook Limited, 2014-03-20 +# +# $Id$ +# Copyright (c) 2014 Ravenbrook Limited. See end of file for license. # # # 1. INTRODUCTION