diff -r 029aabc7f3c2 -r 79a08dfa50c9 Array.st --- a/Array.st Mon May 25 16:10:36 1998 +0200 +++ b/Array.st Mon May 25 16:11:14 1998 +0200 @@ -571,8 +571,6 @@ #endif { -#define UNROLL_LOOPS2 - /* * boy; what an ugly looking piece of code ... * however, this software pipelined thing has no taken conditional @@ -581,8 +579,8 @@ * notice, that those gotos expand to forward branches (which are predicted * as NOT taken by most machines ... which is exactly what we want) */ -#if defined(UNROLL_LOOPS2) REGISTER OBJ el; +#if defined(UNROLL_LOOPS) { int i8; @@ -623,7 +621,7 @@ index = i8; } } -#endif /* UNROLL_LOOPS2 */ +#endif /* UNROLL_LOOPS */ for (; index < nIndex; index++) { el = __InstPtr(self)->i_instvars[index]; @@ -633,7 +631,7 @@ } RETURN (self); -#if defined(UNROLL_LOOPS2) +#if defined(UNROLL_LOOPS) interrupt0: __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; @@ -671,7 +669,7 @@ el = __InstPtr(self)->i_instvars[index]; goto continueX; -#endif /* UNROLL_LOOPS2 */ +#endif /* UNROLL_LOOPS */ } } } @@ -754,34 +752,42 @@ OBJ slf; int nIndex, nInsts; static struct inlineCache val = _ILC1; - int indexLow, indexHigh; + int indexHigh; OBJ myClass; + OBJ __start, __stop; slf = self; myClass = __qClass(slf); - if ( __bothSmallInteger(start, stop) && ((indexLow = __intVal(start)) > 0) ) { - indexHigh = __intVal(stop); + + __start = start; + __stop = stop; + if ( __bothSmallInteger(__start, __stop) + && ((index = __intVal(__start)) > 0) ) { + indexHigh = __intVal(__stop); nIndex = __BYTES2OBJS__(__qSize(slf) - OHDR_SIZE); if (myClass != @global(Array)) { nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars); - indexLow += nInsts; + index += nInsts; indexHigh += nInsts; } if (indexHigh <= nIndex) { - indexLow--; - indexHigh--; + OBJ __aBlock = aBlock; + int n; - if (__isBlockLike(aBlock) - && (__BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) { + index--; /* 0-based */ + n = indexHigh - index; + + if (__isBlockLike(__aBlock) + && (__BlockInstPtr(__aBlock)->b_nargs == __MKSMALLINT(1))) { { /* * the most common case: a static compiled block, with home on the stack ... */ REGISTER OBJFUNC codeVal; - if (((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) + if (((codeVal = __BlockInstPtr(__aBlock)->b_code) != (OBJFUNC)nil) #ifdef PARANOIA - && (! ((INT)(__BlockInstPtr(aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC))) + && (! ((INT)(__BlockInstPtr(__aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC))) #endif ) { #ifdef NEW_BLOCK_CALL @@ -790,15 +796,13 @@ # define BLOCK_ARG rHome REGISTER OBJ rHome; - rHome = __BlockInstPtr(aBlock)->b_home; + rHome = __BlockInstPtr(__aBlock)->b_home; if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) #endif { REGISTER OBJ el; - index = indexLow; - -#if defined(UNROLL_LOOPS2) +#if defined(UNROLL_LOOPS) /* * boy; what an ugly looking piece of code ... * however, this software pipelined thing has no taken conditional @@ -808,9 +812,7 @@ * as NOT taken by most machines ... which is exactly what we want) */ { - int i8; - - while ((i8 = index+8) <= indexHigh) { + while ( n >= 8) { el = __InstPtr(self)->i_instvars[index]; if (InterruptPending != nil) goto interrupt0; continue0: @@ -843,19 +845,62 @@ if (InterruptPending != nil) goto interrupt7; continue7: (*codeVal)(BLOCK_ARG, el); - index = i8; + n -= 8; + index += 8; } + if (n >= 4) { + el = __InstPtr(self)->i_instvars[index]; + if (InterruptPending != nil) goto interrupt0b; + continue0b: + (*codeVal)(BLOCK_ARG, el); + el = __InstPtr(self)->i_instvars[index+1]; + if (InterruptPending != nil) goto interrupt1b; + continue1b: + (*codeVal)(BLOCK_ARG, el); + el = __InstPtr(self)->i_instvars[index+2]; + if (InterruptPending != nil) goto interrupt2b; + continue2b: + (*codeVal)(BLOCK_ARG, el); + el = __InstPtr(self)->i_instvars[index+3]; + if (InterruptPending != nil) goto interrupt3b; + continue3b: + (*codeVal)(BLOCK_ARG, el); + n -= 4; + index += 4; + } + if (n >= 2) { + el = __InstPtr(self)->i_instvars[index]; + if (InterruptPending != nil) goto interrupt0c; + continue0c: + (*codeVal)(BLOCK_ARG, el); + el = __InstPtr(self)->i_instvars[index+1]; + if (InterruptPending != nil) goto interrupt1c; + continue1c: + (*codeVal)(BLOCK_ARG, el); + n -= 2; + index += 2; + } + if (n) { + el = __InstPtr(self)->i_instvars[index]; + if (InterruptPending != nil) goto interrupt0d; + continue0d: + (*codeVal)(BLOCK_ARG, el); + } + RETURN (self); } -#endif /* UNROLL_LOOPS2 */ - for (; index <= indexHigh; index++) { +#else /* not UNROLL_LOOPS */ + while (n > 0) { el = __InstPtr(self)->i_instvars[index]; if (InterruptPending != nil) goto interruptX; continueX: (*codeVal)(BLOCK_ARG, el); + n--; + index++; } RETURN (self); +#endif /* UNROLL_LOOPS */ -#if defined(UNROLL_LOOPS2) +#if defined(UNROLL_LOOPS) interrupt0: __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; goto continue0; @@ -880,10 +925,35 @@ interrupt7: __interruptL(@line); el = __InstPtr(self)->i_instvars[index+7]; goto continue7; -#endif /* UNROLL_LOOPS2 */ + + interrupt0b: + __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; + goto continue0b; + interrupt1b: + __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; + goto continue1b; + interrupt2b: + __interruptL(@line); el = __InstPtr(self)->i_instvars[index+2]; + goto continue2b; + interrupt3b: + __interruptL(@line); el = __InstPtr(self)->i_instvars[index+3]; + goto continue3b; + + interrupt0c: + __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; + goto continue0c; + interrupt1c: + __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1]; + goto continue1c; + + interrupt0d: + __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; + goto continue0d; +#else /* not UNROLL_LOOPS */ interruptX: __interruptL(@line); el = __InstPtr(self)->i_instvars[index]; goto continueX; +#endif /* UNROLL_LOOPS */ } } } @@ -901,13 +971,18 @@ # define IBLOCK_ARG (__BlockInstPtr(aBlock)->b_home) #endif - for (index=indexLow; index <= indexHigh; index++) { + while (n) { REGISTER OBJFUNC codeVal; + OBJ el; - if (InterruptPending != nil) __interruptL(@line); + el = __InstPtr(self)->i_instvars[index]; + if (InterruptPending != nil) { + __interruptL(@line); + el = __InstPtr(self)->i_instvars[index]; + } if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) { - (*codeVal)(BLOCK_ARG, __InstPtr(self)->i_instvars[index]); + (*codeVal)(BLOCK_ARG, el); } else { if (__BlockInstPtr(aBlock)->b_bytecodes != nil) { /* @@ -915,17 +990,19 @@ * directly call interpreter without going through Block>>value */ #ifdef PASS_ARG_POINTER - __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &(__InstPtr(self)->i_instvars[index])); + __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &el); #else - __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __InstPtr(self)->i_instvars[index]); + __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, el); #endif } else { (*val.ilc_func)(aBlock, @symbol(value:), nil, &val, - __InstPtr(self)->i_instvars[index]); + el); } } + n--; + index++; } # undef BLOCK_ARG @@ -937,13 +1014,15 @@ /* * not a block - send it #value: */ - for (index=indexLow; index <= indexHigh; index++) { + while (n > 0) { if (InterruptPending != nil) __interruptL(@line); (*val.ilc_func)(aBlock, @symbol(value:), nil, &val, __InstPtr(self)->i_instvars[index]); + n--; + index++; } RETURN ( self ); } @@ -2241,5 +2320,5 @@ !Array class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.106 1998-01-28 15:51:49 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.107 1998-05-25 14:11:14 cg Exp $' ! !