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 )