Mercurial > hg > xemacs-beta
diff src/dynarr.c @ 5125:b5df3737028a ben-lisp-object
merge
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 24 Feb 2010 01:58:04 -0600 |
parents | d1247f3cc363 838630c0734f |
children | 2a462149bd6a |
line wrap: on
line diff
--- a/src/dynarr.c Wed Jan 20 07:05:57 2010 -0600 +++ b/src/dynarr.c Wed Feb 24 01:58:04 2010 -0600 @@ -1,6 +1,6 @@ /* Support for dynamic arrays. Copyright (C) 1993 Sun Microsystems, Inc. - Copyright (C) 2002, 2003, 2004 Ben Wing. + Copyright (C) 2002, 2003, 2004, 2005, 2010 Ben Wing. This file is part of XEmacs. @@ -98,7 +98,8 @@ int Dynarr_largest(d) [MACRO] Return the maximum value that Dynarr_length(d) would - ever have returned. + ever have returned. This is used esp. in the redisplay code, + which reuses dynarrs for performance reasons. type Dynarr_at(d, i) [MACRO] Return the element at the specified index (no bounds checking @@ -126,6 +127,27 @@ #include <config.h> #include "lisp.h" +static const struct memory_description const_Ascbyte_ptr_description_1[] = { + { XD_ASCII_STRING, 0 }, + { XD_END } +}; + +const struct sized_memory_description const_Ascbyte_ptr_description = { + sizeof (const Ascbyte *), + const_Ascbyte_ptr_description_1 +}; + +static const struct memory_description const_Ascbyte_ptr_dynarr_description_1[] = { + XD_DYNARR_DESC (const_Ascbyte_ptr_dynarr, &const_Ascbyte_ptr_description), + { XD_END } +}; + +const struct sized_memory_description const_Ascbyte_ptr_dynarr_description = { + sizeof (const_Ascbyte_ptr_dynarr), + const_Ascbyte_ptr_dynarr_description_1 +}; + + static int Dynarr_min_size = 8; static void @@ -135,7 +157,8 @@ { void *new_base = malloc (new_size * dy->elsize); memcpy (new_base, dy->base, - (dy->max < new_size ? dy->max : new_size) * dy->elsize); + (Dynarr_max (dy) < new_size ? Dynarr_max (dy) : new_size) * + dy->elsize); dy->base = new_base; } else @@ -163,7 +186,8 @@ XPNTR (alloc_sized_lrecord_array (dy->elsize, new_size, dy->lisp_imp)); if (dy->base) memcpy (new_base, dy->base, - (dy->max < new_size ? dy->max : new_size) * dy->elsize); + (Dynarr_max (dy) < new_size ? Dynarr_max (dy) : new_size) * + dy->elsize); dy->base = new_base; } @@ -188,16 +212,16 @@ double multiplier; Dynarr *dy = (Dynarr *) Dynarr_verify (d); - if (dy->max <= 8) + if (Dynarr_max (dy) <= 8) multiplier = 2; else multiplier = 1.5; - for (newsize = dy->max; newsize < size;) + for (newsize = Dynarr_max (dy); newsize < size;) newsize = max (Dynarr_min_size, (int) (multiplier * newsize)); /* Don't do anything if the array is already big enough. */ - if (newsize > dy->max) + if (newsize > Dynarr_max (dy)) { #ifdef NEW_GC if (dy->lisp_imp) @@ -207,7 +231,7 @@ #else /* not NEW_GC */ Dynarr_realloc (dy, newsize); #endif /* not NEW_GC */ - dy->max = newsize; + dy->max_ = newsize; } } @@ -215,44 +239,43 @@ void Dynarr_insert_many (void *d, const void *el, int len, int start) { - Dynarr *dy = (Dynarr *) Dynarr_verify (d); - - Dynarr_resize (dy, dy->cur+len); -#if 0 - /* WTF? We should be catching these problems. */ - /* Silently adjust start to be valid. */ - if (start > dy->cur) - start = dy->cur; - else if (start < 0) - start = 0; -#else - assert (start >= 0 && start <= dy->cur); -#endif + Dynarr *dy = Dynarr_verify_mod (d); + + Dynarr_resize_if (dy, len); - if (start != dy->cur) + /* #### This could conceivably be wrong, if code wants to access stuff + between len and largest. */ + dynarr_checking_assert (start >= 0 && start <= Dynarr_length (dy)); + + if (start != Dynarr_length (dy)) { memmove ((char *) dy->base + (start + len)*dy->elsize, (char *) dy->base + start*dy->elsize, - (dy->cur - start)*dy->elsize); + (Dynarr_length (dy) - start)*dy->elsize); } + /* Some functions call us with a value of 0 to mean "reserve space but + don't write into it" */ if (el) memcpy ((char *) dy->base + start*dy->elsize, el, len*dy->elsize); - dy->cur += len; - if (dy->cur > dy->largest) - dy->largest = dy->cur; + Dynarr_set_length_1 (dy, Dynarr_length (dy) + len); + (void) Dynarr_verify_mod (dy); } void Dynarr_delete_many (void *d, int start, int len) { - Dynarr *dy = (Dynarr *) Dynarr_verify (d); + Dynarr *dy = Dynarr_verify_mod (d); - assert (start >= 0 && len >= 0 && start + len <= dy->cur); + dynarr_checking_assert (start >= 0 && len >= 0 && + start + len <= Dynarr_length (dy)); + memmove ((char *) dy->base + start*dy->elsize, (char *) dy->base + (start + len)*dy->elsize, - (dy->cur - start - len)*dy->elsize); - dy->cur -= len; + (Dynarr_length (dy) - start - len)*dy->elsize); + + Dynarr_set_length_1 (dy, Dynarr_length (dy) - len); + (void) Dynarr_verify_mod (dy); } void @@ -264,18 +287,18 @@ if (dy->base && !DUMPEDP (dy->base)) { if (!dy->lisp_imp) - xfree (dy->base, void *); + xfree (dy->base); } if(!DUMPEDP (dy)) { if (!dy->lisp_imp) - xfree (dy, Dynarr *); + xfree (dy); } #else /* not NEW_GC */ if (dy->base && !DUMPEDP (dy->base)) - xfree (dy->base, void *); + xfree (dy->base); if(!DUMPEDP (dy)) - xfree (dy, Dynarr *); + xfree (dy); #endif /* not NEW_GC */ } @@ -301,12 +324,13 @@ if (dy->base) { - Bytecount malloc_used = malloced_storage_size (dy->base, - dy->elsize * dy->max, 0); + Bytecount malloc_used = + malloced_storage_size (dy->base, dy->elsize * Dynarr_max (dy), 0); /* #### This may or may not be correct. Some Dynarrs would - prefer that we use dy->cur instead of dy->largest here. */ - Bytecount was_requested = dy->elsize * dy->largest; - Bytecount dynarr_overhead = dy->elsize * (dy->max - dy->largest); + prefer that we use dy->len instead of dy->largest here. */ + Bytecount was_requested = dy->elsize * Dynarr_largest (dy); + Bytecount dynarr_overhead = + dy->elsize * (Dynarr_max (dy) - Dynarr_largest (dy)); total += malloc_used; stats->was_requested += was_requested; @@ -353,8 +377,9 @@ else this_one = Dynarr_new (char); Dynarr_add (stack_like_in_use_list, this_one); - Dynarr_resize (this_one, size); - return Dynarr_atp (this_one, 0); + Dynarr_reset (this_one); + Dynarr_add_many (this_one, 0, size); + return Dynarr_begin (this_one); } void @@ -366,7 +391,7 @@ order, and the item at the end of the list will be the one we're looking for, so just check for this first and avoid any function calls. */ - if (Dynarr_atp (Dynarr_at (stack_like_in_use_list, len - 1), 0) == val) + if (Dynarr_begin (Dynarr_at (stack_like_in_use_list, len - 1)) == val) { char_dynarr *this_one = Dynarr_pop (stack_like_in_use_list); Dynarr_add (stack_like_free_list, this_one); @@ -377,7 +402,7 @@ int i; assert (len >= 2); for (i = len - 2; i >= 0; i--) - if (Dynarr_atp (Dynarr_at (stack_like_in_use_list, i), 0) == + if (Dynarr_begin (Dynarr_at (stack_like_in_use_list, i)) == val) { char_dynarr *this_one = Dynarr_at (stack_like_in_use_list, i);