From d7eb859c0a3f93efbb9af01486012c6abe9243a5 Mon Sep 17 00:00:00 2001 From: "Alexander S.Kresin" Date: Tue, 28 Jan 2003 08:26:01 +0000 Subject: [PATCH] 2003-01-28 11:25 UTC+0300 Alexander Kresin --- harbour/ChangeLog | 13 +++++- harbour/include/hbapi.h | 8 +++- harbour/source/rtl/philes.c | 4 +- harbour/source/vm/hvm.c | 35 +++++++++------ harbour/source/vm/itemapi.c | 86 ++++++++++++++++++++++++++----------- 5 files changed, 105 insertions(+), 41 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index e210faea13..dd06a2b616 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,8 +8,19 @@ 2002-12-01 23:12 UTC+0100 Foo Bar */ +2003-01-28 11:25 UTC+0300 Alexander Kresin + * include/hbapi.h + * source/rtl/philes.c + * source/vm/itemapi.c + * source/vm/hvm.c + * Optimization of string operations. Now if the size of the string is less + than sizeof(short int *) - in most systems it is 4, it is kept in the + item itself, additional memory isn't allocated for it. + This leads to performance improvement and decreasing of memory + fragmentation/usage. + 2003-01-26 16:20 UTC+0300 Alexander Kresin - * hbapiitm.h + * include/hbapiitm.h * source/vm/itemapi.c * source/vm/hvm.c * hb_itemMove() function added, which is intended for use instead of diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index e7d87bf344..534c6b0a93 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -200,8 +200,12 @@ struct hb_struString { ULONG length; char * value; - BOOL bStatic; /* it is a static string from pcode or from a C string */ - USHORT * puiHolders; /* number of holders of this string */ + SHORT bStatic; /* it is a static string from pcode or from a C string */ + union + { + char value[1]; + USHORT * puiHolders; /* number of holders of this string */ + } u; }; struct hb_struSymbol diff --git a/harbour/source/rtl/philes.c b/harbour/source/rtl/philes.c index 496f7231ae..1ec073f0ad 100644 --- a/harbour/source/rtl/philes.c +++ b/harbour/source/rtl/philes.c @@ -96,8 +96,8 @@ HB_FUNC( FREAD ) { PHB_ITEM pItem = hb_itemUnRef( hb_stackItemFromBase( 2 ) ); - if( pItem->item.asString.bStatic /* == TRUE */ || - ( * pItem->item.asString.puiHolders ) > 1 ) + if( pItem->item.asString.bStatic || + ( * pItem->item.asString.u.puiHolders ) > 1 ) hb_itemPutC( pItem, hb_parc( 2 ) ); ulRead = hb_parnl( 3 ); diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index ad07dd762f..9a6f1537a2 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -2784,7 +2784,7 @@ static void hb_vmArrayPop( void ) { if( ulIndex > 0 && ulIndex <= pArray->item.asString.length ) { - if( pArray->item.asString.bStatic || *( pArray->item.asString.puiHolders ) > 1 ) + if( pArray->item.asString.bStatic || *( pArray->item.asString.u.puiHolders ) > 1 ) hb_itemPutC( pArray, pArray->item.asString.value ); pArray->item.asString.value[ ulIndex - 1 ] = hb_itemGetNI( pValue ); @@ -3890,21 +3890,32 @@ void hb_vmPushPointer( void * pPointer ) void hb_vmPushString( char * szText, ULONG length ) { - char * szTemp; PHB_ITEM pStackTopItem = hb_stackTopItem(); HB_TRACE(HB_TR_DEBUG, ("hb_vmPushString(%s, %lu)", szText, length)); - szTemp = ( char * ) hb_xgrab( length + 1 ); - hb_xmemcpy( szTemp, szText, length ); - szTemp[ length ] = '\0'; - pStackTopItem->type = HB_IT_STRING; - pStackTopItem->item.asString.length = length; - pStackTopItem->item.asString.value = szTemp; - pStackTopItem->item.asString.bStatic = FALSE; - pStackTopItem->item.asString.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - *( pStackTopItem->item.asString.puiHolders ) = 1; + if( length < sizeof(USHORT*) ) + { + ULONG i = 0; + pStackTopItem->item.asString.value = pStackTopItem->item.asString.u.value; + for( ; iitem.asString.value[i] = *szText; + pStackTopItem->item.asString.value[ length ] = '\0'; + pStackTopItem->item.asString.bStatic = -1; + } + else + { + char * szTemp = ( char * ) hb_xgrab( length + 1 ); + hb_xmemcpy( szTemp, szText, length ); + szTemp[ length ] = '\0'; + + pStackTopItem->item.asString.length = length; + pStackTopItem->item.asString.value = szTemp; + pStackTopItem->item.asString.bStatic = 0; + pStackTopItem->item.asString.u.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + *( pStackTopItem->item.asString.u.puiHolders ) = 1; + } hb_stackPush(); } @@ -3917,7 +3928,7 @@ void hb_vmPushStringPcode( char * szText, ULONG length ) pStackTopItem->type = HB_IT_STRING; pStackTopItem->item.asString.length = length; pStackTopItem->item.asString.value = szText; - pStackTopItem->item.asString.bStatic = TRUE; + pStackTopItem->item.asString.bStatic = 1; hb_stackPush(); } diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index c524b8cf42..c71b86d1ce 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -204,20 +204,33 @@ PHB_ITEM hb_itemPutC( PHB_ITEM pItem, char * szText ) pItem->type = HB_IT_STRING; - if( szText == NULL ) + if( szText == NULL || szText[0] == '\0' ) { pItem->item.asString.length = 0; - pItem->item.asString.value = ""; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.value = pItem->item.asString.u.value; + pItem->item.asString.u.value[0] = '\0'; + pItem->item.asString.bStatic = -1; } else { pItem->item.asString.length = strlen( szText ); - pItem->item.asString.value = ( char * ) hb_xgrab( pItem->item.asString.length + 1 ); - pItem->item.asString.bStatic = FALSE; - pItem->item.asString.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - * ( pItem->item.asString.puiHolders ) = 1; - strcpy( pItem->item.asString.value, szText ); + if( pItem->item.asString.length < sizeof(USHORT*) ) + { + int i = 0; + pItem->item.asString.value = pItem->item.asString.u.value; + for( ; *szText; szText++, i++ ) + pItem->item.asString.value[i] = *szText; + pItem->item.asString.u.value[i] = '\0'; + pItem->item.asString.bStatic = -1; + } + else + { + pItem->item.asString.value = ( char * ) hb_xgrab( pItem->item.asString.length + 1 ); + pItem->item.asString.bStatic = 0; + pItem->item.asString.u.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + * ( pItem->item.asString.u.puiHolders ) = 1; + strcpy( pItem->item.asString.value, szText ); + } } return pItem; @@ -233,7 +246,7 @@ PHB_ITEM hb_itemPutCConst( PHB_ITEM pItem, char * szText ) pItem = hb_itemNew( NULL ); pItem->type = HB_IT_STRING; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.bStatic = 1; if( szText == NULL ) { @@ -264,21 +277,33 @@ PHB_ITEM hb_itemPutCL( PHB_ITEM pItem, char * szText, ULONG ulLen ) pItem->type = HB_IT_STRING; - if( szText == NULL ) + if( szText == NULL || ulLen == 0) { pItem->item.asString.length = 0; - pItem->item.asString.value = ""; - pItem->item.asString.bStatic = TRUE; + pItem->item.asString.value = pItem->item.asString.u.value; + pItem->item.asString.u.value[0] = '\0'; + pItem->item.asString.bStatic = -1; } else { pItem->item.asString.length = ulLen; - pItem->item.asString.value = ( char * ) hb_xgrab( ulLen + 1 ); - hb_xmemcpy( pItem->item.asString.value, szText, ulLen ); + if( ulLen < sizeof(USHORT*) ) + { + ULONG i = 0; + pItem->item.asString.value = pItem->item.asString.u.value; + for( ; iitem.asString.value[i] = *szText; + pItem->item.asString.bStatic = -1; + } + else + { + pItem->item.asString.value = ( char * ) hb_xgrab( ulLen + 1 ); + pItem->item.asString.bStatic = 0; + pItem->item.asString.u.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + * ( pItem->item.asString.u.puiHolders ) = 1; + hb_xmemcpy( pItem->item.asString.value, szText, ulLen ); + } pItem->item.asString.value[ ulLen ] = '\0'; - pItem->item.asString.bStatic = FALSE; - pItem->item.asString.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - * ( pItem->item.asString.puiHolders ) = 1; } return pItem; @@ -297,9 +322,9 @@ PHB_ITEM hb_itemPutCPtr( PHB_ITEM pItem, char * szText, ULONG ulLen ) pItem->item.asString.length = ulLen; pItem->item.asString.value = szText; pItem->item.asString.value[ ulLen ] = '\0'; - pItem->item.asString.bStatic = FALSE; - pItem->item.asString.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); - * ( pItem->item.asString.puiHolders ) = 1; + pItem->item.asString.bStatic = 0; + pItem->item.asString.u.puiHolders = ( USHORT * ) hb_xgrab( sizeof( USHORT ) ); + * ( pItem->item.asString.u.puiHolders ) = 1; return pItem; } @@ -858,11 +883,11 @@ void hb_itemClear( PHB_ITEM pItem ) pItem->item.asString.value = NULL; else { - if( --*( pItem->item.asString.puiHolders ) == 0 ) + if( --*( pItem->item.asString.u.puiHolders ) == 0 ) { hb_xfree( pItem->item.asString.value ); pItem->item.asString.value = NULL; - hb_xfree( pItem->item.asString.puiHolders ); + hb_xfree( pItem->item.asString.u.puiHolders ); } } pItem->item.asString.length = 0; @@ -895,9 +920,15 @@ void hb_itemCopy( PHB_ITEM pDest, PHB_ITEM pSource ) memcpy( pDest, pSource, sizeof( HB_ITEM ) ); - if( HB_IS_STRING( pSource ) && ! pSource->item.asString.bStatic ) + if( HB_IS_STRING( pSource ) ) { - ++*( pSource->item.asString.puiHolders ); + if( pSource->item.asString.bStatic ) + { + if( pSource->item.asString.bStatic < 0 ) + pDest->item.asString.value = pDest->item.asString.u.value; + } + else + ++*( pSource->item.asString.u.puiHolders ); } else if( HB_IS_ARRAY( pSource ) ) { @@ -922,6 +953,8 @@ void hb_itemMove( PHB_ITEM pDest, PHB_ITEM pSource ) hb_itemClear( pDest ); memcpy( pDest, pSource, sizeof( HB_ITEM ) ); + if( HB_IS_STRING( pSource ) && pSource->item.asString.bStatic < 0 ) + pDest->item.asString.value = pDest->item.asString.u.value; pSource->type = HB_IT_NIL; } @@ -933,6 +966,11 @@ void hb_itemSwap( PHB_ITEM pItem1, PHB_ITEM pItem2 ) HB_TRACE(HB_TR_DEBUG, ("hb_itemSwap(%p, %p)", pItem1, pItem2)); temp.type = HB_IT_NIL; + /* + hb_itemMove( &temp, pItem2 ); + hb_itemMove( pItem2, pItem1 ); + hb_itemMove( pItem1, &temp ); + */ hb_itemCopy( &temp, pItem2 ); hb_itemCopy( pItem2, pItem1 ); hb_itemCopy( pItem1, &temp );