Array.st
changeset 12477 0c213a90642b
parent 12452 3484164bcb38
child 13077 87f8b675848f
equal deleted inserted replaced
12476:66b5104cedc9 12477:0c213a90642b
  2095     static struct inlineCache eq = _ILC1;
  2095     static struct inlineCache eq = _ILC1;
  2096     OBJ myClass, e;
  2096     OBJ myClass, e;
  2097 
  2097 
  2098     myClass = __qClass(self);
  2098     myClass = __qClass(self);
  2099     if ( __isSmallInteger(start) ) {
  2099     if ( __isSmallInteger(start) ) {
  2100 	index = __intVal(start) - 1;
  2100         index = __intVal(start) - 1;
  2101 	if (index >= 0) {
  2101         if (index >= 0) {
  2102 	    nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2102             nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2103 	    index += nInsts;
  2103             index += nInsts;
  2104 	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2104             nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2105 
  2105 
  2106 	    e = anElement;
  2106             e = anElement;
  2107 	    if (e != nil) {
  2107             if (e != nil) {
  2108 		/*
  2108                 /*
  2109 		 * special kludge to search for a string;
  2109                  * special kludge to search for a string;
  2110 		 * this is so common, that its worth a special case
  2110                  * this is so common, that its worth a special case
  2111 		 */
  2111                  */
  2112 #define SPECIAL_STRING_OPT
  2112 #define SPECIAL_STRING_OPT
  2113 #ifdef SPECIAL_STRING_OPT
  2113 #ifdef SPECIAL_STRING_OPT
  2114 		if (__isString(e)) {
  2114                 if (__isStringLike(e)) {
  2115 		    while (index < nIndex) {
  2115                     while (index < nIndex) {
  2116 			element = __InstPtr(self)->i_instvars[index++];
  2116                         element = __InstPtr(self)->i_instvars[index++];
  2117 			if (__isNonNilObject(element)) {
  2117                         if (__isNonNilObject(element)) {
  2118 			    if (element == e) {
  2118                             if (element == e) {
  2119 				RETURN ( __mkSmallInteger(index - nInsts) );
  2119                                 RETURN ( __mkSmallInteger(index - nInsts) );
  2120 			    }
  2120                             }
  2121 			    if (__qClass(element) == @global(String)) {
  2121                             if (__qClass(element) == @global(String)) {
  2122 				if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2122                                 if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2123 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2123                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2124 				}
  2124                                 }
  2125 			    } else {
  2125                             } else {
  2126 				if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2126                                 if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2127 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2127                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2128 				}
  2128                                 }
  2129 				/*
  2129                                 /*
  2130 				 * send of #= could have lead to a GC - refetch e
  2130                                  * send of #= could have lead to a GC - refetch e
  2131 				 */
  2131                                  */
  2132 				e = anElement;
  2132                                 e = anElement;
  2133 			    }
  2133                             }
  2134 			}
  2134                         }
  2135 		    }
  2135                     }
  2136 		    RETURN (__mkSmallInteger(0));
  2136                     RETURN (__mkSmallInteger(0));
  2137 		}
  2137                 }
  2138 #endif
  2138 #endif
  2139 		if (__isSmallInteger(e)) {
  2139                 if (__isSmallInteger(e)) {
  2140 		    /* search for a small number */
  2140                     /* search for a small number */
  2141 		    while (index < nIndex) {
  2141                     while (index < nIndex) {
  2142 			element = __InstPtr(self)->i_instvars[index++];
  2142                         element = __InstPtr(self)->i_instvars[index++];
  2143 			if (element == e) {
  2143                         if (element == e) {
  2144 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2144                             RETURN ( __mkSmallInteger(index - nInsts) );
  2145 			}
  2145                         }
  2146 			if (!__isSmallInteger(element)) {
  2146                         if (!__isSmallInteger(element)) {
  2147 			    if ((*eq.ilc_func)(e,
  2147                             if ((*eq.ilc_func)(e,
  2148 						@symbol(=), 
  2148                                                 @symbol(=), 
  2149 						nil,&eq,
  2149                                                 nil,&eq,
  2150 						element) == true) {
  2150                                                 element) == true) {
  2151 				RETURN ( __mkSmallInteger(index - nInsts) );
  2151                                 RETURN ( __mkSmallInteger(index - nInsts) );
  2152 			    }
  2152                             }
  2153 			    /*
  2153                             /*
  2154 			     * send of #= could have lead to a GC - refetch e
  2154                              * send of #= could have lead to a GC - refetch e
  2155 			     */
  2155                              */
  2156 			    e = anElement;
  2156                             e = anElement;
  2157 			}
  2157                         }
  2158 		    }
  2158                     }
  2159 		    RETURN (__mkSmallInteger(0));
  2159                     RETURN (__mkSmallInteger(0));
  2160 		}
  2160                 }
  2161 
  2161 
  2162 		while (index < nIndex) {
  2162                 while (index < nIndex) {
  2163 		    element = __InstPtr(self)->i_instvars[index++];
  2163                     element = __InstPtr(self)->i_instvars[index++];
  2164 		    if (element != nil) {
  2164                     if (element != nil) {
  2165 			e = anElement;
  2165                         e = anElement;
  2166 
  2166 
  2167 			if ((element == e) 
  2167                         if ((element == e) 
  2168 			 || ((*eq.ilc_func)(e,
  2168                          || ((*eq.ilc_func)(e,
  2169 					    @symbol(=), 
  2169                                             @symbol(=), 
  2170 					    nil,&eq,
  2170                                             nil,&eq,
  2171 					    element) == true)) {
  2171                                             element) == true)) {
  2172 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2172                             RETURN ( __mkSmallInteger(index - nInsts) );
  2173 			}
  2173                         }
  2174 		    }
  2174                     }
  2175 		}
  2175                 }
  2176 	    } else {
  2176             } else {
  2177 		OBJ slf = self;
  2177                 OBJ slf = self;
  2178 
  2178 
  2179 		/* 
  2179                 /* 
  2180 		 * search for nil - do an identity-search
  2180                  * search for nil - do an identity-search
  2181 		 */
  2181                  */
  2182 #ifdef __UNROLL_LOOPS__
  2182 #ifdef __UNROLL_LOOPS__
  2183 		{
  2183                 {
  2184 		    unsigned int i8;
  2184                     unsigned int i8;
  2185 
  2185 
  2186 		    while ((i8 = index + 8) < nIndex) {
  2186                     while ((i8 = index + 8) < nIndex) {
  2187 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2187                         if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2188 			if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2188                         if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2189 			if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2189                         if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2190 			if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2190                         if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2191 			if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2191                         if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2192 			if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2192                         if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2193 			if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2193                         if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2194 			if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2194                         if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2195 			index = i8;
  2195                         index = i8;
  2196 		    }
  2196                     }
  2197 		}
  2197                 }
  2198 #endif
  2198 #endif
  2199 
  2199 
  2200 		while (index < nIndex) {
  2200                 while (index < nIndex) {
  2201 		    if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2201                     if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2202 			RETURN ( __mkSmallInteger(index - nInsts) );
  2202                         RETURN ( __mkSmallInteger(index - nInsts) );
  2203 		    }
  2203                     }
  2204 		}
  2204                 }
  2205 	    }
  2205             }
  2206 	}
  2206         }
  2207 	RETURN (__mkSmallInteger(0));
  2207         RETURN (__mkSmallInteger(0));
  2208     }
  2208     }
  2209 %}.
  2209 %}.
  2210     ^ super indexOf:anElement startingAt:start
  2210     ^ super indexOf:anElement startingAt:start
  2211 !
  2211 !
  2212 
  2212 
  2223     static struct inlineCache eq = _ILC1;
  2223     static struct inlineCache eq = _ILC1;
  2224     OBJ myClass, e;
  2224     OBJ myClass, e;
  2225 
  2225 
  2226     myClass = __qClass(self);
  2226     myClass = __qClass(self);
  2227     if ( __bothSmallInteger(start, stop) ) {
  2227     if ( __bothSmallInteger(start, stop) ) {
  2228 	index = __intVal(start) - 1;
  2228         index = __intVal(start) - 1;
  2229 	if (index >= 0) {
  2229         if (index >= 0) {
  2230 	    nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2230             nInsts = __intVal(__ClassInstPtr(myClass)->c_ninstvars);
  2231 	    index += nInsts;
  2231             index += nInsts;
  2232 	    lastIndex = nInsts + __intVal(stop);
  2232             lastIndex = nInsts + __intVal(stop);
  2233 	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2233             nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2234 	    if (nIndex < lastIndex) {
  2234             if (nIndex < lastIndex) {
  2235 		lastIndex = nIndex;
  2235                 lastIndex = nIndex;
  2236 	    }
  2236             }
  2237 
  2237 
  2238 	    e = anElement;
  2238             e = anElement;
  2239 
  2239 
  2240 	    if (e != nil) {
  2240             if (e != nil) {
  2241 		/*
  2241                 /*
  2242 		 * special kludge to search for a string;
  2242                  * special kludge to search for a string;
  2243 		 * this is so common, that its worth a special case
  2243                  * this is so common, that its worth a special case
  2244 		 */
  2244                  */
  2245 #define SPECIAL_STRING_OPT
  2245 #define SPECIAL_STRING_OPT
  2246 #ifdef SPECIAL_STRING_OPT
  2246 #ifdef SPECIAL_STRING_OPT
  2247 		if (__isString(e)) {
  2247                 if (__isStringLike(e)) {
  2248 		    while (index < lastIndex) {
  2248                     while (index < lastIndex) {
  2249 			element = __InstPtr(self)->i_instvars[index++];
  2249                         element = __InstPtr(self)->i_instvars[index++];
  2250 			if (__isNonNilObject(element)) {
  2250                         if (__isNonNilObject(element)) {
  2251 			    if (element == e) {
  2251                             if (element == e) {
  2252 				RETURN ( __mkSmallInteger(index - nInsts) );
  2252                                 RETURN ( __mkSmallInteger(index - nInsts) );
  2253 			    }
  2253                             }
  2254 			    if (__qClass(element) == @global(String)) {
  2254                             if (__qClass(element) == @global(String)) {
  2255 				if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2255                                 if (strcmp(__stringVal(e), __stringVal(element)) == 0) {
  2256 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2256                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2257 				}
  2257                                 }
  2258 			    } else {
  2258                             } else {
  2259 				if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2259                                 if ((*eq.ilc_func)(e, @symbol(=), nil,&eq, element) == true) {
  2260 				    RETURN ( __mkSmallInteger(index - nInsts) );
  2260                                     RETURN ( __mkSmallInteger(index - nInsts) );
  2261 				}
  2261                                 }
  2262 				/*
  2262                                 /*
  2263 				 * send of #= could have lead to a GC - refetch e
  2263                                  * send of #= could have lead to a GC - refetch e
  2264 				 */
  2264                                  */
  2265 				e = anElement;
  2265                                 e = anElement;
  2266 			    }
  2266                             }
  2267 			}
  2267                         }
  2268 		    }
  2268                     }
  2269 		    RETURN (__mkSmallInteger(0));
  2269                     RETURN (__mkSmallInteger(0));
  2270 		}
  2270                 }
  2271 #endif
  2271 #endif
  2272 		if (__isSmallInteger(e)) {
  2272                 if (__isSmallInteger(e)) {
  2273 		    /* search for a small number */
  2273                     /* search for a small number */
  2274 		    while (index < lastIndex) {
  2274                     while (index < lastIndex) {
  2275 			element = __InstPtr(self)->i_instvars[index++];
  2275                         element = __InstPtr(self)->i_instvars[index++];
  2276 			if (element == e) {
  2276                         if (element == e) {
  2277 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2277                             RETURN ( __mkSmallInteger(index - nInsts) );
  2278 			}
  2278                         }
  2279 			if (!__isSmallInteger(element)) {
  2279                         if (!__isSmallInteger(element)) {
  2280 			    if ((*eq.ilc_func)(e,
  2280                             if ((*eq.ilc_func)(e,
  2281 						@symbol(=), 
  2281                                                 @symbol(=), 
  2282 						nil,&eq,
  2282                                                 nil,&eq,
  2283 						element) == true) {
  2283                                                 element) == true) {
  2284 				RETURN ( __mkSmallInteger(index - nInsts) );
  2284                                 RETURN ( __mkSmallInteger(index - nInsts) );
  2285 			    }
  2285                             }
  2286 			    /*
  2286                             /*
  2287 			     * send of #= could have lead to a GC - refetch e
  2287                              * send of #= could have lead to a GC - refetch e
  2288 			     */
  2288                              */
  2289 			    e = anElement;
  2289                             e = anElement;
  2290 			}
  2290                         }
  2291 		    }
  2291                     }
  2292 		    RETURN (__mkSmallInteger(0));
  2292                     RETURN (__mkSmallInteger(0));
  2293 		}
  2293                 }
  2294 
  2294 
  2295 		while (index < lastIndex) {
  2295                 while (index < lastIndex) {
  2296 		    element = __InstPtr(self)->i_instvars[index++];
  2296                     element = __InstPtr(self)->i_instvars[index++];
  2297 		    if (element != nil) {
  2297                     if (element != nil) {
  2298 			e = anElement;
  2298                         e = anElement;
  2299 			if ((element == e) 
  2299                         if ((element == e) 
  2300 			 || ((*eq.ilc_func)(e,
  2300                          || ((*eq.ilc_func)(e,
  2301 					    @symbol(=), 
  2301                                             @symbol(=), 
  2302 					    nil,&eq,
  2302                                             nil,&eq,
  2303 					    element) == true)) {
  2303                                             element) == true)) {
  2304 			    RETURN ( __mkSmallInteger(index - nInsts) );
  2304                             RETURN ( __mkSmallInteger(index - nInsts) );
  2305 			}
  2305                         }
  2306 		    }
  2306                     }
  2307 		}
  2307                 }
  2308 	    } else {
  2308             } else {
  2309 		OBJ slf = self;
  2309                 OBJ slf = self;
  2310 
  2310 
  2311 		/* 
  2311                 /* 
  2312 		 * search for nil - do an identity-search
  2312                  * search for nil - do an identity-search
  2313 		 */
  2313                  */
  2314 #ifdef __UNROLL_LOOPS__
  2314 #ifdef __UNROLL_LOOPS__
  2315 		{
  2315                 {
  2316 		    unsigned int i8;
  2316                     unsigned int i8;
  2317 
  2317 
  2318 		    while ((i8 = index + 8) < lastIndex) {
  2318                     while ((i8 = index + 8) < lastIndex) {
  2319 			if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2319                         if (__InstPtr(slf)->i_instvars[index] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 1) ); }
  2320 			if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2320                         if (__InstPtr(slf)->i_instvars[index+1] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 2) ); }
  2321 			if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2321                         if (__InstPtr(slf)->i_instvars[index+2] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 3) ); }
  2322 			if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2322                         if (__InstPtr(slf)->i_instvars[index+3] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 4) ); }
  2323 			if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2323                         if (__InstPtr(slf)->i_instvars[index+4] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 5) ); }
  2324 			if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2324                         if (__InstPtr(slf)->i_instvars[index+5] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 6) ); }
  2325 			if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2325                         if (__InstPtr(slf)->i_instvars[index+6] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 7) ); }
  2326 			if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2326                         if (__InstPtr(slf)->i_instvars[index+7] == nil) { RETURN ( __mkSmallInteger(index - nInsts + 8) ); }
  2327 			index = i8;
  2327                         index = i8;
  2328 		    }
  2328                     }
  2329 		}
  2329                 }
  2330 #endif
  2330 #endif
  2331 		while (index < lastIndex) {
  2331                 while (index < lastIndex) {
  2332 		    if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2332                     if (__InstPtr(slf)->i_instvars[index++] == nil) {
  2333 			RETURN ( __mkSmallInteger(index - nInsts) );
  2333                         RETURN ( __mkSmallInteger(index - nInsts) );
  2334 		    }
  2334                     }
  2335 		}
  2335                 }
  2336 	    }
  2336             }
  2337 	}
  2337         }
  2338 	RETURN (__mkSmallInteger(0));
  2338         RETURN (__mkSmallInteger(0));
  2339     }
  2339     }
  2340 %}.
  2340 %}.
  2341     ^ super indexOf:anElement startingAt:start endingAt:stop
  2341     ^ super indexOf:anElement startingAt:start endingAt:stop
  2342 ! !
  2342 ! !
  2343 
  2343 
  2551 ! !
  2551 ! !
  2552 
  2552 
  2553 !Array class methodsFor:'documentation'!
  2553 !Array class methodsFor:'documentation'!
  2554 
  2554 
  2555 version
  2555 version
  2556     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.147 2009-11-05 14:33:13 cg Exp $'
  2556     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.148 2009-11-05 16:25:19 stefan Exp $'
  2557 !
  2557 !
  2558 
  2558 
  2559 version_CVS
  2559 version_CVS
  2560     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.147 2009-11-05 14:33:13 cg Exp $'
  2560     ^ '$Header: /cvs/stx/stx/libbasic/Array.st,v 1.148 2009-11-05 16:25:19 stefan Exp $'
  2561 ! !
  2561 ! !