--- 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 $'
! !