Array.st
changeset 8919 707a9ff7f9b2
parent 8913 b9498d27a554
child 9359 6f93b3cfc7d4
equal deleted inserted replaced
8918:600691115e79 8919:707a9ff7f9b2
   467              */
   467              */
   468             spc = __qSpace(nObj);
   468             spc = __qSpace(nObj);
   469             srcP = __arrayVal(self);
   469             srcP = __arrayVal(self);
   470             dstP = __arrayVal(nObj);
   470             dstP = __arrayVal(nObj);
   471 
   471 
   472 #ifdef UNROLL_LOOPS
   472 #ifdef __UNROLL_LOOPS__
   473             while (nIndex >= 4) {
   473             while (nIndex >= 4) {
   474                 OBJ element;
   474                 OBJ element;
   475 
   475 
   476                 element = srcP[0];
   476                 element = srcP[0];
   477                 dstP[0] = element;
   477                 dstP[0] = element;
   580 			     * what an unrolling optimizing compiler produces from the loop below ...
   580 			     * what an unrolling optimizing compiler produces from the loop below ...
   581 			     * notice, that those gotos expand to forward branches (which are predicted
   581 			     * notice, that those gotos expand to forward branches (which are predicted
   582 			     * as NOT taken by most machines ... which is exactly what we want)
   582 			     * as NOT taken by most machines ... which is exactly what we want)
   583 			     */
   583 			     */
   584 			    REGISTER OBJ el;
   584 			    REGISTER OBJ el;
   585 #if defined(UNROLL_LOOPS)
   585 #ifdef __UNROLL_LOOPS__
   586 
   586 
   587 			    {
   587 			    {
   588 				int i8;
   588 				int i8;
   589 
   589 
   590 				while ((i8 = index+8) < nIndex) {
   590 				while ((i8 = index+8) < nIndex) {
   621 		continue7:
   621 		continue7:
   622 				    (*codeVal)(BLOCK_ARG, el);
   622 				    (*codeVal)(BLOCK_ARG, el);
   623 				    index = i8;
   623 				    index = i8;
   624 				}
   624 				}
   625 			    }
   625 			    }
   626 #endif /* UNROLL_LOOPS */
   626 #endif /* __UNROLL_LOOPS__ */
   627 
   627 
   628 			    for (; index < nIndex; index++) {
   628 			    for (; index < nIndex; index++) {
   629 				el = __InstPtr(self)->i_instvars[index];
   629 				el = __InstPtr(self)->i_instvars[index];
   630 				if (InterruptPending != nil) goto interruptX;
   630 				if (InterruptPending != nil) goto interruptX;
   631 		continueX:
   631 		continueX:
   632 				(*codeVal)(BLOCK_ARG, el);
   632 				(*codeVal)(BLOCK_ARG, el);
   633 			    }
   633 			    }
   634 			    RETURN (self);
   634 			    RETURN (self);
   635 
   635 
   636 #if defined(UNROLL_LOOPS)
   636 #ifdef __UNROLL_LOOPS__
   637 		interrupt0:
   637 		interrupt0:
   638 			    __interruptL(@line);
   638 			    __interruptL(@line);
   639 			    el = __InstPtr(self)->i_instvars[index];
   639 			    el = __InstPtr(self)->i_instvars[index];
   640 			    goto continue0;
   640 			    goto continue0;
   641 		interrupt1:
   641 		interrupt1:
   664 			    goto continue6;
   664 			    goto continue6;
   665 		interrupt7:
   665 		interrupt7:
   666 			    __interruptL(@line);
   666 			    __interruptL(@line);
   667 			    el = __InstPtr(self)->i_instvars[index+7];
   667 			    el = __InstPtr(self)->i_instvars[index+7];
   668 			    goto continue7;
   668 			    goto continue7;
   669 #endif /* UNROLL_LOOPS */
   669 #endif /* __UNROLL_LOOPS__ */
   670 		interruptX:
   670 		interruptX:
   671 			    __interruptL(@line);
   671 			    __interruptL(@line);
   672 			    el = __InstPtr(self)->i_instvars[index];
   672 			    el = __InstPtr(self)->i_instvars[index];
   673 			    goto continueX;
   673 			    goto continueX;
   674 		    }
   674 		    }
   799 			if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
   799 			if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
   800 #endif
   800 #endif
   801 			{
   801 			{
   802 			    REGISTER OBJ el;
   802 			    REGISTER OBJ el;
   803 
   803 
   804 #if defined(UNROLL_LOOPS)
   804 #ifdef __UNROLL_LOOPS__
   805 			    /*
   805 			    /*
   806 			     * boy; what an ugly looking piece of code ...
   806 			     * boy; what an ugly looking piece of code ...
   807 			     * however, this software pipelined thing has no taken conditional
   807 			     * however, this software pipelined thing has no taken conditional
   808 			     * branches in the normal case and is almost twice as fast to even
   808 			     * branches in the normal case and is almost twice as fast to even
   809 			     * what an unrolling optimizing compiler produces from the loop below ...
   809 			     * what an unrolling optimizing compiler produces from the loop below ...
   845 		continue7:
   845 		continue7:
   846 				    (*codeVal)(BLOCK_ARG, el);
   846 				    (*codeVal)(BLOCK_ARG, el);
   847 				    n -= 8;
   847 				    n -= 8;
   848 				    index += 8;
   848 				    index += 8;
   849 				}
   849 				}
   850 # ifdef UNROLL_LOOPS2 /* this makes small loops slower */
   850 # ifdef __UNROLL_LOOPS2__ /* this makes small loops slower */
   851 				if (n >= 4) {
   851 				if (n >= 4) {
   852 				    el = __InstPtr(self)->i_instvars[index];
   852 				    el = __InstPtr(self)->i_instvars[index];
   853 				    if (InterruptPending != nil) goto interrupt0b;
   853 				    if (InterruptPending != nil) goto interrupt0b;
   854 		continue0b:
   854 		continue0b:
   855 				    (*codeVal)(BLOCK_ARG, el);
   855 				    (*codeVal)(BLOCK_ARG, el);
   878 		continue1c:
   878 		continue1c:
   879 				    (*codeVal)(BLOCK_ARG, el);
   879 				    (*codeVal)(BLOCK_ARG, el);
   880 				    n -= 2;
   880 				    n -= 2;
   881 				    index += 2;
   881 				    index += 2;
   882 				}
   882 				}
   883 # endif /* UNROLL_LOOPS2 */
   883 # endif /* __UNROLL_LOOPS2__ */
   884 			    }
   884 			    }
   885 #endif /* UNROLL_LOOPS */
   885 #endif /* __UNROLL_LOOPS__ */
   886 			    while (n > 0) {
   886 			    while (n > 0) {
   887 				el = __InstPtr(self)->i_instvars[index];
   887 				el = __InstPtr(self)->i_instvars[index];
   888 				if (InterruptPending != nil) goto interruptX;
   888 				if (InterruptPending != nil) goto interruptX;
   889 		continueX:
   889 		continueX:
   890 				(*codeVal)(BLOCK_ARG, el);
   890 				(*codeVal)(BLOCK_ARG, el);
   891 				n--;
   891 				n--;
   892 				index++;
   892 				index++;
   893 			    }
   893 			    }
   894 			    RETURN (self);
   894 			    RETURN (self);
   895 
   895 
   896 #if defined(UNROLL_LOOPS)
   896 #ifdef __UNROLL_LOOPS__
   897 		interrupt0:
   897 		interrupt0:
   898 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   898 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   899 			    goto continue0;
   899 			    goto continue0;
   900 		interrupt1:
   900 		interrupt1:
   901 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1];
   901 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1];
   917 			    goto continue6;
   917 			    goto continue6;
   918 		interrupt7:
   918 		interrupt7:
   919 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+7];
   919 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+7];
   920 			    goto continue7;
   920 			    goto continue7;
   921 
   921 
   922 # ifdef UNROLL_LOOPS2
   922 # ifdef __UNROLL_LOOPS2__
   923 		interrupt0b:
   923 		interrupt0b:
   924 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   924 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   925 			    goto continue0b;
   925 			    goto continue0b;
   926 		interrupt1b:
   926 		interrupt1b:
   927 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1];
   927 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1];
   937 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   937 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   938 			    goto continue0c;
   938 			    goto continue0c;
   939 		interrupt1c:
   939 		interrupt1c:
   940 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1];
   940 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index+1];
   941 			    goto continue1c;
   941 			    goto continue1c;
   942 # endif /* UNROLL_LOOPS2 */
   942 # endif /* __UNROLL_LOOPS2__ */
   943 #endif /* UNROLL_LOOPS */
   943 #endif /* __UNROLL_LOOPS__ */
   944 		interruptX:
   944 		interruptX:
   945 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   945 			    __interruptL(@line); el = __InstPtr(self)->i_instvars[index];
   946 			    goto continueX;
   946 			    goto continueX;
   947 			}
   947 			}
   948 		    }
   948 		    }
  1400 		if ((INT)anObject == 0) {
  1400 		if ((INT)anObject == 0) {
  1401 		    memset(dst, 0, __OBJS2BYTES__(endIndex-index+1));
  1401 		    memset(dst, 0, __OBJS2BYTES__(endIndex-index+1));
  1402 		} else 
  1402 		} else 
  1403 # endif
  1403 # endif
  1404 		{
  1404 		{
  1405 # if defined(UNROLL_LOOPS)
  1405 # ifdef __UNROLL_LOOPS__
  1406 		    {
  1406 		    {
  1407 			int i8;
  1407 			int i8;
  1408 
  1408 
  1409 			while ((i8 = index + 8) <= endIndex) {
  1409 			while ((i8 = index + 8) <= endIndex) {
  1410 			    dst[3] = dst[2] = dst[1] = dst[0] = anObject;
  1410 			    dst[3] = dst[2] = dst[1] = dst[0] = anObject;
  1481 			     */
  1481 			     */
  1482 			    if (src < dst) {
  1482 			    if (src < dst) {
  1483 				/* must do a reverse copy */
  1483 				/* must do a reverse copy */
  1484 				src += count;
  1484 				src += count;
  1485 				dst += count;
  1485 				dst += count;
  1486 #if defined(UNROLL_LOOPS)
  1486 #ifdef __UNROLL_LOOPS__
  1487 				while (count > 8) {
  1487 				while (count > 8) {
  1488 				    dst[-1] = src[-1];
  1488 				    dst[-1] = src[-1];
  1489 				    dst[-2] = src[-2];
  1489 				    dst[-2] = src[-2];
  1490 				    dst[-3] = src[-3];
  1490 				    dst[-3] = src[-3];
  1491 				    dst[-4] = src[-4];
  1491 				    dst[-4] = src[-4];
  1530 			    bcopy4(src, dst, count);
  1530 			    bcopy4(src, dst, count);
  1531 # else
  1531 # else
  1532 #  ifdef FAST_MEMCPY
  1532 #  ifdef FAST_MEMCPY
  1533 			    bcopy(src, dst, __OBJS2BYTES__(count));
  1533 			    bcopy(src, dst, __OBJS2BYTES__(count));
  1534 #  else
  1534 #  else
  1535 #   if defined(UNROLL_LOOPS)
  1535 #   ifdef __UNROLL_LOOPS__
  1536 			    while (count >= 8) {
  1536 			    while (count >= 8) {
  1537 				dst[0] = src[0];
  1537 				dst[0] = src[0];
  1538 				dst[1] = src[1];
  1538 				dst[1] = src[1];
  1539 				dst[2] = src[2];
  1539 				dst[2] = src[2];
  1540 				dst[3] = src[3];
  1540 				dst[3] = src[3];
  1554 #endif
  1554 #endif
  1555 			} else {
  1555 			} else {
  1556 			    REGISTER int spc;
  1556 			    REGISTER int spc;
  1557 
  1557 
  1558 			    spc = __qSpace(self);
  1558 			    spc = __qSpace(self);
  1559 #if defined(UNROLL_LOOPS)
  1559 #ifdef __UNROLL_LOOPS__
  1560 			    while (count >= 8) {
  1560 			    while (count >= 8) {
  1561 				t = src[0]; dst[0] = t; __STORE_SPC(self, t, spc);
  1561 				t = src[0]; dst[0] = t; __STORE_SPC(self, t, spc);
  1562 				t = src[1]; dst[1] = t; __STORE_SPC(self, t, spc);
  1562 				t = src[1]; dst[1] = t; __STORE_SPC(self, t, spc);
  1563 				t = src[2]; dst[2] = t; __STORE_SPC(self, t, spc);
  1563 				t = src[2]; dst[2] = t; __STORE_SPC(self, t, spc);
  1564 				t = src[3]; dst[3] = t; __STORE_SPC(self, t, spc);
  1564 				t = src[3]; dst[3] = t; __STORE_SPC(self, t, spc);
  1859 		    RETURN ( __mkSmallInteger(index) ); 
  1859 		    RETURN ( __mkSmallInteger(index) ); 
  1860 		}
  1860 		}
  1861 	    }
  1861 	    }
  1862 #else
  1862 #else
  1863 
  1863 
  1864 # if defined(UNROLL_LOOPS)
  1864 # ifdef __UNROLL_LOOPS__
  1865 	    {
  1865 	    {
  1866 		/*
  1866 		/*
  1867 		 * dont argue about those gotos below - they speed up that thing by 30%;
  1867 		 * dont argue about those gotos below - they speed up that thing by 30%;
  1868 		 * its better to exit the loops below with a goto,
  1868 		 * its better to exit the loops below with a goto,
  1869 		 * since the generated code will then be:
  1869 		 * since the generated code will then be:
  1913 			RETURN ( __mkSmallInteger(index + 7 - nInsts) );
  1913 			RETURN ( __mkSmallInteger(index + 7 - nInsts) );
  1914 		    found8:
  1914 		    found8:
  1915 			RETURN ( __mkSmallInteger(index + 8 - nInsts) );
  1915 			RETURN ( __mkSmallInteger(index + 8 - nInsts) );
  1916 		}
  1916 		}
  1917 	    }
  1917 	    }
  1918 # endif /* UNROLLED_LOOPS */
  1918 # endif /* __UNROLLED_LOOPS__ */
  1919 
  1919 
  1920 	    while (index++ < nIndex) {
  1920 	    while (index++ < nIndex) {
  1921 		if (*op++ == el) goto found0;
  1921 		if (*op++ == el) goto found0;
  1922 	    }
  1922 	    }
  1923 
  1923 
  1970 		    RETURN ( __mkSmallInteger(index) ); 
  1970 		    RETURN ( __mkSmallInteger(index) ); 
  1971 		}
  1971 		}
  1972 	    }
  1972 	    }
  1973 #else
  1973 #else
  1974 
  1974 
  1975 # if defined(UNROLL_LOOPS)
  1975 # ifdef __UNROLL_LOOPS__
  1976 	    {
  1976 	    {
  1977 		unsigned int i8;
  1977 		unsigned int i8;
  1978 
  1978 
  1979 		while ((i8 = index + 8) < lastIndex) {
  1979 		while ((i8 = index + 8) < lastIndex) {
  1980 		    if (op[0] == el) goto found1;
  1980 		    if (op[0] == el) goto found1;
  2006 		    RETURN ( __mkSmallInteger(index + 7 - nInsts) );
  2006 		    RETURN ( __mkSmallInteger(index + 7 - nInsts) );
  2007 	    found8:
  2007 	    found8:
  2008 		    RETURN ( __mkSmallInteger(index + 8 - nInsts) );
  2008 		    RETURN ( __mkSmallInteger(index + 8 - nInsts) );
  2009 		}
  2009 		}
  2010 	    }
  2010 	    }
  2011 # endif /* UNROLL_LOOPS */
  2011 # endif /* __UNROLL_LOOPS__ */
  2012 
  2012 
  2013 	    while (index++ < lastIndex) {
  2013 	    while (index++ < lastIndex) {
  2014 		if (*op++ == el) goto found0;
  2014 		if (*op++ == el) goto found0;
  2015 	    }
  2015 	    }
  2016 
  2016 
  2121 		OBJ slf = self;
  2121 		OBJ slf = self;
  2122 
  2122 
  2123 		/* 
  2123 		/* 
  2124 		 * search for nil - do an identity-search
  2124 		 * search for nil - do an identity-search
  2125 		 */
  2125 		 */
  2126 #if defined(UNROLL_LOOPS)
  2126 #ifdef __UNROLL_LOOPS__
  2127 		{
  2127 		{
  2128 		    unsigned int i8;
  2128 		    unsigned int i8;
  2129 
  2129 
  2130 		    while ((i8 = index + 8) < nIndex) {
  2130 		    while ((i8 = index + 8) < nIndex) {
  2131 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2131 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2253 		OBJ slf = self;
  2253 		OBJ slf = self;
  2254 
  2254 
  2255 		/* 
  2255 		/* 
  2256 		 * search for nil - do an identity-search
  2256 		 * search for nil - do an identity-search
  2257 		 */
  2257 		 */
  2258 #if defined(UNROLL_LOOPS)
  2258 #ifdef __UNROLL_LOOPS__
  2259 		{
  2259 		{
  2260 		    unsigned int i8;
  2260 		    unsigned int i8;
  2261 
  2261 
  2262 		    while ((i8 = index + 8) < lastIndex) {
  2262 		    while ((i8 = index + 8) < lastIndex) {
  2263 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2263 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2348      * when found; without the goto, we branch always.
  2348      * when found; without the goto, we branch always.
  2349      * Pipelined CPUs do usually not like taken branches.
  2349      * Pipelined CPUs do usually not like taken branches.
  2350      * also, all branches are forward, which are usually predicted
  2350      * also, all branches are forward, which are usually predicted
  2351      * as not taken.
  2351      * as not taken.
  2352      */
  2352      */
  2353 #  if defined(UNROLL_LOOPS)
  2353 #  ifdef __UNROLL_LOOPS__
  2354     {
  2354     {
  2355 	unsigned int i8;
  2355 	unsigned int i8;
  2356 	REGISTER OBJ slf = self;
  2356 	REGISTER OBJ slf = self;
  2357 
  2357 
  2358 	while ((i8 = index + 8) < nIndex) {
  2358 	while ((i8 = index + 8) < nIndex) {
  2365 	    if (__InstPtr(slf)->i_instvars[index+6] == o) goto found;
  2365 	    if (__InstPtr(slf)->i_instvars[index+6] == o) goto found;
  2366 	    if (__InstPtr(slf)->i_instvars[index+7] == o) goto found;
  2366 	    if (__InstPtr(slf)->i_instvars[index+7] == o) goto found;
  2367 	    index = i8;
  2367 	    index = i8;
  2368 	}
  2368 	}
  2369     }
  2369     }
  2370 #  endif /* UNROLL_LOOPS */
  2370 #  endif /* __UNROLL_LOOPS__ */
  2371 
  2371 
  2372     while (index < nIndex) {
  2372     while (index < nIndex) {
  2373 	if (__InstPtr(self)->i_instvars[index++] == o) goto found;
  2373 	if (__InstPtr(self)->i_instvars[index++] == o) goto found;
  2374     }
  2374     }
  2375     if (0) {
  2375     if (0) {
  2498 ! !
  2498 ! !
  2499 
  2499 
  2500 !Array class methodsFor:'documentation'!
  2500 !Array class methodsFor:'documentation'!
  2501 
  2501 
  2502 version
  2502 version
  2503     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.138 2005-07-08 17:15:00 cg Exp $'
  2503     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.139 2005-07-08 21:13:38 cg Exp $'
  2504 ! !
  2504 ! !