checkin from browser
authorClaus Gittinger <cg@exept.de>
Tue, 14 Nov 1995 15:25:25 +0100
changeset 543 09293a92bddb
parent 542 fec8c38962ba
child 544 d78012b20769
checkin from browser
Array.st
--- a/Array.st	Tue Nov 14 12:18:26 1995 +0100
+++ b/Array.st	Tue Nov 14 15:25:25 1995 +0100
@@ -10,33 +10,17 @@
  hereby transferred.
 "
 
+'From Smalltalk/X, Version:2.10.8 on 14-nov-1995 at 15:25:17'                   !
+
 ArrayedCollection variableSubclass:#Array
-       instanceVariableNames:''
-       classVariableNames:''
-       poolDictionaries:''
-       category:'Collections-Arrayed'
+	 instanceVariableNames:''
+	 classVariableNames:''
+	 poolDictionaries:''
+	 category:'Collections-Arrayed'
 !
 
 !Array class methodsFor:'documentation'!
 
-copyright
-"
- COPYRIGHT (c) 1989 by Claus Gittinger
-	      All Rights Reserved
-
- This software is furnished under a license and may be used
- only in accordance with the terms of that license and with the
- inclusion of the above copyright notice.   This software may not
- be provided or otherwise made available to, or used by, any
- other person.  No title to or ownership of the software is
- hereby transferred.
-"
-!
-
-version
-    ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.40 1995-11-11 14:26:37 cg Exp $'
-!
-
 documentation
 "
     Instances of Array store general objects; the arrays size is fixed, 
@@ -64,14 +48,24 @@
 	#('foo' nil true #true)
 	#('one' two [3 3 3] (4 4 4))
 "
-! !
+!
 
-!Array class methodsFor:'queries'!
+copyright
+"
+ COPYRIGHT (c) 1989 by Claus Gittinger
+	      All Rights Reserved
 
-isBuiltInClass
-    "this class is known by the run-time-system"
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+!
 
-    ^ self == Array
+version
+    ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.41 1995-11-14 14:25:25 cg Exp $'
 ! !
 
 !Array class methodsFor:'instance creation'!
@@ -230,135 +224,16 @@
     ^ ObjectMemory allocationFailureSignal raise.
 ! !
 
-!Array class ignoredMethodsFor:'instance creation'!
-
-with:one
-    "redefined for performance.
-     I really dont know, if it is worth it.
-     Detailed measurements may show that this can be removed to save some
-     space."
-
-%{  /* NOCONTEXT */
-    if (_ClassInstPtr(self)->c_ninstvars == __MKSMALLINT(0)) {
-	if (_CanDoQuickAlignedNew(sizeof(struct __arrayheader) + __OBJS2BYTES__(1))) {
-	    OBJ newArray;
-
-	    _qCheckedAlignedNew(newArray, sizeof(struct __arrayheader) + __OBJS2BYTES__(1));
-	    _InstPtr(newArray)->o_class = self;
-	    _ArrayInstPtr(newArray)->a_element[0] = one;
-	    __qSTORE(newArray, self);
-	    __STORE(newArray, one);
-	    return newArray;
-	}
-    }
-%}.
-    ^ super with:one
-!
-
-with:one with:two
-    "redefined for performance.
-     I really dont know, if it is worth it.
-     Detailed measurements may show that this can be removed to save some
-     space."
-
-%{  /* NOCONTEXT */
-    if (_ClassInstPtr(self)->c_ninstvars == __MKSMALLINT(0)) {
-	if (_CanDoQuickAlignedNew(sizeof(struct __arrayheader) + __OBJS2BYTES__(2))) {
-	    OBJ newArray;
-
-	    _qCheckedAlignedNew(newArray, sizeof(struct __arrayheader) + __OBJS2BYTES__(2));
-	    _InstPtr(newArray)->o_class = self;
-	    _ArrayInstPtr(newArray)->a_element[0] = one;
-	    _ArrayInstPtr(newArray)->a_element[1] = two;
-	    __qSTORE(newArray, self);
-	    __STORE(newArray, one);
-	    __STORE(newArray, two);
-	    return newArray;
-	}
-    }
-%}.
-    ^ super with:one with:two
-!
+!Array class methodsFor:'queries'!
 
-with:one with:two with:three
-    "redefined for performance.
-     I really dont know, if it is worth it.
-     Detailed measurements may show that this can be removed to save some
-     space."
-
-%{  /* NOCONTEXT */
-    if (_ClassInstPtr(self)->c_ninstvars == __MKSMALLINT(0)) {
-	if (_CanDoQuickAlignedNew(sizeof(struct __arrayheader) + __OBJS2BYTES__(3))) {
-	    OBJ newArray;
-
-	    _qCheckedAlignedNew(newArray, sizeof(struct __arrayheader) + __OBJS2BYTES__(3));
-	    _InstPtr(newArray)->o_class = self;
-	    _ArrayInstPtr(newArray)->a_element[0] = one;
-	    _ArrayInstPtr(newArray)->a_element[1] = two;
-	    _ArrayInstPtr(newArray)->a_element[2] = three;
-	    __qSTORE(newArray, self);
-	    __STORE(newArray, one);
-	    __STORE(newArray, two);
-	    __STORE(newArray, three);
-	    return newArray;
-	}
-    }
-%}.
-    ^ super with:one with:two with:three
-!
+isBuiltInClass
+    "this class is known by the run-time-system"
 
-with:one with:two with:three with:four
-    "redefined for performance.
-     I really dont know, if it is worth it.
-     Detailed measurements may show that this can be removed to save some
-     space."
-
-%{  /* NOCONTEXT */
-    if (_ClassInstPtr(self)->c_ninstvars == __MKSMALLINT(0)) {
-	if (_CanDoQuickAlignedNew(sizeof(struct __arrayheader) + __OBJS2BYTES__(4))) {
-	    OBJ newArray;
-
-	    _qCheckedAlignedNew(newArray, sizeof(struct __arrayheader) + __OBJS2BYTES__(4));
-	    _InstPtr(newArray)->o_class = self;
-	    _ArrayInstPtr(newArray)->a_element[0] = one;
-	    _ArrayInstPtr(newArray)->a_element[1] = two;
-	    _ArrayInstPtr(newArray)->a_element[2] = three;
-	    _ArrayInstPtr(newArray)->a_element[3] = four;
-	    __qSTORE(newArray, self);
-	    __STORE(newArray, one);
-	    __STORE(newArray, two);
-	    __STORE(newArray, three);
-	    __STORE(newArray, four);
-	    return newArray;
-	}
-    }
-%}.
-    ^ super with:one with:two with:three with:four
+    ^ self == Array
 ! !
 
 !Array methodsFor:'accessing'!
 
