Array.st
changeset 21623 0fd2de531f9a
parent 21523 b800e9cb0e84
child 21793 9c5b2a6200f9
equal deleted inserted replaced
21622:0feeeed4f432 21623:0fd2de531f9a
   519 
   519 
   520 !Array methodsFor:'copying'!
   520 !Array methodsFor:'copying'!
   521 
   521 
   522 , aCollection
   522 , aCollection
   523 %{
   523 %{
   524     if (__isArray(aCollection)) {
   524     if (__isArrayLike(aCollection)) {
   525 	if (__isArray(self)) {
   525 	if (__isArrayLike(self)) {
   526 	    OBJ newArray;
   526 	    OBJ newArray;
   527 	    int mySize = __arraySize(self);
   527 	    int mySize = __arraySize(self);
   528 	    int otherSize = __arraySize(aCollection);
   528 	    int otherSize = __arraySize(aCollection);
   529 	    REGISTER OBJ src;
   529 	    REGISTER OBJ src;
   530 	    int srcIdx, dstIdx;
   530 	    int srcIdx, dstIdx;
  2021     REGISTER OBJ *op;
  2021     REGISTER OBJ *op;
  2022     REGISTER unsigned INT nIndex;
  2022     REGISTER unsigned INT nIndex;
  2023     INT nInsts;
  2023     INT nInsts;
  2024 
  2024 
  2025     if (__isSmallInteger(start)) {
  2025     if (__isSmallInteger(start)) {
  2026         index = __intVal(start) - 1;
  2026 	index = __intVal(start) - 1;
  2027         if (index >= 0) {
  2027 	if (index >= 0) {
  2028             nInsts = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  2028 	    nInsts = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  2029             index += nInsts;
  2029 	    index += nInsts;
  2030             nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2030 	    nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2031             el = anElement;
  2031 	    el = anElement;
  2032             op = & (__InstPtr(self)->i_instvars[index]);
  2032 	    op = & (__InstPtr(self)->i_instvars[index]);
  2033 
  2033 
  2034 #if defined(memsrch4)
  2034 #if defined(memsrch4)
  2035             if (index < nIndex) {
  2035 	    if (index < nIndex) {
  2036                 OBJ *p;
  2036 		OBJ *p;
  2037 
  2037 
  2038                 p = memsrch4(op, (INT)el, (nIndex - index));
  2038 		p = memsrch4(op, (INT)el, (nIndex - index));
  2039                 if (p) {
  2039 		if (p) {
  2040                     index += (p - op + 1);
  2040 		    index += (p - op + 1);
  2041                     RETURN ( __mkSmallInteger(index) );
  2041 		    RETURN ( __mkSmallInteger(index) );
  2042                 }
  2042 		}
  2043             }
  2043 	    }
  2044 #else
  2044 #else
  2045 
  2045 
  2046 # ifdef __UNROLL_LOOPS__
  2046 # ifdef __UNROLL_LOOPS__
  2047             {
  2047 	    {
  2048                 /*
  2048 		/*
  2049                  * don't argue about those gotos below - they speed up that thing by 30%;
  2049 		 * don't argue about those gotos below - they speed up that thing by 30%;
  2050                  * its better to exit the loops below with a goto,
  2050 		 * its better to exit the loops below with a goto,
  2051                  * since the generated code will then be:
  2051 		 * since the generated code will then be:
  2052                  *   compare
  2052 		 *   compare
  2053                  *   branch-on-equal found
  2053 		 *   branch-on-equal found
  2054                  *
  2054 		 *
  2055                  * otherwise (with ret as if-statement), we get:
  2055 		 * otherwise (with ret as if-statement), we get:
  2056                  *   compare
  2056 		 *   compare
  2057                  *   branch-on-not-equal skipLabel
  2057 		 *   branch-on-not-equal skipLabel
  2058                  *   move-to-ret-register true
  2058 		 *   move-to-ret-register true
  2059                  *   goto ret-label
  2059 		 *   goto ret-label
  2060                  * skipLabel
  2060 		 * skipLabel
  2061                  *
  2061 		 *
  2062                  * therefore, WITH the so-much-blamed goto, we only branch
  2062 		 * therefore, WITH the so-much-blamed goto, we only branch
  2063                  * when found; without the goto, we branch always.
  2063 		 * when found; without the goto, we branch always.
  2064                  * Pipelined CPUs do usually not like taken branches.
  2064 		 * Pipelined CPUs do usually not like taken branches.
  2065                  */
  2065 		 */
  2066 
  2066 
  2067                 unsigned INT i8;
  2067 		unsigned INT i8;
  2068 
  2068 
  2069                 while ((i8 = index + 8) < nIndex) {
  2069 		while ((i8 = index + 8) < nIndex) {
  2070                     if (op[0] == el) goto found1;
  2070 		    if (op[0] == el) goto found1;
  2071                     if (op[1] == el) goto found2;
  2071 		    if (op[1] == el) goto found2;
  2072                     if (op[2] == el) goto found3;
  2072 		    if (op[2] == el) goto found3;
  2073                     if (op[3] == el) goto found4;
  2073 		    if (op[3] == el) goto found4;
  2074                     if (op[4] == el) goto found5;
  2074 		    if (op[4] == el) goto found5;
  2075                     if (op[5] == el) goto found6;
  2075 		    if (op[5] == el) goto found6;
  2076                     if (op[6] == el) goto found7;
  2076 		    if (op[6] == el) goto found7;
  2077                     if (op[7] == el) goto found8;
  2077 		    if (op[7] == el) goto found8;
  2078                     index = i8;
  2078 		    index = i8;
  2079                     op += 8;
  2079 		    op += 8;
  2080                 }
  2080 		}
  2081                 if (0) {
  2081 		if (0) {
  2082                     found1:
  2082 		    found1:
  2083                         RETURN ( __mkSmallInteger(index + 1 - nInsts) );
  2083 			RETURN ( __mkSmallInteger(index + 1 - nInsts) );
  2084                     found2:
  2084 		    found2:
  2085                         RETURN ( __mkSmallInteger(index + 2 - nInsts) );
  2085 			RETURN ( __mkSmallInteger(index + 2 - nInsts) );
  2086                     found3:
  2086 		    found3:
  2087                         RETURN ( __mkSmallInteger(index + 3 - nInsts) );
  2087 			RETURN ( __mkSmallInteger(index + 3 - nInsts) );
  2088                     found4:
  2088 		    found4:
  2089                         RETURN ( __mkSmallInteger(index + 4 - nInsts) );
  2089 			RETURN ( __mkSmallInteger(index + 4 - nInsts) );
  2090                     found5:
  2090 		    found5:
  2091                         RETURN ( __mkSmallInteger(index + 5 - nInsts) );
  2091 			RETURN ( __mkSmallInteger(index + 5 - nInsts) );
  2092                     found6:
  2092 		    found6:
  2093                         RETURN ( __mkSmallInteger(index + 6 - nInsts) );
  2093 			RETURN ( __mkSmallInteger(index + 6 - nInsts) );
  2094                     found7:
  2094 		    found7:
  2095                         RETURN ( __mkSmallInteger(index + 7 - nInsts) );
  2095 			RETURN ( __mkSmallInteger(index + 7 - nInsts) );
  2096                     found8:
  2096 		    found8:
  2097                         RETURN ( __mkSmallInteger(index + 8 - nInsts) );
  2097 			RETURN ( __mkSmallInteger(index + 8 - nInsts) );
  2098                 }
  2098 		}
  2099             }
  2099 	    }
  2100 # endif /* __UNROLLED_LOOPS__ */
  2100 # endif /* __UNROLLED_LOOPS__ */
  2101 
  2101 
  2102             while (index++ < nIndex) {
  2102 	    while (index++ < nIndex) {
  2103                 if (*op++ == el) goto found0;
  2103 		if (*op++ == el) goto found0;
  2104             }
  2104 	    }
  2105 
  2105 
  2106             if (0) {
  2106 	    if (0) {
  2107                 found0:
  2107 		found0:
  2108                     RETURN ( __mkSmallInteger(index - nInsts) );
  2108 		    RETURN ( __mkSmallInteger(index - nInsts) );
  2109             }
  2109 	    }
  2110 #endif /* no memsrch */
  2110 #endif /* no memsrch */
  2111         }
  2111 	}
  2112         RETURN ( __mkSmallInteger(0) );
  2112 	RETURN ( __mkSmallInteger(0) );
  2113     }
  2113     }
  2114 %}.
  2114 %}.
  2115     ^ super identityIndexOf:anElement startingAt:start
  2115     ^ super identityIndexOf:anElement startingAt:start
  2116 !
  2116 !
  2117 
  2117 
  2517      * elements, since otherwise, we may spend too much time
  2517      * elements, since otherwise, we may spend too much time
  2518      * searching for identity if an equal value is found early
  2518      * searching for identity if an equal value is found early
  2519      * (except if searching for nil - there is no need for equal compare ...)
  2519      * (except if searching for nil - there is no need for equal compare ...)
  2520      */
  2520      */
  2521     if (nIndex > 500) {
  2521     if (nIndex > 500) {
  2522         if (o != nil)
  2522 	if (o != nil)
  2523             nIndex = 500;
  2523 	    nIndex = 500;
  2524     }
  2524     }
  2525 
  2525 
  2526 # ifdef memsrch4
  2526 # ifdef memsrch4
  2527     if (index < nIndex) {
  2527     if (index < nIndex) {
  2528         OBJ *p;
  2528 	OBJ *p;
  2529 
  2529 
  2530         p = memsrch4(&(__InstPtr(self)->i_instvars[index]), (INT)o, (nIndex - index));
  2530 	p = memsrch4(&(__InstPtr(self)->i_instvars[index]), (INT)o, (nIndex - index));
  2531         if (p) {
  2531 	if (p) {
  2532             RETURN ( true );
  2532 	    RETURN ( true );
  2533         }
  2533 	}
  2534     }
  2534     }
  2535 
  2535 
  2536 # else
  2536 # else
  2537     /*
  2537     /*
  2538      * don't argue those gotos below - they speed up that thing by 30%
  2538      * don't argue those gotos below - they speed up that thing by 30%
  2554      * also, all branches are forward, which are usually predicted
  2554      * also, all branches are forward, which are usually predicted
  2555      * as not taken.
  2555      * as not taken.
  2556      */
  2556      */
  2557 #  ifdef __UNROLL_LOOPS__
  2557 #  ifdef __UNROLL_LOOPS__
  2558     {
  2558     {
  2559         unsigned INT i8;
  2559 	unsigned INT i8;
  2560         REGISTER OBJ slf = self;
  2560 	REGISTER OBJ slf = self;
  2561 
  2561 
  2562         while ((i8 = index + 8) < nIndex) {
  2562 	while ((i8 = index + 8) < nIndex) {
  2563             if (__InstPtr(slf)->i_instvars[index] == o) goto found;
  2563 	    if (__InstPtr(slf)->i_instvars[index] == o) goto found;
  2564             if (__InstPtr(slf)->i_instvars[index+1] == o) goto found;
  2564 	    if (__InstPtr(slf)->i_instvars[index+1] == o) goto found;
  2565             if (__InstPtr(slf)->i_instvars[index+2] == o) goto found;
  2565 	    if (__InstPtr(slf)->i_instvars[index+2] == o) goto found;
  2566             if (__InstPtr(slf)->i_instvars[index+3] == o) goto found;
  2566 	    if (__InstPtr(slf)->i_instvars[index+3] == o) goto found;
  2567             if (__InstPtr(slf)->i_instvars[index+4] == o) goto found;
  2567 	    if (__InstPtr(slf)->i_instvars[index+4] == o) goto found;
  2568             if (__InstPtr(slf)->i_instvars[index+5] == o) goto found;
  2568 	    if (__InstPtr(slf)->i_instvars[index+5] == o) goto found;
  2569             if (__InstPtr(slf)->i_instvars[index+6] == o) goto found;
  2569 	    if (__InstPtr(slf)->i_instvars[index+6] == o) goto found;
  2570             if (__InstPtr(slf)->i_instvars[index+7] == o) goto found;
  2570 	    if (__InstPtr(slf)->i_instvars[index+7] == o) goto found;
  2571             index = i8;
  2571 	    index = i8;
  2572         }
  2572 	}
  2573     }
  2573     }
  2574 #  endif /* __UNROLL_LOOPS__ */
  2574 #  endif /* __UNROLL_LOOPS__ */
  2575 
  2575 
  2576     while (index < nIndex) {
  2576     while (index < nIndex) {
  2577         if (__InstPtr(self)->i_instvars[index++] == o) goto found;
  2577 	if (__InstPtr(self)->i_instvars[index++] == o) goto found;
  2578     }
  2578     }
  2579     if (0) {
  2579     if (0) {
  2580         found:
  2580 	found:
  2581             RETURN (true);
  2581 	    RETURN (true);
  2582     }
  2582     }
  2583 
  2583 
  2584 # endif /* no memsrch */
  2584 # endif /* no memsrch */
  2585 
  2585 
  2586     if (o == nil) {
  2586     if (o == nil) {
  2587         RETURN ( false );
  2587 	RETURN ( false );
  2588     }
  2588     }
  2589 %}.
  2589 %}.
  2590 
  2590 
  2591 %{
  2591 %{
  2592     REGISTER INT index;
  2592     REGISTER INT index;
  2603      */
  2603      */
  2604     nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2604     nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE);
  2605     index = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  2605     index = __intVal(__ClassInstPtr(__qClass(self))->c_ninstvars);
  2606 
  2606 
  2607     while (index < nIndex) {
  2607     while (index < nIndex) {
  2608         element = __InstPtr(self)->i_instvars[index++];
  2608 	element = __InstPtr(self)->i_instvars[index++];
  2609         if (element != nil) {
  2609 	if (element != nil) {
  2610             if ((*eq.ilc_func)(anObject,
  2610 	    if ((*eq.ilc_func)(anObject,
  2611                                @symbol(=),
  2611 			       @symbol(=),
  2612                                nil,&eq,
  2612 			       nil,&eq,
  2613                                element)==true) {
  2613 			       element)==true) {
  2614                 RETURN ( true );
  2614 		RETURN ( true );
  2615             }
  2615 	    }
  2616         }
  2616 	}
  2617     }
  2617     }
  2618     RETURN (false);
  2618     RETURN (false);
  2619 %}.
  2619 %}.
  2620     ^ super includes:anObject
  2620     ^ super includes:anObject
  2621 !
  2621 !
  2645     "return true if the receiver contains no elements.
  2645     "return true if the receiver contains no elements.
  2646      Reimplemented here for performance."
  2646      Reimplemented here for performance."
  2647 
  2647 
  2648 %{  /* NOCONTEXT */
  2648 %{  /* NOCONTEXT */
  2649     if (__isArrayLike(self)) {
  2649     if (__isArrayLike(self)) {
  2650         RETURN ( (__arraySize(self) == 0) ? true : false);
  2650 	RETURN ( (__arraySize(self) == 0) ? true : false);
  2651     }
  2651     }
  2652 %}.
  2652 %}.
  2653     ^ self size == 0
  2653     ^ self size == 0
  2654 
  2654 
  2655     "Modified: / 16-02-2017 / 14:58:48 / stefan"
  2655     "Modified: / 16-02-2017 / 14:58:48 / stefan"
  2659     "return true if the receiver contains no elements.
  2659     "return true if the receiver contains no elements.
  2660      Reimplemented here for performance."
  2660      Reimplemented here for performance."
  2661 
  2661 
  2662 %{  /* NOCONTEXT */
  2662 %{  /* NOCONTEXT */
  2663     if (__isArrayLike(self)) {
  2663     if (__isArrayLike(self)) {
  2664         RETURN ( (__arraySize(self) == 0) ? true : false);
  2664 	RETURN ( (__arraySize(self) == 0) ? true : false);
  2665     }
  2665     }
  2666 %}.
  2666 %}.
  2667     ^ self size == 0
  2667     ^ self size == 0
  2668 
  2668 
  2669     "Created: / 22-02-2017 / 14:09:13 / stefan"
  2669     "Created: / 22-02-2017 / 14:09:13 / stefan"
  2691     "return true if the receiver contains elements.
  2691     "return true if the receiver contains elements.
  2692      Reimplemented here for performance."
  2692      Reimplemented here for performance."
  2693 
  2693 
  2694 %{  /* NOCONTEXT */
  2694 %{  /* NOCONTEXT */
  2695     if (__isArrayLike(self)) {
  2695     if (__isArrayLike(self)) {
  2696         RETURN ( (__arraySize(self) != 0) ? true : false);
  2696 	RETURN ( (__arraySize(self) != 0) ? true : false);
  2697     }
  2697     }
  2698 %}.
  2698 %}.
  2699     ^ self size ~~ 0
  2699     ^ self size ~~ 0
  2700 
  2700 
  2701     "Modified: / 16-02-2017 / 14:59:28 / stefan"
  2701     "Modified: / 16-02-2017 / 14:59:28 / stefan"
  2705     "return true if the receiver contains elements.
  2705     "return true if the receiver contains elements.
  2706      Reimplemented here for performance."
  2706      Reimplemented here for performance."
  2707 
  2707 
  2708 %{  /* NOCONTEXT */
  2708 %{  /* NOCONTEXT */
  2709     if (__isArrayLike(self)) {
  2709     if (__isArrayLike(self)) {
  2710         RETURN ( (__arraySize(self) != 0) ? true : false);
  2710 	RETURN ( (__arraySize(self) != 0) ? true : false);
  2711     }
  2711     }
  2712 %}.
  2712 %}.
  2713     ^ self size ~~ 0
  2713     ^ self size ~~ 0
  2714 
  2714 
  2715     "Created: / 22-02-2017 / 14:09:05 / stefan"
  2715     "Created: / 22-02-2017 / 14:09:05 / stefan"
  2732 !
  2732 !
  2733 
  2733 
  2734 version_CVS
  2734 version_CVS
  2735     ^ '$Header$'
  2735     ^ '$Header$'
  2736 ! !
  2736 ! !
  2737