mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
Eliminate pagestate and pagepoolunion: spare pages are now represented by the spare page land, and free/allocated pages can be distinguished using the pool pointer.
Copied from Perforce Change: 195991
This commit is contained in:
parent
7e9a3e456d
commit
740d616eaa
4 changed files with 18 additions and 69 deletions
|
|
@ -1156,8 +1156,6 @@ static void VMFree(Addr base, Size size, Pool pool)
|
|||
AVER(TractPool(tract) == pool);
|
||||
|
||||
TractFinish(tract);
|
||||
PageSetPool(page, NULL);
|
||||
PageSetType(page, PageStateSPARE);
|
||||
}
|
||||
BTResRange(chunk->allocTable, piBase, piLimit);
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ void TractInit(Tract tract, Pool pool, Addr base)
|
|||
AVER_CRITICAL(tract != NULL);
|
||||
AVERT_CRITICAL(Pool, pool);
|
||||
|
||||
tract->pool.pool = pool;
|
||||
tract->pool = pool;
|
||||
tract->base = base;
|
||||
tract->seg = NULL;
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ void TractFinish(Tract tract)
|
|||
|
||||
/* Check that there's no segment - and hence no shielding. */
|
||||
AVER(!TractHasSeg(tract));
|
||||
tract->pool.pool = NULL;
|
||||
tract->pool = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -481,8 +481,7 @@ void PageInit(Chunk chunk, Index pi)
|
|||
page = ChunkPage(chunk, pi);
|
||||
|
||||
BTRes(chunk->allocTable, pi);
|
||||
PageSetPool(page, NULL);
|
||||
PageSetType(page, PageStateFREE);
|
||||
page->pool = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,26 +14,6 @@
|
|||
#include "tree.h"
|
||||
|
||||
|
||||
/* Page states
|
||||
*
|
||||
* .states: The first word of the page descriptor contains a pointer to
|
||||
* the page's owning pool if the page is allocated. The bottom two bits
|
||||
* indicate the page state. Note that the page descriptor itself may
|
||||
* not be mapped since it is stored in a SparseArray.
|
||||
*/
|
||||
|
||||
#define PageStateALLOC 0 /* allocated to a pool as a tract */
|
||||
#define PageStateSPARE 1 /* free but mapped to backing store */
|
||||
#define PageStateFREE 2 /* free and unmapped (address space only) */
|
||||
#define PageStateWIDTH 2 /* bitfield width */
|
||||
|
||||
typedef union PagePoolUnion {
|
||||
unsigned state : PageStateWIDTH; /* see .states */
|
||||
Pool pool;
|
||||
} PagePoolUnion;
|
||||
|
||||
|
||||
|
||||
/* TractStruct -- tract structure
|
||||
*
|
||||
* .tract: Tracts represent the grains of memory allocation from
|
||||
|
|
@ -41,7 +21,7 @@ typedef union PagePoolUnion {
|
|||
*/
|
||||
|
||||
typedef struct TractStruct { /* Tract structure */
|
||||
PagePoolUnion pool; /* MUST BE FIRST <design/arena#.tract.field.pool> */
|
||||
Pool pool; /* MUST BE FIRST <design/arena#.tract.field.pool> */
|
||||
Seg seg; /* NULL or segment containing tract */
|
||||
Addr base; /* Base address of the tract */
|
||||
} TractStruct;
|
||||
|
|
@ -51,11 +31,10 @@ extern Addr (TractBase)(Tract tract);
|
|||
#define TractBase(tract) ((tract)->base)
|
||||
extern Addr TractLimit(Tract tract, Arena arena);
|
||||
|
||||
#define TractHasPool(tract) \
|
||||
((tract)->pool.state == PageStateALLOC && TractPool(tract))
|
||||
#define TractPool(tract) ((tract)->pool.pool)
|
||||
#define TractHasPool(tract) (TractPool(tract) != NULL)
|
||||
#define TractPool(tract) RVALUE((tract)->pool)
|
||||
#define TractHasSeg(tract) ((tract)->seg != NULL)
|
||||
#define TractSeg(tract) ((tract)->seg)
|
||||
#define TractSeg(tract) RVALUE((tract)->seg)
|
||||
|
||||
extern Bool TractCheck(Tract tract);
|
||||
extern void TractInit(Tract tract, Pool pool, Addr base);
|
||||
|
|
@ -87,30 +66,15 @@ extern void TractFinish(Tract tract);
|
|||
*/
|
||||
|
||||
typedef union PageUnion { /* page structure */
|
||||
PagePoolUnion pool; /* pool.state is the discriminator */
|
||||
TractStruct alloc; /* allocated tract, pool.state == PoolStateALLOC */
|
||||
Pool pool; /* discriminator */
|
||||
TractStruct alloc; /* allocated tract, pool != NULL */
|
||||
} PageUnion;
|
||||
|
||||
|
||||
#define PageTract(page) (&(page)->alloc)
|
||||
#define PageOfTract(tract) PARENT(PageUnion, alloc, tract)
|
||||
#define PagePool(page) RVALUE((page)->pool.pool)
|
||||
#define PageIsAllocated(page) RVALUE(PagePool(page) != NULL)
|
||||
#define PageState(page) RVALUE((page)->pool.state)
|
||||
|
||||
#define PageSetPool(page, _pool) \
|
||||
BEGIN \
|
||||
Page _page = (page); \
|
||||
_page->pool.pool = (_pool); \
|
||||
AVER(PageState(_page) == PageStateALLOC); \
|
||||
END
|
||||
|
||||
#define PageSetType(page, _state) \
|
||||
BEGIN \
|
||||
Page _page = (page); \
|
||||
AVER(PagePool(_page) == NULL); \
|
||||
_page->pool.state = (_state); \
|
||||
END
|
||||
#define PagePool(page) RVALUE((page)->pool)
|
||||
#define PageIsAllocated(page) (PagePool(page) != NULL)
|
||||
|
||||
|
||||
/* Chunks */
|
||||
|
|
|
|||
|
|
@ -275,13 +275,12 @@ implementation detail, not a requirement.
|
|||
_`.tract.structure`: The tract structure definition looks like this::
|
||||
|
||||
typedef struct TractStruct { /* Tract structure */
|
||||
PagePoolUnion pool; /* MUST BE FIRST (design.mps.arena.tract.field.pool) */
|
||||
void *p; /* pointer for use of owning pool */
|
||||
Addr base; /* Base address of the tract */
|
||||
BOOLFIELD(hasSeg); /* does tract have a seg in p? */
|
||||
Pool pool; /* MUST BE FIRST <design/arena#.tract.field.pool> */
|
||||
Seg seg; /* NULL or segment containing tract */
|
||||
Addr base; /* Base address of the tract */
|
||||
} TractStruct;
|
||||
|
||||
_`.tract.field.pool`: The pool.pool field indicates to which pool the tract
|
||||
_`.tract.field.pool`: The pool field indicates to which pool the tract
|
||||
has been allocated (`.req.fun.trans.pool`_). Tracts are only valid
|
||||
when they are allocated to pools. When tracts are not allocated to
|
||||
pools, arena classes are free to reuse tract objects in undefined
|
||||
|
|
@ -294,20 +293,9 @@ that the private representation can share a common prefix with
|
|||
private representation whether such an object is allocated or not,
|
||||
without requiring an extra field.
|
||||
|
||||
_`.tract.field.p`: The ``p`` field is used by pools to associate tracts
|
||||
with other data (`.req.fun.trans.arbitrary`_). It's used by the
|
||||
segment module to indicate which segment a tract belongs to. If a pool
|
||||
doesn't use segments it may use the ``p`` field for its own purposes.
|
||||
This field has the non-specific type ``(void *)`` so that pools can
|
||||
use it for any purpose.
|
||||
|
||||
_`.tract.field.hasSeg`: The ``hasSeg`` bit-field is a Boolean which
|
||||
indicates whether the ``p`` field is being used by the segment module.
|
||||
If this field is ``TRUE``, then the value of ``p`` is a ``Seg``. See
|
||||
design.mps.type.bool.bitfield_ for why this is declared using the
|
||||
``BOOLFIELD`` macro.
|
||||
|
||||
.. _design.mps.type.bool.bitfield: type#.bool.bitfield
|
||||
_`.tract.field.base`: The seg field is a pointer to the segment
|
||||
containing the tract, or ``NULL`` if the tract is not contained in any
|
||||
segment.
|
||||
|
||||
_`.tract.field.base`: The base field contains the base address of the
|
||||
memory represented by the tract.
|
||||
|
|
|
|||
Loading…
Reference in a new issue