-basicSize
-    "return the number of indexed elements in the receiver"
-
-%{  /* NOCONTEXT */
-
-    RETURN ( __MKSMALLINT(_arraySize(self) - _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars) ));
-%}
-!
-
-size
-    "return the number of indexed elements in the receiver.
-     Reimplemented here to avoid the additional size->basicSize send
-     (which we can do here, since size is obviously not redefined in a subclass).
-     This method is the same as basicSize."
-
-%{  /* NOCONTEXT */
-
-    RETURN ( __MKSMALLINT(_arraySize(self) - _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars) ));
-%}
-!
-
 basicAt:index
     "return the indexed instance variable with index, anInteger
      - added here for speed"
@@ -385,6 +260,47 @@
     ^ super basicAt:index
 !
 
+at:index put:anObject
+    "store the 2nd arg, anObject as indexed instvar with index, anInteger.
+     Reimplemented here to avoid the additional at:put:->basicAt:put: send
+     (which we can do here, since at: is obviously not redefined in a subclass).
+     This method is the same as at:."
+
+%{  /* NOCONTEXT */
+
+    REGISTER int indx;
+    REGISTER unsigned int nIndex;
+    OBJ cls;
+
+    if (__isSmallInteger(index)) {
+	indx = _intVal(index) - 1;
+	if (indx >= 0) {
+	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+	    if ((cls = __qClass(self)) != Array)
+		indx += _intVal(_ClassInstPtr(cls)->c_ninstvars);
+	    if (indx < nIndex) {
+		_InstPtr(self)->i_instvars[indx] = anObject;
+		__STORE(self, anObject);
+		RETURN ( anObject );
+	    }
+	}
+    }
+%}.
+    ^ super at:index put:anObject
+!
+
+size
+    "return the number of indexed elements in the receiver.
+     Reimplemented here to avoid the additional size->basicSize send
+     (which we can do here, since size is obviously not redefined in a subclass).
+     This method is the same as basicSize."
+
+%{  /* NOCONTEXT */
+
+    RETURN ( __MKSMALLINT(_arraySize(self) - _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars) ));
+%}
+!
+
 at:index
     "return the indexed instance variable with index, anInteger.
      Reimplemented here to avoid the additional at:->basicAt: send
@@ -440,33 +356,13 @@
     ^ super basicAt:index put:anObject
 !
 
-at:index put:anObject
-    "store the 2nd arg, anObject as indexed instvar with index, anInteger.
-     Reimplemented here to avoid the additional at:put:->basicAt:put: send
-     (which we can do here, since at: is obviously not redefined in a subclass).
-     This method is the same as at:."
+basicSize
+    "return the number of indexed elements in the receiver"
 
 %{  /* NOCONTEXT */
 
-    REGISTER int indx;
-    REGISTER unsigned int nIndex;
-    OBJ cls;
-
-    if (__isSmallInteger(index)) {
-	indx = _intVal(index) - 1;
-	if (indx >= 0) {
-	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-	    if ((cls = __qClass(self)) != Array)
-		indx += _intVal(_ClassInstPtr(cls)->c_ninstvars);
-	    if (indx < nIndex) {
-		_InstPtr(self)->i_instvars[indx] = anObject;
-		__STORE(self, anObject);
-		RETURN ( anObject );
-	    }
-	}
-    }
-%}.
-    ^ super at:index put:anObject
+    RETURN ( __MKSMALLINT(_arraySize(self) - _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars) ));
+%}
 ! !
 
 !Array methodsFor:'converting'!
@@ -555,542 +451,6 @@
     ^ super copyWith:something
 ! !
 
