mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-24 14:30:43 -08:00
Catch-up merge from master sources to branch/2015-08-06/config.
Copied from Perforce Change: 188146 ServerID: perforce.ravenbrook.com
This commit is contained in:
commit
c2d2eacdb2
8 changed files with 136 additions and 63 deletions
100
mps/code/arena.c
100
mps/code/arena.c
|
|
@ -243,10 +243,11 @@ Res ArenaInit(Arena arena, ArenaClass class, Size grainSize, ArgList args)
|
|||
arena->sig = ArenaSig;
|
||||
AVERT(Arena, arena);
|
||||
|
||||
/* Initialise a pool to hold the arena's CBS blocks. This pool can't be
|
||||
allowed to extend itself using ArenaAlloc because it is used during
|
||||
ArenaAlloc, so MFSExtendSelf is set to FALSE. Failures to extend are
|
||||
handled where the Land is used. */
|
||||
/* Initialise a pool to hold the CBS blocks for the arena's free
|
||||
* land. This pool can't be allowed to extend itself using
|
||||
* ArenaAlloc because it is used to implement ArenaAlloc, so
|
||||
* MFSExtendSelf is set to FALSE. Failures to extend are handled
|
||||
* where the free land is used: see arenaFreeLandInsertExtend. */
|
||||
|
||||
MPS_ARGS_BEGIN(piArgs) {
|
||||
MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSZonedBlockStruct));
|
||||
|
|
@ -258,18 +259,6 @@ Res ArenaInit(Arena arena, ArenaClass class, Size grainSize, ArgList args)
|
|||
if (res != ResOK)
|
||||
goto failMFSInit;
|
||||
|
||||
/* Initialise the freeLand. */
|
||||
MPS_ARGS_BEGIN(liArgs) {
|
||||
MPS_ARGS_ADD(liArgs, CBSBlockPool, ArenaCBSBlockPool(arena));
|
||||
res = LandInit(ArenaFreeLand(arena), CBSZonedLandClassGet(), arena,
|
||||
ArenaGrainSize(arena), arena, liArgs);
|
||||
} MPS_ARGS_END(liArgs);
|
||||
AVER(res == ResOK); /* no allocation, no failure expected */
|
||||
if (res != ResOK)
|
||||
goto failLandInit;
|
||||
/* Note that although freeLand is initialised, it doesn't have any memory
|
||||
for its blocks, so hasFreeLand remains FALSE until later. */
|
||||
|
||||
/* initialize the reservoir, <design/reservoir/> */
|
||||
res = ReservoirInit(&arena->reservoirStruct, arena);
|
||||
if (res != ResOK)
|
||||
|
|
@ -279,8 +268,6 @@ Res ArenaInit(Arena arena, ArenaClass class, Size grainSize, ArgList args)
|
|||
return ResOK;
|
||||
|
||||
failReservoirInit:
|
||||
LandFinish(ArenaFreeLand(arena));
|
||||
failLandInit:
|
||||
PoolFinish(ArenaCBSBlockPool(arena));
|
||||
failMFSInit:
|
||||
GlobalsFinish(ArenaGlobals(arena));
|
||||
|
|
@ -316,16 +303,33 @@ static Res arenaFreeLandInit(Arena arena)
|
|||
AVER(!arena->hasFreeLand);
|
||||
AVER(arena->primary != NULL);
|
||||
|
||||
/* With the primary chunk initialised we can add page memory to the freeLand
|
||||
* that describes the free address space in the primary chunk. */
|
||||
/* Initialise the free land. */
|
||||
MPS_ARGS_BEGIN(liArgs) {
|
||||
MPS_ARGS_ADD(liArgs, CBSBlockPool, ArenaCBSBlockPool(arena));
|
||||
res = LandInit(ArenaFreeLand(arena), CBSZonedLandClassGet(), arena,
|
||||
ArenaGrainSize(arena), arena, liArgs);
|
||||
} MPS_ARGS_END(liArgs);
|
||||
AVER(res == ResOK); /* no allocation, no failure expected */
|
||||
if (res != ResOK)
|
||||
goto failLandInit;
|
||||
|
||||
/* With the primary chunk initialised we can add page memory to the
|
||||
* free land that describes the free address space in the primary
|
||||
* chunk. */
|
||||
res = ArenaFreeLandInsert(arena,
|
||||
PageIndexBase(arena->primary,
|
||||
arena->primary->allocBase),
|
||||
arena->primary->limit);
|
||||
if (res != ResOK)
|
||||
return res;
|
||||
goto failFreeLandInsert;
|
||||
|
||||
arena->hasFreeLand = TRUE;
|
||||
return ResOK;
|
||||
|
||||
failFreeLandInsert:
|
||||
LandFinish(ArenaFreeLand(arena));
|
||||
failLandInit:
|
||||
return res;
|
||||
}
|
||||
|
||||
Res ArenaCreate(Arena *arenaReturn, ArenaClass class, ArgList args)
|
||||
|
|
@ -441,16 +445,16 @@ static void arenaMFSPageFreeVisitor(Pool pool, Addr base, Size size,
|
|||
|
||||
static void arenaFreeLandFinish(Arena arena)
|
||||
{
|
||||
/* We must tear down the freeLand before the chunks, because pages
|
||||
* containing CBS blocks might be allocated in those chunks. */
|
||||
AVERT(Arena, arena);
|
||||
AVER(arena->hasFreeLand);
|
||||
arena->hasFreeLand = FALSE;
|
||||
LandFinish(ArenaFreeLand(arena));
|
||||
|
||||
|
||||
/* The CBS block pool can't free its own memory via ArenaFree because
|
||||
* that would use the freeLand. */
|
||||
* that would use the free land. */
|
||||
MFSFinishTracts(ArenaCBSBlockPool(arena), arenaMFSPageFreeVisitor,
|
||||
UNUSED_POINTER, UNUSED_SIZE);
|
||||
|
||||
arena->hasFreeLand = FALSE;
|
||||
LandFinish(ArenaFreeLand(arena));
|
||||
}
|
||||
|
||||
void ArenaDestroy(Arena arena)
|
||||
|
|
@ -464,6 +468,8 @@ void ArenaDestroy(Arena arena)
|
|||
|
||||
ControlFinish(arena);
|
||||
|
||||
/* We must tear down the free land before the chunks, because pages
|
||||
* containing CBS blocks might be allocated in those chunks. */
|
||||
arenaFreeLandFinish(arena);
|
||||
|
||||
/* Call class-specific finishing. This will call ArenaFinish. */
|
||||
|
|
@ -854,7 +860,7 @@ static Res arenaExtendCBSBlockPool(Range pageRangeReturn, Arena arena)
|
|||
return res;
|
||||
MFSExtend(ArenaCBSBlockPool(arena), pageBase, ArenaGrainSize(arena));
|
||||
|
||||
RangeInit(pageRangeReturn, pageBase, AddrAdd(pageBase, ArenaGrainSize(arena)));
|
||||
RangeInitSize(pageRangeReturn, pageBase, ArenaGrainSize(arena));
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
|
@ -874,15 +880,19 @@ static void arenaExcludePage(Arena arena, Range pageRange)
|
|||
}
|
||||
|
||||
|
||||
/* arenaLandInsert -- add range to arena's land, maybe extending block pool
|
||||
/* arenaFreeLandInsertExtend -- add range to arena's free land, maybe
|
||||
* extending block pool
|
||||
*
|
||||
* The arena's land can't get memory in the usual way because it is
|
||||
* used in the basic allocator, so we allocate pages specially.
|
||||
* The arena's free land can't get memory for its block pool in the
|
||||
* usual way (via ArenaAlloc), because it is the mechanism behind
|
||||
* ArenaAlloc! So we extend the block pool via a back door (see
|
||||
* arenaExtendCBSBlockPool).
|
||||
*
|
||||
* Only fails if it can't get a page for the block pool.
|
||||
*/
|
||||
|
||||
static Res arenaLandInsert(Range rangeReturn, Arena arena, Range range)
|
||||
static Res arenaFreeLandInsertExtend(Range rangeReturn, Arena arena,
|
||||
Range range)
|
||||
{
|
||||
Res res;
|
||||
|
||||
|
|
@ -908,16 +918,18 @@ static Res arenaLandInsert(Range rangeReturn, Arena arena, Range range)
|
|||
}
|
||||
|
||||
|
||||
/* ArenaFreeLandInsert -- add range to arena's land, maybe stealing memory
|
||||
/* arenaFreeLandInsertSteal -- add range to arena's free land, maybe
|
||||
* stealing memory
|
||||
*
|
||||
* See arenaLandInsert. This function may only be applied to mapped
|
||||
* pages and may steal them to store Land nodes if it's unable to
|
||||
* allocate space for CBS blocks.
|
||||
* See arenaFreeLandInsertExtend. This function may only be applied to
|
||||
* mapped pages and may steal them to store Land nodes if it's unable
|
||||
* to allocate space for CBS blocks.
|
||||
*
|
||||
* IMPORTANT: May update rangeIO.
|
||||
*/
|
||||
|
||||
static void arenaLandInsertSteal(Range rangeReturn, Arena arena, Range rangeIO)
|
||||
static void arenaFreeLandInsertSteal(Range rangeReturn, Arena arena,
|
||||
Range rangeIO)
|
||||
{
|
||||
Res res;
|
||||
|
||||
|
|
@ -925,7 +937,7 @@ static void arenaLandInsertSteal(Range rangeReturn, Arena arena, Range rangeIO)
|
|||
AVERT(Arena, arena);
|
||||
AVERT(Range, rangeIO);
|
||||
|
||||
res = arenaLandInsert(rangeReturn, arena, rangeIO);
|
||||
res = arenaFreeLandInsertExtend(rangeReturn, arena, rangeIO);
|
||||
|
||||
if (res != ResOK) {
|
||||
Addr pageBase;
|
||||
|
|
@ -954,7 +966,8 @@ static void arenaLandInsertSteal(Range rangeReturn, Arena arena, Range rangeIO)
|
|||
}
|
||||
|
||||
|
||||
/* ArenaFreeLandInsert -- add range to arena's land, maybe extending block pool
|
||||
/* ArenaFreeLandInsert -- add range to arena's free land, maybe extending
|
||||
* block pool
|
||||
*
|
||||
* The inserted block of address space may not abut any existing block.
|
||||
* This restriction ensures that we don't coalesce chunks and allocate
|
||||
|
|
@ -969,7 +982,7 @@ Res ArenaFreeLandInsert(Arena arena, Addr base, Addr limit)
|
|||
AVERT(Arena, arena);
|
||||
|
||||
RangeInit(&range, base, limit);
|
||||
res = arenaLandInsert(&oldRange, arena, &range);
|
||||
res = arenaFreeLandInsertExtend(&oldRange, arena, &range);
|
||||
if (res != ResOK)
|
||||
return res;
|
||||
|
||||
|
|
@ -984,7 +997,8 @@ Res ArenaFreeLandInsert(Arena arena, Addr base, Addr limit)
|
|||
}
|
||||
|
||||
|
||||
/* ArenaFreeLandDelete -- remove range from arena's land, maybe extending block pool
|
||||
/* ArenaFreeLandDelete -- remove range from arena's free land, maybe
|
||||
* extending block pool
|
||||
*
|
||||
* This is called from ChunkFinish in order to remove address space from
|
||||
* the arena.
|
||||
|
|
@ -1076,7 +1090,7 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high,
|
|||
|
||||
failMark:
|
||||
{
|
||||
Res insertRes = arenaLandInsert(&oldRange, arena, &range);
|
||||
Res insertRes = arenaFreeLandInsertExtend(&oldRange, arena, &range);
|
||||
AVER(insertRes == ResOK); /* We only just deleted it. */
|
||||
/* If the insert does fail, we lose some address space permanently. */
|
||||
}
|
||||
|
|
@ -1288,7 +1302,7 @@ void ArenaFree(Addr base, Size size, Pool pool)
|
|||
|
||||
RangeInit(&range, base, limit);
|
||||
|
||||
arenaLandInsertSteal(&oldRange, arena, &range); /* may update range */
|
||||
arenaFreeLandInsertSteal(&oldRange, arena, &range); /* may update range */
|
||||
|
||||
(*arena->class->free)(RangeBase(&range), RangeSize(&range), pool);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* freelist.c: FREE LIST ALLOCATOR IMPLEMENTATION
|
||||
*
|
||||
* $Id$
|
||||
* Copyright (c) 2013-2014 Ravenbrook Limited. See end of file for license.
|
||||
* Copyright (c) 2013-2015 Ravenbrook Limited. See end of file for license.
|
||||
*
|
||||
* .sources: <design/freelist/>.
|
||||
*/
|
||||
|
|
@ -18,11 +18,11 @@ SRCID(freelist, "$Id$");
|
|||
|
||||
|
||||
typedef union FreelistBlockUnion {
|
||||
struct {
|
||||
struct FreelistBlockSmall {
|
||||
FreelistBlock next; /* tagged with low bit 1 */
|
||||
/* limit is (char *)this + freelistAlignment(fl) */
|
||||
} small;
|
||||
struct {
|
||||
struct FreelistBlockLarge {
|
||||
FreelistBlock next; /* not tagged (low bit 0) */
|
||||
Addr limit;
|
||||
} large;
|
||||
|
|
@ -101,6 +101,9 @@ static Bool FreelistBlockCheck(FreelistBlock block)
|
|||
CHECKL(freelistBlockNext(block) == freelistEND
|
||||
|| block < freelistBlockNext(block));
|
||||
CHECKL(freelistBlockIsSmall(block) || (Addr)block < block->large.limit);
|
||||
/* Would like to CHECKL(!freelistBlockIsSmall(block) ||
|
||||
* freelistBlockSize(fl, block) == freelistAlignment(fl)) but we
|
||||
* don't have 'fl' here. This is checked in freelistBlockSetLimit. */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -139,6 +142,7 @@ static void freelistBlockSetLimit(Freelist fl, FreelistBlock block, Addr limit)
|
|||
} else {
|
||||
AVER(size >= sizeof(block->small));
|
||||
block->small.next = freelistTagSet(block->small.next);
|
||||
AVER(freelistBlockSize(fl, block) == freelistAlignment(fl));
|
||||
}
|
||||
AVER(freelistBlockLimit(fl, block) == limit);
|
||||
}
|
||||
|
|
@ -170,6 +174,9 @@ Bool FreelistCheck(Freelist fl)
|
|||
CHECKS(Freelist, fl);
|
||||
land = FreelistLand(fl);
|
||||
CHECKD(Land, land);
|
||||
CHECKL(AlignCheck(FreelistMinimumAlignment));
|
||||
CHECKL(sizeof(struct FreelistBlockSmall) < sizeof(struct FreelistBlockLarge));
|
||||
CHECKL(sizeof(struct FreelistBlockSmall) <= freelistAlignment(fl));
|
||||
/* See <design/freelist/#impl.grain.align> */
|
||||
CHECKL(AlignIsAligned(freelistAlignment(fl), FreelistMinimumAlignment));
|
||||
CHECKL((fl->list == freelistEND) == (fl->listSize == 0));
|
||||
|
|
@ -236,12 +243,14 @@ 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.
|
||||
* range invariant (it would have to be at a lower address than the
|
||||
* first block in the free list, which the MPS has no mechanism to
|
||||
* enforce), and so it would still have to be special-cased.
|
||||
*/
|
||||
|
||||
static void freelistBlockSetPrevNext(Freelist fl, FreelistBlock prev,
|
||||
|
|
@ -781,6 +790,7 @@ static Res freelistDescribe(Land land, mps_lib_FILE *stream, Count depth)
|
|||
res = WriteF(stream, depth,
|
||||
"Freelist $P {\n", (WriteFP)fl,
|
||||
" listSize = $U\n", (WriteFU)fl->listSize,
|
||||
" size = $U\n", (WriteFU)fl->size,
|
||||
NULL);
|
||||
|
||||
b = LandIterate(land, freelistDescribeVisitor, stream, depth + 2);
|
||||
|
|
@ -815,7 +825,7 @@ DEFINE_LAND_CLASS(FreelistLandClass, class)
|
|||
|
||||
/* C. COPYRIGHT AND LICENSE
|
||||
*
|
||||
* Copyright (C) 2013-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
|
||||
* Copyright (C) 2013-2015 Ravenbrook Limited <http://www.ravenbrook.com/>.
|
||||
* All rights reserved. This is an open source license. Contact
|
||||
* Ravenbrook for commercial licensing options.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -76,14 +76,14 @@ class, a subclass of ``LandClass`` suitable for passing to
|
|||
|
||||
``LandClass CBSFastLandClassGet(void)``
|
||||
|
||||
_`.function.class`: Returns a subclass of ``CBSLandClass`` that
|
||||
_`.function.class.fast`: Returns a subclass of ``CBSLandClass`` that
|
||||
maintains, for each subtree, the size of the largest block in that
|
||||
subtree. This enables the ``LandFindFirst()``, ``LandFindLast()``, and
|
||||
``LandFindLargest()`` generic functions.
|
||||
|
||||
``LandClass CBSZonedLandClassGet(void)``
|
||||
|
||||
_`.function.class`: Returns a subclass of ``CBSFastLandClass`` that
|
||||
_`.function.class.zoned`: Returns a subclass of ``CBSFastLandClass`` that
|
||||
maintains, for each subtree, the union of the zone sets of all ranges
|
||||
in that subtree. This enables the ``LandFindInZones()`` generic
|
||||
function.
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ available, only language facilities.
|
|||
_`.int.free.lib`: We assume that the headers ``<float.h>``,
|
||||
``<limits.h>``, ``<stdarg.h>`` and ``<stddef.h>`` are available in the
|
||||
freestanding environment, because they define only language features
|
||||
and not library calls. We assume that we may not make use of any other
|
||||
definitions if freestanding parts of the system.
|
||||
and not library calls. We assume that we may not make use of
|
||||
definitions in any other headers in freestanding parts of the system.
|
||||
|
||||
_`.int.free.term`: We may not terminate the program in a freestanding
|
||||
environment, and therefore we may not call :c:func:`abort`. We can't
|
||||
|
|
@ -149,7 +149,7 @@ Document History
|
|||
Copyright and License
|
||||
---------------------
|
||||
|
||||
Copyright © 1996-2014 Ravenbrook Limited. All rights reserved.
|
||||
Copyright © 1996-2015 Ravenbrook Limited. All rights reserved.
|
||||
<http://www.ravenbrook.com/>. This is an open source license. Contact
|
||||
Ravenbrook for commercial licensing options.
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ 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
|
||||
_`.type.deletevisitor`: 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
|
||||
|
|
@ -187,6 +187,16 @@ _`.function.iterate.and.delete`: As ``LandIterate()``, but the visitor
|
|||
function additionally returns a Boolean indicating whether the range
|
||||
should be deleted from the land.
|
||||
|
||||
_`.function.iterate.and.delete.justify`: The reason for having both
|
||||
``LandIterate()`` and ``LandIterateAndDelete()`` is that it may be
|
||||
possible to use a more efficient algorithm, or to preserve more
|
||||
properties of the data structure, when it is known that the land willl
|
||||
not be modified during the iteration. For example, in the CBS
|
||||
implementation, ``LandIterate()`` uses ``TreeTraverse()`` which
|
||||
preserves the tree structure, whereas ``LandIterateAndDelete()`` uses
|
||||
``TreeTraverseAndDelete()`` which flattens the tree structure, losing
|
||||
information about recently accessed nodes.
|
||||
|
||||
``Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)``
|
||||
|
||||
_`.function.find.first`: Locate the first block (in address order)
|
||||
|
|
@ -311,7 +321,7 @@ Document History
|
|||
Copyright and License
|
||||
---------------------
|
||||
|
||||
Copyright © 2014 Ravenbrook Limited. All rights reserved.
|
||||
Copyright © 2014-2015 Ravenbrook Limited. All rights reserved.
|
||||
<http://www.ravenbrook.com/>. This is an open source license. Contact
|
||||
Ravenbrook for commercial licensing options.
|
||||
|
||||
|
|
|
|||
|
|
@ -128,8 +128,10 @@ AMC interface
|
|||
pointers` keep objects alive.
|
||||
|
||||
* :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`,
|
||||
default 4096) is the default :term:`size` of block that the pool
|
||||
will request from the :term:`arena`.
|
||||
default 4096) is the minimum :term:`size` of the memory segments
|
||||
that the pool requests from the :term:`arena`. Larger segments
|
||||
reduce the per-segment overhead, but increase
|
||||
:term:`fragmentation` and :term:`retention`.
|
||||
|
||||
For example::
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ Release 1.115.0
|
|||
New features
|
||||
............
|
||||
|
||||
#. When creating an :ref:`pool-amc` pool, :c:func:`mps_pool_create_k`
|
||||
accepts the new keyword argument :c:macro:`MPS_KEY_EXTEND_BY`,
|
||||
specifying the minimum size of the memory segments that the pool
|
||||
requests from the :term:`arena`.
|
||||
|
||||
#. The function :c:func:`mps_arena_create_k` accepts two new
|
||||
:term:`keyword arguments`. :c:macro:`MPS_KEY_ARENA_COMMIT_LIMIT`
|
||||
sets the :term:`commit limit` for the arena, and
|
||||
|
|
@ -49,6 +54,30 @@ Other changes
|
|||
|
||||
.. _job001887: https://www.ravenbrook.com/project/mps/issue/job001887/
|
||||
|
||||
#. :ref:`pool-amc` pools now assert that exact references into the
|
||||
pool are aligned to the pool's alignment. See job002175_.
|
||||
|
||||
.. _job002175: https://www.ravenbrook.com/project/mps/issue/job002175/
|
||||
|
||||
#. Internal calculation of the address space available to the MPS no
|
||||
longer takes time proportional to the number of times the arena has
|
||||
been extended, speeding up allocation when memory is tight. See
|
||||
job003814_.
|
||||
|
||||
.. _job003814: https://www.ravenbrook.com/project/mps/issue/job003814/
|
||||
|
||||
#. Setting :c:macro:`MPS_KEY_SPARE` for a :ref:`pool-mvff` pool now
|
||||
works. See job003870_.
|
||||
|
||||
.. _job003870: https://www.ravenbrook.com/project/mps/issue/job003870/
|
||||
|
||||
#. When the arena is out of memory and cannot be extended without
|
||||
hitting the :term:`commit limit`, the MPS now returns
|
||||
:c:macro:`MPS_RES_COMMIT_LIMIT` rather than substituting
|
||||
:c:macro:`MPS_RES_RESOURCE`. See job003899_.
|
||||
|
||||
.. _job003899: https://www.ravenbrook.com/project/mps/issue/job003899/
|
||||
|
||||
|
||||
.. _release-notes-1.114:
|
||||
|
||||
|
|
@ -180,8 +209,8 @@ Other changes
|
|||
|
||||
#. Allocation into :ref:`pool-awl` pools again reliably provokes
|
||||
garbage collections of the generation that the pool belongs to. (In
|
||||
release 1.113.0, the generation would only be collected if a pool
|
||||
of some other class allocated into it.) See job003772_.
|
||||
version 1.113, the generation would only be collected if a pool of
|
||||
some other class allocated into it.) See job003772_.
|
||||
|
||||
.. _job003772: https://www.ravenbrook.com/project/mps/issue/job003772/
|
||||
|
||||
|
|
@ -193,13 +222,21 @@ Other changes
|
|||
.. _job003773: https://www.ravenbrook.com/project/mps/issue/job003773/
|
||||
|
||||
#. The :ref:`pool-mvt` and :ref:`pool-mvff` pool classes are now
|
||||
around 25% faster (in our benchmarks) than they were in release
|
||||
1.113.0.
|
||||
around 25% faster (in our benchmarks) than they were in version
|
||||
1.113.
|
||||
|
||||
#. The default assertion handler in the default :term:`plinth` now
|
||||
flushes the telemetry stream before aborting. See
|
||||
:c:func:`mps_lib_assert_fail`.
|
||||
|
||||
#. Garbage collection performance is substantially improved in the
|
||||
situation where the arena has been extended many times. Critical
|
||||
operations now take time logarithmic in the number of times the
|
||||
arena has been extended (rather than linear, as in version 1.113
|
||||
and earlier). See job003554_.
|
||||
|
||||
.. _job003554: https://www.ravenbrook.com/project/mps/issue/job003554/
|
||||
|
||||
|
||||
.. _release-notes-1.113:
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ From the test directory::
|
|||
|
||||
PLATFORM=lii6ll # substitute your platform
|
||||
CODE=../code # code directory of the branch you are testing
|
||||
make -C $CODE -f $PLATFORM.gmk VARIETY=cool $PLATFORM/cool/mps.o
|
||||
make -B -C $CODE -f $PLATFORM.gmk VARIETY=cool $PLATFORM/cool/mps.o
|
||||
alias qa="perl test/qa -i $CODE -l $CODE/$PLATFORM/cool/mps.o"
|
||||
qa clib
|
||||
qa run function/5.c
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue