From 9bc635b24d22715c57be596afea06fd91dcb7be2 Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Tue, 11 Feb 2014 14:14:16 +0000 Subject: [PATCH] Further tidying up of the page descriptor and naming. Copied from Perforce Change: 184323 ServerID: perforce.ravenbrook.com --- mps/code/arenavm.c | 46 ++++++++++++++--------------- mps/code/mpmtypes.h | 2 +- mps/code/tract.c | 6 ++-- mps/code/tract.h | 72 ++++++++++++++++++++++----------------------- 4 files changed, 63 insertions(+), 63 deletions(-) diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 63d546f14df..fb55019ff3c 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -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); diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h index 7f035c1c792..131447ed065 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h @@ -88,7 +88,7 @@ typedef struct mps_chain_s *Chain; /* */ typedef struct TractStruct *Tract; /* */ typedef struct ChunkStruct *Chunk; /* */ typedef struct ChunkCacheEntryStruct *ChunkCacheEntry; /* */ -typedef struct PageStruct *Page; /* */ +typedef union PageUnion *Page; /* */ typedef struct SegStruct *Seg; /* */ typedef struct GCSegStruct *GCSeg; /* */ typedef struct SegClassStruct *SegClass; /* */ diff --git a/mps/code/tract.c b/mps/code/tract.c index 1c068201cf4..b87421d6870 100644 --- a/mps/code/tract.c +++ b/mps/code/tract.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) diff --git a/mps/code/tract.h b/mps/code/tract.h index 8c459765b96..9cf59f48d20 100644 --- a/mps/code/tract.h +++ b/mps/code/tract.h @@ -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 . */ -typedef union TractPoolUnion { - Pool pool; - unsigned state : PageStateWIDTH; /* see .states */ -} TractPoolUnion; - typedef struct TractStruct { /* Tract structure */ - TractPoolUnion pool; /* MUST BE FIRST ( pool) */ + PagePoolUnion pool; /* MUST BE FIRST ( 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 .*. * @@ -107,39 +108,38 @@ extern void TractFinish(Tract tract); * field of this union. See . */ -typedef struct PageStruct { /* page structure */ - union PageStructUnion { - TractPoolUnion pool; - TractStruct tractStruct; /* allocated tract */ - struct { - TractPoolUnion pool; /* MUST BE FIRST ( 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;