Array.st
changeset 3484 79a08dfa50c9
parent 3234 4cc58bc6a8ed
child 3485 3c1fb0af87fc
--- 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 $'
 ! !