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

Further tidying up of the page descriptor and naming.

Copied from Perforce
 Change: 184323
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2014-02-11 14:14:16 +00:00
parent f9e9805b39
commit 9bc635b24d
4 changed files with 63 additions and 63 deletions

View file

@ -687,7 +687,7 @@ static Size VMArenaReserved(Arena arena)
*/
#define tablePageBaseIndex(chunk, tablePage) \
(AddrOffset((Addr)(chunk)->pageTable, (tablePage)) \
/ sizeof(PageStruct))
/ sizeof(PageUnion))
/* tablePageWholeBaseIndex
@ -697,8 +697,8 @@ static Size VMArenaReserved(Arena arena)
*/
#define tablePageWholeBaseIndex(chunk, tablePage) \
(AddrOffset((Addr)(chunk)->pageTable, \
AddrAdd((tablePage), sizeof(PageStruct)-1)) \
/ sizeof(PageStruct))
AddrAdd((tablePage), sizeof(PageUnion)-1)) \
/ sizeof(PageUnion))
/* tablePageLimitIndex -- index of the first page descriptor falling
@ -709,7 +709,7 @@ static Size VMArenaReserved(Arena arena)
#define tablePageLimitIndex(chunk, tablePage) \
((AddrOffset((Addr)(chunk)->pageTable, (tablePage)) \
+ ChunkPageSize(chunk) - 1) \
/ sizeof(PageStruct) \
/ sizeof(PageUnion) \
+ 1)
/* tablePageWholeLimitIndex
@ -720,14 +720,14 @@ static Size VMArenaReserved(Arena arena)
#define tablePageWholeLimitIndex(chunk, tablePage) \
((AddrOffset((Addr)(chunk)->pageTable, (tablePage)) \
+ ChunkPageSize(chunk)) \
/ sizeof(PageStruct))
/ sizeof(PageUnion))
/* tablePagesUsed
*
* Takes a range of pages identified by [pageBase, pageLimit), and
* returns the pages occupied by the page table which store the
* PageStruct descriptors for those pages.
* PageUnion descriptors for those pages.
*/
static void tablePagesUsed(Index *tableBaseReturn, Index *tableLimitReturn,
Chunk chunk, Index pageBase, Index pageLimit)
@ -1194,32 +1194,32 @@ static Bool pageDescIsMapped(VMChunk vmChunk, Index pi)
AVER(pi < chunk->pages);
/* Note that unless the pi'th PageStruct crosses a page boundary */
/* Note that unless the pi'th PageUnion crosses a page boundary */
/* Base and Limit will differ by exactly 1. */
/* They will differ by at most 2 assuming that */
/* sizeof(PageStruct) <= ChunkPageSize(chunk) (!) */
/* sizeof(PageUnion) <= ChunkPageSize(chunk) (!) */
tablePagesUsed(&pageTableBaseIndex, &pageTableLimitIndex, chunk, pi, pi+1);
/* using unsigned arithmetic overflow to use just one comparison */
AVER(pageTableLimitIndex - pageTableBaseIndex - 1 < 2);
/* We can examine the PageStruct descriptor iff both table pages */
/* We can examine the page descriptor iff both table pages */
/* are mapped. */
return BTGet(vmChunk->pageTableMapped, pageTableBaseIndex) &&
BTGet(vmChunk->pageTableMapped, pageTableLimitIndex - 1);
}
/* pageType -- determine page type
/* pageState -- determine page state, even if unmapped
*
* Parts of the page table may be unmapped if their corresponding pages are
* free.
*/
static unsigned pageType(VMChunk vmChunk, Index pi)
static unsigned pageState(VMChunk vmChunk, Index pi)
{
Chunk chunk = VMChunk2Chunk(vmChunk);
if (pageDescIsMapped(vmChunk, pi))
return PageType(&chunk->pageTable[pi]);
return PageState(&chunk->pageTable[pi]);
return PageStateFREE;
}
@ -1235,7 +1235,7 @@ static void sparePageRelease(VMChunk vmChunk, Index pi)
Arena arena = ChunkArena(chunk);
Page page = &chunk->pageTable[pi];
AVER(PageType(page) == PageStateSPARE);
AVER(PageState(page) == PageStateSPARE);
AVER(arena->spareCommitted >= ChunkPageSize(chunk));
arena->spareCommitted -= ChunkPageSize(chunk);
@ -1272,14 +1272,14 @@ static void tablePagesUnmap(VMChunk vmChunk, Index basePage, Index limitPage)
beginning of the table. */
while (basePage > 0 &&
pageDescIsMapped(vmChunk, basePage) &&
PageType(&chunk->pageTable[basePage]) == PageStateFREE)
PageState(&chunk->pageTable[basePage]) == PageStateFREE)
--basePage;
/* Raise limitPage until we reach a descriptor we can't unmap, or the end
of the table. */
while (limitPage < chunk->pages &&
pageDescIsMapped(vmChunk, limitPage) &&
PageType(&chunk->pageTable[limitPage]) == PageStateFREE)
PageState(&chunk->pageTable[limitPage]) == PageStateFREE)
++limitPage;
/* Calculate the range of pages in the page table. */
@ -1289,14 +1289,14 @@ static void tablePagesUnmap(VMChunk vmChunk, Index basePage, Index limitPage)
/* If we can't unmap the base page, step up. */
if (!pageDescIsMapped(vmChunk, basePage) ||
PageType(&chunk->pageTable[basePage]) != PageStateFREE)
PageState(&chunk->pageTable[basePage]) != PageStateFREE)
base = AddrAdd(base, chunk->pageSize);
/* If that leaves any pages, then if the limit page contains a desciptor
we can't unmap, step down. Note, limit is the base of the page table
page *after* the one containing the desc for limitPage. */
if (base < limit) {
if (limitPage < chunk->pages &&
pageType(vmChunk, limitPage) != PageStateFREE)
pageState(vmChunk, limitPage) != PageStateFREE)
limit = AddrSub(limit, chunk->pageSize);
/* If that leaves any pages, unmap them. */
if (base < limit) {
@ -1334,7 +1334,7 @@ static Res pagesMarkAllocated(VMArena vmArena, VMChunk vmChunk,
Addr freeBase;
/* Allocate a run of spare pages. */
while(i < limitIndex && PageType(&chunk->pageTable[i]) == PageStateSPARE) {
while(i < limitIndex && PageState(&chunk->pageTable[i]) == PageStateSPARE) {
sparePageRelease(vmChunk, i);
PageAlloc(chunk, i, pool);
++i;
@ -1345,8 +1345,8 @@ static Res pagesMarkAllocated(VMArena vmArena, VMChunk vmChunk,
/* Allocate a run of free pages. */
freeBase = PageIndexBase(chunk, i);
AVER(PageType(&chunk->pageTable[i]) == PageStateFREE);
while (i < limitIndex && PageType(&chunk->pageTable[i]) == PageStateFREE) {
AVER(PageState(&chunk->pageTable[i]) == PageStateFREE);
while (i < limitIndex && PageState(&chunk->pageTable[i]) == PageStateFREE) {
PageAlloc(chunk, i, pool);
++i;
}
@ -1518,7 +1518,7 @@ static Size chunkUnmapAroundPage(Chunk chunk, Size size, Page page)
AVERT(Chunk, chunk);
vmChunk = Chunk2VMChunk(chunk);
AVERT(VMChunk, vmChunk);
AVER(PageType(page) == PageStateSPARE);
AVER(PageState(page) == PageStateSPARE);
/* size is arbitrary */
pageSize = ChunkPageSize(chunk);
@ -1537,10 +1537,10 @@ static Size chunkUnmapAroundPage(Chunk chunk, Size size, Page page)
purged += pageSize;
} while (purged < size &&
limitPage < chunk->pages &&
pageType(vmChunk, limitPage) == PageStateSPARE);
pageState(vmChunk, limitPage) == PageStateSPARE);
while (purged < size &&
basePage > 0 &&
pageType(vmChunk, basePage - 1) == PageStateSPARE) {
pageState(vmChunk, basePage - 1) == PageStateSPARE) {
--basePage;
sparePageRelease(vmChunk, basePage);
PageInit(chunk, basePage);

View file

@ -88,7 +88,7 @@ typedef struct mps_chain_s *Chain; /* <design/trace/> */
typedef struct TractStruct *Tract; /* <design/arena/> */
typedef struct ChunkStruct *Chunk; /* <code/tract.c> */
typedef struct ChunkCacheEntryStruct *ChunkCacheEntry; /* <code/tract.c> */
typedef struct PageStruct *Page; /* <code/tract.c> */
typedef union PageUnion *Page; /* <code/tract.c> */
typedef struct SegStruct *Seg; /* <code/seg.c> */
typedef struct GCSegStruct *GCSeg; /* <code/seg.c> */
typedef struct SegClassStruct *SegClass; /* <code/seg.c> */

View file

@ -159,7 +159,7 @@ Res ChunkInit(Chunk chunk, Arena arena,
{
Size size;
Count pages;
PageStruct *pageTable;
Page pageTable;
Shift pageShift;
Size pageTableSize;
void *p;
@ -192,7 +192,7 @@ Res ChunkInit(Chunk chunk, Arena arena,
goto failAllocTable;
chunk->allocTable = p;
pageTableSize = SizeAlignUp(pages * sizeof(PageStruct), pageSize);
pageTableSize = SizeAlignUp(pages * sizeof(PageUnion), pageSize);
chunk->pageTablePages = pageTableSize >> pageShift;
res = (arena->class->chunkInit)(chunk, boot);
@ -597,7 +597,7 @@ Bool TractNext(Tract *tractReturn, Arena arena, Addr addr)
/* PageAlloc
*
* Sets up the PageStruct for an allocated page to turn it into a Tract.
* Sets up the page descriptor for an allocated page to turn it into a Tract.
*/
void PageAlloc(Chunk chunk, Index pi, Pool pool)

View file

@ -15,17 +15,17 @@
/* Page states
*
* .states: Pages (hence PageStructs that describe them) can be in
* .states: Pages (hence PageUnions that describe them) can be in
* one of 3 states:
* allocated (to a pool as tracts)
* allocated pages are mapped
* BTGet(allocTable, i) == 1
* PageType() == PageStateALLOC
* PageState() == PageStateALLOC
* PagePool()->pool == pool
* spare
* these pages are mapped
* BTGet(allocTable, i) == 0
* PageType() == PageStateSPARE
* PageState() == PageStateSPARE
* PagePool() == NULL
* free
* these pages are not mapped
@ -33,7 +33,7 @@
* PTE may itself be unmapped, but when it is (use pageTableMapped
* to determine whether page occupied by page table is mapped):
* PagePool() == NULL
* PageType() == PageStateFREE
* PageState() == PageStateFREE
*/
#define PageStateALLOC 0
@ -41,6 +41,12 @@
#define PageStateFREE 2
#define PageStateWIDTH 2 /* bitfield width */
typedef union PagePoolUnion {
unsigned state : PageStateWIDTH; /* see .states */
Pool pool;
} PagePoolUnion;
/* TractStruct -- tract structure
*
@ -51,17 +57,12 @@
* as type Bool. See <design/arena/#tract.field.hasSeg>.
*/
typedef union TractPoolUnion {
Pool pool;
unsigned state : PageStateWIDTH; /* see .states */
} TractPoolUnion;
typedef struct TractStruct { /* Tract structure */
TractPoolUnion pool; /* MUST BE FIRST (<design/arena/#tract.field> pool) */
PagePoolUnion pool; /* MUST BE FIRST (<design/arena/#tract.field> pool) */
void *p; /* pointer for use of owning pool */
Addr base; /* Base address of the tract */
TraceSet white : TraceLIMIT; /* traces for which tract is white */
unsigned int hasSeg : 1; /* does tract have a seg in p? See .bool */
unsigned hasSeg : 1; /* does tract have a seg in p? See .bool */
} TractStruct;
@ -97,9 +98,9 @@ extern void TractFinish(Tract tract);
(TractSetHasSeg(tract, FALSE), TractSetP(tract, NULL))
/* PageStruct -- Page structure
/* PageUnion -- page descriptor
*
* .page-table: The page table (defined as a PageStruct array)
* .page-table: The page table (defined as a PageUnion array)
* is central to the design of the arena.
* See <design/arenavm/#table>.*.
*
@ -107,39 +108,38 @@ extern void TractFinish(Tract tract);
* field of this union. See <design/arena/#tract.field.pool>.
*/
typedef struct PageStruct { /* page structure */
union PageStructUnion {
TractPoolUnion pool;
TractStruct tractStruct; /* allocated tract */
struct {
TractPoolUnion pool; /* MUST BE FIRST (<design/arena/#tract.field> pool) */
RingStruct spareRing;
} rest; /* other (non-allocated) page */
} the;
} PageStruct;
typedef struct PageSpareStruct {
PagePoolUnion pool; /* spare tract, pool.state == PoolStateSPARE */
RingStruct ring; /* link in arena spare ring, LRU order */
} PageSpareStruct;
typedef union PageUnion { /* page structure */
PagePoolUnion pool; /* pool.state is the discriminator */
TractStruct alloc; /* allocated tract, pool.state == PoolStateALLOC */
PageSpareStruct spare; /* spare page, pool.state == PoolStateSPARE */
} PageUnion;
#define PageTract(page) (&(page)->the.tractStruct)
#define PageOfTract(tract) \
PARENT(PageStruct, the, PARENT(union PageStructUnion, tractStruct, (tract)))
#define PagePool(page) RVALUE((page)->the.pool.pool)
#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 PageType(page) RVALUE((page)->the.pool.state)
#define PageSpareRing(page) RVALUE(&(page)->the.rest.spareRing)
#define PageOfSpareRing(node) RING_ELT(Page, the.rest.spareRing, node)
#define PageState(page) RVALUE((page)->pool.state)
#define PageSpareRing(page) RVALUE(&(page)->spare.ring)
#define PageOfSpareRing(node) PARENT(PageUnion, spare, RING_ELT(PageSpare, ring, node))
#define PageSetPool(page, _pool) \
BEGIN \
PageStruct *_page = (page); \
_page->the.pool.pool = (_pool); \
AVER(PageType(_page) == PageStateALLOC); \
Page _page = (page); \
_page->pool.pool = (_pool); \
AVER(PageState(_page) == PageStateALLOC); \
END
#define PageSetType(page, _state) \
BEGIN \
PageStruct *_page = (page); \
Page _page = (page); \
AVER(PagePool(_page) == NULL); \
_page->the.pool.state = (_state); \
_page->pool.state = (_state); \
END
@ -160,7 +160,7 @@ typedef struct ChunkStruct {
Index allocBase; /* index of first page allocatable to clients */
Index pages; /* index of the page after the last allocatable page */
BT allocTable; /* page allocation table */
PageStruct* pageTable; /* the page table */
Page pageTable; /* the page table */
Count pageTablePages; /* number of pages occupied by page table */
} ChunkStruct;