| /* $Header$ |
| * |
| * Copyright (c) 1989, Larry Wall |
| * |
| * You may distribute under the terms of the GNU General Public License |
| * as specified in the README file that comes with the perl 3.0 kit. |
| * |
| * $Log$ |
| * Revision 1.2 2004/09/01 14:33:24 criswell |
| * Migrating test suite out of the source tree. |
| * |
| * Revision 1.1 2004/02/17 22:21:15 criswell |
| * Initial commit of the perl Malloc Benchmark. I've cheated a little by |
| * generating the yacc output files and committing them directly, but it was |
| * easier than disabling the Bison Voodoo that gets executed by default. |
| * |
| * Revision 4.0 91/03/20 01:03:32 lwall |
| * 4.0 baseline. |
| * |
| */ |
| |
| #include "EXTERN.h" |
| #include "perl.h" |
| |
| STR * |
| afetch(ar,key,lval) |
| register ARRAY *ar; |
| int key; |
| int lval; |
| { |
| STR *str; |
| |
| if (key < 0 || key > ar->ary_fill) { |
| if (lval && key >= 0) { |
| if (ar->ary_flags & ARF_REAL) |
| str = Str_new(5,0); |
| else |
| str = str_mortal(&str_undef); |
| (void)astore(ar,key,str); |
| return str; |
| } |
| else |
| return &str_undef; |
| } |
| if (!ar->ary_array[key]) { |
| if (lval) { |
| str = Str_new(6,0); |
| (void)astore(ar,key,str); |
| return str; |
| } |
| return &str_undef; |
| } |
| return ar->ary_array[key]; |
| } |
| |
| bool |
| astore(ar,key,val) |
| register ARRAY *ar; |
| int key; |
| STR *val; |
| { |
| int retval; |
| |
| if (key < 0) |
| return FALSE; |
| if (key > ar->ary_max) { |
| int newmax; |
| |
| if (ar->ary_alloc != ar->ary_array) { |
| retval = ar->ary_array - ar->ary_alloc; |
| Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*); |
| Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*); |
| ar->ary_max += retval; |
| ar->ary_array -= retval; |
| if (key > ar->ary_max - 10) { |
| newmax = key + ar->ary_max; |
| goto resize; |
| } |
| } |
| else { |
| if (ar->ary_alloc) { |
| newmax = key + ar->ary_max / 5; |
| resize: |
| Renew(ar->ary_alloc,newmax+1, STR*); |
| Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*); |
| } |
| else { |
| newmax = key < 4 ? 4 : key; |
| Newz(2,ar->ary_alloc, newmax+1, STR*); |
| } |
| ar->ary_array = ar->ary_alloc; |
| ar->ary_max = newmax; |
| } |
| } |
| if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) { |
| while (++ar->ary_fill < key) { |
| if (ar->ary_array[ar->ary_fill] != Nullstr) { |
| str_free(ar->ary_array[ar->ary_fill]); |
| ar->ary_array[ar->ary_fill] = Nullstr; |
| } |
| } |
| } |
| retval = (ar->ary_array[key] != Nullstr); |
| if (retval && (ar->ary_flags & ARF_REAL)) |
| str_free(ar->ary_array[key]); |
| ar->ary_array[key] = val; |
| return retval; |
| } |
| |
| ARRAY * |
| anew(stab) |
| STAB *stab; |
| { |
| register ARRAY *ar; |
| |
| New(1,ar,1,ARRAY); |
| ar->ary_magic = Str_new(7,0); |
| ar->ary_alloc = ar->ary_array = 0; |
| str_magic(ar->ary_magic, stab, '#', Nullch, 0); |
| ar->ary_max = ar->ary_fill = -1; |
| ar->ary_flags = ARF_REAL; |
| return ar; |
| } |
| |
| ARRAY * |
| afake(stab,size,strp) |
| STAB *stab; |
| register int size; |
| register STR **strp; |
| { |
| register ARRAY *ar; |
| |
| New(3,ar,1,ARRAY); |
| New(4,ar->ary_alloc,size+1,STR*); |
| Copy(strp,ar->ary_alloc,size,STR*); |
| ar->ary_array = ar->ary_alloc; |
| ar->ary_magic = Str_new(8,0); |
| str_magic(ar->ary_magic, stab, '#', Nullch, 0); |
| ar->ary_fill = size - 1; |
| ar->ary_max = size - 1; |
| ar->ary_flags = 0; |
| while (size--) { |
| (*strp++)->str_pok &= ~SP_TEMP; |
| } |
| return ar; |
| } |
| |
| void |
| aclear(ar) |
| register ARRAY *ar; |
| { |
| register int key; |
| |
| if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0) |
| return; |
| if (key = ar->ary_array - ar->ary_alloc) { |
| ar->ary_max += key; |
| ar->ary_array -= key; |
| } |
| for (key = 0; key <= ar->ary_max; key++) |
| str_free(ar->ary_array[key]); |
| ar->ary_fill = -1; |
| Zero(ar->ary_array, ar->ary_max+1, STR*); |
| } |
| |
| void |
| afree(ar) |
| register ARRAY *ar; |
| { |
| register int key; |
| |
| if (!ar) |
| return; |
| if (key = ar->ary_array - ar->ary_alloc) { |
| ar->ary_max += key; |
| ar->ary_array -= key; |
| } |
| if (ar->ary_flags & ARF_REAL) { |
| for (key = 0; key <= ar->ary_max; key++) |
| str_free(ar->ary_array[key]); |
| } |
| str_free(ar->ary_magic); |
| Safefree(ar->ary_alloc); |
| Safefree(ar); |
| } |
| |
| bool |
| apush(ar,val) |
| register ARRAY *ar; |
| STR *val; |
| { |
| return astore(ar,++(ar->ary_fill),val); |
| } |
| |
| STR * |
| apop(ar) |
| register ARRAY *ar; |
| { |
| STR *retval; |
| |
| if (ar->ary_fill < 0) |
| return Nullstr; |
| retval = ar->ary_array[ar->ary_fill]; |
| ar->ary_array[ar->ary_fill--] = Nullstr; |
| return retval; |
| } |
| |
| aunshift(ar,num) |
| register ARRAY *ar; |
| register int num; |
| { |
| register int i; |
| register STR **sstr,**dstr; |
| |
| if (num <= 0) |
| return; |
| if (ar->ary_array - ar->ary_alloc >= num) { |
| ar->ary_max += num; |
| ar->ary_fill += num; |
| while (num--) |
| *--ar->ary_array = Nullstr; |
| } |
| else { |
| (void)astore(ar,ar->ary_fill+num,(STR*)0); /* maybe extend array */ |
| dstr = ar->ary_array + ar->ary_fill; |
| sstr = dstr - num; |
| #ifdef BUGGY_MSC5 |
| # pragma loop_opt(off) /* don't loop-optimize the following code */ |
| #endif /* BUGGY_MSC5 */ |
| for (i = ar->ary_fill; i >= 0; i--) { |
| *dstr-- = *sstr--; |
| #ifdef BUGGY_MSC5 |
| # pragma loop_opt() /* loop-optimization back to command-line setting */ |
| #endif /* BUGGY_MSC5 */ |
| } |
| Zero(ar->ary_array, num, STR*); |
| } |
| } |
| |
| STR * |
| ashift(ar) |
| register ARRAY *ar; |
| { |
| STR *retval; |
| |
| if (ar->ary_fill < 0) |
| return Nullstr; |
| retval = *ar->ary_array; |
| *(ar->ary_array++) = Nullstr; |
| ar->ary_max--; |
| ar->ary_fill--; |
| return retval; |
| } |
| |
| int |
| alen(ar) |
| register ARRAY *ar; |
| { |
| return ar->ary_fill; |
| } |
| |
| afill(ar, fill) |
| register ARRAY *ar; |
| int fill; |
| { |
| if (fill < 0) |
| fill = -1; |
| if (fill <= ar->ary_max) |
| ar->ary_fill = fill; |
| else |
| (void)astore(ar,fill,Nullstr); |
| } |