1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-01 01:41:01 -08:00

Amc now respects mps_key_extend_by keyword argument.

AMC also uses MPS_KEY_LARGE_SIZE keyword argument to specify what size objects need to be to live on their own segment.

Copied from Perforce
 Change: 186480
 ServerID: perforce.ravenbrook.com
This commit is contained in:
David Lovemore 2014-06-11 12:12:44 +01:00
parent dea203cdd3
commit 84ddecde2f
7 changed files with 52 additions and 16 deletions

View file

@ -333,8 +333,9 @@
/* Pool AMC Configuration -- see <code/poolamc.c> */
#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 <code/poolams.c> */

View file

@ -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) \

View file

@ -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

View file

@ -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);

View file

@ -471,6 +471,8 @@ typedef struct AMCStruct { /* <design/poolamc/#struct> */
unsigned rampCount; /* <design/poolamc/#ramp.count> */
int rampMode; /* <design/poolamc/#ramp.mode> */
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);

View file

@ -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) {

View file

@ -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`