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:
Gareth Rees 2019-02-07 12:54:41 +00:00 committed by Gareth Rees
parent 7e9a3e456d
commit 740d616eaa
4 changed files with 18 additions and 69 deletions

View file

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

View file

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

View file

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

View file

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