diff --git a/mps/code/config.h b/mps/code/config.h index e4db1be6423..f740d0792ec 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -333,8 +333,9 @@ /* Pool AMC Configuration -- see */ #define AMC_INTERIOR_DEFAULT TRUE -/* AMC treats segments of this many pages (or more) as "Large" */ -#define AMCLargeSegPAGES ((Count)8) +/* AMC treats segments of larger than this as "Large" */ +#define AMC_LARGE_SIZE_DEFAULT ((Size)32768) +#define AMC_EXTEND_BY_DEFAULT ((Size)4096) /* Pool AMS Configuration -- see */ diff --git a/mps/code/eventdef.h b/mps/code/eventdef.h index 0c94da20cf4..ab0310337dc 100644 --- a/mps/code/eventdef.h +++ b/mps/code/eventdef.h @@ -36,7 +36,7 @@ */ #define EVENT_VERSION_MAJOR ((unsigned)1) -#define EVENT_VERSION_MEDIAN ((unsigned)2) +#define EVENT_VERSION_MEDIAN ((unsigned)3) #define EVENT_VERSION_MINOR ((unsigned)0) @@ -693,7 +693,7 @@ PARAM(X, 0, W, epoch) /* current arena epoch */ \ PARAM(X, 1, U, why) /* reason trace started */ \ PARAM(X, 2, W, align) /* arena alignment */ \ - PARAM(X, 3, W, large) /* AMCLargeSegPAGES */ \ + PARAM(X, 3, W, large) /* AMC large size */ \ PARAM(X, 4, W, pRetMin) /* threshold for event */ \ /* remaining parameters are copy of PageRetStruct, which see */ \ PARAM(X, 5, W, pCond) \ diff --git a/mps/code/mps.h b/mps/code/mps.h index 56c0c06061e..2a6c3c82c0d 100644 --- a/mps/code/mps.h +++ b/mps/code/mps.h @@ -176,6 +176,9 @@ extern const struct mps_key_s _mps_key_rank; extern const struct mps_key_s _mps_key_extend_by; #define MPS_KEY_EXTEND_BY (&_mps_key_extend_by) #define MPS_KEY_EXTEND_BY_FIELD size +extern const struct mps_key_s _mps_key_large_size; +#define MPS_KEY_LARGE_SIZE (&_mps_key_large_size) +#define MPS_KEY_LARGE_SIZE_FIELD size extern const struct mps_key_s _mps_key_min_size; #define MPS_KEY_MIN_SIZE (&_mps_key_min_size) #define MPS_KEY_MIN_SIZE_FIELD size diff --git a/mps/code/pool.c b/mps/code/pool.c index a809cc68c10..fea181e7a3f 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -110,6 +110,7 @@ ARG_DEFINE_KEY(chain, Chain); ARG_DEFINE_KEY(gen, Cant); ARG_DEFINE_KEY(rank, Rank); ARG_DEFINE_KEY(extend_by, Size); +ARG_DEFINE_KEY(large_size, Size); ARG_DEFINE_KEY(min_size, Size); ARG_DEFINE_KEY(mean_size, Size); ARG_DEFINE_KEY(max_size, Size); diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index 12f7c5e99f7..c254a5d8a15 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -471,6 +471,8 @@ typedef struct AMCStruct { /* */ unsigned rampCount; /* */ int rampMode; /* */ amcPinnedMethod pinned; /* function determining if block is pinned */ + Size extendBy; /* segment size to extend pool by */ + Size large; /* min size of "large" segments */ /* page retention in an in-progress trace */ STATISTIC_DECL(PageRetStruct pageretstruct[TraceLIMIT]); @@ -803,6 +805,8 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) size_t genCount; Bool interior = AMC_INTERIOR_DEFAULT; Chain chain; + Size extendBy = AMC_EXTEND_BY_DEFAULT; + Size large = AMC_LARGE_SIZE_DEFAULT; ArgStruct arg; /* Suppress a warning about this structure not being used when there @@ -828,9 +832,18 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) chain = ArenaGlobals(arena)->defaultChain; if (ArgPick(&arg, args, MPS_KEY_INTERIOR)) interior = arg.val.b; + if (ArgPick(&arg, args, MPS_KEY_EXTEND_BY)) { + extendBy = arg.val.size; + AVER(SizeIsAligned(extendBy, ArenaAlign(arena))); + } + if (ArgPick(&arg, args, MPS_KEY_LARGE_SIZE)) { + large = arg.val.size; + } AVERT(Format, pool->format); AVERT(Chain, chain); + AVER(extendBy > 0); + AVER(large > 0); pool->alignment = pool->format->alignment; amc->rankSet = rankSet; @@ -861,6 +874,9 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) } else { amc->pinned = amcPinnedBase; } + /* .extend-by.aligned: extendBy is aligned to the arena alignment. */ + amc->extendBy = SizeAlignUp(extendBy, ArenaAlign(arena)); + amc->large = large; amc->sig = AMCSig; AVERT(AMC, amc); @@ -1015,7 +1031,11 @@ static Res AMCBufferFill(Addr *baseReturn, Addr *limitReturn, /* Create and attach segment. The location of this segment is */ /* expressed via the pool generation. We rely on the arena to */ /* organize locations appropriately. */ - alignedSize = SizeAlignUp(size, ArenaAlign(arena)); + if (size < amc->extendBy) { + alignedSize = amc->extendBy; /* .extend-by.aligned */ + } else { + alignedSize = SizeAlignUp(size, ArenaAlign(arena)); + } MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD_FIELD(args, amcKeySegGen, p, gen); res = PoolGenAlloc(&seg, pgen, amcSegClassGet(), alignedSize, @@ -1042,7 +1062,7 @@ static Res AMCBufferFill(Addr *baseReturn, Addr *limitReturn, } base = SegBase(seg); - if(alignedSize < AMCLargeSegPAGES * ArenaAlign(arena)) { + if(alignedSize < amc->large) { /* Small or Medium segment: give the buffer the entire seg. */ limit = AddrAdd(base, alignedSize); AVER(limit == SegLimit(seg)); @@ -1093,7 +1113,7 @@ static void AMCBufferEmpty(Pool pool, Buffer buffer, AVER(init <= limit); arena = BufferArena(buffer); - if(SegSize(seg) < AMCLargeSegPAGES * ArenaAlign(arena)) { + if(SegSize(seg) < amc->large) { /* Small or Medium segment: buffer had the entire seg. */ AVER(limit == SegLimit(seg)); } else { @@ -1282,13 +1302,14 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg) STATISTIC_STAT( { Count pages; - AVER(SizeIsAligned(SegSize(seg), ArenaAlign(pool->arena))); - pages = SegSize(seg) / ArenaAlign(pool->arena); + Size size = SegSize(seg); + AVER(SizeIsAligned(size, ArenaAlign(pool->arena))); + pages = size / ArenaAlign(pool->arena); AVER(pages != 0); amc->pageretstruct[trace->ti].pCond += pages; if(pages == 1) { amc->pageretstruct[trace->ti].pCS += pages; - } else if(pages < AMCLargeSegPAGES) { + } else if(size < amc->large) { amc->pageretstruct[trace->ti].sCM += 1; amc->pageretstruct[trace->ti].pCM += pages; } else { @@ -2007,13 +2028,14 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg) /* Seg retained */ STATISTIC_STAT( { Count pages; - AVER(SizeIsAligned(SegSize(seg), ArenaAlign(pool->arena))); - pages = SegSize(seg) / ArenaAlign(pool->arena); + Size size = SegSize(seg); + AVER(SizeIsAligned(size, ArenaAlign(pool->arena))); + pages = size / ArenaAlign(pool->arena); AVER(pages != 0); amc->pageretstruct[trace->ti].pRet += pages; if(pages == 1) { amc->pageretstruct[trace->ti].pRS += pages; - } else if(pages < AMCLargeSegPAGES) { + } else if(size < amc->large) { amc->pageretstruct[trace->ti].sRM += 1; amc->pageretstruct[trace->ti].pRM += pages; if(obj1pip) { @@ -2104,7 +2126,7 @@ static void AMCTraceEnd(Pool pool, Trace trace) PageRetStruct *pr = &amc->pageretstruct[ti]; if(pr->pRet >= pRetMin) { EVENT21(AMCTraceEnd, ArenaEpoch(pool->arena), (EventFU)trace->why, - ArenaAlign(pool->arena), AMCLargeSegPAGES, pRetMin, pr->pCond, + ArenaAlign(pool->arena), amc->large, pRetMin, pr->pCond, pr->pRet, pr->pCS, pr->pRS, pr->sCM, pr->pCM, pr->sRM, pr->pRM, pr->pRM1, pr->pRMrr, pr->pRMr1, pr->sCL, pr->pCL, pr->sRL, pr->pRL, pr->pRLr); diff --git a/mps/manual/source/pool/amc.rst b/mps/manual/source/pool/amc.rst index e09cef8cb14..00e977b23cf 100644 --- a/mps/manual/source/pool/amc.rst +++ b/mps/manual/source/pool/amc.rst @@ -115,7 +115,7 @@ AMC interface method`, a :term:`forward method`, an :term:`is-forwarded method` and a :term:`padding method`. - It accepts two optional keyword arguments: + It accepts four optional keyword arguments: * :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies the :term:`generation chain` for the pool. If not specified, the @@ -127,6 +127,14 @@ AMC interface objects alive. If this is ``FALSE``, then only :term:`client pointers` keep objects alive. + * :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`, + default 4096) is the default :term:`size` of segment that the pool will + request from the :term:`arena`. + + * :c:macro:`MPS_KEY_LARGE_SIZE` (type :c:type:`size_t`, + default 32768) is the minimum :term:`size` of object (larger than the + extend by value) that will be allocated on its own segment. + For example:: MPS_ARGS_BEGIN(args) { diff --git a/mps/manual/source/topic/keyword.rst b/mps/manual/source/topic/keyword.rst index 3b3fbcb01ad..86e7debe642 100644 --- a/mps/manual/source/topic/keyword.rst +++ b/mps/manual/source/topic/keyword.rst @@ -92,7 +92,8 @@ now :c:macro:`MPS_KEY_ARGS_END`. :c:macro:`MPS_KEY_ARENA_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl` :c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` ``void *(*)(void *)`` ``addr_method`` :c:func:`mps_class_awl` :c:macro:`MPS_KEY_CHAIN` :c:type:`mps_chain_t` ``chain`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` - :c:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff` + :c:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff` + :c:macro:`MPS_KEY_LARGE_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz` :c:macro:`MPS_KEY_FMT_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_CLASS` :c:type:`mps_fmt_class_t` ``fmt_class`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_FWD` :c:type:`mps_fmt_fwd_t` ``fmt_fwd`` :c:func:`mps_fmt_create_k`