-!Array ignoredMethodsFor:'filling & replacing'!
-
-atAllPut:anObject
-    "reimplemented for speed if receiver is an Array"
-
-%{  /* NOCONTEXT */
-
-    unsigned int nIndex;
-    REGISTER OBJ *dst;
-
-    if (__qClass(self) == Array) {
-	nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-	dst = __ArrayInstPtr(self)->a_element;
-#ifdef memset4
-	memset4(dst, anObject, nIndex);
-	__STORE(self, anObject);
-#else
-	if ((INT)anObject == 0) {
-	    memset(dst, 0, __OBJS2BYTES__(nIndex));
-	} else {
-#ifdef UNROLL_LOOPS
-	    while (nIndex >= 8) {
-		dst[0] = anObject;
-		dst[1] = anObject;
-		dst[2] = anObject;
-		dst[3] = anObject;
-		dst[4] = anObject;
-		dst[5] = anObject;
-		dst[6] = anObject;
-		dst[7] = anObject;
-		dst += 8;
-		nIndex -= 8;
-	    }
-#endif
-	    for (; nIndex; nIndex--) {
-		*dst++ = anObject;
-	    }
-	    __STORE(self, anObject);
-	}
-#endif
-	RETURN ( self );
-    }
-%}.
-    ^ super atAllPut:anObject
-! !
-
-!Array methodsFor:'filling & replacing'!
-
-from:index1 to:index2 put:anObject
-    "reimplemented for speed if receiver is an Array"
-
-%{  /* NOCONTEXT */
-
-    REGISTER int index;
-    unsigned int nIndex;
-    unsigned int endIndex;
-    REGISTER OBJ *dst;
-
-    if ((__qClass(self) == Array)
-     && __bothSmallInteger(index1, index2)) {
-	index = _intVal(index1) - 1;
-	if (index >= 0) {
-	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-	    endIndex = _intVal(index2) - 1;
-	    if (endIndex < nIndex) {
-		dst = &(_InstPtr(self)->i_instvars[index]);
-#ifdef memset4
-		memset4(dst, anObject, (endIndex-index+1));
-		__STORE(self, anObject);
-#else
-		if ((INT)anObject == 0) {
-		    memset(dst, 0, __OBJS2BYTES__(endIndex-index+1));
-		} else {
-#if defined(UNROLL_LOOPS)
-		    {
-			int i8;
-
-			while ((i8 = index + 8) <= endIndex) {
-			    dst[0] = anObject;
-			    dst[1] = anObject;
-			    dst[2] = anObject;
-			    dst[3] = anObject;
-			    dst[4] = anObject;
-			    dst[5] = anObject;
-			    dst[6] = anObject;
-			    dst[7] = anObject;
-			    dst += 8;
-			    index = i8;
-			}
-		    }
-#endif
-		    for (; index <= endIndex; index++) {
-			*dst++ = anObject;
-		    }
-		    __STORE(self, anObject);
-		}
-#endif
-		RETURN ( self );
-	    }
-	}
-    }
-%}
-.
-    ^ super from:index1 to:index2 put:anObject
-!
-
-replaceFrom:start to:stop with:aCollection startingAt:repStart
-    "reimplemented for speed if both receiver and aCollection are Arrays"
-
-%{  /* NOCONTEXT */
-
-    unsigned int nIndex;
-    unsigned int repNIndex;
-    int startIndex, stopIndex;
-    REGISTER OBJ *src;
-    REGISTER OBJ *dst;
-    int repStopIndex;
-    REGISTER int repStartIndex;
-    REGISTER OBJ t;
-    REGISTER int count;
-
-    
-    if ((_ClassInstPtr(__qClass(self))->c_ninstvars == __MKSMALLINT(0))
-     && (((t = __Class(aCollection)) == Array) || (t == __qClass(self)))
-     && __bothSmallInteger(start, stop)
-     && __isSmallInteger(repStart)) {
-	startIndex = _intVal(start) - 1;
-	if (startIndex >= 0) {
-	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-	    stopIndex = _intVal(stop) - 1;
-	    count = stopIndex - startIndex + 1;
-	    if (count == 0) {
-		RETURN ( self );
-	    }
-	    if ((count > 0) && (stopIndex < nIndex)) {
-		repStartIndex = _intVal(repStart) - 1;
-		if (repStartIndex >= 0) {
-		    repNIndex = __BYTES2OBJS__(__qSize(aCollection)-OHDR_SIZE);
-		    repStopIndex = repStartIndex + (stopIndex - startIndex);
-		    if (repStopIndex < repNIndex) {
-			src = &(_InstPtr(aCollection)->i_instvars[repStartIndex]);
-			dst = &(_InstPtr(self)->i_instvars[startIndex]);
-			if (aCollection == self) {
-			    /* 
-			     * no need to check stores if copying
-			     * from myself
-			     */
-			    /* 
-			     * take care of overlapping copy
-			     * do not depend on memset being smart enough
-			     * (some are not ;-)
-			     */
-			    if (src < dst) {
-				/* must do a reverse copy */
-				src += count;
-				dst += count;
-#if defined(UNROLL_LOOPS)
-				while (count > 8) {
-				    dst[-1] = src[-1];
-				    dst[-2] = src[-2];
-				    dst[-3] = src[-3];
-				    dst[-4] = src[-4];
-				    dst[-5] = src[-5];
-				    dst[-6] = src[-6];
-				    dst[-7] = src[-7];
-				    dst[-8] = src[-8];
-				    dst -= 8; src -= 8;
-				    count -= 8;
-				}
-#endif
-				while (count-- > 0) {
-				    *--dst = *--src;
-				}
-				RETURN ( self );
-			    }
-#ifdef bcopy4
-			    bcopy4(src, dst, count);
-#else
-# ifdef FAST_MEMCPY
-			    bcopy(src, dst, __OBJS2BYTES__(count));
-# else
-			    while (count--) {
-				*dst++ = *src++;
-			    }
-# endif
-#endif
-			} else {
-			    REGISTER int spc;
-
-			    spc = __qSpace(self);
-#if defined(UNROLL_LOOPS)
-			    while (count >= 4) {
-				t = src[0]; dst[0] = t; __STORE_SPC(self, t, spc);
-				t = src[1]; dst[1] = t; __STORE_SPC(self, t, spc);
-				t = src[2]; dst[2] = t; __STORE_SPC(self, t, spc);
-				t = src[3]; dst[3] = t; __STORE_SPC(self, t, spc);
-				count -= 4; src += 4; dst += 4;
-			    }
-#endif
-			    while (count-- > 0) {
-				t = *src++;
-				*dst++ = t;
-				__STORE_SPC(self, t, spc);
-			    }
-			}
-			RETURN ( self );
-		    }
-		}
-	    }
-	}
-    }
-%}.
-    ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart
-! !
-
-!Array methodsFor:'queries'!
-
-isArray
-    "return true, if the receiver is some kind of array (or weakArray etc).
-     true is returned here"
-
-    ^ true
-!
-
-isLiteral
-    "return true, if the receiver can be used as a literal
-     (i.e. can be used in constant arrays)"
-
-    "no, subclasses of array are not"
-    self class == Array ifFalse:[^ false].
-
-    thisContext isRecursive ifTrue:[^ false].
-
-    self do:[:element |
-	element isLiteral ifFalse:[^ false]
-    ].
-    ^ true
-!
-
-refersToLiteral: aLiteral
-    self do: [ :el | 
-	el == aLiteral ifTrue:[^true].
-	el class == Array ifTrue:[
-	    (el refersToLiteral: aLiteral) ifTrue: [^true]
-	]
-    ].
-    ^ false
-
-    "
-     #(1 2 3) refersToLiteral:#foo  
-     #(1 2 3 foo bar baz) refersToLiteral:#foo 
-     #(1 2 3 (((bar foo))) bar baz) refersToLiteral:#foo  
-    "
-! !
-
-!Array methodsFor:'testing'!
-
-includes:anObject
-    "return true, if the argument, anObject is contained in the array
-     - reimplemented for speed"
-
-    |element|
-
-%{  /* NOCONTEXT */
-
-    /* 
-     * first, do a quick check using ==
-     * this does not need a context or message send.
-     * In many cases this will already find a match.
-     */
-    REGISTER int index;
-    REGISTER OBJ o;
-    unsigned int nIndex;
-
-    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-    index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
-
-    /*
-     * however, the search is limited to the first 1000
-     * elements, since otherwise, we may spend too much time
-     * searching for identity if an equal value is found early
-     */
-    if (nIndex > 1000) nIndex = 1000;
-
-    o = anObject;
-#if defined(UNROLL_LOOPS)
-    {
-	unsigned int i8;
-
-	while ((i8 = index + 8) < nIndex) {
-	    if (_InstPtr(self)->i_instvars[index] == o) { RETURN ( true ); }
-	    if (_InstPtr(self)->i_instvars[index+1] == o) { RETURN ( true ); }
-	    if (_InstPtr(self)->i_instvars[index+2] == o) { RETURN ( true ); }
-	    if (_InstPtr(self)->i_instvars[index+3] == o) { RETURN ( true ); }
-	    if (_InstPtr(self)->i_instvars[index+4] == o) { RETURN ( true ); }
-	    if (_InstPtr(self)->i_instvars[index+5] == o) { RETURN ( true ); }
-	    if (_InstPtr(self)->i_instvars[index+6] == o) { RETURN ( true ); }
-	    if (_InstPtr(self)->i_instvars[index+7] == o) { RETURN ( true ); }
-	    index = i8;
-	}
-    }
-#endif
-    while (index < nIndex) {
-	if (_InstPtr(self)->i_instvars[index++] == o) {
-	    RETURN ( true );
-	}
-    }
-    if (o == nil) {
-	RETURN ( false );
-    }
-%}
-.
-%{
-    /* 
-     * then do a slow(er) check using =
-     */
-    REGISTER int index;
-    unsigned int nIndex;
-    static struct inlineCache eq = _ILC1;
-
-    /* 
-     * sorry: cannot access the stuff from above ...
-     */
-    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-    index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
-
-    while (index < nIndex) {
-	element = _InstPtr(self)->i_instvars[index++];
-	if (element != nil) {
-	    if ((*eq.ilc_func)(anObject,
-			       @symbol(=),
-			       CON_COMMA nil,&eq,
-			       element)==true) {
-		RETURN ( true );
-	    }
-	}
-    }
-%}.
-    ^ false
-!
-
-indexOf:anElement startingAt:start
-    "search the array for anElement; return index if found, 0 otherwise
-     - reimplemented for speed"
-
-    |element|
-%{
-    REGISTER int index;
-    unsigned int nIndex, nInsts;
-    static struct inlineCache eq = _ILC1;
-
-    if (__isSmallInteger(start)) {
-	index = _intVal(start) - 1;
-	if (index >= 0) {
-	    nInsts = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
-	    index += nInsts;
-	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-	    if (anElement != nil) {
-		while (index < nIndex) {
-		    element = _InstPtr(self)->i_instvars[index++];
-		    if (element != nil) {
-			if ((element == anElement) 
-			 || ((*eq.ilc_func)(anElement,
-					    @symbol(=), 
-					    CON_COMMA nil,&eq,
-					    element) == true)) {
-			    RETURN ( __MKSMALLINT(index - nInsts) );
-			}
-		    }
-		}
-	    } else {
-		/* search for nil */
-#if defined(UNROLL_LOOPS)
-		{
-		    unsigned int i8;
-
-		    while ((i8 = index + 8) < nIndex) {
-			if (_InstPtr(self)->i_instvars[index] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 1) ); }
-			if (_InstPtr(self)->i_instvars[index+1] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 2) ); }
-			if (_InstPtr(self)->i_instvars[index+2] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 3) ); }
-			if (_InstPtr(self)->i_instvars[index+3] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 4) ); }
-			if (_InstPtr(self)->i_instvars[index+4] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 5) ); }
-			if (_InstPtr(self)->i_instvars[index+5] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 6) ); }
-			if (_InstPtr(self)->i_instvars[index+6] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 7) ); }
-			if (_InstPtr(self)->i_instvars[index+7] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 8) ); }
-			index = i8;
-		    }
-		}
-#endif
-
-		while (index < nIndex) {
-		    if (_InstPtr(self)->i_instvars[index++] == nil) {
-			RETURN ( __MKSMALLINT(index - nInsts) );
-		    }
-		}
-	    }
-	}
-    }
-%}.
-    ^ 0
-!
-
-identityIndexOf:anElement startingAt:start
-    "search the array for anElement; return index if found, 0 otherwise
-     - reimplemented for speed"
-
-%{  /* NOCONTEXT */
-
-    REGISTER int index;
-    REGISTER OBJ el;
-    REGISTER OBJ *op;
-    REGISTER unsigned int nIndex;
-    int nInsts;
-
-    if (__isSmallInteger(start)) {
-	index = _intVal(start) - 1;
-	if (index >= 0) {
-	    nInsts = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
-	    index += nInsts;
-	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-	    el = anElement;
-	    op = & (_InstPtr(self)->i_instvars[index]);
-#if defined(UNROLL_LOOPS)
-	    {
-		unsigned int i8;
-
-		while ((i8 = index + 8) < nIndex) {
-		    if (op[0] == el) { RETURN ( __MKSMALLINT(index + 1 - nInsts) ); }
-		    if (op[1] == el) { RETURN ( __MKSMALLINT(index + 2 - nInsts) ); }
-		    if (op[2] == el) { RETURN ( __MKSMALLINT(index + 3 - nInsts) ); }
-		    if (op[3] == el) { RETURN ( __MKSMALLINT(index + 4 - nInsts) ); }
-		    if (op[4] == el) { RETURN ( __MKSMALLINT(index + 5 - nInsts) ); }
-		    if (op[5] == el) { RETURN ( __MKSMALLINT(index + 6 - nInsts) ); }
-		    if (op[6] == el) { RETURN ( __MKSMALLINT(index + 7 - nInsts) ); }
-		    if (op[7] == el) { RETURN ( __MKSMALLINT(index + 8 - nInsts) ); }
-		    index = i8;
-		    op += 8;
-		}
-	    }
-#endif
-	    while (index++ < nIndex) {
-		if (*op++ == el) {
-		    RETURN ( __MKSMALLINT(index - nInsts) );
-		}
-	    }
-	    RETURN ( __MKSMALLINT(0) );
-	}
-    }
-%}.
-    ^ super identityIndexOf:anElement startingAt:start
-!
-
-identityIndexOf:anElement or:alternative 
-    "search the array for anElement or alternative; 
-     return the index of anElement if found, or the index of anAlternative,
-     if not found. If anAlternative is also not found, return 0.
-     This is a special interface for high-speed searching in an array
-     and at the same time searching for an empty slot.
-     Do not use this method for your application classes, since it is
-     not portable (i.e. other smalltalks do not offer this)"
-
-%{  /* NOCONTEXT */
-
-    REGISTER int index;
-    REGISTER OBJ o, el1, el2;
-    REGISTER OBJ *op;
-    REGISTER unsigned int nIndex;
-    int altIndex = 0;
-    int nInsts;
-
-    index = 0;
-    nInsts = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
-    index += nInsts;
-    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
-    el1 = anElement; el2 = alternative; 
-    op = & (_InstPtr(self)->i_instvars[index]);
-    while (index++ < nIndex) {
-	if ((o = *op++) == el1) {
-	    RETURN ( __MKSMALLINT(index - nInsts) );
-	}
-	if (o == el2) {
-	    if (altIndex == 0) {
-		altIndex = index;
-	    }
-	}
-    }
-    RETURN ( __MKSMALLINT(altIndex) );
-%}
-
-    "
-     #(1 2 3 4 5 6 7 8 9) identityIndexOf:3 or:5
-     #(1 2 0 4 5 6 7 8 9) identityIndexOf:3 or:5
-     #(1 2 0 4 5 6 7 3 9) identityIndexOf:3 or:5
-     #(1 2 3 4 5 nil 7 3 9) identityIndexOf:3 or:nil 
-     #(1 2 nil 4 5 6 7 3 9) identityIndexOf:3 or:nil  
-     #(1 2 nil 4 5 6 7 8 9) identityIndexOf:3 or:nil 
-     #() identityIndexOf:3 or:nil        
-     #(1 2) identityIndexOf:3 or:nil 
-    "
-! !
-
-!Array methodsFor:'printing & storing'!
-
-displayString
-    "return a printed representation of the receiver for displaying"
-
-    |s|
-
-    (self isLiteral) ifTrue:[
-	s := WriteStream on:String new.
-	s nextPutAll:'#('.
-	self do:[:element | s nextPutAll:element displayString. s space].
-	s nextPutAll:')'.
-	^ s contents
-    ].
-    ^ super displayString
-!
-
-storeOn:aStream
-    "append a printed representation of the receiver to aStream,
-     which allows reconstructing it via readFrom:.
-     Redefined to output a somewhat more user friendly string."
-
-    self isLiteral ifTrue:[
-	aStream nextPutAll:'#('.
-	self do:[:element | element storeOn:aStream. aStream space].
-	aStream nextPutAll:')'
-    ] ifFalse:[
-	super storeOn:aStream
-    ]
-
-    "
-     #(1 2 $a 'hello') storeString 
-    "
-! !
-
 !Array methodsFor:'enumerating'!
 
 do:aBlock
