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:
parent
f9e9805b39
commit
9bc635b24d
4 changed files with 63 additions and 63 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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> */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue