From 89a337ce4dbd54bbe050f5cfe59541ad312784c2 Mon Sep 17 00:00:00 2001 From: Chris Jefferson Date: Fri, 23 Mar 2018 14:30:38 +0000 Subject: [PATCH] Add MptrEndBags This allows for a seperation between the end of the master pointers, and the beginning of the bag data area --- src/gap.c | 2 +- src/gasman.c | 54 +++++++++++++++++++++++++++++++------------------- src/gasman.h | 4 ++-- src/saveload.c | 6 +++--- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/gap.c b/src/gap.c index 018e37ece2..e62e6db722 100644 --- a/src/gap.c +++ b/src/gap.c @@ -1987,7 +1987,7 @@ Obj FuncMASTER_POINTER_NUMBER(Obj self, Obj o) #ifdef HPCGAP return ObjInt_UInt((UInt)o / sizeof(Obj)); #else - if ((void **) o >= (void **) MptrBags && (void **) o < (void **) OldBags) { + if ((void **) o >= (void **) MptrBags && (void **) o < (void **) MptrEndBags) { return INTOBJ_INT( ((void **) o - (void **) MptrBags) + 1 ); } else { return INTOBJ_INT( 0 ); diff --git a/src/gasman.c b/src/gasman.c index f7548fa034..5368463478 100644 --- a/src/gasman.c +++ b/src/gasman.c @@ -211,6 +211,7 @@ static inline Bag *DATA(BagHeader *bag) /**************************************************************************** ** *V MptrBags . . . . . . . . . . . . . . beginning of the masterpointer area +*V MptrEndBags . . . . . . . . . . . . . . . end of the masterpointer area *V OldBags . . . . . . . . . . . . . . . . . beginning of the old bags area *V YoungBags . . . . . . . . . . . . . . . beginning of the young bags area *V AllocBags . . . . . . . . . . . . . . . beginning of the allocation area @@ -220,15 +221,21 @@ static inline Bag *DATA(BagHeader *bag) ** {\Gasman} manages one large block of storage called the *workspace*. The ** layout of the workspace is as follows{\:} ** -** +-----------------+-----------------+-----------------+-----------------+ -** | masterpointer | old bags | young bags | allocation | -** | area | area | area | area | -** +-----------------+-----------------+-----------------+-----------------+ -** ^ ^ ^ ^ ^ -** MptrBags OldBags YoungBags AllocBags EndBags +** +----------------+----------+----------+-----------------+--------------+ +** | masterpointer | unused | old bags | young bags | allocation | +** | area | area | area | area | area | +** +----------------+----------+----------+-----------------+--------------+ +** ^ ^ ^ ^ ^ ^ +** MptrBags MptrEndBags OldBags YoungBags AllocBags EndBags ** ** The *masterpointer area* contains all the masterpointers of the bags. -** 'MptrBags' points to the beginning of this area and 'OldBags' to the end. +** 'MptrBags' points to the beginning of this area and 'MptrEndBags' to the +** end. +** +** Between MptrEndBags and OldBags is an *unused area*. This exists so the +** master points, and bags area, can be moved independently. MptrEndBags +** will always come earlier in memory than OldBags. GASMAN should not touch +** this memory, as it may be used for other purposes. ** ** The *old bags area* contains the bodies of all the bags that survived at ** least one garbage collection. This area is only scanned for dead bags @@ -253,6 +260,7 @@ static inline Bag *DATA(BagHeader *bag) ** empties the young bags area. */ Bag * MptrBags; +Bag * MptrEndBags; Bag * OldBags; Bag * YoungBags; Bag * AllocBags; @@ -307,7 +315,7 @@ static inline UInt SpaceBetweenPointers(const Bag * a, const Bag * b) return res; } -#define SizeMptrsArea SpaceBetweenPointers(OldBags, MptrBags) +#define SizeMptrsArea SpaceBetweenPointers(MptrEndBags, MptrBags) #define SizeOldBagsArea SpaceBetweenPointers(YoungBags, OldBags) #define SizeYoungBagsArea SpaceBetweenPointers(AllocBags, YoungBags) #define SizeAllocationArea SpaceBetweenPointers(EndBags, AllocBags) @@ -318,7 +326,8 @@ static inline UInt SpaceBetweenPointers(const Bag * a, const Bag * b) #if defined(GAP_KERNEL_DEBUG) static int SanityCheckGasmanPointers(void) { - return MptrBags <= OldBags && + return MptrBags <= MptrEndBags && + MptrEndBags <= OldBags && OldBags <= YoungBags && YoungBags <= AllocBags && AllocBags <= EndBags; @@ -457,7 +466,7 @@ TNumInfoBags InfoBags [ NTYPES ]; */ static inline UInt IS_BAG_ID(void * ptr) { - return (((void *)MptrBags <= ptr) && (ptr < (void *)OldBags) && + return (((void *)MptrBags <= ptr) && (ptr < (void *)MptrEndBags) && ((UInt)ptr & (sizeof(Bag) - 1)) == 0); } @@ -687,7 +696,7 @@ void MarkBagWeakly(Bag bag) */ void CallbackForAllBags(void (*func)(Bag)) { - for (Bag bag = (Bag)MptrBags; bag < (Bag)OldBags; bag++) { + for (Bag bag = (Bag)MptrBags; bag < (Bag)MptrEndBags; bag++) { if (IS_BAG_BODY(*bag)) { (*func)(bag); } @@ -872,6 +881,7 @@ void StartRestoringBags( UInt nBags, UInt maxSize) EndBags = MptrBags + target; } OldBags = MptrBags + nBags + (SizeWorkspace - nBags - maxSize)/8; + MptrEndBags = OldBags; AllocBags = OldBags; NextMptrRestoring = (Bag)MptrBags; SizeAllBags = 0; @@ -891,7 +901,7 @@ Bag NextBagRestoring( UInt type, UInt flags, UInt size ) header->link = NextMptrRestoring; NextMptrRestoring++; - if ((Bag *)NextMptrRestoring >= OldBags) + if ((Bag *)NextMptrRestoring >= MptrEndBags) SyAbortBags("Overran Masterpointer area"); for (i = 0; i < WORDS_BAG(size); i++) @@ -917,7 +927,7 @@ void FinishedRestoringBags( void ) /* Bag *ptr; */ YoungBags = AllocBags; FreeMptrBags = NextMptrRestoring; - for (p = NextMptrRestoring; p +1 < (Bag)OldBags; p++) + for (p = NextMptrRestoring; p +1 < (Bag)MptrEndBags; p++) *(Bag *)p = p+1; *p = 0; NrLiveBags = NrAllBags; @@ -1032,7 +1042,11 @@ void InitBags ( } /* the rest is for bags */ - OldBags = MptrBags + 1024*initial_size/8/sizeof(Bag*); + MptrEndBags = MptrBags + 1024*initial_size/8/sizeof(Bag*); + // Add a small gap between the end of the master pointers and OldBags + // This is mainly here to ensure we do not break allowing OldBags and + // MptrEndBags to differ. + OldBags = MptrEndBags + 10; YoungBags = OldBags; AllocBags = OldBags; @@ -2007,7 +2021,7 @@ UInt CollectBags ( also reorder the free masterpointer linked list to get more locality */ FreeMptrBags = (Bag)0L; - for (p = MptrBags; p < OldBags; p+= SIZE_MPTR_BAGS) + for (p = MptrBags; p < MptrEndBags; p+= SIZE_MPTR_BAGS) { Bag *mptr = (Bag *)*p; if ( mptr == OldWeakDeadBagMarker) @@ -2039,13 +2053,13 @@ UInt CollectBags ( AllocSizeBags = 7*(Endbags - stopBags)/8; */ /* if less than 1/16th is free, prepare for an interrupt */ - if (SpaceBetweenPointers(stopBags,OldBags)/15 < SpaceBetweenPointers(EndBags,stopBags) ) { + if (SpaceBetweenPointers(stopBags,MptrEndBags)/15 < SpaceBetweenPointers(EndBags,stopBags) ) { /*N 1993/05/16 martin must change 'gap.c' */ ; } /* if more than 1/8th is free, give back storage (in 1/2 MBytes) */ - while (SpaceBetweenPointers(stopBags,OldBags)/7 <= SpaceBetweenPointers(EndBags,stopBags)-WORDS_BAG(512*1024L) + while (SpaceBetweenPointers(stopBags,MptrEndBags)/7 <= SpaceBetweenPointers(EndBags,stopBags)-WORDS_BAG(512*1024L) && SpaceBetweenPointers(EndBags,stopBags) > WORDS_BAG(AllocSizeBags) + WORDS_BAG(512*1024L) && SyAllocBags(-512,0) ) EndBags -= WORDS_BAG(512*1024L); @@ -2074,12 +2088,12 @@ UInt CollectBags ( *p = (Bag)FreeMptrBags; FreeMptrBags = (Bag)OldBags; - /* update 'OldBags', 'YoungBags', 'AllocBags', and 'stopBags' */ + /* update 'MptrEndBags', 'OldBags', 'YoungBags', 'AllocBags', and 'stopBags' */ + MptrEndBags += i; OldBags += i; YoungBags += i; AllocBags += i; stopBags += i; - } /* now we are done */ @@ -2132,7 +2146,7 @@ void CheckMasterPointers( void ) Bag bag; // iterate over all bag identifiers - for (Bag * ptr = MptrBags; ptr < OldBags; ptr++) { + for (Bag * ptr = MptrBags; ptr < MptrEndBags; ptr++) { bag = (Bag)ptr; // weakly dead bag? diff --git a/src/gasman.h b/src/gasman.h index 05e4246d70..307162992c 100644 --- a/src/gasman.h +++ b/src/gasman.h @@ -877,12 +877,12 @@ extern void MarkArrayOfBags(const Bag array[], UInt count); #if !defined(BOEHM_GC) extern Bag * MptrBags; -extern Bag * OldBags; +extern Bag * MptrEndBags; extern Bag * AllocBags; #define IS_WEAK_DEAD_BAG(bag) ( (((UInt)bag & (sizeof(Bag)-1)) == 0) && \ (Bag)MptrBags <= (bag) && \ - (bag) < (Bag)OldBags && \ + (bag) < (Bag)MptrEndBags && \ (((UInt)*bag) & (sizeof(Bag)-1)) == 1) #else diff --git a/src/saveload.c b/src/saveload.c index b0c0b279cb..148133e931 100644 --- a/src/saveload.c +++ b/src/saveload.c @@ -314,8 +314,8 @@ void SaveSubObj( Obj subobj ) SaveUInt((UInt) subobj); else if ((((UInt)subobj & 3) != 0) || subobj < (Bag)MptrBags || - subobj > (Bag)OldBags || - (Bag *)PTR_BAG(subobj) < OldBags) + subobj > (Bag)MptrEndBags || + (Bag *)PTR_BAG(subobj) < MptrEndBags) { Pr("#W bad bag id %d found, 0 saved\n", (Int)subobj, 0L); SaveUInt(0); @@ -573,7 +573,7 @@ static void WriteSaveHeader( void ) globalcount++; SaveUInt(globalcount); SaveUInt(NextSaveIndex-1); - SaveUInt(AllocBags - OldBags); + SaveUInt(AllocBags - MptrEndBags); SaveCStr("Loaded Modules");