From 84ddecde2f29f00c139527fc310e2ae4abdfbdc9 Mon Sep 17 00:00:00 2001 From: David Lovemore
*/
#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`