From 2e751d16e90cda34df8d9682f8bf611b1f35ec6f Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Tue, 8 Nov 2005 01:07:00 +0000 Subject: [PATCH] 2005-11-08 01:56 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/vm/garbage.c - removed unnecessary memset() * harbour/source/vm/hvm.c % use startup initialized symbols: hb_symEnumIndex, hb_symEnumBase, hb_symEnumValue instead of strcmp( pSym->szName, ... ) in hb_vmSend() % remove unnecessary temporary item in hb_vmEnumStart() and use hb_itemMove() instead of hb_itemCopy()+hb_itemClear() % changed main VM loop to eliminate one comparision done on each loop. Now HB_P_ENDBLOCK and HB_P_ENDPROC pcodes set HB_ENDPROC_REQUESTED and the main loop can be exited only from one place. It gives some small but noticeable speed improvement. Ryszard please check this modification. AFAIK it should not cause any bad side effect and IMHO the code is cleaner now. * harbour/source/vm/itemapi.c % removed two unnecessary hb_itemClear() before hb_itemRelease() --- harbour/ChangeLog | 19 ++++++++ harbour/source/vm/garbage.c | 13 ++--- harbour/source/vm/hvm.c | 94 ++++++++++++++++++++++--------------- harbour/source/vm/itemapi.c | 4 -- 4 files changed, 78 insertions(+), 52 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 7e47cb7060..91853b2ed8 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,25 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ +2005-11-08 01:56 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/vm/garbage.c + - removed unnecessary memset() + + * harbour/source/vm/hvm.c + % use startup initialized symbols: hb_symEnumIndex, hb_symEnumBase, + hb_symEnumValue instead of strcmp( pSym->szName, ... ) in hb_vmSend() + % remove unnecessary temporary item in hb_vmEnumStart() and use + hb_itemMove() instead of hb_itemCopy()+hb_itemClear() + % changed main VM loop to eliminate one comparision done on each + loop. Now HB_P_ENDBLOCK and HB_P_ENDPROC pcodes set HB_ENDPROC_REQUESTED + and the main loop can be exited only from one place. It gives some + small but noticeable speed improvement. + Ryszard please check this modification. AFAIK it should not cause + any bad side effect and IMHO the code is cleaner now. + + * harbour/source/vm/itemapi.c + % removed two unnecessary hb_itemClear() before hb_itemRelease() + 2005-11-07 14:35 UTC+0100 Ryszard Glab * include/hbapi.h * include/hbapiitm.h diff --git a/harbour/source/vm/garbage.c b/harbour/source/vm/garbage.c index 95b213fc80..f9d7959394 100644 --- a/harbour/source/vm/garbage.c +++ b/harbour/source/vm/garbage.c @@ -191,16 +191,10 @@ HB_ITEM_PTR hb_gcGripGet( HB_ITEM_PTR pOrigin ) pAlloc->pFunc = hb_gcGripRelease; pAlloc->locked = 1; pAlloc->used = s_uUsedFlag; + + pItem->type = HB_IT_NIL; if( pOrigin ) - { - pItem->type = HB_IT_NIL; hb_itemCopy( pItem, pOrigin ); - } - else - { - memset( pItem, 0, sizeof( HB_ITEM ) ); - pItem->type = HB_IT_NIL; - } return pItem; } @@ -214,7 +208,8 @@ void hb_gcGripDrop( HB_ITEM_PTR pItem ) { HB_GARBAGE_PTR pAlloc = ( HB_GARBAGE_PTR ) ( ( BYTE * ) pItem - HB_GARBAGE_SIZE ); - hb_itemClear( pItem ); /* clear value stored in this item */ + if( HB_IS_COMPLEX( pItem ) ) + hb_itemClear( pItem ); /* clear value stored in this item */ hb_gcUnlink( &s_pLockedBlock, pAlloc ); HB_GARBAGE_FREE( pAlloc ); diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index eef83817ce..a9ac173bf1 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -227,6 +227,9 @@ ULONG hb_ulOpcodesTime[ HB_P_LAST_PCODE ]; /* array to profile opcodes consumed /* virtual machine state */ HB_SYMB hb_symEval = { "__EVAL", HB_FS_PUBLIC, {hb_vmDoBlock}, NULL }; /* symbol to evaluate codeblocks */ +HB_SYMB hb_symEnumIndex = { "__ENUMINDEX", HB_FS_PUBLIC, {NULL}, NULL }; +HB_SYMB hb_symEnumBase = { "__ENUMBASE", HB_FS_PUBLIC, {NULL}, NULL }; +HB_SYMB hb_symEnumValue = { "__ENUMVALUE", HB_FS_PUBLIC, {NULL}, NULL }; static HB_ITEM s_aStatics; /* Harbour array to hold all application statics variables */ static USHORT s_uiStatics; /* Number of statics added after processing hb_vmStatics() */ @@ -409,7 +412,12 @@ void HB_EXPORT hb_vmInit( BOOL bStartMainProc ) hb_xinit(); hb_errInit(); hb_stackInit(); + hb_dynsymNew( &hb_symEval ); /* initialize dynamic symbol for evaluating codeblocks */ + hb_dynsymNew( &hb_symEnumIndex ); + hb_dynsymNew( &hb_symEnumBase ); + hb_dynsymNew( &hb_symEnumValue ); + hb_setInitialize(); /* initialize Sets */ hb_conInit(); /* initialize Console */ hb_memvarsInit(); @@ -583,7 +591,6 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) { LONG w = 0; BOOL bCanRecover = FALSE; - BYTE curPCode; ULONG ulPrivateBase; ULONG ulLastOpcode = 0; /* opcodes profiler support */ ULONG ulPastClock = 0; /* opcodes profiler support */ @@ -605,7 +612,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) if( hb_bProfiler ) ulPastClock = ( ULONG ) clock(); - while( ( curPCode = pCode[ w ] ) != HB_P_ENDPROC ) + while( TRUE ) { if( hb_bProfiler ) { @@ -621,7 +628,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) if( ! --uiPolls ) { hb_inkeyPoll(); - uiPolls = 255; + //uiPolls = 255; /* IMHO we should have a _SET_ controlled by user * sth like: @@ -642,7 +649,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) } #endif - switch( curPCode ) + switch( pCode[ w ] ) { /* Operators ( mathematical / character / misc ) */ @@ -946,11 +953,22 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_ENDBLOCK: - HB_TRACE(HB_TR_INFO, ("(EndBlock)")); + HB_TRACE(HB_TR_INFO, ("HB_P_ENDBLOCK")); hb_vmEndBlock(); - if( pSymbols ) - hb_memvarSetPrivatesBase( ulPrivateBase ); - return; /* end of a codeblock - stop evaluation */ + /* manually inlined hb_vmRequestEndProc() for some C compilers + * which does not make such optimisation + */ + s_uiActionRequest = HB_ENDPROC_REQUESTED; + + break; + + case HB_P_ENDPROC: + HB_TRACE(HB_TR_INFO, ("HB_P_ENDPROC")); + /* manually inlined hb_vmRequestEndProc() for some C compilers + * which does not make such optimisation + */ + s_uiActionRequest = HB_ENDPROC_REQUESTED; + break; /* BEGIN SEQUENCE/RECOVER/END SEQUENCE */ @@ -1835,7 +1853,15 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) if( s_uiActionRequest ) { - if( s_uiActionRequest & HB_BREAK_REQUESTED ) + if( s_uiActionRequest & HB_ENDPROC_REQUESTED ) + { + /* request to stop current procedure was issued + * (from macro evaluation) + */ + s_uiActionRequest = 0; + break; + } + else if( s_uiActionRequest & HB_BREAK_REQUESTED ) { if( bCanRecover ) { @@ -1843,7 +1869,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) * There is the BEGIN/END sequence deifined in current * procedure/function - use it to continue opcodes execution */ - while( lForEachBase && lForEachBase > s_lRecoverBase ) + while( lForEachBase > s_lRecoverBase ) { /* remove FOR EACH stack frame so there is no orphan * item pointers hanging @@ -1871,14 +1897,6 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) } else if( s_uiActionRequest & HB_QUIT_REQUESTED ) break; - else if( s_uiActionRequest & HB_ENDPROC_REQUESTED ) - { - /* request to stop current procedure was issued - * (from macro evaluation) - */ - s_uiActionRequest = 0; - break; - } } } @@ -3052,26 +3070,22 @@ static LONG hb_vmEnumStart( BYTE nVars, BYTE nDescend, LONG lOldBase ) return lOldBase; } - for( i=nVars; i>=0; i-- ) + for( i = nVars * 2; i >= 0; i -= 2 ) { - HB_ITEM item; - - /* value to iterate store it in temporary holder */ - item.type = HB_IT_NIL; - hb_itemCopy( &item, hb_itemUnRef( hb_stackItemFromTop( -(i*2) -2 ) ) ); + PHB_ITEM pBaseValue; + /* copy value to iterate */ + pBaseValue = hb_itemNew( hb_itemUnRef( hb_stackItemFromTop( -i -2 ) ) ); /* the control variable */ - pRef = hb_itemUnRefOnce( hb_stackItemFromTop( -(i*2) -1 ) ); - /* store the old value of variable */ - hb_itemCopy( hb_stackItemFromTop( -(i*2) -2 ), pRef ); - hb_itemClear( pRef ); /* clear the old value of variable */ + pRef = hb_itemUnRefOnce( hb_stackItemFromTop( -i -1 ) ); + /* store the old value of variable and clear it */ + hb_itemMove( hb_stackItemFromTop( -i -2 ), pRef ); /* set the iterator value */ pRef->type = HB_IT_BYREF; pRef->item.asRefer.ValuePtr.itemPtr = NULL; - pRef->item.asRefer.BasePtr.itemPtr = hb_itemNew( &item ); + pRef->item.asRefer.BasePtr.itemPtr = pBaseValue; pRef->item.asRefer.offset = -1; /* enumerator variable */ - hb_itemClear( &item ); pItem = pRef->item.asRefer.BasePtr.itemPtr; if( HB_IS_ARRAY(pItem) ) @@ -3132,7 +3146,7 @@ static void hb_vmEnumNext( void ) { for( i=lVars; i >= 0; i-- ) { - pRef = hb_itemUnRefRefer( hb_stackItemFromTop( -(i*2) - 4 ) ); + pRef = hb_itemUnRefRefer( hb_stackItemFromTop( -(i<<1) - 4 ) ); if( HB_IS_ARRAY(pRef->item.asRefer.BasePtr.itemPtr) ) { pRef->item.asRefer.value++; @@ -3219,7 +3233,7 @@ static void hb_vmEnumPrev( void ) * -2 -> * -1 -> */ -static LONG hb_vmEnumEnd() +static LONG hb_vmEnumEnd( void ) { int i; LONG lOldBase; @@ -3984,7 +3998,7 @@ void HB_EXPORT hb_vmSend( USHORT uiParams ) /* printf( "Symbol: '%s'\n", pSym->szName ); */ - if ( HB_IS_BYREF(pSelf) ) + if( HB_IS_BYREF(pSelf) ) { /* method of enumerator variable from FOR EACH statement */ @@ -3993,25 +4007,24 @@ void HB_EXPORT hb_vmSend( USHORT uiParams ) pRef = hb_itemUnRefRefer( pSelf ); if( HB_IS_BYREF(pRef) && pRef->item.asRefer.offset < 0 && pRef->item.asRefer.value >= 0 ) { - if( hb_stricmp( (const char *)pSym->szName, "__ENUMINDEX" ) == 0 ) + if( pSym->pDynSym == hb_symEnumIndex.pDynSym ) { hb_itemPutNL( &hb_stack.Return, pRef->item.asRefer.value ); bNotHandled = FALSE; } - else if( hb_stricmp( (const char *)pSym->szName, "__ENUMBASE" ) == 0 ) + else if( pSym->pDynSym == hb_symEnumBase.pDynSym ) { hb_itemCopy( &hb_stack.Return, pRef->item.asRefer.BasePtr.itemPtr ); bNotHandled = FALSE; } - else if( hb_stricmp( (const char *)pSym->szName, "__ENUMVALUE" ) == 0 ) + else if( pSym->pDynSym == hb_symEnumValue.pDynSym ) { hb_itemCopy( &hb_stack.Return, hb_itemUnRefOnce(pRef) ); bNotHandled = FALSE; } } } - - if( HB_IS_NIL( pSelf ) && bNotHandled ) /* are we sending a message ? */ + else if( HB_IS_NIL( pSelf ) ) /* are we sending a message ? */ { pFunc = pSym->value.pFunPtr; @@ -4062,8 +4075,11 @@ void HB_EXPORT hb_vmSend( USHORT uiParams ) hb_itemRelease( pArgsArray ); } } + + bNotHandled = FALSE; } - else if( bNotHandled ) + + if( bNotHandled ) { PHB_BASEARRAY pSelfBase = NULL; BOOL lPopSuper = FALSE; diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index 5a4075d5c1..fd7caf1c5a 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -1127,13 +1127,9 @@ void HB_EXPORT hb_itemClear( PHB_ITEM pItem ) else if( HB_IS_BYREF( pItem ) && pItem->item.asRefer.offset < 0 && pItem->item.asRefer.value >= 0 ) { /* FOR EACH control variable */ - hb_itemClear( pItem->item.asRefer.BasePtr.itemPtr ); hb_itemRelease( pItem->item.asRefer.BasePtr.itemPtr ); if( pItem->item.asRefer.ValuePtr.itemPtr ) - { - hb_itemClear( pItem->item.asRefer.ValuePtr.itemPtr ); hb_itemRelease( pItem->item.asRefer.ValuePtr.itemPtr ); - } } #if defined( HB_FM_STATISTICS ) && defined( HB_PARANOID_MEM_CHECK )