From 5c01e3a1343fc10ed258a11f18da0b57df93e28e Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Mon, 26 Jun 2006 14:27:57 +0000 Subject: [PATCH] 2006-06-26 16:35 UTC+0100 Ryszard Glab * include/hbapi.h * source/vm/garbage.c * changed hb_gcUnregistedSweep to static function * fixed handling of sweeper functions * there is no need to call hb_UnregisterSweep - this is done automatically inside hb_gcFree and during garbage collecting --- harbour/ChangeLog | 10 ++++++ harbour/include/hbapi.h | 1 - harbour/source/vm/garbage.c | 72 ++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index a90f0c5c74..a8c8333dc7 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,16 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + debuger. + * changed HB_DBG_VMSTKGLIST() to operate on functions/macros. + It's possible that the above will badly interact with core debugger + code so I stop farther modifications leaving them for someone who + knows debugger core code. + +2006-06-26 16:35 UTC+0100 Ryszard Glab + is done automatically inside hb_gcFree and during + * source/vm/garbage.c + * changed hb_gcUnregistedSweep to static function * fixed handling of sweeper functions * there is no need to call hb_UnregisterSweep - this is done automatically inside hb_gcFree and during diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 2d3ff81af3..8d6bb92992 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -547,7 +547,6 @@ typedef HB_GARBAGE_SWEEPER( HB_GARBAGE_SWEEPER_ ); typedef HB_GARBAGE_SWEEPER_ * HB_GARBAGE_SWEEPER_PTR; extern void hb_gcRegisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo ); -extern void hb_gcUnregisterSweep( void * Cargo ); extern PHB_ITEM hb_gcGripGet( HB_ITEM_PTR pItem ); extern void hb_gcGripDrop( HB_ITEM_PTR pItem ); diff --git a/harbour/source/vm/garbage.c b/harbour/source/vm/garbage.c index b6fc283ac4..410f5c1e48 100644 --- a/harbour/source/vm/garbage.c +++ b/harbour/source/vm/garbage.c @@ -71,7 +71,8 @@ typedef struct HB_GARBAGE_ struct HB_GARBAGE_ *pPrev; /* previous memory block */ HB_GARBAGE_FUNC_PTR pFunc; /* cleanup function called before memory releasing */ USHORT locked; /* locking counter */ - USHORT used; /* used/unused block */ + BYTE used; /* used/unused block */ + BYTE flags; } HB_GARBAGE, *HB_GARBAGE_PTR; #ifdef HB_ALLOC_ALIGNMENT @@ -92,10 +93,13 @@ typedef struct HB_GARBAGE_ #define HB_GARBAGE_FREE( pAlloc ) hb_xfree( ( void * ) ( pAlloc ) ) /* status of memory block */ +/* flags stored in 'locked' slot */ #define HB_GC_UNLOCKED 0 #define HB_GC_LOCKED 1 /* do not collect a memory block */ +/* flags stored in 'used' slot */ #define HB_GC_USED_FLAG 2 /* the bit for used/unused flag */ #define HB_GC_DELETE 4 /* item will be deleted during finalization */ +/* flags stored in 'flags' slot */ #define HB_GC_USERSWEEP 8 /* memory block with user defined sweep function */ /* pointer to memory block that will be checked in next step */ @@ -125,6 +129,8 @@ static BOOL s_bCollecting = FALSE; */ static USHORT s_uUsedFlag = HB_GC_USED_FLAG; +static void hb_gcUnregisterSweep( void * Cargo ); + static void hb_gcLink( HB_GARBAGE_PTR *pList, HB_GARBAGE_PTR pAlloc ) { if( *pList ) @@ -163,6 +169,7 @@ void * hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pCleanupFunc ) pAlloc->pFunc = pCleanupFunc; pAlloc->locked = 0; pAlloc->used = s_uUsedFlag; + pAlloc->flags = 0; return HB_MEM_PTR( pAlloc ); /* hide the internal data */ } else @@ -183,6 +190,10 @@ void hb_gcFree( void *pBlock ) hb_gcUnlink( &s_pLockedBlock, pAlloc ); else hb_gcUnlink( &s_pCurrBlock, pAlloc ); + + if( pAlloc->flags & HB_GC_USERSWEEP ) + hb_gcUnregisterSweep( pBlock ); + HB_GARBAGE_FREE( pAlloc ); } } @@ -280,6 +291,7 @@ HB_ITEM_PTR hb_gcGripGet( HB_ITEM_PTR pOrigin ) pAlloc->pFunc = hb_gcGripRelease; pAlloc->locked = 1; pAlloc->used = s_uUsedFlag; + pAlloc->flags = 0; pItem->type = HB_IT_NIL; if( pOrigin ) @@ -401,7 +413,17 @@ void hb_gcItemRef( HB_ITEM_PTR pItem ) HB_GARBAGE_PTR pAlloc = HB_GC_PTR( pItem->item.asPointer.value ); if( pAlloc->used == s_uUsedFlag ) - pAlloc->used ^= HB_GC_USED_FLAG; /* mark this codeblock as used */ + { + if( ! (pAlloc->flags & HB_GC_USERSWEEP) ) + { + /* Mark this pointer as used only if it doesn't have + registerd his own sweeper function that checks if + this pointer is still used. + The sweeper function will be called elsewhere. + */ + pAlloc->used ^= HB_GC_USED_FLAG; /* mark this codeblock as used */ + } + } } } /* all other data types don't need the GC */ @@ -424,10 +446,10 @@ void hb_gcRegisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo ) s_pSweepExtern = pExt; /* set user sweep flag */ - HB_GC_PTR( Cargo )->used ^= HB_GC_USERSWEEP; + HB_GC_PTR( Cargo )->flags ^= HB_GC_USERSWEEP; } -void hb_gcUnregisterSweep( void * Cargo ) +static void hb_gcUnregisterSweep( void * Cargo ) { HB_GARBAGE_EXTERN_PTR pExt; HB_GARBAGE_EXTERN_PTR pPrev; @@ -440,7 +462,7 @@ void hb_gcUnregisterSweep( void * Cargo ) HB_GARBAGE_PTR pAlloc = HB_GC_PTR( Cargo ); /* clear user sweep flag */ - pAlloc->used &= ~ HB_GC_USERSWEEP; + pAlloc->flags &= ~ HB_GC_USERSWEEP; if( pExt == s_pSweepExtern ) { @@ -491,50 +513,31 @@ void hb_gcCollectAll( void ) hb_gcItemRef( hb_stackReturnItem() ); hb_clsIsClassRef(); -#if 1 if( s_pSweepExtern ) { - HB_GARBAGE_EXTERN_PTR pExt = s_pSweepExtern; + HB_GARBAGE_EXTERN_PTR *pExtPtr = &s_pSweepExtern; do { - if( ( pExt->pFunc )( pExt->pBlock ) ) - { - /* block is still used */ - pAlloc = HB_GC_PTR( pExt->pBlock ); - pAlloc->used ^= HB_GC_USED_FLAG; - } - pExt = pExt->pNext; - } - while( pExt ); - } -#else - /* alternate version which unregister sweep functions in one pass */ - if( s_pSweepExtern ) - { - HB_GARBAGE_EXTERN_PTR * pExtPtr = &s_pSweepExtern; + pAlloc = HB_GC_PTR( ( *pExtPtr )->pBlock ); - do - { - pAlloc = HB_GC_PTR( ( * pExtPtr )->pBlock ); - - if( ( ( * pExtPtr )->pFunc )( ( * pExtPtr )->pBlock ) ) + if( ( ( *pExtPtr )->pFunc )( ( *pExtPtr )->pBlock ) ) { /* block is still used */ pAlloc->used ^= HB_GC_USED_FLAG; - pExtPtr = &( * pExtPtr )->pNext; + pExtPtr = &( *pExtPtr )->pNext; } else { - HB_GARBAGE_EXTERN_PTR pFree = * pExtPtr; - pAlloc->used &= ~HB_GC_USERSWEEP; - * pExtPtr = ( * pExtPtr )->pNext; + HB_GARBAGE_EXTERN_PTR pFree = *pExtPtr; + + pAlloc->flags &= ~ HB_GC_USERSWEEP; + *pExtPtr = ( *pExtPtr )->pNext; hb_xfree( pFree ); } } - while( * pExtPtr ); + while( *pExtPtr ); } -#endif /* check list of locked block for blocks referenced from * locked block @@ -595,9 +598,6 @@ void hb_gcCollectAll( void ) pAlloc = s_pDeletedBlock; do { - if( s_pDeletedBlock->used & HB_GC_USERSWEEP ) - hb_gcUnregisterSweep( HB_MEM_PTR( s_pDeletedBlock ) ); - if( s_pDeletedBlock->pFunc ) ( s_pDeletedBlock->pFunc )( HB_MEM_PTR( s_pDeletedBlock ) );