diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 555755a78b..62e90bc54f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,19 @@ 2002-12-01 23:12 UTC+0100 Foo Bar */ +2003-11-10 12:25 UTC+0100 Ryszard Glab + * include/hbcomp.h + * source/compiler/cmdcheck.c + * source/compiler/genc.c + * source/compiler/harbour.c + * source/compiler/hbusage.c + * source/vm/hvm.c + * doc/en/compiler.txt + * fixed to correctly generate an address for far jumps + * fixed optimalization of far jumps + + added a new switch -kJ to disable jump optimalization and + NOOP pcode removal (optimalization is enabled by default) + 2003-11-09 00:50 UTC+0300 Alexander Kresin * source/pp/pptable.c + SET MBLOCKSIZE TO diff --git a/harbour/doc/en/compiler.txt b/harbour/doc/en/compiler.txt index 96a0527795..a59b189469 100644 --- a/harbour/doc/en/compiler.txt +++ b/harbour/doc/en/compiler.txt @@ -84,6 +84,8 @@ * * /kx other xbase dialects extensions (default) * + * /kJ disable optimalization of jump and noop pcodes + * * /k? invoke help information * * /l suppress line number information diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index 27942911c8..44b65e8d72 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -537,6 +537,7 @@ extern ULONG hb_comp_Supported; #define HB_COMPFLAG_XBASE 2 /* -kx */ #define HB_COMPFLAG_HB_INLINE 4 /* -ki */ #define HB_COMPFLAG_ARRSTR 8 /* -ks strings as array of bytes */ +#define HB_COMPFLAG_OPTJUMP 16 /* -kj turn off jump optimalization */ #define HB_COMPFLAG_RT_MACRO 64 /* -kr */ #ifdef HB_MACRO_SUPPORT diff --git a/harbour/source/compiler/cmdcheck.c b/harbour/source/compiler/cmdcheck.c index 94860dc00a..c6a2bd9837 100644 --- a/harbour/source/compiler/cmdcheck.c +++ b/harbour/source/compiler/cmdcheck.c @@ -639,7 +639,7 @@ void hb_compChkEnvironVar( char * szSwitch ) case 'c': /* clear all flags - minimal set of features */ - hb_comp_Supported = 0; + hb_comp_Supported = HB_COMPFLAG_OPTJUMP; break; case 'x': @@ -650,6 +650,10 @@ void hb_compChkEnvironVar( char * szSwitch ) hb_comp_Supported |= HB_COMPFLAG_HB_INLINE; break; + case 'J': + hb_comp_Supported &= ~HB_COMPFLAG_OPTJUMP; + break; + case 'r': hb_comp_Supported |= HB_COMPFLAG_RT_MACRO; break; diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 0a91b8b054..c6a0de71ae 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -626,7 +626,7 @@ static HB_GENC_FUNC( hb_p_jumpfar ) if( lOffset > 8388607L ) lOffset -= 16777216; - fprintf( cargo->yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); + fprintf( cargo->yyc, "\t/* %li (abs: %08li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) ); } fprintf( cargo->yyc, "\n" ); return 4; diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index 599ae23e37..9d1a9fca48 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -188,9 +188,10 @@ int main( int argc, char * argv[] ) hb_comp_pOutPath = NULL; /* Activate Harbour extensions by default. */ - hb_comp_Supported = HB_COMPFLAG_HARBOUR; - hb_comp_Supported |= HB_COMPFLAG_XBASE; - hb_comp_Supported |= HB_COMPFLAG_HB_INLINE; + hb_comp_Supported = HB_COMPFLAG_HARBOUR | + HB_COMPFLAG_XBASE | + HB_COMPFLAG_HB_INLINE | + HB_COMPFLAG_OPTJUMP; /* First check the environment variables */ hb_compChkCompilerSwitch( 0, NULL ); @@ -2178,35 +2179,43 @@ void hb_compNOOPadd( PFUNCTION pFunc, ULONG ulPos ) static void hb_compPrepareOptimize() { - hb_comp_functions.pLast->iJumps++; - - if( hb_comp_functions.pLast->pJumps ) + if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_OPTJUMP) ) { - hb_comp_functions.pLast->pJumps = ( ULONG * ) hb_xrealloc( hb_comp_functions.pLast->pJumps, sizeof( ULONG ) * hb_comp_functions.pLast->iJumps ); - hb_comp_functions.pLast->pJumps[ hb_comp_functions.pLast->iJumps - 1 ] = ( ULONG ) ( hb_comp_functions.pLast->lPCodePos - 4 ); - } - else - { - hb_comp_functions.pLast->pJumps = ( ULONG * ) hb_xgrab( sizeof( ULONG ) ); - hb_comp_functions.pLast->pJumps[ hb_comp_functions.pLast->iJumps - 1 ] = ( LONG ) ( hb_comp_functions.pLast->lPCodePos - 4 ); - } + hb_comp_functions.pLast->iJumps++; - /* Only Reserve Request - Don't know if NOOPs will remain yet. */ - if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 3 ] == 0 && - hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 2 ] == 0 && - hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 1 ] == 0 ) - return; - - /* 3rd. Byte might be not used */ - if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 1 ] == HB_P_NOOP ) - { - hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); - - /* 2nd. Byte might be not used */ - if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 2 ] == HB_P_NOOP ) + if( hb_comp_functions.pLast->pJumps ) { - hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 2 ); + hb_comp_functions.pLast->pJumps = ( ULONG * ) hb_xrealloc( hb_comp_functions.pLast->pJumps, sizeof( ULONG ) * hb_comp_functions.pLast->iJumps ); + hb_comp_functions.pLast->pJumps[ hb_comp_functions.pLast->iJumps - 1 ] = ( ULONG ) ( hb_comp_functions.pLast->lPCodePos - 4 ); } + else + { + hb_comp_functions.pLast->pJumps = ( ULONG * ) hb_xgrab( sizeof( ULONG ) ); + hb_comp_functions.pLast->pJumps[ hb_comp_functions.pLast->iJumps - 1 ] = ( ULONG ) ( hb_comp_functions.pLast->lPCodePos - 4 ); + } +#if 0 + /* rglab: Sun Nov 9 10:46:56 2003 + * Checking for HB_P_NOOP is not safe here - the value + * of HB_P_NOOP can be a part of valid offset + */ + /* Only Reserve Request - Don't know if NOOPs will remain yet. */ + if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 3 ] == 0 && + hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 2 ] == 0 && + hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 1 ] == 0 ) + return; + + /* 3rd. Byte might be not used */ + if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 1 ] == HB_P_NOOP ) + { + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); + + /* 2nd. Byte might be not used */ + if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 2 ] == HB_P_NOOP ) + { + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 2 ); + } + } +#endif } } @@ -2220,14 +2229,17 @@ ULONG hb_compGenJump( LONG lOffset ) else if( lOffset >= -128 && lOffset <= 127 ) { hb_compGenPCode4( HB_P_JUMPNEAR, HB_LOBYTE( lOffset ), HB_P_NOOP, HB_P_NOOP, ( BOOL ) 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 2 ); } else if( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX ) { hb_compGenPCode4( HB_P_JUMP, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_P_NOOP, ( BOOL ) 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); } else if( lOffset >= (-8388608L) && lOffset <= 8388607L ) { - hb_compGenPCode4( HB_P_JUMPFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( ( ( USHORT ) ( lOffset ) >> 16 ) & 0xFF ), ( BOOL ) 1 ); + hb_compGenPCode4( HB_P_JUMPFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( (USHORT)( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); } else { @@ -2249,14 +2261,17 @@ ULONG hb_compGenJumpFalse( LONG lOffset ) else if( lOffset >= -128 && lOffset <= 127 ) { hb_compGenPCode4( HB_P_JUMPFALSENEAR, HB_LOBYTE( lOffset ), HB_P_NOOP, HB_P_NOOP, ( BOOL ) 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 2 ); } else if( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX ) { hb_compGenPCode4( HB_P_JUMPFALSE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_P_NOOP, ( BOOL ) 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); } else if( lOffset >= (-8388608L) && lOffset <= 8388607L ) { - hb_compGenPCode4( HB_P_JUMPFALSEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( ( ( USHORT ) ( lOffset ) >> 16 ) & 0xFF ), ( BOOL ) 1 ); + hb_compGenPCode4( HB_P_JUMPFALSEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( (USHORT)( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); } else { @@ -2278,14 +2293,17 @@ ULONG hb_compGenJumpTrue( LONG lOffset ) else if( lOffset >= -128 && lOffset <= 127 ) { hb_compGenPCode4( HB_P_JUMPTRUENEAR, HB_LOBYTE( lOffset ), HB_P_NOOP, HB_P_NOOP, ( BOOL ) 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 2 ); } else if( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX ) { hb_compGenPCode4( HB_P_JUMPTRUE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_P_NOOP, ( BOOL ) 1 ); + hb_compNOOPadd( hb_comp_functions.pLast, hb_comp_functions.pLast->lPCodePos - 1 ); } else if( lOffset >= (-8388608L) && lOffset <= 8388607L ) { - hb_compGenPCode4( HB_P_JUMPTRUEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( ( ( USHORT ) ( lOffset ) >> 16 ) & 0xFF ), ( BOOL ) 1 ); + hb_compGenPCode4( HB_P_JUMPTRUEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), ( BYTE ) ( (USHORT)( lOffset >> 16 ) & 0xFF ), ( BOOL ) 1 ); } else { @@ -2456,7 +2474,7 @@ void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo ) { pCode[ ulFrom ] = HB_LOBYTE( lOffset ); pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_HIBYTE( lOffset ); - pCode[ ( ULONG ) ( ulFrom + 2 ) ] = ( BYTE ) ( ( ( USHORT ) ( lOffset ) >> 16 ) & 0xFF ); + pCode[ ( ULONG ) ( ulFrom + 2 ) ] = ( BYTE ) ( (USHORT)( lOffset >> 16 ) & 0xFF ); } else hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_TOO_LONG, NULL, NULL ); @@ -3429,18 +3447,22 @@ static void hb_compOptimizeJumps( void ) ULONG * pJumps = hb_comp_functions.pLast->pJumps; ULONG ulOptimized = 0; ULONG ulNextByte = 0; - int * piShifts = NULL; + LONG * piShifts = NULL; ULONG iNOOP; - ULONG ulOffset; + LONG ulOffset; ULONG ulBytes2Copy; ULONG iJump; BOOL bForward = FALSE; + BOOL bSet; + if( ! HB_COMP_ISSUPPORTED(HB_COMPFLAG_OPTJUMP) ) + return; + /* Needed so the pasting of PCODE pieces below will work correctly */ qsort( ( void * ) pNOOPs, hb_comp_functions.pLast->iNOOPs, sizeof( ULONG ), hb_compSort_ULONG ); if ( hb_comp_functions.pLast->iJumps ) - piShifts = ( int * ) hb_xgrab( sizeof( int ) * hb_comp_functions.pLast->iJumps ); + piShifts = ( LONG * ) hb_xgrab( sizeof( LONG ) * hb_comp_functions.pLast->iJumps ); for( iJump = 0; iJump < hb_comp_functions.pLast->iJumps; iJump++ ) piShifts[ iJump ] = 0; @@ -3448,7 +3470,8 @@ static void hb_compOptimizeJumps( void ) /* First Scan NOOPS - Adjust Jump addresses. */ for( iNOOP = 0; iNOOP < hb_comp_functions.pLast->iNOOPs; iNOOP++ ) { - /* Adjusting preceding jumps that pooint to code beyond the current NOOP or trailing backward jumps pointing to lower address. */ + /* Adjusting preceding jumps that pooint to code beyond the current NOOP + or trailing backward jumps pointing to lower address. */ for( iJump = 0; iJump < hb_comp_functions.pLast->iJumps ; iJump++ ) { switch( pCode[ pJumps[ iJump ] ] ) @@ -3486,7 +3509,7 @@ static void hb_compOptimizeJumps( void ) default: { - ulOffset = ( ULONG )( pCode[ pJumps[ iJump ] + 1 ] + ( pCode[ pJumps[ iJump ] + 2 ] * 256 ) + ( pCode[ pJumps[ iJump ] + 3 ] * 65536 ) ); + ulOffset = ( LONG )( pCode[ pJumps[ iJump ] + 1 ] + ( pCode[ pJumps[ iJump ] + 2 ] * 256L ) + ( pCode[ pJumps[ iJump ] + 3 ] * 65536L ) ); if( ulOffset > 8388607L ) { ulOffset -= 16777216L; @@ -3498,46 +3521,72 @@ static void hb_compOptimizeJumps( void ) break; } + bSet = FALSE; /* Only interested in forward (positive) jumps. */ +/*printf("\nF=%i,pJump=%li,off=%li,pNew=%li,pNoop=%li",bForward,pJumps[ iJump ],ulOffset,(pJumps[ iJump ] + piShifts[ iJump ] + ulOffset), pNOOPs[ iNOOP ]);*/ if( bForward ) { /* Only if points to code beyond the current fix. */ - if( pJumps[ iJump ] < pNOOPs[ iNOOP ] && pJumps[ iJump ] + piShifts[ iJump ] + ulOffset > pNOOPs[ iNOOP ] ) + if( pJumps[ iJump ] < pNOOPs[ iNOOP ] && + (ULONG)(pJumps[ iJump ] + piShifts[ iJump ] + ulOffset) > pNOOPs[ iNOOP ] ) { /* Increasing Shift Counter for this Jump. */ piShifts[ iJump ]++; - if( pCode[ pJumps[ iJump ] + 1 ] ) - pCode[ pJumps[ iJump ] + 1 ]--; - else - { - pCode[ pJumps[ iJump ] + 1 ] = 255; - pCode[ pJumps[ iJump ] + 2 ]--; - } + ulOffset--; + bSet = TRUE; } } else { - /* Adjusting all later jumps (if negative) and target prior the current NOOP. */ + /* Adjusting all later jumps (if negative) and target prior + the current NOOP. */ /* Only if points to code beyond the current fix. */ - if( pJumps[ iJump ] > pNOOPs[ iNOOP ] && pJumps[ iJump ] + piShifts[ iJump ] + ulOffset < pNOOPs[ iNOOP ] ) + if( pJumps[ iJump ] > pNOOPs[ iNOOP ] && + (ULONG)(pJumps[ iJump ] + piShifts[ iJump ] + ulOffset) < pNOOPs[ iNOOP ] ) { /* Decreasing Shift Counter for this Jump. */ piShifts[ iJump ]--; - if( pCode[ pJumps[ iJump ] + 1 ] < 255 ) - pCode[ pJumps[ iJump ] + 1 ]++; - else + ulOffset++; + bSet = TRUE; + } + } +/*printf("\tbSet=%i",bSet);*/ + if( bSet ) + { + switch( pCode[ pJumps[ iJump ] ] ) + { + case HB_P_JUMPNEAR : + case HB_P_JUMPFALSENEAR : + case HB_P_JUMPTRUENEAR : { - pCode[ pJumps[ iJump ] + 1 ] = 0; - pCode[ pJumps[ iJump ] + 2 ]++; + pCode[ pJumps[ iJump ] + 1 ] = HB_LOBYTE( ulOffset ); + } + break; + + case HB_P_JUMP : + case HB_P_JUMPFALSE : + case HB_P_JUMPTRUE : + { + pCode[ pJumps[ iJump ] + 1 ] = HB_LOBYTE( ulOffset ); + pCode[ pJumps[ iJump ] + 2 ] = HB_HIBYTE( ulOffset ); + } + break; + + default: + { + pCode[ pJumps[ iJump ] + 1 ] = HB_LOBYTE( ulOffset ); + pCode[ pJumps[ iJump ] + 2 ] = HB_HIBYTE( ulOffset ); + pCode[ pJumps[ iJump ] + 3 ] = ( BYTE ) ( (USHORT)( ulOffset >> 16 ) & 0xFF ); } } } } } + /* Second Scan, after all adjustements been made, we can copy the optimized code. */ for( iNOOP = 0; iNOOP < hb_comp_functions.pLast->iNOOPs; iNOOP++ ) { diff --git a/harbour/source/compiler/hbusage.c b/harbour/source/compiler/hbusage.c index d5f2c2e69b..8545b93586 100644 --- a/harbour/source/compiler/hbusage.c +++ b/harbour/source/compiler/hbusage.c @@ -121,6 +121,7 @@ void hb_compPrintModes( void ) "\n r runtime settings enabled", "\n c string as bytes array enabled", "\n x extended xbase mode", + "\n J turn off jump optimization in pcode", "\n ? this info", "\n" }; diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 7b0b9c3a7e..8ce5d18c44 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -951,7 +951,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_JUMPFAR: - lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 ); + lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536L ); if( lOffset > 8388607L ) lOffset -= 16777216L; w += lOffset;