@@ -1236,50 +596,6 @@
     ^ self
 !
 
-reverseDo:aBlock
-    "evaluate the argument, aBlock for each element in the collection in reverse order.
-     - reimplemented for speed"
-
-    |home|
-%{
-    REGISTER OBJFUNC codeVal;
-    REGISTER int index;
-    unsigned int nIndex;
-    int endIndex;
-    extern OBJ Block;
-    static struct inlineCache val = _ILC1;
-
-    endIndex = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
-    nIndex = __arraySize(self);
-
-    if (__isBlockLike(aBlock)
-     && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
-     && (_BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) {
-#ifdef NEW_BLOCK_CALL
-	for (index=nIndex-1; index >= endIndex; index--) {
-	    if (InterruptPending != nil) __interruptL(@line COMMA_CON);
-	    (*codeVal)(aBlock, CON_COMMA  _InstPtr(self)->i_instvars[index]);
-	} 
-#else
-	home = _BlockInstPtr(aBlock)->b_home;
-	for (index=nIndex-1; index >= endIndex; index--) {
-	    if (InterruptPending != nil) __interruptL(@line COMMA_CON);
-	    (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
-	} 
-#endif
-    } else {
-	for (index=nIndex-1; index >= endIndex; index--) {
-	    if (InterruptPending != nil) __interruptL(@line COMMA_CON);
-	    (*val.ilc_func)(aBlock, 
-			    @symbol(value:), 
-			    CON_COMMA  nil, &val, 
-			    _InstPtr(self)->i_instvars[index]);
-	} 
-    }
-%}.
-    ^ self
-!
-
 from:start to:stop do:aBlock
     "evaluate the argument, aBlock for the elements starting at index start
      up to (and including) stop in the collection.
@@ -1367,6 +683,73 @@
     ^ super from:start to:stop do:aBlock
 !
 
+nonNilElementsDo:aBlock
+    "evaluate the argument, aBlock for each non-nil element"
+
+    |home|
+%{
+    REGISTER OBJFUNC codeVal;
+    REGISTER int index;
+    int nIndex;
+    extern OBJ Block;
+    static struct inlineCache val = _ILC1;
+    REGISTER OBJ rHome;
+    REGISTER OBJ element;
+
+    index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
+    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+    if (__isBlockLike(aBlock)
+     && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
+     && (_BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) {
+#ifdef NEW_BLOCK_CALL
+	for (; index < nIndex; index++) {
+	    if (InterruptPending != nil) __interruptL(CONARG);
+
+	    element = _InstPtr(self)->i_instvars[index];
+	    if (element != nil)
+		(*codeVal)(aBlock, CON_COMMA  element);
+	} 
+#else
+	home = _BlockInstPtr(aBlock)->b_home;
+	rHome = home;
+	if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) {
+	    /*
+	     * home will not move - keep in in a register
+	     */
+	    for (; index < nIndex; index++) {
+		if (InterruptPending != nil) __interruptL(CONARG);
+
+		element = _InstPtr(self)->i_instvars[index];
+		if (element != nil)
+		    (*codeVal)(rHome, CON_COMMA  element);
+	    } 
+	} else {
+	    for (; index < nIndex; index++) {
+		if (InterruptPending != nil) __interruptL(@line CONARG);
+
+		element = _InstPtr(self)->i_instvars[index];
+		if (element != nil)
+		    (*codeVal)(home, CON_COMMA  element);
+	    }
+	} 
+#endif
+    } else {
+	for (; index < nIndex; index++) {
+	    if (InterruptPending != nil) __interruptL(@line CONARG);
+
+	    element = _InstPtr(self)->i_instvars[index];
+	    if (element != nil)
+		(*val.ilc_func)(aBlock, 
+				@symbol(value:), 
+				CON_COMMA nil, &val, 
+				element);
+	} 
+    }
+%}
+.
+    ^ self
+!
+
 from:start to:stop reverseDo:aBlock
     "evaluate the argument, aBlock for the elements starting at index start
      up to (and including) stop in the collection. Step in reverse order.
@@ -1436,73 +819,63 @@
     ^ super from:start to:stop reverseDo:aBlock
 !
 
-nonNilElementsDo:aBlock
-    "evaluate the argument, aBlock for each non-nil element"
+reverseDo:aBlock
+    "evaluate the argument, aBlock for each element in the collection in reverse order.
+     - reimplemented for speed"
 
     |home|
 %{
     REGISTER OBJFUNC codeVal;
     REGISTER int index;
-    int nIndex;
+    unsigned int nIndex;
+    int endIndex;
     extern OBJ Block;
     static struct inlineCache val = _ILC1;
-    REGISTER OBJ rHome;
-    REGISTER OBJ element;
 
-    index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
-    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+    endIndex = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
+    nIndex = __arraySize(self);
+
     if (__isBlockLike(aBlock)
      && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
      && (_BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) {
 #ifdef NEW_BLOCK_CALL
-	for (; index < nIndex; index++) {
-	    if (InterruptPending != nil) __interruptL(CONARG);
-
-	    element = _InstPtr(self)->i_instvars[index];
-	    if (element != nil)
-		(*codeVal)(aBlock, CON_COMMA  element);
+	for (index=nIndex-1; index >= endIndex; index--) {
+	    if (InterruptPending != nil) __interruptL(@line COMMA_CON);
+	    (*codeVal)(aBlock, CON_COMMA  _InstPtr(self)->i_instvars[index]);
 	} 
 #else
 	home = _BlockInstPtr(aBlock)->b_home;
-	rHome = home;
-	if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) {
-	    /*
-	     * home will not move - keep in in a register
-	     */
-	    for (; index < nIndex; index++) {
-		if (InterruptPending != nil) __interruptL(CONARG);
-
-		element = _InstPtr(self)->i_instvars[index];
-		if (element != nil)
-		    (*codeVal)(rHome, CON_COMMA  element);
-	    } 
-	} else {
-	    for (; index < nIndex; index++) {
-		if (InterruptPending != nil) __interruptL(@line CONARG);
-
-		element = _InstPtr(self)->i_instvars[index];
-		if (element != nil)
-		    (*codeVal)(home, CON_COMMA  element);
-	    }
+	for (index=nIndex-1; index >= endIndex; index--) {
+	    if (InterruptPending != nil) __interruptL(@line COMMA_CON);
+	    (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
 	} 
 #endif
     } else {
-	for (; index < nIndex; index++) {
-	    if (InterruptPending != nil) __interruptL(@line CONARG);
-
-	    element = _InstPtr(self)->i_instvars[index];
-	    if (element != nil)
-		(*val.ilc_func)(aBlock, 
-				@symbol(value:), 
-				CON_COMMA nil, &val, 
-				element);
+	for (index=nIndex-1; index >= endIndex; index--) {
+	    if (InterruptPending != nil) __interruptL(@line COMMA_CON);
+	    (*val.ilc_func)(aBlock, 
+			    @symbol(value:), 
+			    CON_COMMA  nil, &val, 
+			    _InstPtr(self)->i_instvars[index]);
 	} 
     }
-%}
-.
+%}.
     ^ self
 !
 
+addAllTo:aCollection
+    "add all elements of the receiver to aCollection.
+     return aCollection."
+
+    |stop "{ Class: SmallInteger }"|
+
+    stop := self size.
+    1 to:stop do:[:idx |
+	aCollection add:(self at:idx)
+    ].
+    ^ aCollection
+!
+
 traverse:aBlock
     "Evaluate aBlock for every element that is not an Array, 
      and traverse Arrays.
@@ -1525,17 +898,495 @@
      #(1 2 (3 (4 5 (6 7) 8) 9 10) 11 (12 (13)) 14) traverse:[:el | s nextPut:el].
      s contents 
     "
+! !
+
+!Array methodsFor:'filling & replacing'!
+
+replaceFrom:start to:stop with:aCollection startingAt:repStart
+    "reimplemented for speed if both receiver and aCollection are Arrays"
+
+%{  /* NOCONTEXT */
+
+    unsigned int nIndex;
+    unsigned int repNIndex;
+    int startIndex, stopIndex;
+    REGISTER OBJ *src;
+    REGISTER OBJ *dst;
+    int repStopIndex;
+    REGISTER int repStartIndex;
+    REGISTER OBJ t;
+    REGISTER int count;
+
+    
+    if ((_ClassInstPtr(__qClass(self))->c_ninstvars == __MKSMALLINT(0))
+     && (((t = __Class(aCollection)) == Array) || (t == __qClass(self)))
+     && __bothSmallInteger(start, stop)
+     && __isSmallInteger(repStart)) {
+	startIndex = _intVal(start) - 1;
+	if (startIndex >= 0) {
+	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+	    stopIndex = _intVal(stop) - 1;
+	    count = stopIndex - startIndex + 1;
+	    if (count == 0) {
+		RETURN ( self );
+	    }
+	    if ((count > 0) && (stopIndex < nIndex)) {
+		repStartIndex = _intVal(repStart) - 1;
+		if (repStartIndex >= 0) {
+		    repNIndex = __BYTES2OBJS__(__qSize(aCollection)-OHDR_SIZE);
+		    repStopIndex = repStartIndex + (stopIndex - startIndex);
+		    if (repStopIndex < repNIndex) {
+			src = &(_InstPtr(aCollection)->i_instvars[repStartIndex]);
+			dst = &(_InstPtr(self)->i_instvars[startIndex]);
+			if (aCollection == self) {
+			    /* 
+			     * no need to check stores if copying
+			     * from myself
+			     */
+			    /* 
+			     * take care of overlapping copy
+			     * do not depend on memset being smart enough
+			     * (some are not ;-)
+			     */
+			    if (src < dst) {
+				/* must do a reverse copy */
+				src += count;
+				dst += count;
+#if defined(UNROLL_LOOPS)
+				while (count > 8) {
+				    dst[-1] = src[-1];
+				    dst[-2] = src[-2];
+				    dst[-3] = src[-3];
+				    dst[-4] = src[-4];
+				    dst[-5] = src[-5];
+				    dst[-6] = src[-6];
+				    dst[-7] = src[-7];
+				    dst[-8] = src[-8];
+				    dst -= 8; src -= 8;
+				    count -= 8;
+				}
+#endif
+				while (count-- > 0) {
+				    *--dst = *--src;
+				}
+				RETURN ( self );
+			    }
+#ifdef bcopy4
+			    bcopy4(src, dst, count);
+#else
+# ifdef FAST_MEMCPY
+			    bcopy(src, dst, __OBJS2BYTES__(count));
+# else
+			    while (count--) {
+				*dst++ = *src++;
+			    }
+# endif
+#endif
+			} else {
+			    REGISTER int spc;
+
+			    spc = __qSpace(self);
+#if defined(UNROLL_LOOPS)
+			    while (count >= 4) {
+				t = src[0]; dst[0] = t; __STORE_SPC(self, t, spc);
+				t = src[1]; dst[1] = t; __STORE_SPC(self, t, spc);
+				t = src[2]; dst[2] = t; __STORE_SPC(self, t, spc);
+				t = src[3]; dst[3] = t; __STORE_SPC(self, t, spc);
+				count -= 4; src += 4; dst += 4;
+			    }
+#endif
+			    while (count-- > 0) {
+				t = *src++;
+				*dst++ = t;
+				__STORE_SPC(self, t, spc);
+			    }
+			}
+			RETURN ( self );
+		    }
+		}
+	    }
+	}
+    }
+%}.
+    ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart
+!
+
+from:index1 to:index2 put:anObject
+    "reimplemented for speed if receiver is an Array"
+
+%{  /* NOCONTEXT */
+
+    REGISTER int index;
+    unsigned int nIndex;
+    unsigned int endIndex;
+    REGISTER OBJ *dst;
+
+    if ((__qClass(self) == Array)
+     && __bothSmallInteger(index1, index2)) {
+	index = _intVal(index1) - 1;
+	if (index >= 0) {
+	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+	    endIndex = _intVal(index2) - 1;
+	    if (endIndex < nIndex) {
+		dst = &(_InstPtr(self)->i_instvars[index]);
+#ifdef memset4
+		memset4(dst, anObject, (endIndex-index+1));
+		__STORE(self, anObject);
+#else
+		if ((INT)anObject == 0) {
+		    memset(dst, 0, __OBJS2BYTES__(endIndex-index+1));
+		} else {
+#if defined(UNROLL_LOOPS)
+		    {
+			int i8;
+
+			while ((i8 = index + 8) <= endIndex) {
+			    dst[0] = anObject;
+			    dst[1] = anObject;
+			    dst[2] = anObject;
+			    dst[3] = anObject;
+			    dst[4] = anObject;
+			    dst[5] = anObject;
+			    dst[6] = anObject;
+			    dst[7] = anObject;
+			    dst += 8;
+			    index = i8;
+			}
+		    }
+#endif
+		    for (; index <= endIndex; index++) {
+			*dst++ = anObject;
+		    }
+		    __STORE(self, anObject);
+		}
+#endif
+		RETURN ( self );
+	    }
+	}
+    }
+%}
+.
+    ^ super from:index1 to:index2 put:anObject
+! !
+
+!Array methodsFor:'printing & storing'!
+
+displayString
+    "return a printed representation of the receiver for displaying"
+
+    |s|
+
+    (self isLiteral) ifTrue:[
+	s := WriteStream on:String new.
+	s nextPutAll:'#('.
+	self do:[:element | s nextPutAll:element displayString. s space].
+	s nextPutAll:')'.
+	^ s contents
+    ].
+    ^ super displayString
+!
+
+storeOn:aStream
+    "append a printed representation of the receiver to aStream,
+     which allows reconstructing it via readFrom:.
+     Redefined to output a somewhat more user friendly string."
+
+    self isLiteral ifTrue:[
+	aStream nextPutAll:'#('.
+	self do:[:element | element storeOn:aStream. aStream space].
+	aStream nextPutAll:')'
+    ] ifFalse:[
+	super storeOn:aStream
+    ]
+
+    "
+     #(1 2 $a 'hello') storeString 
+    "
+! !
+
+!Array methodsFor:'queries'!
+
+isArray
+    "return true, if the receiver is some kind of array (or weakArray etc).
+     true is returned here"
+
+    ^ true
+!
+
+isLiteral
+    "return true, if the receiver can be used as a literal
+     (i.e. can be used in constant arrays)"
+
+    "no, subclasses of array are not"
+    self class == Array ifFalse:[^ false].
+
+    thisContext isRecursive ifTrue:[^ false].
+
+    self do:[:element |
+	element isLiteral ifFalse:[^ false]
+    ].
+    ^ true
 !
 
-addAllTo:aCollection
-    "add all elements of the receiver to aCollection.
-     return aCollection."
+refersToLiteral: aLiteral
+    self do: [ :el | 
+	el == aLiteral ifTrue:[^true].
+	el class == Array ifTrue:[
+	    (el refersToLiteral: aLiteral) ifTrue: [^true]
+	]
+    ].
+    ^ false
+
+    "
+     #(1 2 3) refersToLiteral:#foo  
+     #(1 2 3 foo bar baz) refersToLiteral:#foo 
+     #(1 2 3 (((bar foo))) bar baz) refersToLiteral:#foo  
+    "
+! !
+
+!Array methodsFor:'testing'!
+
+identityIndexOf:anElement startingAt:start
+    "search the array for anElement; return index if found, 0 otherwise
+     - reimplemented for speed"
+
+%{  /* NOCONTEXT */
+
+    REGISTER int index;
+    REGISTER OBJ el;
+    REGISTER OBJ *op;
+    REGISTER unsigned int nIndex;
+    int nInsts;
+
+    if (__isSmallInteger(start)) {
+	index = _intVal(start) - 1;
+	if (index >= 0) {
+	    nInsts = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
+	    index += nInsts;
+	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+	    el = anElement;
+	    op = & (_InstPtr(self)->i_instvars[index]);
+#if defined(UNROLL_LOOPS)
+	    {
+		unsigned int i8;
 
-    |stop "{ Class: SmallInteger }"|
+		while ((i8 = index + 8) < nIndex) {
+		    if (op[0] == el) { RETURN ( __MKSMALLINT(index + 1 - nInsts) ); }
+		    if (op[1] == el) { RETURN ( __MKSMALLINT(index + 2 - nInsts) ); }
+		    if (op[2] == el) { RETURN ( __MKSMALLINT(index + 3 - nInsts) ); }
+		    if (op[3] == el) { RETURN ( __MKSMALLINT(index + 4 - nInsts) ); }
+		    if (op[4] == el) { RETURN ( __MKSMALLINT(index + 5 - nInsts) ); }
+		    if (op[5] == el) { RETURN ( __MKSMALLINT(index + 6 - nInsts) ); }
+		    if (op[6] == el) { RETURN ( __MKSMALLINT(index + 7 - nInsts) ); }
+		    if (op[7] == el) { RETURN ( __MKSMALLINT(index + 8 - nInsts) ); }
+		    index = i8;
+		    op += 8;
+		}
+	    }
+#endif
+	    while (index++ < nIndex) {
+		if (*op++ == el) {
+		    RETURN ( __MKSMALLINT(index - nInsts) );
+		}
+	    }
+	    RETURN ( __MKSMALLINT(0) );
+	}
+    }
+%}.
+    ^ super identityIndexOf:anElement startingAt:start
+!
+
+includes:anObject
+    "return true, if the argument, anObject is contained in the array
+     - reimplemented for speed"
+
+    |element|
+
+%{  /* NOCONTEXT */
+
+    /* 
+     * first, do a quick check using ==
+     * this does not need a context or message send.
+     * In many cases this will already find a match.
+     */
+    REGISTER int index;
+    REGISTER OBJ o;
+    unsigned int nIndex;
+
+    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+    index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
+
+    /*
+     * however, the search is limited to the first 1000
+     * elements, since otherwise, we may spend too much time
+     * searching for identity if an equal value is found early
+     */
+    if (nIndex > 1000) nIndex = 1000;
+
+    o = anObject;
+#if defined(UNROLL_LOOPS)
+    {
+	unsigned int i8;
+
+	while ((i8 = index + 8) < nIndex) {
+	    if (_InstPtr(self)->i_instvars[index] == o) { RETURN ( true ); }
+	    if (_InstPtr(self)->i_instvars[index+1] == o) { RETURN ( true ); }
+	    if (_InstPtr(self)->i_instvars[index+2] == o) { RETURN ( true ); }
+	    if (_InstPtr(self)->i_instvars[index+3] == o) { RETURN ( true ); }
+	    if (_InstPtr(self)->i_instvars[index+4] == o) { RETURN ( true ); }
+	    if (_InstPtr(self)->i_instvars[index+5] == o) { RETURN ( true ); }
+	    if (_InstPtr(self)->i_instvars[index+6] == o) { RETURN ( true ); }
+	    if (_InstPtr(self)->i_instvars[index+7] == o) { RETURN ( true ); }
+	    index = i8;
+	}
+    }
+#endif
+    while (index < nIndex) {
+	if (_InstPtr(self)->i_instvars[index++] == o) {
+	    RETURN ( true );
+	}
+    }
+    if (o == nil) {
+	RETURN ( false );
+    }
+%}
+.
+%{
+    /* 
+     * then do a slow(er) check using =
+     */
+    REGISTER int index;
+    unsigned int nIndex;
+    static struct inlineCache eq = _ILC1;
 
-    stop := self size.
-    1 to:stop do:[:idx |
-	aCollection add:(self at:idx)
-    ].
-    ^ aCollection
+    /* 
+     * sorry: cannot access the stuff from above ...
+     */
+    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+    index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
+
+    while (index < nIndex) {
+	element = _InstPtr(self)->i_instvars[index++];
+	if (element != nil) {
+	    if ((*eq.ilc_func)(anObject,
+			       @symbol(=),
+			       CON_COMMA nil,&eq,
+			       element)==true) {
+		RETURN ( true );
+	    }
+	}
+    }
+%}.
+    ^ false
+!
+
+indexOf:anElement startingAt:start
+    "search the array for anElement; return index if found, 0 otherwise
+     - reimplemented for speed"
+
+    |element|
+%{
+    REGISTER int index;
+    unsigned int nIndex, nInsts;
+    static struct inlineCache eq = _ILC1;
+
+    if (__isSmallInteger(start)) {
+	index = _intVal(start) - 1;
+	if (index >= 0) {
+	    nInsts = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
+	    index += nInsts;
+	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+	    if (anElement != nil) {
+		while (index < nIndex) {
+		    element = _InstPtr(self)->i_instvars[index++];
+		    if (element != nil) {
+			if ((element == anElement) 
+			 || ((*eq.ilc_func)(anElement,
+					    @symbol(=), 
+					    CON_COMMA nil,&eq,
+					    element) == true)) {
+			    RETURN ( __MKSMALLINT(index - nInsts) );
+			}
+		    }
+		}
+	    } else {
+		/* search for nil */
+#if defined(UNROLL_LOOPS)
+		{
+		    unsigned int i8;
+
+		    while ((i8 = index + 8) < nIndex) {
+			if (_InstPtr(self)->i_instvars[index] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 1) ); }
+			if (_InstPtr(self)->i_instvars[index+1] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 2) ); }
+			if (_InstPtr(self)->i_instvars[index+2] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 3) ); }
+			if (_InstPtr(self)->i_instvars[index+3] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 4) ); }
+			if (_InstPtr(self)->i_instvars[index+4] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 5) ); }
+			if (_InstPtr(self)->i_instvars[index+5] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 6) ); }
+			if (_InstPtr(self)->i_instvars[index+6] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 7) ); }
+			if (_InstPtr(self)->i_instvars[index+7] == nil) { RETURN ( __MKSMALLINT(index - nInsts + 8) ); }
+			index = i8;
+		    }
+		}
+#endif
+
+		while (index < nIndex) {
+		    if (_InstPtr(self)->i_instvars[index++] == nil) {
+			RETURN ( __MKSMALLINT(index - nInsts) );
+		    }
+		}
+	    }
+	}
+    }
+%}.
+    ^ 0
+!
+
+identityIndexOf:anElement or:alternative 
+    "search the array for anElement or alternative; 
+     return the index of anElement if found, or the index of anAlternative,
+     if not found. If anAlternative is also not found, return 0.
+     This is a special interface for high-speed searching in an array
+     and at the same time searching for an empty slot.
+     Do not use this method for your application classes, since it is
+     not portable (i.e. other smalltalks do not offer this)"
+
+%{  /* NOCONTEXT */
+
+    REGISTER int index;
+    REGISTER OBJ o, el1, el2;
+    REGISTER OBJ *op;
+    REGISTER unsigned int nIndex;
+    int altIndex = 0;
+    int nInsts;
+
+    index = 0;
+    nInsts = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars);
+    index += nInsts;
+    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
+    el1 = anElement; el2 = alternative; 
+    op = & (_InstPtr(self)->i_instvars[index]);
+    while (index++ < nIndex) {
+	if ((o = *op++) == el1) {
+	    RETURN ( __MKSMALLINT(index - nInsts) );
+	}
+	if (o == el2) {
+	    if (altIndex == 0) {
+		altIndex = index;
+	    }
+	}
+    }
+    RETURN ( __MKSMALLINT(altIndex) );
+%}
+
+    "
+     #(1 2 3 4 5 6 7 8 9) identityIndexOf:3 or:5
+     #(1 2 0 4 5 6 7 8 9) identityIndexOf:3 or:5
+     #(1 2 0 4 5 6 7 3 9) identityIndexOf:3 or:5
+     #(1 2 3 4 5 nil 7 3 9) identityIndexOf:3 or:nil 
+     #(1 2 nil 4 5 6 7 3 9) identityIndexOf:3 or:nil  
+     #(1 2 nil 4 5 6 7 8 9) identityIndexOf:3 or:nil 
+     #() identityIndexOf:3 or:nil        
+     #(1 2) identityIndexOf:3 or:nil 
+    "
 ! !
+