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.