diff --git a/harbour/ChangeLog b/harbour/ChangeLog index ca09bcb03d..dae84d2377 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,15 @@ +2000-06-26 19:20 UTC+0100 Ryszard Glab + + *include/hbapi.h + * added declaration of hb_gcLockItem()/hb_gcUnlockItem() + + *source/vm/garbage.c + * added definition of hb_gcLockItem()/hb_gcUnlockItem() + + *source/vm/classes.c + * all arrays created internally for CLASS structure are now locked + to prevent premature deallocation by the garbage collector + 2000-06-26 20:11 UTC-0800 Ron Pinkas * source/pp/ppcomp.c ! Fixed line number to ignore empty lines in #include files,when resuming parent file. diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 6da83c7c42..03eb109fb5 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -523,6 +523,8 @@ extern void * hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pFunc ); /* allocate extern void hb_gcFree( void *pAlloc ); /* deallocates a memory allocated by the garbage collector */ extern void * hb_gcLock( void *pAlloc ); /* do not release passed memory block */ extern void * hb_gcUnlock( void *pAlloc ); /* passed block is allowed to be released */ +extern void hb_gcLockItem( HB_ITEM_PTR pItem ); /* do not release a memory block stored inside an item */ +extern void hb_gcUnlockItem( HB_ITEM_PTR pItem ); /* allow to release the item */ extern void hb_gcCollect( void ); /* checks if a single memory block can be released */ extern void hb_gcCollectAll( void ); /* checks if all memory blocks can be released */ extern BOOL hb_gcItemRef( HB_ITEM_PTR pItem, void *pAlloc ); /* checks if passed item refers passed memory block pointer */ diff --git a/harbour/source/vm/classes.c b/harbour/source/vm/classes.c index 58733de668..9afe60953a 100644 --- a/harbour/source/vm/classes.c +++ b/harbour/source/vm/classes.c @@ -290,11 +290,16 @@ static void hb_clsRelease( PCLASS pClass ) for( uiAt = 0; uiAt < uiLimit; uiAt++, pMeth++ ) if( pMeth->pInitValue ) + { + hb_gcUnlockItem( pMeth->pInitValue ); hb_itemRelease( pMeth->pInitValue ); + } hb_xfree( pClass->szName ); hb_xfree( pClass->pMethods ); + hb_gcUnlockItem( pClass->pClassDatas ); + hb_gcUnlockItem( pClass->pInlines ); hb_itemRelease( pClass->pClassDatas ); hb_itemRelease( pClass->pInlines ); } @@ -721,6 +726,11 @@ HB_FUNC( __CLSADDMSG ) pNewMeth->pInitValue = hb_itemNew( NULL ); hb_itemCopy( pNewMeth->pInitValue, pInit ); } + /* The init value is not stored inside of any harbour + variable then it can be deallocated prematurely by the GC + We have to lock the item with the value to prevent it. + */ + hb_gcLockItem( pNewMeth->pInitValue ); } } break; @@ -748,6 +758,11 @@ HB_FUNC( __CLSADDMSG ) pNewMeth->pInitValue = hb_itemNew( NULL ); hb_itemCopy( pNewMeth->pInitValue, pInit ); } + /* The init value is not stored inside of any harbour + variable then it can be deallocated prematurely by the GC + We have to lock the item with the value to prevent it. + */ + hb_gcLockItem( pNewMeth->pInitValue ); } } @@ -761,8 +776,6 @@ HB_FUNC( __CLSADDMSG ) } else { - PHB_ITEM pTmpItemPtr; - if( pMessage->pSymbol->szName[ 0 ] == '_' ) { pNewMeth->pFunction = hb___msgSetShrData; @@ -889,8 +902,10 @@ HB_FUNC( __CLSNEW ) /* CLASS DATA Not Shared ( new array, new value ) */ pNewCls->pClassDatas = hb_arrayClone( pSprCls->pClassDatas ); + hb_gcLockItem( pNewCls->pClassDatas ); pNewCls->pInlines = hb_arrayClone( pSprCls->pInlines ); + hb_gcLockItem( pNewCls->pInlines ); pNewCls->uiDatasShared = pSprCls->uiDatasShared; @@ -1012,6 +1027,11 @@ HB_FUNC( __CLSNEW ) hb_itemCopy( pInitValue, pSprCls->pMethods[ ui ].pInitValue ); pNewCls->pMethods[ uiAt + uiBucket ].pInitValue = pInitValue; } + /* The init value is not stored inside of any harbour + * variable then it can be deallocated prematurely by the GC + * We have to lock the item with the value to prevent it. + */ + hb_gcLockItem( pNewCls->pMethods[ uiAt + uiBucket ].pInitValue ); } break; } @@ -1035,7 +1055,9 @@ HB_FUNC( __CLSNEW ) pNewCls->uiHashKey = HASH_KEY; pNewCls->pClassDatas = hb_itemArrayNew( 0 ); + hb_gcLockItem( pNewCls->pClassDatas ); pNewCls->pInlines = hb_itemArrayNew( 0 ); + hb_gcLockItem( pNewCls->pInlines ); pNewCls->pFunError = NULL; } hb_itemRelease( pahSuper ); diff --git a/harbour/source/vm/garbage.c b/harbour/source/vm/garbage.c index 91ee572817..5f82d6d76d 100644 --- a/harbour/source/vm/garbage.c +++ b/harbour/source/vm/garbage.c @@ -145,6 +145,22 @@ void *hb_gcUnlock( void *pBlock ) return pBlock; } +void hb_gcLockItem( HB_ITEM_PTR pItem ) +{ + if( HB_IS_ARRAY( pItem ) ) + hb_gcLock( pItem->item.asArray.value ); + else if( HB_IS_BLOCK( pItem ) ) + hb_gcLock( pItem->item.asBlock.value ); +} + +void hb_gcUnlockItem( HB_ITEM_PTR pItem ) +{ + if( HB_IS_ARRAY( pItem ) ) + hb_gcUnlock( pItem->item.asArray.value ); + else if( HB_IS_BLOCK( pItem ) ) + hb_gcUnlock( pItem->item.asBlock.value ); +} + void hb_gcCollect( void ) { if( s_pCurrBlock && !s_bCollecting )