Mercurial > hg > xemacs-beta
annotate src/dynarr.c @ 4976:16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-04 Ben Wing <ben@xemacs.org>
* alloc.c (release_breathing_space):
* alloc.c (resize_string):
* alloc.c (sweep_lcrecords_1):
* alloc.c (SWEEP_FIXED_TYPE_BLOCK_1):
* alloc.c (ADDITIONAL_FREE_compiled_function):
* alloc.c (compact_string_chars):
* alloc.c (ADDITIONAL_FREE_string):
* alloc.c (sweep_strings):
* alloca.c (xemacs_c_alloca):
* alsaplay.c (alsa_play_sound_file):
* buffer.c (init_initial_directory):
* buffer.h:
* buffer.h (BUFFER_FREE):
* console-stream.c (stream_delete_console):
* console-tty.c (free_tty_console_struct):
* data.c (Fnumber_to_string):
* device-gtk.c (gtk_init_device):
* device-gtk.c (free_gtk_device_struct):
* device-gtk.c (gtk_delete_device):
* device-msw.c (mswindows_delete_device):
* device-msw.c (msprinter_delete_device):
* device-tty.c (free_tty_device_struct):
* device-tty.c (tty_delete_device):
* device-x.c (x_init_device):
* device-x.c (free_x_device_struct):
* device-x.c (x_delete_device):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-x.c (dbox_descriptor_to_widget_value):
* dired-msw.c (Fmswindows_insert_directory):
* dired.c (free_user_cache):
* dired.c (user_name_completion_unwind):
* doc.c (unparesseuxify_doc_string):
* doc.c (Fsubstitute_command_keys):
* doprnt.c (emacs_doprnt_1):
* dumper.c (pdump_load_finish):
* dumper.c (pdump_file_free):
* dumper.c (pdump_file_unmap):
* dynarr.c:
* dynarr.c (Dynarr_free):
* editfns.c (uncache_home_directory):
* editfns.c (Fset_time_zone_rule):
* elhash.c:
* elhash.c (pdump_reorganize_hash_table):
* elhash.c (maphash_unwind):
* emacs.c (make_arg_list_1):
* emacs.c (free_argc_argv):
* emacs.c (sort_args):
* emacs.c (Frunning_temacs_p):
* emodules.c (attempt_module_delete):
* eval.c (free_pointer):
* event-Xt.c (unselect_filedesc):
* event-Xt.c (emacs_Xt_select_process):
* event-gtk.c (unselect_filedesc):
* event-gtk.c (dragndrop_data_received):
* event-msw.c (winsock_closer):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (mswindows_wnd_proc):
* event-stream.c (finalize_command_builder):
* event-stream.c (free_command_builder):
* extents.c (free_gap_array):
* extents.c (free_extent_list):
* extents.c (free_soe):
* extents.c (extent_fragment_delete):
* extents.c (extent_priority_sort_function):
* file-coding.c (make_coding_system_1):
* file-coding.c (coding_finalizer):
* file-coding.c (set_coding_stream_coding_system):
* file-coding.c (chain_finalize_coding_stream_1):
* file-coding.c (chain_finalize):
* file-coding.c (free_detection_state):
* file-coding.c (coding_category_symbol_to_id):
* fileio.c:
* fileio.c (Ffile_name_directory):
* fileio.c (if):
* fileio.c (Ffile_symlink_p):
* filelock.c (FREE_LOCK_INFO):
* filelock.c (current_lock_owner):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* frame-gtk.c (gtk_delete_frame):
* frame-msw.c (mswindows_delete_frame):
* frame-msw.c (msprinter_delete_frame):
* frame-x.c (x_cde_destroy_callback):
* frame-x.c (Fcde_start_drag_internal):
* frame-x.c (x_cde_transfer_callback):
* frame-x.c (x_delete_frame):
* frame.c (update_frame_title):
* frame.c (Fset_frame_pointer):
* gc.c (register_for_finalization):
* gccache-gtk.c (free_gc_cache):
* gccache-gtk.c (gc_cache_lookup):
* gccache-x.c (free_gc_cache):
* gccache-x.c (gc_cache_lookup):
* glyphs-eimage.c:
* glyphs-eimage.c (jpeg_instantiate_unwind):
* glyphs-eimage.c (gif_instantiate_unwind):
* glyphs-eimage.c (png_instantiate_unwind):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate_unwind):
* glyphs-gtk.c (convert_EImage_to_GDKImage):
* glyphs-gtk.c (gtk_finalize_image_instance):
* glyphs-gtk.c (gtk_init_image_instance_from_eimage):
* glyphs-gtk.c (gtk_xpm_instantiate):
* glyphs-msw.c (convert_EImage_to_DIBitmap):
* glyphs-msw.c (mswindows_init_image_instance_from_eimage):
* glyphs-msw.c (mswindows_initialize_image_instance_mask):
* glyphs-msw.c (xpm_to_eimage):
* glyphs-msw.c (mswindows_xpm_instantiate):
* glyphs-msw.c (xbm_create_bitmap_from_data):
* glyphs-msw.c (mswindows_finalize_image_instance):
* glyphs-x.c (convert_EImage_to_XImage):
* glyphs-x.c (x_finalize_image_instance):
* glyphs-x.c (x_init_image_instance_from_eimage):
* glyphs-x.c (x_xpm_instantiate):
* gui-x.c (free_popup_widget_value_tree):
* hash.c (free_hash_table):
* hash.c (grow_hash_table):
* hash.c (pregrow_hash_table_if_necessary):
* imgproc.c (build_EImage_quantable):
* insdel.c (uninit_buffer_text):
* intl-win32.c (convert_multibyte_to_internal_malloc):
* intl.c:
* intl.c (Fset_current_locale):
* keymap.c:
* keymap.c (where_is_recursive_mapper):
* keymap.c (where_is_internal):
* lisp.h:
* lisp.h (xfree):
* lstream.c (Lstream_close):
* lstream.c (resizing_buffer_closer):
* mule-coding.c:
* mule-coding.c (iso2022_finalize_detection_state):
* nt.c:
* nt.c (mswindows_get_long_filename):
* nt.c (nt_get_resource):
* nt.c (init_mswindows_environment):
* nt.c (get_cached_volume_information):
* nt.c (mswindows_opendir):
* nt.c (mswindows_closedir):
* nt.c (mswindows_readdir):
* nt.c (mswindows_stat):
* nt.c (mswindows_getdcwd):
* nt.c (Fmswindows_long_file_name):
* ntplay.c (nt_play_sound_file):
* ntplay.c (play_sound_data_1):
* number-gmp.c (gmp_free):
* number-gmp.c (init_number_gmp):
* number-mp.c (bignum_to_string):
* number-mp.c (BIGNUM_TO_TYPE):
* number.c (bignum_print):
* number.c (bignum_convfree):
* number.c (ratio_print):
* number.c (bigfloat_print):
* number.c (bigfloat_finalize):
* objects-gtk.c (gtk_finalize_color_instance):
* objects-gtk.c (gtk_finalize_font_instance):
* objects-msw.c (mswindows_finalize_color_instance):
* objects-msw.c (mswindows_finalize_font_instance):
* objects-tty.c (tty_finalize_color_instance):
* objects-tty.c (tty_finalize_font_instance):
* objects-tty.c (tty_font_list):
* objects-x.c (x_finalize_color_instance):
* objects-x.c (x_finalize_font_instance):
* process.c:
* process.c (finalize_process):
* realpath.c:
* redisplay.c (add_propagation_runes):
* regex.c:
* regex.c (xfree):
* regex.c (REGEX_FREE_STACK):
* regex.c (FREE_STACK_RETURN):
* regex.c (regex_compile):
* regex.c (regexec):
* regex.c (regfree):
* scrollbar-gtk.c (gtk_free_scrollbar_instance):
* scrollbar-gtk.c (gtk_release_scrollbar_instance):
* scrollbar-msw.c (mswindows_free_scrollbar_instance):
* scrollbar-msw.c (unshow_that_mofo):
* scrollbar-x.c (x_free_scrollbar_instance):
* scrollbar-x.c (x_release_scrollbar_instance):
* select-gtk.c (emacs_gtk_selection_handle):
* select-msw.c (mswindows_own_selection):
* select-x.c:
* select-x.c (x_handle_selection_request):
* select-x.c (unexpect_property_change):
* select-x.c (x_handle_property_notify):
* select-x.c (receive_incremental_selection):
* select-x.c (x_get_window_property_as_lisp_data):
* select-x.c (Fx_get_cutbuffer_internal):
* specifier.c (finalize_specifier):
* syntax.c (uninit_buffer_syntax_cache):
* sysdep.c (qxe_allocating_getcwd):
* sysdep.c (qxe_lstat):
* sysdep.c (copy_in_passwd):
* sysdep.c (qxe_ctime):
* sysdep.c (closedir):
* sysdep.c (DIRSIZ):
* termcap.c (tgetent):
* termcap.c (tprint):
* tests.c (Ftest_data_format_conversion):
* text.c (new_dfc_convert_copy_data):
* text.h (eifree):
* text.h (eito_alloca):
* text.h (eito_external):
* toolbar-msw.c (mswindows_output_toolbar):
* ui-gtk.c (CONVERT_RETVAL):
* ui-gtk.c (__allocate_object_storage):
* unicode.c (free_from_unicode_table):
* unicode.c (free_to_unicode_table):
* unicode.c (free_charset_unicode_tables):
* win32.c (mswindows_read_link_1):
Rename: xfree(VAL, TYPE)->xfree(VAL)
Command used:
gr 'xfree *\((.*),.*\);' 'xfree (\1);' *.[ch]
Followed by grepping for 'xfree.*,' and fixing anything left.
Rationale: Having to specify the TYPE argument is annoying and
error-prone. It was originally put in to work around warnings
due to strict aliasing but years and years ago I rewrote it
in a way that doesn't use the TYPE argument at all and no one
has complained since then. (And anyway, XEmacs is far from
ever being in compliance with strict aliasing and would require
far-reaching changes to get that way.)
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Thu, 04 Feb 2010 07:28:14 -0600 |
parents | 0d4c9d0f6a8d |
children | 838630c0734f |
rev | line source |
---|---|
1318 | 1 /* Support for dynamic arrays. |
428 | 2 Copyright (C) 1993 Sun Microsystems, Inc. |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
3 Copyright (C) 2002, 2003, 2004, 2005, 2010 Ben Wing. |
428 | 4 |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF. */ | |
23 | |
24 /* Written by Ben Wing, December 1993. */ | |
25 | |
26 /* | |
27 | |
28 A "dynamic array" is a contiguous array of fixed-size elements where there | |
29 is no upper limit (except available memory) on the number of elements in the | |
30 array. Because the elements are maintained contiguously, space is used | |
31 efficiently (no per-element pointers necessary) and random access to a | |
32 particular element is in constant time. At any one point, the block of memory | |
33 that holds the array has an upper limit; if this limit is exceeded, the | |
34 memory is realloc()ed into a new array that is twice as big. Assuming that | |
35 the time to grow the array is on the order of the new size of the array | |
36 block, this scheme has a provably constant amortized time (i.e. average | |
37 time over all additions). | |
38 | |
39 When you add elements or retrieve elements, pointers are used. Note that | |
40 the element itself (of whatever size it is), and not the pointer to it, | |
41 is stored in the array; thus you do not have to allocate any heap memory | |
42 on your own. Also, returned pointers are only guaranteed to be valid | |
43 until the next operation that changes the length of the array. | |
44 | |
45 This is a container object. Declare a dynamic array of a specific type | |
46 as follows: | |
47 | |
2367 | 48 typedef struct |
49 { | |
50 Dynarr_declare (mytype); | |
51 } mytype_dynarr; | |
428 | 52 |
53 Use the following functions/macros: | |
54 | |
55 void *Dynarr_new(type) | |
56 [MACRO] Create a new dynamic-array object, with each element of the | |
57 specified type. The return value is cast to (type##_dynarr). | |
58 This requires following the convention that types are declared in | |
59 such a way that this type concatenation works. In particular, TYPE | |
60 must be a symbol, not an arbitrary C type. | |
61 | |
62 Dynarr_add(d, el) | |
63 [MACRO] Add an element to the end of a dynamic array. EL is a pointer | |
64 to the element; the element itself is stored in the array, however. | |
65 No function call is performed unless the array needs to be resized. | |
66 | |
67 Dynarr_add_many(d, base, len) | |
68 [MACRO] Add LEN elements to the end of the dynamic array. The elements | |
771 | 69 should be contiguous in memory, starting at BASE. If BASE if NULL, |
70 just make space for the elements; don't actually add them. | |
428 | 71 |
72 Dynarr_insert_many_at_start(d, base, len) | |
73 [MACRO] Append LEN elements to the beginning of the dynamic array. | |
74 The elements should be contiguous in memory, starting at BASE. | |
771 | 75 If BASE if NULL, just make space for the elements; don't actually |
76 add them. | |
428 | 77 |
78 Dynarr_insert_many(d, base, len, start) | |
79 Insert LEN elements to the dynamic array starting at position | |
80 START. The elements should be contiguous in memory, starting at BASE. | |
771 | 81 If BASE if NULL, just make space for the elements; don't actually |
82 add them. | |
83 | |
84 Dynarr_delete(d, i) | |
85 [MACRO] Delete an element from the dynamic array at position I. | |
86 | |
87 Dynarr_delete_many(d, start, len) | |
88 Delete LEN elements from the dynamic array starting at position | |
89 START. | |
90 | |
91 Dynarr_delete_by_pointer(d, p) | |
92 [MACRO] Delete an element from the dynamic array at pointer P, | |
93 which must point within the block of memory that stores the data. | |
94 P should be obtained using Dynarr_atp(). | |
428 | 95 |
96 int Dynarr_length(d) | |
97 [MACRO] Return the number of elements currently in a dynamic array. | |
98 | |
99 int Dynarr_largest(d) | |
100 [MACRO] Return the maximum value that Dynarr_length(d) would | |
4844
91b3d00e717f
Various cleanups for Dynarr code, from Unicode-internal ws
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
101 ever have returned. This is used esp. in the redisplay code, |
91b3d00e717f
Various cleanups for Dynarr code, from Unicode-internal ws
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
102 which reuses dynarrs for performance reasons. |
428 | 103 |
104 type Dynarr_at(d, i) | |
105 [MACRO] Return the element at the specified index (no bounds checking | |
106 done on the index). The element itself is returned, not a pointer | |
107 to it. | |
108 | |
109 type *Dynarr_atp(d, i) | |
110 [MACRO] Return a pointer to the element at the specified index (no | |
111 bounds checking done on the index). The pointer may not be valid | |
112 after an element is added to or removed from the array. | |
113 | |
114 Dynarr_reset(d) | |
115 [MACRO] Reset the length of a dynamic array to 0. | |
116 | |
117 Dynarr_free(d) | |
118 Destroy a dynamic array and the memory allocated to it. | |
119 | |
120 Use the following global variable: | |
121 | |
122 Dynarr_min_size | |
440 | 123 Minimum allowable size for a dynamic array when it is resized. |
428 | 124 |
125 */ | |
126 | |
127 #include <config.h> | |
128 #include "lisp.h" | |
129 | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
130 static const struct memory_description const_Ascbyte_ptr_description_1[] = { |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
131 { XD_ASCII_STRING, 0 }, |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
132 { XD_END } |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
133 }; |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
134 |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
135 const struct sized_memory_description const_Ascbyte_ptr_description = { |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
136 sizeof (const Ascbyte *), |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
137 const_Ascbyte_ptr_description_1 |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
138 }; |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
139 |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
140 static const struct memory_description const_Ascbyte_ptr_dynarr_description_1[] = { |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
141 XD_DYNARR_DESC (const_Ascbyte_ptr_dynarr, &const_Ascbyte_ptr_description), |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
142 { XD_END } |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
143 }; |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
144 |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
145 const struct sized_memory_description const_Ascbyte_ptr_dynarr_description = { |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
146 sizeof (const_Ascbyte_ptr_dynarr), |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
147 const_Ascbyte_ptr_dynarr_description_1 |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
148 }; |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
149 |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4844
diff
changeset
|
150 |
440 | 151 static int Dynarr_min_size = 8; |
428 | 152 |
153 static void | |
3210 | 154 Dynarr_realloc (Dynarr *dy, int new_size) |
428 | 155 { |
156 if (DUMPEDP (dy->base)) | |
157 { | |
3293 | 158 void *new_base = malloc (new_size * dy->elsize); |
3210 | 159 memcpy (new_base, dy->base, |
4967 | 160 (Dynarr_max (dy) < new_size ? Dynarr_max (dy) : new_size) * |
161 dy->elsize); | |
428 | 162 dy->base = new_base; |
163 } | |
164 else | |
3210 | 165 dy->base = xrealloc (dy->base, new_size * dy->elsize); |
428 | 166 } |
167 | |
168 void * | |
169 Dynarr_newf (int elsize) | |
170 { | |
171 Dynarr *d = xnew_and_zero (Dynarr); | |
172 d->elsize = elsize; | |
173 | |
174 return d; | |
175 } | |
176 | |
3092 | 177 #ifdef NEW_GC |
178 DEFINE_LRECORD_IMPLEMENTATION ("dynarr", dynarr, | |
179 1, /*dumpable-flag*/ | |
180 0, 0, 0, 0, 0, | |
181 0, | |
182 Dynarr); | |
183 | |
184 static void | |
3210 | 185 Dynarr_lisp_realloc (Dynarr *dy, int new_size) |
3092 | 186 { |
187 void *new_base = alloc_lrecord_array (dy->elsize, new_size, dy->lisp_imp); | |
188 if (dy->base) | |
189 memcpy (new_base, dy->base, | |
4967 | 190 (Dynarr_max (dy) < new_size ? Dynarr_max (dy) : new_size) * |
191 dy->elsize); | |
3092 | 192 dy->base = new_base; |
193 } | |
194 | |
195 void * | |
196 Dynarr_lisp_newf (int elsize, | |
197 const struct lrecord_implementation *dynarr_imp, | |
198 const struct lrecord_implementation *imp) | |
199 { | |
200 Dynarr *d = (Dynarr *) alloc_lrecord (sizeof (Dynarr), dynarr_imp); | |
201 d->elsize = elsize; | |
202 d->lisp_imp = imp; | |
203 | |
204 return d; | |
205 } | |
206 #endif /* not NEW_GC */ | |
207 | |
428 | 208 void |
2367 | 209 Dynarr_resize (void *d, Elemcount size) |
428 | 210 { |
211 int newsize; | |
212 double multiplier; | |
1318 | 213 Dynarr *dy = (Dynarr *) Dynarr_verify (d); |
428 | 214 |
4967 | 215 if (Dynarr_max (dy) <= 8) |
428 | 216 multiplier = 2; |
217 else | |
218 multiplier = 1.5; | |
219 | |
4967 | 220 for (newsize = Dynarr_max (dy); newsize < size;) |
428 | 221 newsize = max (Dynarr_min_size, (int) (multiplier * newsize)); |
222 | |
223 /* Don't do anything if the array is already big enough. */ | |
4967 | 224 if (newsize > Dynarr_max (dy)) |
428 | 225 { |
3092 | 226 #ifdef NEW_GC |
227 if (dy->lisp_imp) | |
228 Dynarr_lisp_realloc (dy, newsize); | |
229 else | |
3210 | 230 Dynarr_realloc (dy, newsize); |
3092 | 231 #else /* not NEW_GC */ |
3210 | 232 Dynarr_realloc (dy, newsize); |
3092 | 233 #endif /* not NEW_GC */ |
4967 | 234 dy->max_ = newsize; |
428 | 235 } |
236 } | |
237 | |
238 /* Add a number of contiguous elements to the array starting at START. */ | |
239 void | |
442 | 240 Dynarr_insert_many (void *d, const void *el, int len, int start) |
428 | 241 { |
4967 | 242 Dynarr *dy = Dynarr_verify_mod (d); |
243 | |
244 Dynarr_resize_if (dy, len); | |
245 | |
4844
91b3d00e717f
Various cleanups for Dynarr code, from Unicode-internal ws
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
246 /* #### This could conceivably be wrong, if code wants to access stuff |
91b3d00e717f
Various cleanups for Dynarr code, from Unicode-internal ws
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
247 between len and largest. */ |
4967 | 248 structure_checking_assert (start >= 0 && start <= Dynarr_length (dy)); |
428 | 249 |
4967 | 250 if (start != Dynarr_length (dy)) |
428 | 251 { |
252 memmove ((char *) dy->base + (start + len)*dy->elsize, | |
253 (char *) dy->base + start*dy->elsize, | |
4967 | 254 (Dynarr_length (dy) - start)*dy->elsize); |
428 | 255 } |
4967 | 256 /* Some functions call us with a value of 0 to mean "reserve space but |
257 don't write into it" */ | |
771 | 258 if (el) |
259 memcpy ((char *) dy->base + start*dy->elsize, el, len*dy->elsize); | |
428 | 260 |
4967 | 261 Dynarr_set_length_1 (dy, Dynarr_length (dy) + len); |
262 (void) Dynarr_verify_mod (dy); | |
428 | 263 } |
264 | |
265 void | |
266 Dynarr_delete_many (void *d, int start, int len) | |
267 { | |
4967 | 268 Dynarr *dy = Dynarr_verify_mod (d); |
428 | 269 |
4967 | 270 structure_checking_assert (start >= 0 && len >= 0 && |
271 start + len <= Dynarr_length (dy)); | |
272 | |
428 | 273 memmove ((char *) dy->base + start*dy->elsize, |
274 (char *) dy->base + (start + len)*dy->elsize, | |
4967 | 275 (Dynarr_length (dy) - start - len)*dy->elsize); |
276 | |
277 Dynarr_set_length_1 (dy, Dynarr_length (dy) - len); | |
278 (void) Dynarr_verify_mod (dy); | |
428 | 279 } |
280 | |
281 void | |
282 Dynarr_free (void *d) | |
283 { | |
284 Dynarr *dy = (Dynarr *) d; | |
285 | |
3092 | 286 #ifdef NEW_GC |
287 if (dy->base && !DUMPEDP (dy->base)) | |
288 { | |
4117 | 289 if (!dy->lisp_imp) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
290 xfree (dy->base); |
3092 | 291 } |
292 if(!DUMPEDP (dy)) | |
293 { | |
4117 | 294 if (!dy->lisp_imp) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
295 xfree (dy); |
3092 | 296 } |
297 #else /* not NEW_GC */ | |
428 | 298 if (dy->base && !DUMPEDP (dy->base)) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
299 xfree (dy->base); |
428 | 300 if(!DUMPEDP (dy)) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
301 xfree (dy); |
3092 | 302 #endif /* not NEW_GC */ |
428 | 303 } |
304 | |
305 #ifdef MEMORY_USAGE_STATS | |
306 | |
307 /* Return memory usage for Dynarr D. The returned value is the total | |
308 amount of bytes actually being used for the Dynarr, including all | |
309 overhead. The extra amount of space in the Dynarr that is | |
310 allocated beyond what was requested is returned in DYNARR_OVERHEAD | |
311 in STATS. The extra amount of space that malloc() allocates beyond | |
312 what was requested of it is returned in MALLOC_OVERHEAD in STATS. | |
313 See the comment above the definition of this structure. */ | |
314 | |
665 | 315 Bytecount |
428 | 316 Dynarr_memory_usage (void *d, struct overhead_stats *stats) |
317 { | |
665 | 318 Bytecount total = 0; |
428 | 319 Dynarr *dy = (Dynarr *) d; |
320 | |
321 /* We have to be a bit tricky here because not all of the | |
322 memory that malloc() will claim as "requested" was actually | |
323 requested. */ | |
324 | |
325 if (dy->base) | |
326 { | |
4967 | 327 Bytecount malloc_used = |
328 malloced_storage_size (dy->base, dy->elsize * Dynarr_max (dy), 0); | |
428 | 329 /* #### This may or may not be correct. Some Dynarrs would |
4844
91b3d00e717f
Various cleanups for Dynarr code, from Unicode-internal ws
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
330 prefer that we use dy->len instead of dy->largest here. */ |
4967 | 331 Bytecount was_requested = dy->elsize * Dynarr_largest (dy); |
332 Bytecount dynarr_overhead = | |
333 dy->elsize * (Dynarr_max (dy) - Dynarr_largest (dy)); | |
428 | 334 |
335 total += malloc_used; | |
336 stats->was_requested += was_requested; | |
337 stats->dynarr_overhead += dynarr_overhead; | |
338 /* And the remainder must be malloc overhead. */ | |
339 stats->malloc_overhead += | |
340 malloc_used - was_requested - dynarr_overhead; | |
341 } | |
342 | |
343 total += malloced_storage_size (d, sizeof (*dy), stats); | |
344 | |
345 return total; | |
346 } | |
347 | |
348 #endif /* MEMORY_USAGE_STATS */ | |
2367 | 349 |
350 /* Version of malloc() that will be extremely efficient when allocation | |
351 nearly always occurs in LIFO (stack) order. | |
352 | |
353 #### Perhaps shouldn't be in this file, but where else? */ | |
354 | |
355 typedef struct | |
356 { | |
357 Dynarr_declare (char_dynarr *); | |
358 } char_dynarr_dynarr; | |
359 | |
360 char_dynarr_dynarr *stack_like_free_list; | |
361 char_dynarr_dynarr *stack_like_in_use_list; | |
362 | |
363 void * | |
364 stack_like_malloc (Bytecount size) | |
365 { | |
366 char_dynarr *this_one; | |
367 if (!stack_like_free_list) | |
368 { | |
369 stack_like_free_list = Dynarr_new2 (char_dynarr_dynarr, | |
370 char_dynarr *); | |
371 stack_like_in_use_list = Dynarr_new2 (char_dynarr_dynarr, | |
372 char_dynarr *); | |
373 } | |
374 | |
375 if (Dynarr_length (stack_like_free_list) > 0) | |
376 this_one = Dynarr_pop (stack_like_free_list); | |
377 else | |
378 this_one = Dynarr_new (char); | |
379 Dynarr_add (stack_like_in_use_list, this_one); | |
4844
91b3d00e717f
Various cleanups for Dynarr code, from Unicode-internal ws
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
380 Dynarr_reset (this_one); |
91b3d00e717f
Various cleanups for Dynarr code, from Unicode-internal ws
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
381 Dynarr_add_many (this_one, 0, size); |
4967 | 382 return Dynarr_begin (this_one); |
2367 | 383 } |
384 | |
385 void | |
386 stack_like_free (void *val) | |
387 { | |
388 int len = Dynarr_length (stack_like_in_use_list); | |
389 assert (len > 0); | |
390 /* The vast majority of times, we will be called in a last-in first-out | |
391 order, and the item at the end of the list will be the one we're | |
392 looking for, so just check for this first and avoid any function | |
393 calls. */ | |
4967 | 394 if (Dynarr_begin (Dynarr_at (stack_like_in_use_list, len - 1)) == val) |
2367 | 395 { |
396 char_dynarr *this_one = Dynarr_pop (stack_like_in_use_list); | |
397 Dynarr_add (stack_like_free_list, this_one); | |
398 } | |
399 else | |
400 { | |
401 /* Find the item and delete it. */ | |
402 int i; | |
403 assert (len >= 2); | |
404 for (i = len - 2; i >= 0; i--) | |
4967 | 405 if (Dynarr_begin (Dynarr_at (stack_like_in_use_list, i)) == |
2367 | 406 val) |
407 { | |
408 char_dynarr *this_one = Dynarr_at (stack_like_in_use_list, i); | |
409 Dynarr_add (stack_like_free_list, this_one); | |
410 Dynarr_delete (stack_like_in_use_list, i); | |
411 return; | |
412 } | |
413 | |
2500 | 414 ABORT (); |
2367 | 415 } |
416 } |