Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 801:2b676dc88c66
[xemacs-hg @ 2002-04-01 03:58:02 by ben]
bug fixes (e.g. ballooning on X windows)
Makefile.in.in: Try to make the Makefile notice if its source Makefile.in.in is
changed, and regenerate and run itself.
Use a bigger default SHEAP_ADJUSTMENT on Cygwin; otherwise you
can't compile under Mule if a Lisp file has changed. (can't run
temacs)
TODO.ben-mule-21-5: update.
mule/mule-cmds.el: Hash the result of mswindows-get-language-environment-from-locale,
since it's very expensive (and causes huge ballooning of memory
under X Windows, since it's called from x-get-resource).
cl-extra.el, code-files.el, files.el, simple.el, subr.el, x-faces.el: Create new string-equal-ignore-case, based on built-in
compare-strings -- compare strings ignoring case without the need
to generate garbage by calling downcase. Use it in equalp and
elsewhere.
alloc.c, bytecode.c, chartab.c, data.c, elhash.c, emacs.c, eval.c, event-Xt.c, event-unixoid.c, extents.c, file-coding.c, fileio.c, fns.c, glyphs.c, gutter.c, lisp-union.h, lisp.h, mule-charset.c, nt.c, process-unix.c, process.c, specifier.c, symbols.c, sysdep.c, sysdep.h, text.c, toolbar.c: Try to implement GC triggering based on percentage of total memory
usage. Not currently activated (percentage set to 0) because not
quite working. Add `memory-usage' primitive to return XEmacs'
idea of its memory usage.
Add primitive compare-strings, compatible with FSF 21.1 -- can
compare any part of two strings, optionally ignoring case.
Improve qxe() functions in text.c for text comparison.
Use RETURN_NOT_REACHED to try to avoid warnings about unreachable
code.
Add volatile_make_int() to fix warning in unix_send_process().
author | ben |
---|---|
date | Mon, 01 Apr 2002 03:59:04 +0000 |
parents | a5954632b187 |
children | a634e3b7acc8 |
comparison
equal
deleted
inserted
replaced
800:a5954632b187 | 801:2b676dc88c66 |
---|---|
98 if (debug_allocation_backtrace_length > 0) \ | 98 if (debug_allocation_backtrace_length > 0) \ |
99 debug_short_backtrace (debug_allocation_backtrace_length); \ | 99 debug_short_backtrace (debug_allocation_backtrace_length); \ |
100 } while (0) | 100 } while (0) |
101 | 101 |
102 #ifdef DEBUG_XEMACS | 102 #ifdef DEBUG_XEMACS |
103 #define INCREMENT_CONS_COUNTER(foosize, type) \ | 103 #define INCREMENT_CONS_COUNTER(foosize, type) \ |
104 do { \ | 104 do { \ |
105 if (debug_allocation) \ | 105 if (debug_allocation) \ |
106 { \ | 106 { \ |
107 stderr_out ("allocating %s (size %ld)\n", type, (long)foosize); \ | 107 stderr_out ("allocating %s (size %ld)\n", type, \ |
108 debug_allocation_backtrace (); \ | 108 (long) foosize); \ |
109 } \ | 109 debug_allocation_backtrace (); \ |
110 INCREMENT_CONS_COUNTER_1 (foosize); \ | 110 } \ |
111 INCREMENT_CONS_COUNTER_1 (foosize); \ | |
111 } while (0) | 112 } while (0) |
112 #define NOSEEUM_INCREMENT_CONS_COUNTER(foosize, type) \ | 113 #define NOSEEUM_INCREMENT_CONS_COUNTER(foosize, type) \ |
113 do { \ | 114 do { \ |
114 if (debug_allocation > 1) \ | 115 if (debug_allocation > 1) \ |
115 { \ | 116 { \ |
116 stderr_out ("allocating noseeum %s (size %ld)\n", type, (long)foosize); \ | 117 stderr_out ("allocating noseeum %s (size %ld)\n", type, \ |
118 (long) foosize); \ | |
117 debug_allocation_backtrace (); \ | 119 debug_allocation_backtrace (); \ |
118 } \ | 120 } \ |
119 INCREMENT_CONS_COUNTER_1 (foosize); \ | 121 INCREMENT_CONS_COUNTER_1 (foosize); \ |
120 } while (0) | 122 } while (0) |
121 #else | 123 #else |
129 if (consing_since_gc < 0) \ | 131 if (consing_since_gc < 0) \ |
130 consing_since_gc = 0; \ | 132 consing_since_gc = 0; \ |
131 } while (0) | 133 } while (0) |
132 | 134 |
133 /* Number of bytes of consing since gc before another gc should be done. */ | 135 /* Number of bytes of consing since gc before another gc should be done. */ |
134 EMACS_INT gc_cons_threshold; | 136 static EMACS_INT gc_cons_threshold; |
137 | |
138 /* Percentage of consing of total data size before another GC. */ | |
139 static EMACS_INT gc_cons_percentage; | |
140 | |
141 #ifdef ERROR_CHECK_GC | |
142 int always_gc; /* Debugging hack */ | |
143 #else | |
144 #define always_gc 0 | |
145 #endif | |
135 | 146 |
136 /* Nonzero during gc */ | 147 /* Nonzero during gc */ |
137 int gc_in_progress; | 148 int gc_in_progress; |
138 | 149 |
139 /* Number of times GC has happened at this level or below. | 150 /* Number of times GC has happened at this level or below. |
164 #ifdef ERROR_CHECK_TYPES | 175 #ifdef ERROR_CHECK_TYPES |
165 | 176 |
166 Error_Behavior ERROR_ME, ERROR_ME_NOT, ERROR_ME_WARN, ERROR_ME_DEBUG_WARN; | 177 Error_Behavior ERROR_ME, ERROR_ME_NOT, ERROR_ME_WARN, ERROR_ME_DEBUG_WARN; |
167 | 178 |
168 #endif | 179 #endif |
180 | |
181 /* Very cheesy ways of figuring out how much memory is being used for | |
182 data. #### Need better (system-dependent) ways. */ | |
183 void *minimum_address_seen; | |
184 void *maximum_address_seen; | |
169 | 185 |
170 int | 186 int |
171 c_readonly (Lisp_Object obj) | 187 c_readonly (Lisp_Object obj) |
172 { | 188 { |
173 return POINTER_TYPE_P (XTYPE (obj)) && C_READONLY (obj); | 189 return POINTER_TYPE_P (XTYPE (obj)) && C_READONLY (obj); |
237 Vcommand_history = Qnil; | 253 Vcommand_history = Qnil; |
238 | 254 |
239 out_of_memory ("Memory exhausted", Qunbound); | 255 out_of_memory ("Memory exhausted", Qunbound); |
240 } | 256 } |
241 | 257 |
242 /* like malloc and realloc but check for no memory left, and block input. */ | 258 static void |
259 set_alloc_mins_and_maxes (void *val, Bytecount size) | |
260 { | |
261 if (!val) | |
262 return; | |
263 if ((char *) val + size > (char *) maximum_address_seen) | |
264 maximum_address_seen = (char *) val + size; | |
265 if (!minimum_address_seen) | |
266 minimum_address_seen = | |
267 #if SIZEOF_VOID_P == 8 | |
268 (void *) 0xFFFFFFFFFFFFFFFF; | |
269 #else | |
270 (void *) 0xFFFFFFFF; | |
271 #endif | |
272 if ((char *) val < (char *) minimum_address_seen) | |
273 minimum_address_seen = (char *) val; | |
274 } | |
275 | |
276 /* like malloc and realloc but check for no memory left. */ | |
243 | 277 |
244 #undef xmalloc | 278 #undef xmalloc |
245 void * | 279 void * |
246 xmalloc (Bytecount size) | 280 xmalloc (Bytecount size) |
247 { | 281 { |
248 void *val = malloc (size); | 282 void *val = malloc (size); |
249 | |
250 if (!val && (size != 0)) memory_full (); | 283 if (!val && (size != 0)) memory_full (); |
284 set_alloc_mins_and_maxes (val, size); | |
251 return val; | 285 return val; |
252 } | 286 } |
253 | 287 |
254 #undef xcalloc | 288 #undef xcalloc |
255 static void * | 289 static void * |
256 xcalloc (Elemcount nelem, Bytecount elsize) | 290 xcalloc (Elemcount nelem, Bytecount elsize) |
257 { | 291 { |
258 void *val = calloc (nelem, elsize); | 292 void *val = calloc (nelem, elsize); |
259 | 293 |
260 if (!val && (nelem != 0)) memory_full (); | 294 if (!val && (nelem != 0)) memory_full (); |
295 set_alloc_mins_and_maxes (val, nelem * elsize); | |
261 return val; | 296 return val; |
262 } | 297 } |
263 | 298 |
264 void * | 299 void * |
265 xmalloc_and_zero (Bytecount size) | 300 xmalloc_and_zero (Bytecount size) |
272 xrealloc (void *block, Bytecount size) | 307 xrealloc (void *block, Bytecount size) |
273 { | 308 { |
274 block = realloc (block, size); | 309 block = realloc (block, size); |
275 | 310 |
276 if (!block && (size != 0)) memory_full (); | 311 if (!block && (size != 0)) memory_full (); |
312 set_alloc_mins_and_maxes (block, size); | |
277 return block; | 313 return block; |
278 } | 314 } |
279 | 315 |
280 void | 316 void |
281 #ifdef ERROR_CHECK_MALLOC | 317 #ifdef ERROR_CHECK_MALLOC |
3898 return make_int (consing_since_gc); | 3934 return make_int (consing_since_gc); |
3899 } | 3935 } |
3900 | 3936 |
3901 #if 0 | 3937 #if 0 |
3902 DEFUN ("memory-limit", Fmemory_limit, 0, 0, 0, /* | 3938 DEFUN ("memory-limit", Fmemory_limit, 0, 0, 0, /* |
3903 Return the address of the last byte Emacs has allocated, divided by 1024. | 3939 Return the address of the last byte XEmacs has allocated, divided by 1024. |
3904 This may be helpful in debugging Emacs's memory usage. | 3940 This may be helpful in debugging XEmacs's memory usage. |
3905 The value is divided by 1024 to make sure it will fit in a lisp integer. | 3941 The value is divided by 1024 to make sure it will fit in a lisp integer. |
3906 */ | 3942 */ |
3907 ()) | 3943 ()) |
3908 { | 3944 { |
3909 return make_int ((EMACS_INT) sbrk (0) / 1024); | 3945 return make_int ((EMACS_INT) sbrk (0) / 1024); |
3910 } | 3946 } |
3911 #endif | 3947 #endif |
3948 | |
3949 DEFUN ("memory-usage", Fmemory_usage, 0, 0, 0, /* | |
3950 Return the total number of bytes used by the data segment in XEmacs. | |
3951 This may be helpful in debugging XEmacs's memory usage. | |
3952 */ | |
3953 ()) | |
3954 { | |
3955 return make_int (total_data_usage ()); | |
3956 } | |
3957 | |
3958 /* True if it's time to garbage collect now. */ | |
3959 int | |
3960 need_to_garbage_collect (void) | |
3961 { | |
3962 if (always_gc) | |
3963 return 1; | |
3964 | |
3965 return (consing_since_gc > gc_cons_threshold && | |
3966 (100 * consing_since_gc) / total_data_usage () >= | |
3967 gc_cons_percentage); | |
3968 } | |
3912 | 3969 |
3913 | 3970 |
3914 int | 3971 int |
3915 object_dead_p (Lisp_Object obj) | 3972 object_dead_p (Lisp_Object obj) |
3916 { | 3973 { |
4115 #if 1 | 4172 #if 1 |
4116 gc_cons_threshold = 500000; /* XEmacs change */ | 4173 gc_cons_threshold = 500000; /* XEmacs change */ |
4117 #else | 4174 #else |
4118 gc_cons_threshold = 15000; /* debugging */ | 4175 gc_cons_threshold = 15000; /* debugging */ |
4119 #endif | 4176 #endif |
4177 gc_cons_percentage = 0; /* #### 20; Don't have an accurate measure of | |
4178 memory usage on Windows; not verified on other | |
4179 systems */ | |
4120 lrecord_uid_counter = 259; | 4180 lrecord_uid_counter = 259; |
4121 debug_string_purity = 0; | 4181 debug_string_purity = 0; |
4122 gcprolist = 0; | 4182 gcprolist = 0; |
4123 | 4183 |
4124 gc_currently_forbidden = 0; | 4184 gc_currently_forbidden = 0; |
4213 DEFSUBR (Fpurecopy); | 4273 DEFSUBR (Fpurecopy); |
4214 DEFSUBR (Fgarbage_collect); | 4274 DEFSUBR (Fgarbage_collect); |
4215 #if 0 | 4275 #if 0 |
4216 DEFSUBR (Fmemory_limit); | 4276 DEFSUBR (Fmemory_limit); |
4217 #endif | 4277 #endif |
4278 DEFSUBR (Fmemory_usage); | |
4218 DEFSUBR (Fconsing_since_gc); | 4279 DEFSUBR (Fconsing_since_gc); |
4219 } | 4280 } |
4220 | 4281 |
4221 void | 4282 void |
4222 vars_of_alloc (void) | 4283 vars_of_alloc (void) |
4225 *Number of bytes of consing between garbage collections. | 4286 *Number of bytes of consing between garbage collections. |
4226 \"Consing\" is a misnomer in that this actually counts allocation | 4287 \"Consing\" is a misnomer in that this actually counts allocation |
4227 of all different kinds of objects, not just conses. | 4288 of all different kinds of objects, not just conses. |
4228 Garbage collection can happen automatically once this many bytes have been | 4289 Garbage collection can happen automatically once this many bytes have been |
4229 allocated since the last garbage collection. All data types count. | 4290 allocated since the last garbage collection. All data types count. |
4291 | |
4292 Garbage collection happens automatically when `eval' or `funcall' are | |
4293 called. (Note that `funcall' is called implicitly as part of evaluation.) | |
4294 By binding this temporarily to a large number, you can effectively | |
4295 prevent garbage collection during a part of the program. | |
4296 | |
4297 See also `consing-since-gc'. | |
4298 */ ); | |
4299 | |
4300 DEFVAR_INT ("gc-cons-percentage", &gc_cons_percentage /* | |
4301 *Percentage of memory allocated between garbage collections. | |
4302 | |
4303 Garbage collection will happen if this percentage of the total amount of | |
4304 memory used for data has been allocated since the last garbage collection. | |
4305 However, it will not happen if less than `gc-cons-threshold' bytes have | |
4306 been allocated -- this sets an absolute minimum in case very little data | |
4307 has been allocated or the percentage is set very low. Set this to 0 to | |
4308 have garbage collection always happen after `gc-cons-threshold' bytes have | |
4309 been allocated, regardless of current memory usage. | |
4230 | 4310 |
4231 Garbage collection happens automatically when `eval' or `funcall' are | 4311 Garbage collection happens automatically when `eval' or `funcall' are |
4232 called. (Note that `funcall' is called implicitly as part of evaluation.) | 4312 called. (Note that `funcall' is called implicitly as part of evaluation.) |
4233 By binding this temporarily to a large number, you can effectively | 4313 By binding this temporarily to a large number, you can effectively |
4234 prevent garbage collection during a part of the program. | 4314 prevent garbage collection during a part of the program. |