/* Release all allocated memory when called from the garbage collector */ static HB_GARBAGE_FUNC( hb_codeblockGarbageDelete ) { PHB_CODEBLOCK pCBlock = ( PHB_CODEBLOCK ) Cargo; HB_TRACE( HB_TR_DEBUG, ( "hb_codeblockGarbageDelete(%p)", Cargo ) ); /* free space allocated for pcodes - if it was a macro-compiled codeblock */ if( pCBlock->pCode && pCBlock->dynBuffer ) { pCBlock->dynBuffer = HB_FALSE; hb_xfree( HB_UNCONST( pCBlock->pCode ) ); } pCBlock->pCode = s_pCode; /* free space allocated for local variables */ if( pCBlock->pLocals ) { if( hb_xRefDec( pCBlock->pLocals ) ) { while( pCBlock->uiLocals ) hb_memvarValueDecRef( pCBlock->pLocals[ pCBlock->uiLocals-- ].item.asMemvar.value ); hb_xfree( pCBlock->pLocals ); } pCBlock->pLocals = NULL; pCBlock->uiLocals = 0; } }
/* * This function decreases the number of references to passed global value. * If it is the last reference then this value is deleted. */ void hb_memvarValueDecRef( PHB_ITEM pMemvar ) { HB_TRACE( HB_TR_DEBUG, ( "hb_memvarValueDecRef(%p)", pMemvar ) ); if( hb_xRefDec( pMemvar ) ) { if( HB_IS_COMPLEX( pMemvar ) ) hb_itemClear( pMemvar ); hb_xfree( pMemvar ); } }
void hb_gcRefFree( void * pBlock ) { if( pBlock ) { PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock ); if( hb_xRefDec( pAlloc ) ) { /* Don't release the block that will be deleted during finalization */ if( ! ( pAlloc->used & HB_GC_DELETE ) ) { pAlloc->used |= HB_GC_DELETE; /* execute clean-up function */ pAlloc->pFuncs->clear( pBlock ); if( hb_xRefCount( pAlloc ) != 0 ) { if( pAlloc->used & HB_GC_DELETE ) { pAlloc->used = s_uUsedFlag; if( hb_vmRequestQuery() == 0 ) hb_errRT_BASE( EG_DESTRUCTOR, 1301, NULL, "Reference to freed block", 0 ); } } else { HB_GC_LOCK(); if( pAlloc->locked ) hb_gcUnlink( &s_pLockedBlock, pAlloc ); else { hb_gcUnlink( &s_pCurrBlock, pAlloc ); HB_GC_AUTO_DEC(); } HB_GC_UNLOCK(); HB_GARBAGE_FREE( pAlloc ); } } } } else { hb_errInternal( HB_EI_XFREENULL, NULL, NULL, NULL ); } }
/* Release all allocated memory when called from the garbage collector */ static HB_GARBAGE_FUNC( hb_codeblockGarbageDelete ) { PHB_CODEBLOCK pCBlock = ( PHB_CODEBLOCK ) Cargo; HB_TRACE( HB_TR_DEBUG, ( "hb_codeblockGarbageDelete(%p)", Cargo ) ); /* free space allocated for pcodes - if it was a macro-compiled codeblock */ if( pCBlock->pCode && pCBlock->dynBuffer ) { pCBlock->dynBuffer = HB_FALSE; hb_xfree( ( void * ) pCBlock->pCode ); } pCBlock->pCode = s_pCode; /* free space allocated for local variables */ if( pCBlock->pLocals ) { PHB_ITEM pLocals = pCBlock->pLocals; HB_USHORT uiLocals = pCBlock->uiLocals; /* clear pCBlock->pLocals to avoid infinit loop in cross * referenced items */ pCBlock->pLocals = NULL; pCBlock->uiLocals = 0; if( hb_xRefDec( pLocals ) ) { while( uiLocals ) hb_memvarValueDecRef( pLocals[ uiLocals-- ].item.asMemvar.value ); hb_xfree( pLocals ); } } }