From 7da18ea3dcebf2d36ab2ee995e7674a8fcd1979f Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Thu, 4 Mar 2010 10:06:32 +0000 Subject: [PATCH] 2010-03-04 11:06 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbcompdf.h * harbour/src/vm/macro.c % changed HB_PCODE_INFO structure to eliminate one memory allocation in macro compiler * harbour/include/hbapi.h * harbour/include/hbvm.h * harbour/src/vm/codebloc.c * harbour/src/vm/itemapi.c * harbour/src/vm/hvm.c * changed second parameter in hb_codeblockGet*() function to 'int' * merged codeblock execution context setting into one function hb_vmDoBlock() and removed hb_codeblockEvaluate() + added new internal function hb_vmEval() * harbour/src/vm/arrays.c % use hb_vmEval() * harbour/src/macro/macrolex.c * added missing const to maro text declaration * harbour/tests/speedtst.prg ! fixed to work with CLIP and xHarbour after we changed SECONDSCPU() to HB_SECONDSCPU() - all these compilers and FlagShip have SECONDSCPU() function --- harbour/ChangeLog | 27 +++++++++++++ harbour/include/hbapi.h | 5 +-- harbour/include/hbcompdf.h | 3 +- harbour/include/hbvm.h | 1 + harbour/src/macro/macrolex.c | 12 +++--- harbour/src/vm/arrays.c | 6 +-- harbour/src/vm/codebloc.c | 24 ++---------- harbour/src/vm/hvm.c | 74 +++++++++++++++++++++++++++--------- harbour/src/vm/itemapi.c | 2 +- harbour/src/vm/macro.c | 16 ++++---- harbour/tests/speedtst.prg | 60 +++++++++++++++-------------- 11 files changed, 140 insertions(+), 90 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 31ab0a70af..864863e0ce 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,33 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-03-04 11:06 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbcompdf.h + * harbour/src/vm/macro.c + % changed HB_PCODE_INFO structure to eliminate one memory allocation + in macro compiler + + * harbour/include/hbapi.h + * harbour/include/hbvm.h + * harbour/src/vm/codebloc.c + * harbour/src/vm/itemapi.c + * harbour/src/vm/hvm.c + * changed second parameter in hb_codeblockGet*() function to 'int' + * merged codeblock execution context setting into one function + hb_vmDoBlock() and removed hb_codeblockEvaluate() + + added new internal function hb_vmEval() + + * harbour/src/vm/arrays.c + % use hb_vmEval() + + * harbour/src/macro/macrolex.c + * added missing const to maro text declaration + + * harbour/tests/speedtst.prg + ! fixed to work with CLIP and xHarbour after we changed + SECONDSCPU() to HB_SECONDSCPU() - all these compilers and FlagShip + have SECONDSCPU() function + 2010-03-04 03:07 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbmisc/hbeditc.c * Reverted previous strcpy changes as they were causing GPF diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index c0eb528928..1100a0ae6f 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -1011,9 +1011,8 @@ extern HB_EXPORT HB_BOOL hb_winmainArgGet( void * phInstance, void * phPrevInsta extern HB_EXPORT void * hb_codeblockId( PHB_ITEM pItem ); /* retrieves the codeblock unique ID */ extern HB_CODEBLOCK_PTR hb_codeblockNew( const HB_BYTE * pBuffer, HB_USHORT uiLocals, const HB_BYTE * pLocalPosTable, PHB_SYMB pSymbols, HB_SIZE ulLen ); /* create a code-block */ extern HB_CODEBLOCK_PTR hb_codeblockMacroNew( const HB_BYTE * pBuffer, HB_SIZE ulLen ); -extern PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, HB_LONG iItemPos ); /* get local variable referenced in a codeblock */ -extern PHB_ITEM hb_codeblockGetRef( HB_CODEBLOCK_PTR pCBlock, HB_LONG iItemPos ); /* get local variable passed by reference */ -extern void hb_codeblockEvaluate( HB_ITEM_PTR pItem ); /* evaluate a codeblock */ +extern PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, int iItemPos ); /* get local variable referenced in a codeblock */ +extern PHB_ITEM hb_codeblockGetRef( HB_CODEBLOCK_PTR pCBlock, int iItemPos ); /* get local variable passed by reference */ /* memvars subsystem */ extern void hb_memvarsClear( HB_BOOL fAll ); /* clear all PUBLIC and PRIVATE variables optionally without GetList PUBLIC variable */ diff --git a/harbour/include/hbcompdf.h b/harbour/include/hbcompdf.h index a900152fbb..58fe85a1c7 100644 --- a/harbour/include/hbcompdf.h +++ b/harbour/include/hbcompdf.h @@ -649,8 +649,8 @@ typedef struct HB_PCODE_INFO_ /* compiled pcode container for macro compiler */ HB_ULONG lPCodeSize; /* total memory size for pcode */ HB_ULONG lPCodePos; /* actual pcode offset */ HB_BOOL fVParams; /* function/codeblock with variable parameters */ - struct HB_PCODE_INFO_ * pPrev; HB_CBVAR_PTR pLocals; + struct HB_PCODE_INFO_ * pPrev; } HB_PCODE_INFO, * HB_PCODE_INFO_PTR; typedef struct HB_MACRO_ /* a macro compiled pcode container */ @@ -673,6 +673,7 @@ typedef struct HB_MACRO_ /* a macro compiled pcode container */ int exprType; /* type of successfully compiled expression */ HB_USHORT uiListElements; /* number of elements in macro list expression */ HB_USHORT uiNameLen; /* the maximum symbol name length */ + HB_PCODE_INFO pCodeInfoBuffer; } HB_MACRO; #else diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index da9fd8d4bc..8f9af5b975 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -112,6 +112,7 @@ extern HB_EXPORT PHB_SYMB hb_vmProcessDynLibSymbols( PHB_SYMB pSymbols, HB_USHOR extern void hb_vmUpdateAllocator( PHB_ALLOCUPDT_FUNC pFunc, int iCount ); + extern void hb_vmEval( HB_USHORT uiParams ); #endif extern void hb_vmSetExceptionHandler( void ); diff --git a/harbour/src/macro/macrolex.c b/harbour/src/macro/macrolex.c index 72b271af7a..2a1ea74222 100644 --- a/harbour/src/macro/macrolex.c +++ b/harbour/src/macro/macrolex.c @@ -59,12 +59,12 @@ typedef struct _HB_MACRO_LEX { - char * pString; - char * pDst; - HB_SIZE ulLen; - HB_SIZE ulSrc; - HB_BOOL quote; - char pBuffer[ 2 ]; + const char * pString; + char * pDst; + HB_SIZE ulLen; + HB_SIZE ulSrc; + HB_BOOL quote; + char pBuffer[ 2 ]; } HB_MACRO_LEX, * PHB_MACRO_LEX; diff --git a/harbour/src/vm/arrays.c b/harbour/src/vm/arrays.c index 55f9041171..5512fa8ae6 100644 --- a/harbour/src/vm/arrays.c +++ b/harbour/src/vm/arrays.c @@ -1001,7 +1001,7 @@ HB_SIZE hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, HB_SIZE * pulStart, HB_S hb_vmPush( pValue ); hb_vmPush( pBaseArray->pItems + ulStart ); hb_vmPushLong( ++ulStart ); - hb_vmSend( 2 ); + hb_vmEval( 2 ); if( HB_IS_LOGICAL( hb_stackReturnItem() ) && hb_stackReturnItem()->item.asLogical.value ) return ulStart; @@ -1168,7 +1168,7 @@ HB_SIZE hb_arrayRevScan( PHB_ITEM pArray, PHB_ITEM pValue, HB_SIZE * pulStart, H else hb_vmPushNil(); hb_vmPushLong( ulStart + 1 ); - hb_vmSend( 2 ); + hb_vmEval( 2 ); if( HB_IS_LOGICAL( hb_stackReturnItem() ) && hb_stackReturnItem()->item.asLogical.value ) return ulStart + 1; @@ -1326,7 +1326,7 @@ HB_BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, HB_SIZE * pulStart, HB_S hb_vmPush( bBlock ); hb_vmPush( pBaseArray->pItems + ulStart ); hb_vmPushLong( ulStart + 1 ); - hb_vmSend( 2 ); + hb_vmEval( 2 ); } while( --ulCount > 0 && ++ulStart < pBaseArray->ulLen ); /* diff --git a/harbour/src/vm/codebloc.c b/harbour/src/vm/codebloc.c index 32db416952..0616224ddd 100644 --- a/harbour/src/vm/codebloc.c +++ b/harbour/src/vm/codebloc.c @@ -293,29 +293,13 @@ HB_CODEBLOCK_PTR hb_codeblockMacroNew( const HB_BYTE * pBuffer, HB_SIZE ulLen ) return pCBlock; } -/* Evaluate passed codeblock - * Before evaluation we have to switch to a static variable base that - * was defined when the codeblock was created. - * (The codeblock can only see the static variables defined in a module - * where the codeblock was created) - */ -void hb_codeblockEvaluate( HB_ITEM_PTR pItem ) -{ - HB_STACK_TLS_PRELOAD - - HB_TRACE(HB_TR_DEBUG, ("hb_codeblockEvaluate(%p)", pItem)); - - hb_stackSetStaticsBase( pItem->item.asBlock.value->pStatics ); - hb_vmExecute( pItem->item.asBlock.value->pCode, pItem->item.asBlock.value->pSymbols ); -} - /* Get local variable referenced in a codeblock */ -PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, HB_LONG iItemPos ) +PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, int iItemPos ) { HB_CODEBLOCK_PTR pCBlock = pItem->item.asBlock.value; - HB_TRACE(HB_TR_DEBUG, ("hb_codeblockGetVar(%p, %ld)", pItem, iItemPos)); + HB_TRACE(HB_TR_DEBUG, ("hb_codeblockGetVar(%p, %d)", pItem, iItemPos)); /* local variables accessed in a codeblock are always stored as reference */ return hb_itemUnRef( pCBlock->pLocals - iItemPos ); @@ -323,9 +307,9 @@ PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, HB_LONG iItemPos ) /* Get local variable passed by reference */ -PHB_ITEM hb_codeblockGetRef( HB_CODEBLOCK_PTR pCBlock, HB_LONG iItemPos ) +PHB_ITEM hb_codeblockGetRef( HB_CODEBLOCK_PTR pCBlock, int iItemPos ) { - HB_TRACE(HB_TR_DEBUG, ("hb_codeblockGetRef(%p, %ld)", pCBlock, iItemPos)); + HB_TRACE(HB_TR_DEBUG, ("hb_codeblockGetRef(%p, %d)", pCBlock, iItemPos)); return pCBlock->pLocals - iItemPos; } diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index 865bc51dd7..32e1b89517 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -5557,11 +5557,13 @@ static void hb_vmPushVParams( void ) { HB_STACK_TLS_PRELOAD int iPCount, iFirst, i = 0; + PHB_ITEM pBase; HB_TRACE(HB_TR_DEBUG, ("hb_vmPushVParams()")); - iFirst = hb_stackBaseItem()->item.asSymbol.paramdeclcnt; - iPCount = hb_pcount(); + pBase = hb_stackBaseItem(); + iFirst = pBase->item.asSymbol.paramdeclcnt; + iPCount = pBase->item.asSymbol.paramcnt; while( ++iFirst <= iPCount ) { hb_vmPush( hb_stackItemFromBase( iFirst ) ); @@ -5953,35 +5955,71 @@ static void hb_vmPushObjectVarRef( void ) hb_stackPushReturn(); } +void hb_vmEval( HB_USHORT uiParams ) +{ + HB_STACK_TLS_PRELOAD + HB_STACK_STATE sStackState; +#ifndef HB_NO_PROFILER + HB_ULONG ulClock = 0; + HB_BOOL bProfiler = hb_bProfiler; /* because profiler state may change */ +#endif + + HB_TASK_SHEDULER + + HB_TRACE(HB_TR_DEBUG, ("hb_vmEval(%hu)", uiParams)); + +#ifndef HB_NO_PROFILER + if( bProfiler ) + ulClock = ( HB_ULONG ) clock(); +#endif + + hb_stackNewFrame( &sStackState, uiParams ); + + hb_vmDoBlock(); + +#ifndef HB_NO_PROFILER + if( bProfiler ) + hb_mthAddTime( clock() - ulClock ); +#endif + +#ifndef HB_NO_DEBUG + if( sStackState.fDebugging ) + hb_vmDebuggerEndProc(); +#endif + + hb_stackOldFrame( &sStackState ); +} + static HARBOUR hb_vmDoBlock( void ) { HB_STACK_TLS_PRELOAD - PHB_ITEM pBlock; + PHB_ITEM pBlock, pBase; int iParam; HB_TRACE(HB_TR_DEBUG, ("hb_vmDoBlock()")); pBlock = hb_stackSelfItem(); - if( ! HB_IS_BLOCK( pBlock ) ) hb_errInternal( HB_EI_VMNOTCBLOCK, NULL, "hb_vmDoBlock()", NULL ); - /* Check for valid count of parameters */ - iParam = pBlock->item.asBlock.paramcnt - hb_pcount(); - hb_stackBaseItem()->item.asSymbol.paramdeclcnt = - pBlock->item.asBlock.paramcnt; + pBase = hb_stackBaseItem(); + /* set number of declared parameters */ + pBase->item.asSymbol.paramdeclcnt = pBlock->item.asBlock.paramcnt; + /* set the current line number to a line where the codeblock was defined */ + pBase->item.asSymbol.stackstate->uiLineNo = pBlock->item.asBlock.lineno; + /* set execution context for OOP scope */ + pBase->item.asSymbol.stackstate->uiClass = pBlock->item.asBlock.hclass; + pBase->item.asSymbol.stackstate->uiMethod = pBlock->item.asBlock.method; /* add missing parameters */ + iParam = pBlock->item.asBlock.paramcnt - pBase->item.asSymbol.paramcnt; while( --iParam >= 0 ) - hb_vmPushNil(); + hb_stackAllocItem()->type = HB_IT_NIL; + /* set static base offset */ + hb_stackSetStaticsBase( pBlock->item.asBlock.value->pStatics ); - /* set the current line number to a line where the codeblock was defined - */ - hb_stackBaseItem()->item.asSymbol.stackstate->uiLineNo = pBlock->item.asBlock.lineno; - hb_stackBaseItem()->item.asSymbol.stackstate->uiClass = pBlock->item.asBlock.hclass; - hb_stackBaseItem()->item.asSymbol.stackstate->uiMethod = pBlock->item.asBlock.method; - - hb_codeblockEvaluate( pBlock ); + hb_vmExecute( pBlock->item.asBlock.value->pCode, + pBlock->item.asBlock.value->pSymbols ); } /* Evaluates a passed codeblock item with no arguments passed to a codeblock @@ -6953,7 +6991,7 @@ static void hb_vmPushLocal( int iLocal ) /* local variable referenced in a codeblock * hb_stackSelfItem() points to a codeblock that is currently evaluated */ - pLocal = hb_codeblockGetRef( hb_stackSelfItem()->item.asBlock.value, ( HB_LONG ) iLocal ); + pLocal = hb_codeblockGetRef( hb_stackSelfItem()->item.asBlock.value, iLocal ); } hb_itemCopy( hb_stackAllocItem(), @@ -9093,7 +9131,7 @@ static PHB_ITEM hb_xvmLocalPtr( int iLocal ) /* local variable referenced in a codeblock * hb_stackSelfItem() points to a codeblock that is currently evaluated */ - return hb_codeblockGetRef( hb_stackSelfItem()->item.asBlock.value, ( HB_LONG ) iLocal ); + return hb_codeblockGetRef( hb_stackSelfItem()->item.asBlock.value, iLocal ); } } diff --git a/harbour/src/vm/itemapi.c b/harbour/src/vm/itemapi.c index 13fa43b4bc..f485569a00 100644 --- a/harbour/src/vm/itemapi.c +++ b/harbour/src/vm/itemapi.c @@ -1845,7 +1845,7 @@ PHB_ITEM hb_itemUnRefOnce( PHB_ITEM pItem ) { /* local variable referenced in a codeblock */ pItem = hb_codeblockGetRef( pItem->item.asRefer.BasePtr.block, - pItem->item.asRefer.value ); + ( int ) pItem->item.asRefer.value ); } } } diff --git a/harbour/src/vm/macro.c b/harbour/src/vm/macro.c index 76b8edaa2e..b5a7dfabaf 100644 --- a/harbour/src/vm/macro.c +++ b/harbour/src/vm/macro.c @@ -112,7 +112,7 @@ static int hb_macroParse( HB_MACRO_PTR pMacro ) HB_TRACE(HB_TR_DEBUG, ("hb_macroParse(%p)", pMacro)); /* initialize the output (pcode) buffer - it will be filled by yacc */ - pMacro->pCodeInfo = (HB_PCODE_INFO_PTR ) hb_xgrab( sizeof( HB_PCODE_INFO ) ); + pMacro->pCodeInfo = &pMacro->pCodeInfoBuffer; pMacro->pCodeInfo->lPCodeSize = HB_PCODE_SIZE; pMacro->pCodeInfo->lPCodePos = 0; pMacro->pCodeInfo->fVParams = HB_FALSE; @@ -140,8 +140,7 @@ void hb_macroDelete( HB_MACRO_PTR pMacro ) { HB_TRACE(HB_TR_DEBUG, ("hb_macroDelete(%p)", pMacro)); - hb_xfree( (void *) pMacro->pCodeInfo->pCode ); - hb_xfree( (void *) pMacro->pCodeInfo ); + hb_xfree( ( void * ) pMacro->pCodeInfo->pCode ); if( pMacro->pError ) hb_errRelease( pMacro->pError ); if( pMacro->Flags & HB_MACRO_DEALLOCATE ) @@ -1639,17 +1638,16 @@ void hb_macroCodeBlockStart( HB_COMP_DECL ) pCB = ( HB_PCODE_INFO_PTR ) hb_xgrab( sizeof( HB_PCODE_INFO ) ); - /* replace current pcode buffer with the new one - */ - pCB->pPrev = HB_PCODE_DATA; - HB_PCODE_DATA = pCB; - - HB_TRACE(HB_TR_DEBUG, ("hb_macroCodeBlockStart.(%p)", HB_COMP_PARAM)); pCB->pCode = ( HB_BYTE * ) hb_xgrab( HB_PCODE_SIZE ); pCB->lPCodeSize = HB_PCODE_SIZE; pCB->lPCodePos = 0; pCB->fVParams = HB_FALSE; pCB->pLocals = NULL; + + /* replace current pcode buffer with the new one + */ + pCB->pPrev = HB_PCODE_DATA; + HB_PCODE_DATA = pCB; } void hb_macroCodeBlockEnd( HB_COMP_DECL ) diff --git a/harbour/tests/speedtst.prg b/harbour/tests/speedtst.prg index c901628a10..99ed7ef5fd 100644 --- a/harbour/tests/speedtst.prg +++ b/harbour/tests/speedtst.prg @@ -43,7 +43,7 @@ #define __ST__ #endif /* Clipper does not have function to extract process time */ - #xtranslate hb_secondsCPU() => seconds() + #xtranslate hb_secondsCPU([]) => seconds() #endif #ifdef FlagShip @@ -52,7 +52,7 @@ #ifndef __ST__ #define __ST__ #endif - #xtranslate hb_secondsCPU([]) => secondsCPU([]) + #xtranslate hb_secondsCPU([]) => secondsCPU() /* the FlagShip version of seconds() returns integer values */ #xtranslate seconds() => fs_seconds() #endif @@ -60,7 +60,7 @@ #ifdef __XPP__ #define __NO_OBJ_ARRAY__ /* Has xBase++ function to extract process time? */ - #xtranslate hb_secondsCPU() => seconds() + #xtranslate hb_secondsCPU([]) => seconds() #endif #ifdef __CLIP__ @@ -69,6 +69,7 @@ #ifndef __ST__ #define __ST__ #endif + #xtranslate hb_secondsCPU([]) => secondsCPU() #endif #ifdef __XHARBOUR__ @@ -85,6 +86,7 @@ #endif #endif #endif + #xtranslate hb_secondsCPU([]) => secondsCPU() #endif /* by default create MT version */ @@ -107,32 +109,32 @@ #endif #endif -#xcommand TEST ; - [ WITH ] ; - [ STATIC ] ; - [ FIELD ] ; - [ MEMVAR ] ; - [ PRIVATE ]; - [ PUBLIC ] ; - [ INIT ] ; - [ EXIT ] ; - [ INFO ] ; - CODE [ ] => ; - func ; ; - local time, i:=nil, x:=nil ; ; - [ local ; ] ; - [ static ; ] ; - [ field ; ] ; - [ memvar ; ] ; - [ private ; ] ; - [ public ; ] ; - [ ; ] ; - time := hb_secondsCPU() ; ; - for i:=1 to N_LOOPS ; ; - [ ( ) ; ] ; - next ; ; - time := hb_secondsCPU() - time ; ; - [ ; ] ; +#xcommand TEST ; + [ WITH ] ; + [ STATIC ] ; + [ FIELD ] ; + [ MEMVAR ] ; + [ PRIVATE ] ; + [ PUBLIC ] ; + [ INIT ] ; + [ EXIT ] ; + [ INFO ] ; + CODE [ ] => ; + func ; ; + local time, i:=nil, x:=nil ; ; + [ local ; ] ; + [ static ; ] ; + [ field ; ] ; + [ memvar ; ] ; + [ private ; ] ; + [ public ; ] ; + [ ; ] ; + time := hb_secondsCPU() ; ; + for i:=1 to N_LOOPS ; ; + [ ( ) ; ] ; + next ; ; + time := hb_secondsCPU() - time ; ; + [ ; ] ; return { procname() + ": " + iif( <.info.>, <(info)>, # ), time } STATIC s_lStdOut := .F.