Mercurial > hg > xemacs-beta
annotate src/gc.c @ 5223:acc4a6c9f5f9
Remove the definition of Q_data from glyphs.c, fixing C++ build.
2010-06-01 Aidan Kehoe <kehoea@parhasard.net>
* glyphs.c (syms_of_glyphs):
Remove the definition of Q_data from this file, now it's in
general-slots.h. Problem picked up by a C++ build.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Tue, 01 Jun 2010 20:31:11 +0100 |
parents | 71ee43b8a74d |
children | 2cc24c69446c |
rev | line source |
---|---|
3092 | 1 /* New incremental garbage collector for XEmacs. |
2 Copyright (C) 2005 Marcus Crestani. | |
4934
714f7c9fabb1
make it easier to debug staticpro crashes.
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
3 Copyright (C) 2010 Ben Wing. |
3092 | 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 #include <config.h> | |
25 #include "lisp.h" | |
26 | |
27 #include "backtrace.h" | |
28 #include "buffer.h" | |
29 #include "bytecode.h" | |
30 #include "chartab.h" | |
31 #include "console-stream.h" | |
32 #include "device.h" | |
33 #include "elhash.h" | |
34 #include "events.h" | |
35 #include "extents-impl.h" | |
36 #include "file-coding.h" | |
37 #include "frame-impl.h" | |
38 #include "gc.h" | |
39 #include "glyphs.h" | |
40 #include "opaque.h" | |
41 #include "lrecord.h" | |
42 #include "lstream.h" | |
43 #include "process.h" | |
44 #include "profile.h" | |
45 #include "redisplay.h" | |
46 #include "specifier.h" | |
47 #include "sysfile.h" | |
48 #include "sysdep.h" | |
49 #include "window.h" | |
50 #include "vdb.h" | |
51 | |
52 | |
53 #define GC_CONS_THRESHOLD 2000000 | |
54 #define GC_CONS_INCREMENTAL_THRESHOLD 200000 | |
55 #define GC_INCREMENTAL_TRAVERSAL_THRESHOLD 100000 | |
56 | |
57 /* Number of bytes of consing done since the last GC. */ | |
58 EMACS_INT consing_since_gc; | |
59 | |
60 /* Number of bytes of consing done since startup. */ | |
61 EMACS_UINT total_consing; | |
62 | |
63 /* Number of bytes of current allocated heap objects. */ | |
64 EMACS_INT total_gc_usage; | |
65 | |
66 /* If the above is set. */ | |
67 int total_gc_usage_set; | |
68 | |
69 /* Number of bytes of consing since gc before another gc should be done. */ | |
70 EMACS_INT gc_cons_threshold; | |
71 | |
72 /* Nonzero during gc */ | |
73 int gc_in_progress; | |
74 | |
75 /* Percentage of consing of total data size before another GC. */ | |
76 EMACS_INT gc_cons_percentage; | |
77 | |
78 #ifdef NEW_GC | |
79 /* Number of bytes of consing since gc before another cycle of the gc | |
80 should be done in incremental mode. */ | |
81 EMACS_INT gc_cons_incremental_threshold; | |
82 | |
83 /* Number of elements marked in one cycle of incremental GC. */ | |
84 EMACS_INT gc_incremental_traversal_threshold; | |
85 | |
86 /* Nonzero during write barrier */ | |
87 int write_barrier_enabled; | |
88 #endif /* NEW_GC */ | |
89 | |
90 | |
91 | |
92 #ifdef NEW_GC | |
93 /************************************************************************/ | |
94 /* Incremental State and Statistics */ | |
95 /************************************************************************/ | |
96 | |
97 enum gc_phase | |
98 { | |
99 NONE, | |
100 INIT_GC, | |
101 PUSH_ROOT_SET, | |
102 MARK, | |
103 REPUSH_ROOT_SET, | |
104 FINISH_MARK, | |
105 FINALIZE, | |
106 SWEEP, | |
107 FINISH_GC | |
108 }; | |
109 | |
110 #ifndef ERROR_CHECK_GC | |
4124 | 111 typedef struct gc_state_type |
3092 | 112 { |
113 enum gc_phase phase; | |
4124 | 114 } gc_state_type; |
3092 | 115 #else /* ERROR_CHECK_GC */ |
116 enum gc_stat_id | |
117 { | |
118 GC_STAT_TOTAL, | |
119 GC_STAT_IN_LAST_GC, | |
120 GC_STAT_IN_THIS_GC, | |
121 GC_STAT_IN_LAST_CYCLE, | |
122 GC_STAT_IN_THIS_CYCLE, | |
123 GC_STAT_COUNT /* has to be last */ | |
124 }; | |
125 | |
4124 | 126 typedef struct gc_state_type |
3092 | 127 { |
128 enum gc_phase phase; | |
3313 | 129 double n_gc[GC_STAT_COUNT]; |
130 double n_cycles[GC_STAT_COUNT]; | |
131 double enqueued[GC_STAT_COUNT]; | |
132 double dequeued[GC_STAT_COUNT]; | |
133 double repushed[GC_STAT_COUNT]; | |
134 double enqueued2[GC_STAT_COUNT]; | |
135 double dequeued2[GC_STAT_COUNT]; | |
136 double finalized[GC_STAT_COUNT]; | |
137 double freed[GC_STAT_COUNT]; | |
4124 | 138 } gc_state_type; |
3092 | 139 #endif /* ERROR_CHECK_GC */ |
140 | |
4124 | 141 gc_state_type gc_state; |
142 | |
3092 | 143 #define GC_PHASE gc_state.phase |
144 #define GC_SET_PHASE(p) GC_PHASE = p | |
145 | |
146 #ifdef ERROR_CHECK_GC | |
147 # define GC_STAT_START_NEW_GC gc_stat_start_new_gc () | |
148 # define GC_STAT_RESUME_GC gc_stat_resume_gc () | |
149 | |
150 #define GC_STAT_TICK(STAT) \ | |
151 gc_state.STAT[GC_STAT_TOTAL]++; \ | |
152 gc_state.STAT[GC_STAT_IN_THIS_GC]++; \ | |
153 gc_state.STAT[GC_STAT_IN_THIS_CYCLE]++ | |
154 | |
155 # define GC_STAT_ENQUEUED \ | |
156 if (GC_PHASE == REPUSH_ROOT_SET) \ | |
157 { \ | |
158 GC_STAT_TICK (enqueued2); \ | |
159 } \ | |
160 else \ | |
161 { \ | |
162 GC_STAT_TICK (enqueued); \ | |
163 } | |
164 | |
165 # define GC_STAT_DEQUEUED \ | |
166 if (gc_state.phase == REPUSH_ROOT_SET) \ | |
167 { \ | |
168 GC_STAT_TICK (dequeued2); \ | |
169 } \ | |
170 else \ | |
171 { \ | |
172 GC_STAT_TICK (dequeued); \ | |
173 } | |
174 # define GC_STAT_REPUSHED GC_STAT_TICK (repushed) | |
175 | |
176 #define GC_STAT_RESUME(stat) \ | |
177 gc_state.stat[GC_STAT_IN_LAST_CYCLE] = \ | |
178 gc_state.stat[GC_STAT_IN_THIS_CYCLE]; \ | |
179 gc_state.stat[GC_STAT_IN_THIS_CYCLE] = 0 | |
180 | |
181 #define GC_STAT_RESTART(stat) \ | |
182 gc_state.stat[GC_STAT_IN_LAST_GC] = \ | |
183 gc_state.stat[GC_STAT_IN_THIS_GC]; \ | |
184 gc_state.stat[GC_STAT_IN_THIS_GC] = 0; \ | |
185 GC_STAT_RESUME (stat) | |
186 | |
5046 | 187 static void |
3092 | 188 gc_stat_start_new_gc (void) |
189 { | |
190 gc_state.n_gc[GC_STAT_TOTAL]++; | |
191 gc_state.n_cycles[GC_STAT_TOTAL]++; | |
192 gc_state.n_cycles[GC_STAT_IN_LAST_GC] = gc_state.n_cycles[GC_STAT_IN_THIS_GC]; | |
193 gc_state.n_cycles[GC_STAT_IN_THIS_GC] = 1; | |
194 | |
195 GC_STAT_RESTART (enqueued); | |
196 GC_STAT_RESTART (dequeued); | |
197 GC_STAT_RESTART (repushed); | |
198 GC_STAT_RESTART (finalized); | |
199 GC_STAT_RESTART (enqueued2); | |
200 GC_STAT_RESTART (dequeued2); | |
201 GC_STAT_RESTART (freed); | |
202 } | |
203 | |
5046 | 204 static void |
3092 | 205 gc_stat_resume_gc (void) |
206 { | |
207 gc_state.n_cycles[GC_STAT_TOTAL]++; | |
208 gc_state.n_cycles[GC_STAT_IN_THIS_GC]++; | |
209 GC_STAT_RESUME (enqueued); | |
210 GC_STAT_RESUME (dequeued); | |
211 GC_STAT_RESUME (repushed); | |
212 GC_STAT_RESUME (finalized); | |
213 GC_STAT_RESUME (enqueued2); | |
214 GC_STAT_RESUME (dequeued2); | |
215 GC_STAT_RESUME (freed); | |
216 } | |
217 | |
218 void | |
219 gc_stat_finalized (void) | |
220 { | |
221 GC_STAT_TICK (finalized); | |
222 } | |
223 | |
224 void | |
225 gc_stat_freed (void) | |
226 { | |
227 GC_STAT_TICK (freed); | |
228 } | |
229 | |
230 DEFUN("gc-stats", Fgc_stats, 0, 0 ,"", /* | |
231 Return statistics about garbage collection cycles in a property list. | |
232 */ | |
233 ()) | |
234 { | |
235 Lisp_Object pl = Qnil; | |
236 #define PL(name,value) \ | |
3313 | 237 pl = cons3 (intern (name), make_float (gc_state.value), pl) |
3092 | 238 |
239 PL ("freed-in-this-cycle", freed[GC_STAT_IN_THIS_CYCLE]); | |
240 PL ("freed-in-this-gc", freed[GC_STAT_IN_THIS_GC]); | |
241 PL ("freed-in-last-cycle", freed[GC_STAT_IN_LAST_CYCLE]); | |
242 PL ("freed-in-last-gc", freed[GC_STAT_IN_LAST_GC]); | |
243 PL ("freed-total", freed[GC_STAT_TOTAL]); | |
244 PL ("finalized-in-this-cycle", finalized[GC_STAT_IN_THIS_CYCLE]); | |
245 PL ("finalized-in-this-gc", finalized[GC_STAT_IN_THIS_GC]); | |
246 PL ("finalized-in-last-cycle", finalized[GC_STAT_IN_LAST_CYCLE]); | |
247 PL ("finalized-in-last-gc", finalized[GC_STAT_IN_LAST_GC]); | |
248 PL ("finalized-total", finalized[GC_STAT_TOTAL]); | |
249 PL ("repushed-in-this-cycle", repushed[GC_STAT_IN_THIS_CYCLE]); | |
250 PL ("repushed-in-this-gc", repushed[GC_STAT_IN_THIS_GC]); | |
251 PL ("repushed-in-last-cycle", repushed[GC_STAT_IN_LAST_CYCLE]); | |
252 PL ("repushed-in-last-gc", repushed[GC_STAT_IN_LAST_GC]); | |
253 PL ("repushed-total", repushed[GC_STAT_TOTAL]); | |
254 PL ("dequeued2-in-this-cycle", dequeued2[GC_STAT_IN_THIS_CYCLE]); | |
255 PL ("dequeued2-in-this-gc", dequeued2[GC_STAT_IN_THIS_GC]); | |
256 PL ("dequeued2-in-last-cycle", dequeued2[GC_STAT_IN_LAST_CYCLE]); | |
257 PL ("dequeued2-in-last-gc", dequeued2[GC_STAT_IN_LAST_GC]); | |
258 PL ("dequeued2-total", dequeued2[GC_STAT_TOTAL]); | |
259 PL ("enqueued2-in-this-cycle", enqueued2[GC_STAT_IN_THIS_CYCLE]); | |
260 PL ("enqueued2-in-this-gc", enqueued2[GC_STAT_IN_THIS_GC]); | |
261 PL ("enqueued2-in-last-cycle", enqueued2[GC_STAT_IN_LAST_CYCLE]); | |
262 PL ("enqueued2-in-last-gc", enqueued2[GC_STAT_IN_LAST_GC]); | |
263 PL ("enqueued2-total", enqueued2[GC_STAT_TOTAL]); | |
264 PL ("dequeued-in-this-cycle", dequeued[GC_STAT_IN_THIS_CYCLE]); | |
265 PL ("dequeued-in-this-gc", dequeued[GC_STAT_IN_THIS_GC]); | |
266 PL ("dequeued-in-last-cycle", dequeued[GC_STAT_IN_LAST_CYCLE]); | |
267 PL ("dequeued-in-last-gc", dequeued[GC_STAT_IN_LAST_GC]); | |
268 PL ("dequeued-total", dequeued[GC_STAT_TOTAL]); | |
269 PL ("enqueued-in-this-cycle", enqueued[GC_STAT_IN_THIS_CYCLE]); | |
270 PL ("enqueued-in-this-gc", enqueued[GC_STAT_IN_THIS_GC]); | |
271 PL ("enqueued-in-last-cycle", enqueued[GC_STAT_IN_LAST_CYCLE]); | |
272 PL ("enqueued-in-last-gc", enqueued[GC_STAT_IN_LAST_GC]); | |
273 PL ("enqueued-total", enqueued[GC_STAT_TOTAL]); | |
274 PL ("n-cycles-in-this-gc", n_cycles[GC_STAT_IN_THIS_GC]); | |
275 PL ("n-cycles-in-last-gc", n_cycles[GC_STAT_IN_LAST_GC]); | |
276 PL ("n-cycles-total", n_cycles[GC_STAT_TOTAL]); | |
277 PL ("n-gc-total", n_gc[GC_STAT_TOTAL]); | |
278 PL ("phase", phase); | |
279 return pl; | |
280 } | |
281 #else /* not ERROR_CHECK_GC */ | |
282 # define GC_STAT_START_NEW_GC | |
283 # define GC_STAT_RESUME_GC | |
284 # define GC_STAT_ENQUEUED | |
285 # define GC_STAT_DEQUEUED | |
286 # define GC_STAT_REPUSHED | |
287 # define GC_STAT_REMOVED | |
288 #endif /* not ERROR_CHECK_GC */ | |
289 #endif /* NEW_GC */ | |
290 | |
291 | |
292 /************************************************************************/ | |
293 /* Recompute need to garbage collect */ | |
294 /************************************************************************/ | |
295 | |
296 int need_to_garbage_collect; | |
297 | |
298 #ifdef ERROR_CHECK_GC | |
299 int always_gc = 0; /* Debugging hack; equivalent to | |
300 (setq gc-cons-thresold -1) */ | |
301 #else | |
302 #define always_gc 0 | |
303 #endif | |
304 | |
305 /* True if it's time to garbage collect now. */ | |
306 void | |
307 recompute_need_to_garbage_collect (void) | |
308 { | |
309 if (always_gc) | |
310 need_to_garbage_collect = 1; | |
311 else | |
312 need_to_garbage_collect = | |
313 #ifdef NEW_GC | |
314 write_barrier_enabled ? | |
315 (consing_since_gc > gc_cons_incremental_threshold) : | |
316 #endif /* NEW_GC */ | |
317 (consing_since_gc > gc_cons_threshold | |
318 && | |
319 #if 0 /* #### implement this better */ | |
4115 | 320 ((double)consing_since_gc) / total_data_usage()) >= |
321 ((double)gc_cons_percentage / 100) | |
3092 | 322 #else |
323 (!total_gc_usage_set || | |
4115 | 324 ((double)consing_since_gc / total_gc_usage) >= |
325 ((double)gc_cons_percentage / 100)) | |
3092 | 326 #endif |
327 ); | |
328 recompute_funcall_allocation_flag (); | |
329 } | |
330 | |
331 | |
332 | |
333 /************************************************************************/ | |
334 /* Mark Phase */ | |
335 /************************************************************************/ | |
336 | |
337 static const struct memory_description lisp_object_description_1[] = { | |
338 { XD_LISP_OBJECT, 0 }, | |
339 { XD_END } | |
340 }; | |
341 | |
342 const struct sized_memory_description lisp_object_description = { | |
343 sizeof (Lisp_Object), | |
344 lisp_object_description_1 | |
345 }; | |
346 | |
347 #if defined (USE_KKCC) || defined (PDUMP) | |
348 | |
349 /* This function extracts the value of a count variable described somewhere | |
350 else in the description. It is converted corresponding to the type */ | |
351 EMACS_INT | |
352 lispdesc_indirect_count_1 (EMACS_INT code, | |
353 const struct memory_description *idesc, | |
354 const void *idata) | |
355 { | |
356 EMACS_INT count; | |
357 const void *irdata; | |
358 | |
359 int line = XD_INDIRECT_VAL (code); | |
360 int delta = XD_INDIRECT_DELTA (code); | |
361 | |
362 irdata = ((char *) idata) + | |
363 lispdesc_indirect_count (idesc[line].offset, idesc, idata); | |
364 switch (idesc[line].type) | |
365 { | |
366 case XD_BYTECOUNT: | |
367 count = * (Bytecount *) irdata; | |
368 break; | |
369 case XD_ELEMCOUNT: | |
370 count = * (Elemcount *) irdata; | |
371 break; | |
372 case XD_HASHCODE: | |
373 count = * (Hashcode *) irdata; | |
374 break; | |
375 case XD_INT: | |
376 count = * (int *) irdata; | |
377 break; | |
378 case XD_LONG: | |
379 count = * (long *) irdata; | |
380 break; | |
381 default: | |
382 stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n", | |
383 idesc[line].type, line, (long) code); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
384 #if defined (USE_KKCC) && defined (DEBUG_XEMACS) |
3092 | 385 if (gc_in_progress) |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
386 kkcc_detailed_backtrace (); |
3092 | 387 #endif |
388 #ifdef PDUMP | |
389 if (in_pdump) | |
390 pdump_backtrace (); | |
391 #endif | |
392 count = 0; /* warning suppression */ | |
393 ABORT (); | |
394 } | |
395 count += delta; | |
396 return count; | |
397 } | |
398 | |
399 /* SDESC is a "description map" (basically, a list of offsets used for | |
400 successive indirections) and OBJ is the first object to indirect off of. | |
401 Return the description ultimately found. */ | |
402 | |
403 const struct sized_memory_description * | |
404 lispdesc_indirect_description_1 (const void *obj, | |
405 const struct sized_memory_description *sdesc) | |
406 { | |
407 int pos; | |
408 | |
409 for (pos = 0; sdesc[pos].size >= 0; pos++) | |
410 obj = * (const void **) ((const char *) obj + sdesc[pos].size); | |
411 | |
412 return (const struct sized_memory_description *) obj; | |
413 } | |
414 | |
415 /* Compute the size of the data at RDATA, described by a single entry | |
416 DESC1 in a description array. OBJ and DESC are used for | |
417 XD_INDIRECT references. */ | |
418 | |
419 static Bytecount | |
420 lispdesc_one_description_line_size (void *rdata, | |
421 const struct memory_description *desc1, | |
422 const void *obj, | |
423 const struct memory_description *desc) | |
424 { | |
425 union_switcheroo: | |
426 switch (desc1->type) | |
427 { | |
428 case XD_LISP_OBJECT_ARRAY: | |
429 { | |
430 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj); | |
431 return (val * sizeof (Lisp_Object)); | |
432 } | |
433 case XD_LISP_OBJECT: | |
434 case XD_LO_LINK: | |
435 return sizeof (Lisp_Object); | |
436 case XD_OPAQUE_PTR: | |
437 return sizeof (void *); | |
438 #ifdef NEW_GC | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
439 case XD_INLINE_LISP_OBJECT_BLOCK_PTR: |
3092 | 440 #endif /* NEW_GC */ |
441 case XD_BLOCK_PTR: | |
442 { | |
443 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj); | |
444 return val * sizeof (void *); | |
445 } | |
446 case XD_BLOCK_ARRAY: | |
447 { | |
448 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj); | |
449 | |
450 return (val * | |
451 lispdesc_block_size | |
452 (rdata, | |
453 lispdesc_indirect_description (obj, desc1->data2.descr))); | |
454 } | |
455 case XD_OPAQUE_DATA_PTR: | |
456 return sizeof (void *); | |
457 case XD_UNION_DYNAMIC_SIZE: | |
458 { | |
459 /* If an explicit size was given in the first-level structure | |
460 description, use it; else compute size based on current union | |
461 constant. */ | |
462 const struct sized_memory_description *sdesc = | |
463 lispdesc_indirect_description (obj, desc1->data2.descr); | |
464 if (sdesc->size) | |
465 return sdesc->size; | |
466 else | |
467 { | |
468 desc1 = lispdesc_process_xd_union (desc1, desc, obj); | |
469 if (desc1) | |
470 goto union_switcheroo; | |
471 break; | |
472 } | |
473 } | |
474 case XD_UNION: | |
475 { | |
476 /* If an explicit size was given in the first-level structure | |
477 description, use it; else compute size based on maximum of all | |
478 possible structures. */ | |
479 const struct sized_memory_description *sdesc = | |
480 lispdesc_indirect_description (obj, desc1->data2.descr); | |
481 if (sdesc->size) | |
482 return sdesc->size; | |
483 else | |
484 { | |
485 int count; | |
486 Bytecount max_size = -1, size; | |
487 | |
488 desc1 = sdesc->description; | |
489 | |
490 for (count = 0; desc1[count].type != XD_END; count++) | |
491 { | |
492 size = lispdesc_one_description_line_size (rdata, | |
493 &desc1[count], | |
494 obj, desc); | |
495 if (size > max_size) | |
496 max_size = size; | |
497 } | |
498 return max_size; | |
499 } | |
500 } | |
501 case XD_ASCII_STRING: | |
502 return sizeof (void *); | |
503 case XD_DOC_STRING: | |
504 return sizeof (void *); | |
505 case XD_INT_RESET: | |
506 return sizeof (int); | |
507 case XD_BYTECOUNT: | |
508 return sizeof (Bytecount); | |
509 case XD_ELEMCOUNT: | |
510 return sizeof (Elemcount); | |
511 case XD_HASHCODE: | |
512 return sizeof (Hashcode); | |
513 case XD_INT: | |
514 return sizeof (int); | |
515 case XD_LONG: | |
516 return sizeof (long); | |
517 default: | |
518 stderr_out ("Unsupported dump type : %d\n", desc1->type); | |
519 ABORT (); | |
520 } | |
521 | |
522 return 0; | |
523 } | |
524 | |
525 | |
526 /* Return the size of the memory block (NOT necessarily a structure!) | |
527 described by SDESC and pointed to by OBJ. If SDESC records an | |
528 explicit size (i.e. non-zero), it is simply returned; otherwise, | |
529 the size is calculated by the maximum offset and the size of the | |
530 object at that offset, rounded up to the maximum alignment. In | |
531 this case, we may need the object, for example when retrieving an | |
532 "indirect count" of an inlined array (the count is not constant, | |
533 but is specified by one of the elements of the memory block). (It | |
534 is generally not a problem if we return an overly large size -- we | |
535 will simply end up reserving more space than necessary; but if the | |
536 size is too small we could be in serious trouble, in particular | |
537 with nested inlined structures, where there may be alignment | |
538 padding in the middle of a block. #### In fact there is an (at | |
539 least theoretical) problem with an overly large size -- we may | |
540 trigger a protection fault when reading from invalid memory. We | |
541 need to handle this -- perhaps in a stupid but dependable way, | |
542 i.e. by trapping SIGSEGV and SIGBUS.) */ | |
543 | |
544 Bytecount | |
545 lispdesc_block_size_1 (const void *obj, Bytecount size, | |
546 const struct memory_description *desc) | |
547 { | |
548 EMACS_INT max_offset = -1; | |
549 int max_offset_pos = -1; | |
550 int pos; | |
551 | |
552 if (size) | |
553 return size; | |
554 | |
555 for (pos = 0; desc[pos].type != XD_END; pos++) | |
556 { | |
557 EMACS_INT offset = lispdesc_indirect_count (desc[pos].offset, desc, obj); | |
558 if (offset == max_offset) | |
559 { | |
5168
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
560 #if 0 |
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
561 /* This can legitimately happen with gap arrays -- if there are |
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
562 no elements in the array, and the gap size is 0, then both |
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
563 parts of the array will be of size 0 and in the same place. */ |
3092 | 564 stderr_out ("Two relocatable elements at same offset?\n"); |
565 ABORT (); | |
5168
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
566 #endif |
3092 | 567 } |
568 else if (offset > max_offset) | |
569 { | |
570 max_offset = offset; | |
571 max_offset_pos = pos; | |
572 } | |
573 } | |
574 | |
575 if (max_offset_pos < 0) | |
576 return 0; | |
577 | |
578 { | |
579 Bytecount size_at_max; | |
580 size_at_max = | |
581 lispdesc_one_description_line_size ((char *) obj + max_offset, | |
582 &desc[max_offset_pos], obj, desc); | |
583 | |
584 /* We have no way of knowing the required alignment for this structure, | |
585 so just make it maximally aligned. */ | |
586 return MAX_ALIGN_SIZE (max_offset + size_at_max); | |
587 } | |
588 } | |
589 #endif /* defined (USE_KKCC) || defined (PDUMP) */ | |
590 | |
3263 | 591 #ifdef NEW_GC |
3092 | 592 #define GC_CHECK_NOT_FREE(lheader) \ |
593 gc_checking_assert (! LRECORD_FREE_P (lheader)); | |
3263 | 594 #else /* not NEW_GC */ |
3092 | 595 #define GC_CHECK_NOT_FREE(lheader) \ |
596 gc_checking_assert (! LRECORD_FREE_P (lheader)); \ | |
5142
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5127
diff
changeset
|
597 gc_checking_assert (LHEADER_IMPLEMENTATION (lheader)->frob_block_p || \ |
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5127
diff
changeset
|
598 ! (lheader)->free) |
3263 | 599 #endif /* not NEW_GC */ |
3092 | 600 |
601 #ifdef USE_KKCC | |
602 /* The following functions implement the new mark algorithm. | |
603 They mark objects according to their descriptions. They | |
604 are modeled on the corresponding pdumper procedures. */ | |
605 | |
606 #if 0 | |
607 # define KKCC_STACK_AS_QUEUE 1 | |
608 #endif | |
609 | |
610 #ifdef DEBUG_XEMACS | |
611 /* The backtrace for the KKCC mark functions. */ | |
612 #define KKCC_INIT_BT_STACK_SIZE 4096 | |
613 | |
614 typedef struct | |
615 { | |
616 void *obj; | |
617 const struct memory_description *desc; | |
618 int pos; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
619 int is_lisp; |
3092 | 620 } kkcc_bt_stack_entry; |
621 | |
622 static kkcc_bt_stack_entry *kkcc_bt; | |
623 static int kkcc_bt_stack_size; | |
624 static int kkcc_bt_depth = 0; | |
625 | |
626 static void | |
627 kkcc_bt_init (void) | |
628 { | |
629 kkcc_bt_depth = 0; | |
630 kkcc_bt_stack_size = KKCC_INIT_BT_STACK_SIZE; | |
631 kkcc_bt = (kkcc_bt_stack_entry *) | |
632 xmalloc_and_zero (kkcc_bt_stack_size * sizeof (kkcc_bt_stack_entry)); | |
633 if (!kkcc_bt) | |
634 { | |
635 stderr_out ("KKCC backtrace stack init failed for size %d\n", | |
636 kkcc_bt_stack_size); | |
637 ABORT (); | |
638 } | |
639 } | |
640 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
641 /* Workhorse backtrace function. Not static because may potentially be |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
642 called from a debugger. */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
643 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
644 void kkcc_backtrace_1 (int size, int detailed); |
3092 | 645 void |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
646 kkcc_backtrace_1 (int size, int detailed) |
3092 | 647 { |
648 int i; | |
649 stderr_out ("KKCC mark stack backtrace :\n"); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
650 for (i = kkcc_bt_depth - 1; i >= kkcc_bt_depth - size && i >= 0; i--) |
3092 | 651 { |
652 Lisp_Object obj = wrap_pointer_1 (kkcc_bt[i].obj); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
653 stderr_out (" [%d] ", i); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
654 if (!kkcc_bt[i].is_lisp) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
655 stderr_out ("non Lisp Object"); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
656 else if (!LRECORDP (obj)) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
657 stderr_out ("Lisp Object, non-record"); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
658 else if (XRECORD_LHEADER (obj)->type >= lrecord_type_last_built_in_type |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
659 || (!XRECORD_LHEADER_IMPLEMENTATION (obj))) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
660 stderr_out ("WARNING! Bad Lisp Object type %d", |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
661 XRECORD_LHEADER (obj)->type); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
662 else |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
663 stderr_out ("%s", XRECORD_LHEADER_IMPLEMENTATION (obj)->name); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
664 if (detailed && kkcc_bt[i].is_lisp) |
3092 | 665 { |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
666 stderr_out (" "); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
667 debug_print (obj); |
3092 | 668 } |
3519 | 669 stderr_out (" (addr: %p, desc: %p, ", |
670 (void *) kkcc_bt[i].obj, | |
671 (void *) kkcc_bt[i].desc); | |
3092 | 672 if (kkcc_bt[i].pos >= 0) |
673 stderr_out ("pos: %d)\n", kkcc_bt[i].pos); | |
674 else | |
675 if (kkcc_bt[i].pos == -1) | |
676 stderr_out ("root set)\n"); | |
677 else if (kkcc_bt[i].pos == -2) | |
678 stderr_out ("dirty object)\n"); | |
679 } | |
680 } | |
681 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
682 /* Various front ends onto kkcc_backtrace_1(), meant to be called from |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
683 a debugger. |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
684 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
685 The variants are: |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
686 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
687 normal vs _full(): Normal displays up to the topmost 100 items on the |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
688 stack, whereas full displays all items (even if there are thousands) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
689 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
690 _detailed_() vs _short_(): Detailed here means print out the actual |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
691 Lisp objects on the stack using debug_print() in addition to their type, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
692 whereas short means only show the type |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
693 */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
694 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
695 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
696 kkcc_detailed_backtrace (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
697 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
698 kkcc_backtrace_1 (100, 1); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
699 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
700 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
701 void kkcc_short_backtrace (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
702 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
703 kkcc_short_backtrace (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
704 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
705 kkcc_backtrace_1 (100, 0); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
706 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
707 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
708 void kkcc_detailed_backtrace_full (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
709 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
710 kkcc_detailed_backtrace_full (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
711 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
712 kkcc_backtrace_1 (kkcc_bt_depth, 1); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
713 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
714 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
715 void kkcc_short_backtrace_full (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
716 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
717 kkcc_short_backtrace_full (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
718 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
719 kkcc_backtrace_1 (kkcc_bt_depth, 0); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
720 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
721 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
722 /* Short versions for ease in calling from a debugger */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
723 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
724 void kbt (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
725 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
726 kbt (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
727 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
728 kkcc_detailed_backtrace (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
729 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
730 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
731 void kbts (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
732 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
733 kbts (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
734 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
735 kkcc_short_backtrace (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
736 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
737 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
738 void kbtf (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
739 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
740 kbtf (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
741 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
742 kkcc_detailed_backtrace_full (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
743 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
744 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
745 void kbtsf (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
746 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
747 kbtsf (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
748 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
749 kkcc_short_backtrace_full (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
750 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
751 |
3092 | 752 static void |
753 kkcc_bt_stack_realloc (void) | |
754 { | |
755 kkcc_bt_stack_size *= 2; | |
756 kkcc_bt = (kkcc_bt_stack_entry *) | |
757 xrealloc (kkcc_bt, kkcc_bt_stack_size * sizeof (kkcc_bt_stack_entry)); | |
758 if (!kkcc_bt) | |
759 { | |
760 stderr_out ("KKCC backtrace stack realloc failed for size %d\n", | |
761 kkcc_bt_stack_size); | |
762 ABORT (); | |
763 } | |
764 } | |
765 | |
766 static void | |
767 kkcc_bt_free (void) | |
768 { | |
769 xfree_1 (kkcc_bt); | |
770 kkcc_bt = 0; | |
771 kkcc_bt_stack_size = 0; | |
772 } | |
773 | |
774 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
775 kkcc_bt_push (void *obj, const struct memory_description *desc, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
776 int is_lisp DECLARE_KKCC_DEBUG_ARGS) |
3092 | 777 { |
778 kkcc_bt_depth = level; | |
779 kkcc_bt[kkcc_bt_depth].obj = obj; | |
780 kkcc_bt[kkcc_bt_depth].desc = desc; | |
781 kkcc_bt[kkcc_bt_depth].pos = pos; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
782 kkcc_bt[kkcc_bt_depth].is_lisp = is_lisp; |
3092 | 783 kkcc_bt_depth++; |
784 if (kkcc_bt_depth >= kkcc_bt_stack_size) | |
785 kkcc_bt_stack_realloc (); | |
786 } | |
787 | |
788 #else /* not DEBUG_XEMACS */ | |
789 #define kkcc_bt_init() | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
790 #define kkcc_bt_push(obj, desc) |
3092 | 791 #endif /* not DEBUG_XEMACS */ |
792 | |
793 /* Object memory descriptions are in the lrecord_implementation structure. | |
794 But copying them to a parallel array is much more cache-friendly. */ | |
795 const struct memory_description *lrecord_memory_descriptions[countof (lrecord_implementations_table)]; | |
796 | |
797 /* the initial stack size in kkcc_gc_stack_entries */ | |
798 #define KKCC_INIT_GC_STACK_SIZE 16384 | |
799 | |
800 typedef struct | |
801 { | |
802 void *data; | |
803 const struct memory_description *desc; | |
804 #ifdef DEBUG_XEMACS | |
805 int level; | |
806 int pos; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
807 int is_lisp; |
3092 | 808 #endif |
809 } kkcc_gc_stack_entry; | |
810 | |
811 | |
812 static kkcc_gc_stack_entry *kkcc_gc_stack_ptr; | |
813 static int kkcc_gc_stack_front; | |
814 static int kkcc_gc_stack_rear; | |
815 static int kkcc_gc_stack_size; | |
816 | |
817 #define KKCC_INC(i) ((i + 1) % kkcc_gc_stack_size) | |
818 #define KKCC_INC2(i) ((i + 2) % kkcc_gc_stack_size) | |
819 | |
820 #define KKCC_GC_STACK_FULL (KKCC_INC2 (kkcc_gc_stack_rear) == kkcc_gc_stack_front) | |
821 #define KKCC_GC_STACK_EMPTY (KKCC_INC (kkcc_gc_stack_rear) == kkcc_gc_stack_front) | |
822 | |
823 static void | |
824 kkcc_gc_stack_init (void) | |
825 { | |
826 kkcc_gc_stack_size = KKCC_INIT_GC_STACK_SIZE; | |
827 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
828 xmalloc_and_zero (kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
829 if (!kkcc_gc_stack_ptr) | |
830 { | |
831 stderr_out ("stack init failed for size %d\n", kkcc_gc_stack_size); | |
832 ABORT (); | |
833 } | |
834 kkcc_gc_stack_front = 0; | |
835 kkcc_gc_stack_rear = kkcc_gc_stack_size - 1; | |
836 } | |
837 | |
838 static void | |
839 kkcc_gc_stack_free (void) | |
840 { | |
841 xfree_1 (kkcc_gc_stack_ptr); | |
842 kkcc_gc_stack_ptr = 0; | |
843 kkcc_gc_stack_front = 0; | |
844 kkcc_gc_stack_rear = 0; | |
845 kkcc_gc_stack_size = 0; | |
846 } | |
847 | |
848 static void | |
849 kkcc_gc_stack_realloc (void) | |
850 { | |
851 kkcc_gc_stack_entry *old_ptr = kkcc_gc_stack_ptr; | |
852 int old_size = kkcc_gc_stack_size; | |
853 kkcc_gc_stack_size *= 2; | |
854 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
855 xmalloc_and_zero (kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
856 if (!kkcc_gc_stack_ptr) | |
857 { | |
858 stderr_out ("stack realloc failed for size %d\n", kkcc_gc_stack_size); | |
859 ABORT (); | |
860 } | |
861 if (kkcc_gc_stack_rear >= kkcc_gc_stack_front) | |
862 { | |
863 int number_elements = kkcc_gc_stack_rear - kkcc_gc_stack_front + 1; | |
864 memcpy (kkcc_gc_stack_ptr, &old_ptr[kkcc_gc_stack_front], | |
865 number_elements * sizeof (kkcc_gc_stack_entry)); | |
866 kkcc_gc_stack_front = 0; | |
867 kkcc_gc_stack_rear = number_elements - 1; | |
868 } | |
869 else | |
870 { | |
871 int number_elements = old_size - kkcc_gc_stack_front; | |
872 memcpy (kkcc_gc_stack_ptr, &old_ptr[kkcc_gc_stack_front], | |
873 number_elements * sizeof (kkcc_gc_stack_entry)); | |
874 memcpy (&kkcc_gc_stack_ptr[number_elements], &old_ptr[0], | |
875 (kkcc_gc_stack_rear + 1) * sizeof (kkcc_gc_stack_entry)); | |
876 kkcc_gc_stack_front = 0; | |
877 kkcc_gc_stack_rear = kkcc_gc_stack_rear + number_elements; | |
878 } | |
879 xfree_1 (old_ptr); | |
880 } | |
881 | |
882 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
883 kkcc_gc_stack_push (void *data, const struct memory_description *desc |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
884 DECLARE_KKCC_DEBUG_ARGS) |
3092 | 885 { |
886 #ifdef NEW_GC | |
887 GC_STAT_ENQUEUED; | |
888 #endif /* NEW_GC */ | |
889 if (KKCC_GC_STACK_FULL) | |
890 kkcc_gc_stack_realloc(); | |
891 kkcc_gc_stack_rear = KKCC_INC (kkcc_gc_stack_rear); | |
892 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].data = data; | |
893 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].desc = desc; | |
894 #ifdef DEBUG_XEMACS | |
895 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].level = level; | |
896 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].pos = pos; | |
897 #endif | |
898 } | |
899 | |
900 #ifdef DEBUG_XEMACS | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
901 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
902 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
903 kkcc_gc_stack_push_0 (void *data, const struct memory_description *desc, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
904 int is_lisp DECLARE_KKCC_DEBUG_ARGS) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
905 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
906 kkcc_gc_stack_push (data, desc KKCC_DEBUG_ARGS); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
907 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].is_lisp = is_lisp; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
908 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
909 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
910 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
911 kkcc_gc_stack_push_lisp (void *data, const struct memory_description *desc |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
912 DECLARE_KKCC_DEBUG_ARGS) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
913 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
914 kkcc_gc_stack_push_0 (data, desc, 1 KKCC_DEBUG_ARGS); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
915 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
916 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
917 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
918 kkcc_gc_stack_push_nonlisp (void *data, const struct memory_description *desc |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
919 DECLARE_KKCC_DEBUG_ARGS) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
920 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
921 kkcc_gc_stack_push_0 (data, desc, 0 KKCC_DEBUG_ARGS); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
922 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
923 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
924 #else /* not DEBUG_XEMACS */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
925 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
926 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
927 kkcc_gc_stack_push_lisp (void *data, const struct memory_description *desc) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
928 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
929 kkcc_gc_stack_push (data, desc); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
930 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
931 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
932 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
933 kkcc_gc_stack_push_nonlisp (void *data, const struct memory_description *desc) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
934 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
935 kkcc_gc_stack_push (data, desc); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
936 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
937 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
938 #endif /* (not) DEBUG_XEMACS */ |
3092 | 939 |
940 static kkcc_gc_stack_entry * | |
941 kkcc_gc_stack_pop (void) | |
942 { | |
943 if (KKCC_GC_STACK_EMPTY) | |
944 return 0; | |
945 #ifdef NEW_GC | |
946 GC_STAT_DEQUEUED; | |
947 #endif /* NEW_GC */ | |
948 #ifndef KKCC_STACK_AS_QUEUE | |
949 /* stack behaviour */ | |
950 return &kkcc_gc_stack_ptr[kkcc_gc_stack_rear--]; | |
951 #else | |
952 /* queue behaviour */ | |
953 { | |
954 int old_front = kkcc_gc_stack_front; | |
955 kkcc_gc_stack_front = KKCC_INC (kkcc_gc_stack_front); | |
956 return &kkcc_gc_stack_ptr[old_front]; | |
957 } | |
958 #endif | |
959 } | |
960 | |
961 void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
962 kkcc_gc_stack_push_lisp_object (Lisp_Object obj DECLARE_KKCC_DEBUG_ARGS) |
3092 | 963 { |
964 if (XTYPE (obj) == Lisp_Type_Record) | |
965 { | |
966 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
967 const struct memory_description *desc; | |
968 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
969 desc = RECORD_DESCRIPTION (lheader); | |
970 if (! MARKED_RECORD_HEADER_P (lheader)) | |
971 { | |
972 #ifdef NEW_GC | |
973 MARK_GREY (lheader); | |
974 #else /* not NEW_GC */ | |
975 MARK_RECORD_HEADER (lheader); | |
976 #endif /* not NEW_GC */ | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
977 kkcc_gc_stack_push_lisp ((void *) lheader, desc KKCC_DEBUG_ARGS); |
3092 | 978 } |
979 } | |
980 } | |
981 | |
982 #ifdef NEW_GC | |
983 | |
984 void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
985 kkcc_gc_stack_repush_dirty_object (Lisp_Object obj DECLARE_KKCC_DEBUG_ARGS) |
3092 | 986 { |
987 if (XTYPE (obj) == Lisp_Type_Record) | |
988 { | |
989 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
990 const struct memory_description *desc; | |
991 GC_STAT_REPUSHED; | |
992 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
993 desc = RECORD_DESCRIPTION (lheader); | |
994 MARK_GREY (lheader); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
995 kkcc_gc_stack_push_lisp ((void*) lheader, desc KKCC_DEBUG_ARGS); |
3092 | 996 } |
997 } | |
998 #endif /* NEW_GC */ | |
999 | |
1000 #ifdef ERROR_CHECK_GC | |
1001 #define KKCC_DO_CHECK_FREE(obj, allow_free) \ | |
1002 do \ | |
1003 { \ | |
1004 if (!allow_free && XTYPE (obj) == Lisp_Type_Record) \ | |
1005 { \ | |
1006 struct lrecord_header *lheader = XRECORD_LHEADER (obj); \ | |
1007 GC_CHECK_NOT_FREE (lheader); \ | |
1008 } \ | |
1009 } while (0) | |
1010 #else | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1011 #define KKCC_DO_CHECK_FREE(obj, allow_free) DO_NOTHING |
3092 | 1012 #endif |
1013 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1014 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1015 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1016 DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1017 { |
1018 KKCC_DO_CHECK_FREE (obj, allow_free); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1019 kkcc_gc_stack_push_lisp_object (obj KKCC_DEBUG_ARGS); |
3092 | 1020 } |
1021 | |
1022 /* This function loops all elements of a struct pointer and calls | |
1023 mark_with_description with each element. */ | |
1024 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1025 mark_struct_contents (const void *data, |
3092 | 1026 const struct sized_memory_description *sdesc, |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1027 int count DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1028 { |
1029 int i; | |
1030 Bytecount elsize; | |
1031 elsize = lispdesc_block_size (data, sdesc); | |
1032 | |
1033 for (i = 0; i < count; i++) | |
1034 { | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1035 kkcc_gc_stack_push_nonlisp (((char *) data) + elsize * i, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1036 sdesc->description |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1037 KKCC_DEBUG_ARGS); |
3092 | 1038 } |
1039 } | |
1040 | |
1041 #ifdef NEW_GC | |
1042 /* This function loops all elements of a struct pointer and calls | |
1043 mark_with_description with each element. */ | |
1044 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1045 mark_lisp_object_block_contents (const void *data, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1046 const struct sized_memory_description *sdesc, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1047 int count DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1048 { |
1049 int i; | |
1050 Bytecount elsize; | |
1051 elsize = lispdesc_block_size (data, sdesc); | |
1052 | |
1053 for (i = 0; i < count; i++) | |
1054 { | |
1055 const Lisp_Object obj = wrap_pointer_1 (((char *) data) + elsize * i); | |
1056 if (XTYPE (obj) == Lisp_Type_Record) | |
1057 { | |
1058 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1059 const struct memory_description *desc; | |
1060 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1061 desc = sdesc->description; | |
1062 if (! MARKED_RECORD_HEADER_P (lheader)) | |
1063 { | |
1064 MARK_GREY (lheader); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1065 kkcc_gc_stack_push_lisp ((void *) lheader, desc KKCC_DEBUG_ARGS); |
3092 | 1066 } |
1067 } | |
1068 } | |
1069 } | |
1070 | |
1071 #endif /* not NEW_GC */ | |
1072 | |
1073 /* This function implements the KKCC mark algorithm. | |
1074 Instead of calling mark_object, all the alive Lisp_Objects are pushed | |
1075 on the kkcc_gc_stack. This function processes all elements on the stack | |
1076 according to their descriptions. */ | |
1077 static void | |
5054 | 1078 kkcc_marking (int USED_IF_NEW_GC (cnt)) |
3092 | 1079 { |
1080 kkcc_gc_stack_entry *stack_entry = 0; | |
1081 void *data = 0; | |
1082 const struct memory_description *desc = 0; | |
1083 int pos; | |
1084 #ifdef NEW_GC | |
5046 | 1085 int obj_count = cnt; |
3092 | 1086 #endif /* NEW_GC */ |
1087 #ifdef DEBUG_XEMACS | |
1088 int level = 0; | |
1089 #endif | |
1090 | |
1091 while ((stack_entry = kkcc_gc_stack_pop ()) != 0) | |
1092 { | |
1093 data = stack_entry->data; | |
1094 desc = stack_entry->desc; | |
1095 #ifdef DEBUG_XEMACS | |
1096 level = stack_entry->level + 1; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1097 kkcc_bt_push (data, desc, stack_entry->is_lisp, stack_entry->level, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1098 stack_entry->pos); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1099 #else |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1100 kkcc_bt_push (data, desc); |
3092 | 1101 #endif |
1102 | |
1103 #ifdef NEW_GC | |
1104 /* Mark black if object is currently grey. This first checks, | |
1105 if the object is really allocated on the mc-heap. If it is, | |
1106 it can be marked black; if it is not, it cannot be marked. */ | |
1107 maybe_mark_black (data); | |
1108 #endif /* NEW_GC */ | |
1109 | |
1110 if (!data) continue; | |
1111 | |
1112 gc_checking_assert (data); | |
1113 gc_checking_assert (desc); | |
1114 | |
1115 for (pos = 0; desc[pos].type != XD_END; pos++) | |
1116 { | |
1117 const struct memory_description *desc1 = &desc[pos]; | |
1118 const void *rdata = | |
1119 (const char *) data + lispdesc_indirect_count (desc1->offset, | |
1120 desc, data); | |
1121 union_switcheroo: | |
1122 | |
1123 /* If the flag says don't mark, then don't mark. */ | |
1124 if ((desc1->flags) & XD_FLAG_NO_KKCC) | |
1125 continue; | |
1126 | |
1127 switch (desc1->type) | |
1128 { | |
1129 case XD_BYTECOUNT: | |
1130 case XD_ELEMCOUNT: | |
1131 case XD_HASHCODE: | |
1132 case XD_INT: | |
1133 case XD_LONG: | |
1134 case XD_INT_RESET: | |
1135 case XD_LO_LINK: | |
1136 case XD_OPAQUE_PTR: | |
1137 case XD_OPAQUE_DATA_PTR: | |
1138 case XD_ASCII_STRING: | |
1139 case XD_DOC_STRING: | |
1140 break; | |
1141 case XD_LISP_OBJECT: | |
1142 { | |
1143 const Lisp_Object *stored_obj = (const Lisp_Object *) rdata; | |
1144 | |
1145 /* Because of the way that tagged objects work (pointers and | |
1146 Lisp_Objects have the same representation), XD_LISP_OBJECT | |
1147 can be used for untagged pointers. They might be NULL, | |
1148 though. */ | |
1149 if (EQ (*stored_obj, Qnull_pointer)) | |
1150 break; | |
3263 | 1151 #ifdef NEW_GC |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1152 mark_object_maybe_checking_free (*stored_obj, 0 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1153 KKCC_DEBUG_ARGS); |
3263 | 1154 #else /* not NEW_GC */ |
3092 | 1155 mark_object_maybe_checking_free |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1156 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1157 KKCC_DEBUG_ARGS); |
3263 | 1158 #endif /* not NEW_GC */ |
3092 | 1159 break; |
1160 } | |
1161 case XD_LISP_OBJECT_ARRAY: | |
1162 { | |
1163 int i; | |
1164 EMACS_INT count = | |
1165 lispdesc_indirect_count (desc1->data1, desc, data); | |
1166 | |
1167 for (i = 0; i < count; i++) | |
1168 { | |
1169 const Lisp_Object *stored_obj = | |
1170 (const Lisp_Object *) rdata + i; | |
1171 | |
1172 if (EQ (*stored_obj, Qnull_pointer)) | |
1173 break; | |
3263 | 1174 #ifdef NEW_GC |
3092 | 1175 mark_object_maybe_checking_free |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1176 (*stored_obj, 0 KKCC_DEBUG_ARGS); |
3263 | 1177 #else /* not NEW_GC */ |
3092 | 1178 mark_object_maybe_checking_free |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1179 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1180 KKCC_DEBUG_ARGS); |
3263 | 1181 #endif /* not NEW_GC */ |
3092 | 1182 } |
1183 break; | |
1184 } | |
1185 #ifdef NEW_GC | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1186 case XD_INLINE_LISP_OBJECT_BLOCK_PTR: |
3092 | 1187 { |
1188 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | |
1189 data); | |
1190 const struct sized_memory_description *sdesc = | |
1191 lispdesc_indirect_description (data, desc1->data2.descr); | |
1192 const char *dobj = * (const char **) rdata; | |
1193 if (dobj) | |
1194 mark_lisp_object_block_contents | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1195 (dobj, sdesc, count KKCC_DEBUG_ARGS); |
3092 | 1196 break; |
1197 } | |
1198 #endif /* NEW_GC */ | |
1199 case XD_BLOCK_PTR: | |
1200 { | |
1201 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | |
1202 data); | |
1203 const struct sized_memory_description *sdesc = | |
1204 lispdesc_indirect_description (data, desc1->data2.descr); | |
1205 const char *dobj = * (const char **) rdata; | |
1206 if (dobj) | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1207 mark_struct_contents (dobj, sdesc, count KKCC_DEBUG_ARGS); |
3092 | 1208 break; |
1209 } | |
1210 case XD_BLOCK_ARRAY: | |
1211 { | |
1212 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | |
1213 data); | |
1214 const struct sized_memory_description *sdesc = | |
1215 lispdesc_indirect_description (data, desc1->data2.descr); | |
1216 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1217 mark_struct_contents (rdata, sdesc, count KKCC_DEBUG_ARGS); |
3092 | 1218 break; |
1219 } | |
1220 case XD_UNION: | |
1221 case XD_UNION_DYNAMIC_SIZE: | |
1222 desc1 = lispdesc_process_xd_union (desc1, desc, data); | |
1223 if (desc1) | |
1224 goto union_switcheroo; | |
1225 break; | |
1226 | |
1227 default: | |
1228 stderr_out ("Unsupported description type : %d\n", desc1->type); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1229 kkcc_detailed_backtrace (); |
3092 | 1230 ABORT (); |
1231 } | |
1232 } | |
1233 | |
1234 #ifdef NEW_GC | |
1235 if (cnt) | |
5046 | 1236 if (!--obj_count) |
3092 | 1237 break; |
1238 #endif /* NEW_GC */ | |
1239 } | |
1240 } | |
1241 #endif /* USE_KKCC */ | |
1242 | |
1243 /* I hate duplicating all this crap! */ | |
1244 int | |
1245 marked_p (Lisp_Object obj) | |
1246 { | |
1247 /* Checks we used to perform. */ | |
1248 /* if (EQ (obj, Qnull_pointer)) return 1; */ | |
1249 /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return 1; */ | |
1250 /* if (PURIFIED (XPNTR (obj))) return 1; */ | |
1251 | |
1252 if (XTYPE (obj) == Lisp_Type_Record) | |
1253 { | |
1254 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1255 | |
1256 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1257 | |
1258 return MARKED_RECORD_HEADER_P (lheader); | |
1259 } | |
1260 return 1; | |
1261 } | |
1262 | |
1263 | |
1264 /* Mark reference to a Lisp_Object. If the object referred to has not been | |
1265 seen yet, recursively mark all the references contained in it. */ | |
1266 void | |
1267 mark_object ( | |
1268 #ifdef USE_KKCC | |
1269 Lisp_Object UNUSED (obj) | |
1270 #else | |
1271 Lisp_Object obj | |
1272 #endif | |
1273 ) | |
1274 { | |
1275 #ifdef USE_KKCC | |
1276 /* this code should never be reached when configured for KKCC */ | |
1277 stderr_out ("KKCC: Invalid mark_object call.\n"); | |
1278 stderr_out ("Replace mark_object with kkcc_gc_stack_push_lisp_object.\n"); | |
1279 ABORT (); | |
1280 #else /* not USE_KKCC */ | |
1281 | |
1282 tail_recurse: | |
1283 | |
1284 /* Checks we used to perform */ | |
1285 /* if (EQ (obj, Qnull_pointer)) return; */ | |
1286 /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return; */ | |
1287 /* if (PURIFIED (XPNTR (obj))) return; */ | |
1288 | |
1289 if (XTYPE (obj) == Lisp_Type_Record) | |
1290 { | |
1291 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1292 | |
1293 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1294 | |
1295 /* We handle this separately, above, so we can mark free objects */ | |
1296 GC_CHECK_NOT_FREE (lheader); | |
1297 | |
1298 /* All c_readonly objects have their mark bit set, | |
1299 so that we only need to check the mark bit here. */ | |
1300 if (! MARKED_RECORD_HEADER_P (lheader)) | |
1301 { | |
1302 MARK_RECORD_HEADER (lheader); | |
1303 | |
1304 if (RECORD_MARKER (lheader)) | |
1305 { | |
1306 obj = RECORD_MARKER (lheader) (obj); | |
1307 if (!NILP (obj)) goto tail_recurse; | |
1308 } | |
1309 } | |
1310 } | |
1311 #endif /* not KKCC */ | |
1312 } | |
1313 | |
1314 | |
1315 /************************************************************************/ | |
1316 /* Hooks */ | |
1317 /************************************************************************/ | |
1318 | |
1319 /* Nonzero when calling certain hooks or doing other things where a GC | |
1320 would be bad. It prevents infinite recursive calls to gc. */ | |
1321 int gc_currently_forbidden; | |
1322 | |
1323 int | |
1324 begin_gc_forbidden (void) | |
1325 { | |
1326 return internal_bind_int (&gc_currently_forbidden, 1); | |
1327 } | |
1328 | |
1329 void | |
1330 end_gc_forbidden (int count) | |
1331 { | |
1332 unbind_to (count); | |
1333 } | |
1334 | |
1335 /* Hooks. */ | |
1336 Lisp_Object Vpre_gc_hook, Qpre_gc_hook; | |
1337 Lisp_Object Vpost_gc_hook, Qpost_gc_hook; | |
1338 | |
1339 /* Maybe we want to use this when doing a "panic" gc after memory_full()? */ | |
1340 static int gc_hooks_inhibited; | |
1341 | |
1342 struct post_gc_action | |
1343 { | |
1344 void (*fun) (void *); | |
1345 void *arg; | |
1346 }; | |
1347 | |
1348 typedef struct post_gc_action post_gc_action; | |
1349 | |
1350 typedef struct | |
1351 { | |
1352 Dynarr_declare (post_gc_action); | |
1353 } post_gc_action_dynarr; | |
1354 | |
1355 static post_gc_action_dynarr *post_gc_actions; | |
1356 | |
1357 /* Register an action to be called at the end of GC. | |
1358 gc_in_progress is 0 when this is called. | |
1359 This is used when it is discovered that an action needs to be taken, | |
1360 but it's during GC, so it's not safe. (e.g. in a finalize method.) | |
1361 | |
1362 As a general rule, do not use Lisp objects here. | |
1363 And NEVER signal an error. | |
1364 */ | |
1365 | |
1366 void | |
1367 register_post_gc_action (void (*fun) (void *), void *arg) | |
1368 { | |
1369 post_gc_action action; | |
1370 | |
1371 if (!post_gc_actions) | |
1372 post_gc_actions = Dynarr_new (post_gc_action); | |
1373 | |
1374 action.fun = fun; | |
1375 action.arg = arg; | |
1376 | |
1377 Dynarr_add (post_gc_actions, action); | |
1378 } | |
1379 | |
1380 static void | |
1381 run_post_gc_actions (void) | |
1382 { | |
1383 int i; | |
1384 | |
1385 if (post_gc_actions) | |
1386 { | |
1387 for (i = 0; i < Dynarr_length (post_gc_actions); i++) | |
1388 { | |
1389 post_gc_action action = Dynarr_at (post_gc_actions, i); | |
1390 (action.fun) (action.arg); | |
1391 } | |
1392 | |
1393 Dynarr_reset (post_gc_actions); | |
1394 } | |
1395 } | |
1396 | |
3263 | 1397 #ifdef NEW_GC |
1398 /* Asynchronous finalization. */ | |
1399 typedef struct finalize_elem | |
1400 { | |
1401 Lisp_Object obj; | |
1402 struct finalize_elem *next; | |
1403 } finalize_elem; | |
1404 | |
1405 finalize_elem *Vall_finalizable_objs; | |
1406 Lisp_Object Vfinalizers_to_run; | |
1407 | |
1408 void | |
1409 add_finalizable_obj (Lisp_Object obj) | |
1410 { | |
1411 finalize_elem *next = Vall_finalizable_objs; | |
1412 Vall_finalizable_objs = | |
1413 (finalize_elem *) xmalloc_and_zero (sizeof (finalize_elem)); | |
1414 Vall_finalizable_objs->obj = obj; | |
1415 Vall_finalizable_objs->next = next; | |
1416 } | |
1417 | |
1418 void | |
1419 register_for_finalization (void) | |
1420 { | |
1421 finalize_elem *rest = Vall_finalizable_objs; | |
1422 | |
1423 if (!rest) | |
1424 return; | |
1425 | |
1426 while (!marked_p (rest->obj)) | |
1427 { | |
1428 finalize_elem *temp = rest; | |
1429 Vfinalizers_to_run = Fcons (rest->obj, Vfinalizers_to_run); | |
1430 Vall_finalizable_objs = rest->next; | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1431 xfree (temp); |
3263 | 1432 rest = Vall_finalizable_objs; |
1433 } | |
1434 | |
1435 while (rest->next) | |
1436 { | |
1437 if (LRECORDP (rest->next->obj) | |
1438 && !marked_p (rest->next->obj)) | |
1439 { | |
1440 finalize_elem *temp = rest->next; | |
1441 Vfinalizers_to_run = Fcons (rest->next->obj, Vfinalizers_to_run); | |
1442 rest->next = rest->next->next; | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1443 xfree (temp); |
3263 | 1444 } |
1445 else | |
1446 { | |
1447 rest = rest->next; | |
1448 } | |
1449 } | |
1450 /* Keep objects alive that need to be finalized by marking | |
1451 Vfinalizers_to_run transitively. */ | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1452 kkcc_gc_stack_push_lisp_object_0 (Vfinalizers_to_run); |
3263 | 1453 kkcc_marking (0); |
1454 } | |
1455 | |
1456 void | |
1457 run_finalizers (void) | |
1458 { | |
1459 Lisp_Object rest; | |
1460 for (rest = Vfinalizers_to_run; !NILP (rest); rest = XCDR (rest)) | |
1461 { | |
1462 MC_ALLOC_CALL_FINALIZER (XPNTR (XCAR (rest))); | |
1463 } | |
1464 Vfinalizers_to_run = Qnil; | |
1465 } | |
1466 #endif /* not NEW_GC */ | |
3092 | 1467 |
1468 | |
1469 /************************************************************************/ | |
1470 /* Garbage Collection */ | |
1471 /************************************************************************/ | |
1472 | |
1473 /* Enable/disable incremental garbage collection during runtime. */ | |
1474 int allow_incremental_gc; | |
1475 | |
1476 /* For profiling. */ | |
1477 static Lisp_Object QSin_garbage_collection; | |
1478 | |
1479 /* Nonzero means display messages at beginning and end of GC. */ | |
1480 int garbage_collection_messages; | |
1481 | |
1482 /* "Garbage collecting" */ | |
1483 Lisp_Object Vgc_message; | |
1484 Lisp_Object Vgc_pointer_glyph; | |
1485 static const Ascbyte gc_default_message[] = "Garbage collecting"; | |
1486 Lisp_Object Qgarbage_collecting; | |
1487 | |
1488 /* "Locals" during GC. */ | |
1489 struct frame *f; | |
1490 int speccount; | |
1491 int cursor_changed; | |
1492 Lisp_Object pre_gc_cursor; | |
1493 | |
1494 /* PROFILE_DECLARE */ | |
1495 int do_backtrace; | |
1496 struct backtrace backtrace; | |
1497 | |
1498 /* Maximum amount of C stack to save when a GC happens. */ | |
1499 #ifndef MAX_SAVE_STACK | |
1500 #define MAX_SAVE_STACK 0 /* 16000 */ | |
1501 #endif | |
1502 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1503 static void |
3267 | 1504 show_gc_cursor_and_message (void) |
3092 | 1505 { |
3267 | 1506 /* Now show the GC cursor/message. */ |
1507 pre_gc_cursor = Qnil; | |
1508 cursor_changed = 0; | |
3092 | 1509 |
1510 /* We used to call selected_frame() here. | |
1511 | |
1512 The following functions cannot be called inside GC | |
1513 so we move to after the above tests. */ | |
1514 { | |
1515 Lisp_Object frame; | |
1516 Lisp_Object device = Fselected_device (Qnil); | |
1517 if (NILP (device)) /* Could happen during startup, eg. if always_gc */ | |
1518 return; | |
1519 frame = Fselected_frame (device); | |
1520 if (NILP (frame)) | |
1521 invalid_state ("No frames exist on device", device); | |
1522 f = XFRAME (frame); | |
1523 } | |
1524 | |
1525 if (!noninteractive) | |
1526 { | |
1527 if (FRAME_WIN_P (f)) | |
1528 { | |
1529 Lisp_Object frame = wrap_frame (f); | |
1530 Lisp_Object cursor = glyph_image_instance (Vgc_pointer_glyph, | |
1531 FRAME_SELECTED_WINDOW (f), | |
1532 ERROR_ME_NOT, 1); | |
1533 pre_gc_cursor = f->pointer; | |
1534 if (POINTER_IMAGE_INSTANCEP (cursor) | |
1535 /* don't change if we don't know how to change back. */ | |
1536 && POINTER_IMAGE_INSTANCEP (pre_gc_cursor)) | |
1537 { | |
1538 cursor_changed = 1; | |
1539 Fset_frame_pointer (frame, cursor); | |
1540 } | |
1541 } | |
1542 | |
1543 /* Don't print messages to the stream device. */ | |
1544 if (!cursor_changed && !FRAME_STREAM_P (f)) | |
1545 { | |
1546 if (garbage_collection_messages) | |
1547 { | |
1548 Lisp_Object args[2], whole_msg; | |
1549 args[0] = (STRINGP (Vgc_message) ? Vgc_message : | |
1550 build_msg_string (gc_default_message)); | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4934
diff
changeset
|
1551 args[1] = build_ascstring ("..."); |
3092 | 1552 whole_msg = Fconcat (2, args); |
1553 echo_area_message (f, (Ibyte *) 0, whole_msg, 0, -1, | |
1554 Qgarbage_collecting); | |
1555 } | |
1556 } | |
1557 } | |
3267 | 1558 } |
1559 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1560 static void |
3267 | 1561 remove_gc_cursor_and_message (void) |
1562 { | |
1563 /* Now remove the GC cursor/message */ | |
1564 if (!noninteractive) | |
1565 { | |
1566 if (cursor_changed) | |
1567 Fset_frame_pointer (wrap_frame (f), pre_gc_cursor); | |
1568 else if (!FRAME_STREAM_P (f)) | |
1569 { | |
1570 /* Show "...done" only if the echo area would otherwise be empty. */ | |
1571 if (NILP (clear_echo_area (selected_frame (), | |
1572 Qgarbage_collecting, 0))) | |
1573 { | |
1574 if (garbage_collection_messages) | |
1575 { | |
1576 Lisp_Object args[2], whole_msg; | |
1577 args[0] = (STRINGP (Vgc_message) ? Vgc_message : | |
1578 build_msg_string (gc_default_message)); | |
1579 args[1] = build_msg_string ("... done"); | |
1580 whole_msg = Fconcat (2, args); | |
1581 echo_area_message (selected_frame (), (Ibyte *) 0, | |
1582 whole_msg, 0, -1, | |
1583 Qgarbage_collecting); | |
1584 } | |
1585 } | |
1586 } | |
1587 } | |
1588 } | |
1589 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1590 static void |
3267 | 1591 gc_prepare (void) |
1592 { | |
1593 #if MAX_SAVE_STACK > 0 | |
1594 char stack_top_variable; | |
1595 extern char *stack_bottom; | |
1596 #endif | |
1597 | |
1598 #ifdef NEW_GC | |
1599 GC_STAT_START_NEW_GC; | |
1600 GC_SET_PHASE (INIT_GC); | |
1601 #endif /* NEW_GC */ | |
1602 | |
1603 do_backtrace = profiling_active || backtrace_with_internal_sections; | |
1604 | |
1605 assert (!gc_in_progress); | |
1606 assert (!in_display || gc_currently_forbidden); | |
1607 | |
1608 PROFILE_RECORD_ENTERING_SECTION (QSin_garbage_collection); | |
1609 | |
1610 need_to_signal_post_gc = 0; | |
1611 recompute_funcall_allocation_flag (); | |
1612 | |
1613 if (!gc_hooks_inhibited) | |
1614 run_hook_trapping_problems | |
1615 (Qgarbage_collecting, Qpre_gc_hook, | |
1616 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION); | |
3092 | 1617 |
1618 /***** Now we actually start the garbage collection. */ | |
1619 | |
1620 gc_in_progress = 1; | |
1621 #ifndef NEW_GC | |
5014
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
1622 inhibit_non_essential_conversion_operations++; |
3263 | 1623 #endif /* not NEW_GC */ |
3092 | 1624 |
1625 #if MAX_SAVE_STACK > 0 | |
1626 | |
1627 /* Save a copy of the contents of the stack, for debugging. */ | |
1628 if (!purify_flag) | |
1629 { | |
1630 /* Static buffer in which we save a copy of the C stack at each GC. */ | |
1631 static char *stack_copy; | |
1632 static Bytecount stack_copy_size; | |
1633 | |
1634 ptrdiff_t stack_diff = &stack_top_variable - stack_bottom; | |
1635 Bytecount stack_size = (stack_diff > 0 ? stack_diff : -stack_diff); | |
1636 if (stack_size < MAX_SAVE_STACK) | |
1637 { | |
1638 if (stack_copy_size < stack_size) | |
1639 { | |
1640 stack_copy = (char *) xrealloc (stack_copy, stack_size); | |
1641 stack_copy_size = stack_size; | |
1642 } | |
1643 | |
1644 memcpy (stack_copy, | |
1645 stack_diff > 0 ? stack_bottom : &stack_top_variable, | |
1646 stack_size); | |
1647 } | |
1648 } | |
1649 #endif /* MAX_SAVE_STACK > 0 */ | |
1650 | |
1651 /* Do some totally ad-hoc resource clearing. */ | |
1652 /* #### generalize this? */ | |
1653 clear_event_resource (); | |
1654 cleanup_specifiers (); | |
1655 cleanup_buffer_undo_lists (); | |
1656 } | |
1657 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1658 static void |
3092 | 1659 gc_mark_root_set ( |
1660 #ifdef NEW_GC | |
1661 enum gc_phase phase | |
1662 #else /* not NEW_GC */ | |
1663 void | |
1664 #endif /* not NEW_GC */ | |
1665 ) | |
1666 { | |
1667 #ifdef NEW_GC | |
1668 GC_SET_PHASE (phase); | |
1669 #endif /* NEW_GC */ | |
1670 | |
1671 /* Mark all the special slots that serve as the roots of accessibility. */ | |
1672 | |
1673 #ifdef USE_KKCC | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1674 # define mark_object(obj) kkcc_gc_stack_push_lisp_object_0 (obj) |
3092 | 1675 #endif /* USE_KKCC */ |
1676 | |
1677 { /* staticpro() */ | |
1678 Lisp_Object **p = Dynarr_begin (staticpros); | |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1679 Elemcount len = Dynarr_length (staticpros); |
3092 | 1680 Elemcount count; |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1681 for (count = 0; count < len; count++, p++) |
3092 | 1682 /* Need to check if the pointer in the staticpro array is not |
1683 NULL. A gc can occur after variable is added to the staticpro | |
1684 array and _before_ it is correctly initialized. In this case | |
1685 its value is NULL, which we have to catch here. */ | |
1686 if (*p) | |
3486 | 1687 mark_object (**p); |
3092 | 1688 } |
1689 | |
1690 { /* staticpro_nodump() */ | |
1691 Lisp_Object **p = Dynarr_begin (staticpros_nodump); | |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1692 Elemcount len = Dynarr_length (staticpros_nodump); |
3092 | 1693 Elemcount count; |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1694 for (count = 0; count < len; count++, p++) |
3092 | 1695 /* Need to check if the pointer in the staticpro array is not |
1696 NULL. A gc can occur after variable is added to the staticpro | |
1697 array and _before_ it is correctly initialized. In this case | |
1698 its value is NULL, which we have to catch here. */ | |
1699 if (*p) | |
3486 | 1700 mark_object (**p); |
3092 | 1701 } |
1702 | |
3263 | 1703 #ifdef NEW_GC |
3092 | 1704 { /* mcpro () */ |
1705 Lisp_Object *p = Dynarr_begin (mcpros); | |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1706 Elemcount len = Dynarr_length (mcpros); |
3092 | 1707 Elemcount count; |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1708 for (count = 0; count < len; count++, p++) |
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1709 mark_object (*p); |
3092 | 1710 } |
3263 | 1711 #endif /* NEW_GC */ |
3092 | 1712 |
1713 { /* GCPRO() */ | |
1714 struct gcpro *tail; | |
1715 int i; | |
1716 for (tail = gcprolist; tail; tail = tail->next) | |
1717 for (i = 0; i < tail->nvars; i++) | |
1718 mark_object (tail->var[i]); | |
1719 } | |
1720 | |
1721 { /* specbind() */ | |
1722 struct specbinding *bind; | |
1723 for (bind = specpdl; bind != specpdl_ptr; bind++) | |
1724 { | |
1725 mark_object (bind->symbol); | |
1726 mark_object (bind->old_value); | |
1727 } | |
1728 } | |
1729 | |
1730 { | |
1731 struct catchtag *c; | |
1732 for (c = catchlist; c; c = c->next) | |
1733 { | |
1734 mark_object (c->tag); | |
1735 mark_object (c->val); | |
1736 mark_object (c->actual_tag); | |
1737 mark_object (c->backtrace); | |
1738 } | |
1739 } | |
1740 | |
1741 { | |
1742 struct backtrace *backlist; | |
1743 for (backlist = backtrace_list; backlist; backlist = backlist->next) | |
1744 { | |
1745 int nargs = backlist->nargs; | |
1746 int i; | |
1747 | |
1748 mark_object (*backlist->function); | |
1749 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */ | |
1750 /* might be fake (internal profiling entry) */ | |
1751 && backlist->args) | |
1752 mark_object (backlist->args[0]); | |
1753 else | |
1754 for (i = 0; i < nargs; i++) | |
1755 mark_object (backlist->args[i]); | |
1756 } | |
1757 } | |
1758 | |
1759 mark_profiling_info (); | |
5191
71ee43b8a74d
Add #'equalp as a hash test by default; add #'define-hash-table-test, GNU API
Aidan Kehoe <kehoea@parhasard.net>
parents:
5169
diff
changeset
|
1760 |
3092 | 1761 #ifdef USE_KKCC |
1762 # undef mark_object | |
1763 #endif | |
1764 } | |
1765 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1766 static void |
3092 | 1767 gc_finish_mark (void) |
1768 { | |
1769 #ifdef NEW_GC | |
1770 GC_SET_PHASE (FINISH_MARK); | |
1771 #endif /* NEW_GC */ | |
1772 init_marking_ephemerons (); | |
1773 | |
1774 while (finish_marking_weak_hash_tables () > 0 || | |
1775 finish_marking_weak_lists () > 0 || | |
1776 continue_marking_ephemerons () > 0) | |
1777 #ifdef USE_KKCC | |
1778 { | |
1779 kkcc_marking (0); | |
1780 } | |
1781 #else /* not USE_KKCC */ | |
1782 ; | |
1783 #endif /* not USE_KKCC */ | |
1784 | |
1785 /* At this point, we know which objects need to be finalized: we | |
1786 still need to resurrect them */ | |
1787 | |
1788 while (finish_marking_ephemerons () > 0 || | |
1789 finish_marking_weak_lists () > 0 || | |
1790 finish_marking_weak_hash_tables () > 0) | |
1791 #ifdef USE_KKCC | |
1792 { | |
1793 kkcc_marking (0); | |
1794 } | |
1795 #else /* not USE_KKCC */ | |
1796 ; | |
1797 #endif /* not USE_KKCC */ | |
1798 | |
1799 /* And prune (this needs to be called after everything else has been | |
1800 marked and before we do any sweeping). */ | |
1801 /* #### this is somewhat ad-hoc and should probably be an object | |
1802 method */ | |
1803 prune_weak_hash_tables (); | |
1804 prune_weak_lists (); | |
1805 prune_specifiers (); | |
1806 prune_syntax_tables (); | |
1807 | |
1808 prune_ephemerons (); | |
1809 prune_weak_boxes (); | |
1810 } | |
1811 | |
1812 #ifdef NEW_GC | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1813 static void |
3092 | 1814 gc_finalize (void) |
1815 { | |
1816 GC_SET_PHASE (FINALIZE); | |
3263 | 1817 register_for_finalization (); |
3092 | 1818 } |
1819 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1820 static void |
3092 | 1821 gc_sweep (void) |
1822 { | |
1823 GC_SET_PHASE (SWEEP); | |
1824 mc_sweep (); | |
1825 } | |
1826 #endif /* NEW_GC */ | |
1827 | |
1828 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1829 static void |
3092 | 1830 gc_finish (void) |
1831 { | |
1832 #ifdef NEW_GC | |
1833 GC_SET_PHASE (FINISH_GC); | |
1834 #endif /* NEW_GC */ | |
5158
9e0b43d3095c
more cleanups to object-memory-usage stuff
Ben Wing <ben@xemacs.org>
parents:
5142
diff
changeset
|
1835 finish_object_memory_usage_stats (); |
3092 | 1836 consing_since_gc = 0; |
1837 #ifndef DEBUG_XEMACS | |
1838 /* Allow you to set it really fucking low if you really want ... */ | |
1839 if (gc_cons_threshold < 10000) | |
1840 gc_cons_threshold = 10000; | |
1841 #endif | |
1842 recompute_need_to_garbage_collect (); | |
1843 | |
1844 #ifndef NEW_GC | |
5014
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
1845 inhibit_non_essential_conversion_operations--; |
3092 | 1846 #endif /* not NEW_GC */ |
1847 gc_in_progress = 0; | |
1848 | |
1849 run_post_gc_actions (); | |
1850 | |
1851 /******* End of garbage collection ********/ | |
1852 | |
3263 | 1853 #ifndef NEW_GC |
3092 | 1854 if (!breathing_space) |
1855 { | |
1856 breathing_space = malloc (4096 - MALLOC_OVERHEAD); | |
1857 } | |
3263 | 1858 #endif /* not NEW_GC */ |
3092 | 1859 |
1860 need_to_signal_post_gc = 1; | |
1861 funcall_allocation_flag = 1; | |
1862 | |
1863 PROFILE_RECORD_EXITING_SECTION (QSin_garbage_collection); | |
1864 | |
1865 #ifdef NEW_GC | |
1866 GC_SET_PHASE (NONE); | |
1867 #endif /* NEW_GC */ | |
1868 } | |
1869 | |
1870 #ifdef NEW_GC | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1871 static void |
3092 | 1872 gc_suspend_mark_phase (void) |
1873 { | |
1874 PROFILE_RECORD_EXITING_SECTION (QSin_garbage_collection); | |
1875 write_barrier_enabled = 1; | |
1876 consing_since_gc = 0; | |
1877 vdb_start_dirty_bits_recording (); | |
1878 } | |
1879 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1880 static int |
3092 | 1881 gc_resume_mark_phase (void) |
1882 { | |
1883 PROFILE_RECORD_ENTERING_SECTION (QSin_garbage_collection); | |
1884 assert (write_barrier_enabled); | |
1885 vdb_stop_dirty_bits_recording (); | |
1886 write_barrier_enabled = 0; | |
1887 return vdb_read_dirty_bits (); | |
1888 } | |
1889 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1890 static int |
3092 | 1891 gc_mark (int incremental) |
1892 { | |
1893 GC_SET_PHASE (MARK); | |
1894 if (!incremental) | |
1895 { | |
1896 kkcc_marking (0); | |
1897 } | |
1898 else | |
1899 { | |
1900 kkcc_marking (gc_incremental_traversal_threshold); | |
1901 if (!KKCC_GC_STACK_EMPTY) | |
1902 { | |
1903 gc_suspend_mark_phase (); | |
1904 return 0; | |
1905 } | |
1906 } | |
1907 return 1; | |
1908 } | |
1909 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1910 static int |
3092 | 1911 gc_resume_mark (int incremental) |
1912 { | |
1913 if (!incremental) | |
1914 { | |
1915 if (!KKCC_GC_STACK_EMPTY) | |
1916 { | |
1917 GC_STAT_RESUME_GC; | |
1918 /* An incremental garbage collection is already running --- | |
1919 now wrap it up and resume it atomically. */ | |
1920 gc_resume_mark_phase (); | |
1921 gc_mark_root_set (REPUSH_ROOT_SET); | |
1922 kkcc_marking (0); | |
1923 } | |
1924 } | |
1925 else | |
1926 { | |
1927 int repushed_objects; | |
1928 int mark_work; | |
1929 GC_STAT_RESUME_GC; | |
1930 repushed_objects = gc_resume_mark_phase (); | |
1931 mark_work = (gc_incremental_traversal_threshold > repushed_objects) ? | |
1932 gc_incremental_traversal_threshold : repushed_objects; | |
1933 kkcc_marking (mark_work); | |
1934 if (KKCC_GC_STACK_EMPTY) | |
1935 { | |
1936 /* Mark root set again and finish up marking. */ | |
1937 gc_mark_root_set (REPUSH_ROOT_SET); | |
1938 kkcc_marking (0); | |
1939 } | |
1940 else | |
1941 { | |
1942 gc_suspend_mark_phase (); | |
1943 return 0; | |
1944 } | |
1945 } | |
1946 return 1; | |
1947 } | |
1948 | |
1949 | |
5046 | 1950 static void |
3092 | 1951 gc_1 (int incremental) |
1952 { | |
1953 switch (GC_PHASE) | |
1954 { | |
1955 case NONE: | |
1956 gc_prepare (); | |
1957 kkcc_gc_stack_init(); | |
1958 #ifdef DEBUG_XEMACS | |
1959 kkcc_bt_init (); | |
1960 #endif | |
1961 case INIT_GC: | |
1962 gc_mark_root_set (PUSH_ROOT_SET); | |
1963 case PUSH_ROOT_SET: | |
1964 if (!gc_mark (incremental)) | |
1965 return; /* suspend gc */ | |
1966 case MARK: | |
1967 if (!KKCC_GC_STACK_EMPTY) | |
1968 if (!gc_resume_mark (incremental)) | |
1969 return; /* suspend gc */ | |
1970 gc_finish_mark (); | |
3263 | 1971 case FINISH_MARK: |
1972 gc_finalize (); | |
3092 | 1973 kkcc_gc_stack_free (); |
1974 #ifdef DEBUG_XEMACS | |
1975 kkcc_bt_free (); | |
1976 #endif | |
1977 case FINALIZE: | |
1978 gc_sweep (); | |
1979 case SWEEP: | |
1980 gc_finish (); | |
1981 case FINISH_GC: | |
1982 break; | |
1983 } | |
1984 } | |
1985 | |
5046 | 1986 static void |
1987 gc (int incremental) | |
3092 | 1988 { |
1989 if (gc_currently_forbidden | |
1990 || in_display | |
1991 || preparing_for_armageddon) | |
1992 return; | |
1993 | |
1994 /* Very important to prevent GC during any of the following | |
1995 stuff that might run Lisp code; otherwise, we'll likely | |
1996 have infinite GC recursion. */ | |
1997 speccount = begin_gc_forbidden (); | |
1998 | |
3267 | 1999 show_gc_cursor_and_message (); |
2000 | |
3092 | 2001 gc_1 (incremental); |
2002 | |
3267 | 2003 remove_gc_cursor_and_message (); |
2004 | |
3092 | 2005 /* now stop inhibiting GC */ |
2006 unbind_to (speccount); | |
2007 } | |
2008 | |
2009 void | |
2010 gc_full (void) | |
2011 { | |
2012 gc (0); | |
2013 } | |
2014 | |
2015 DEFUN ("gc-full", Fgc_full, 0, 0, "", /* | |
2016 This function performs a full garbage collection. If an incremental | |
2017 garbage collection is already running, it completes without any | |
2018 further interruption. This function guarantees that unused objects | |
2019 are freed when it returns. Garbage collection happens automatically if | |
2020 the client allocates more than `gc-cons-threshold' bytes of Lisp data | |
2021 since the previous garbage collection. | |
2022 */ | |
2023 ()) | |
2024 { | |
2025 gc_full (); | |
2026 return Qt; | |
2027 } | |
2028 | |
2029 void | |
2030 gc_incremental (void) | |
2031 { | |
2032 gc (allow_incremental_gc); | |
2033 } | |
2034 | |
2035 DEFUN ("gc-incremental", Fgc_incremental, 0, 0, "", /* | |
2036 This function starts an incremental garbage collection. If an | |
2037 incremental garbage collection is already running, the next cycle | |
2038 starts. Note that this function has not necessarily freed any memory | |
2039 when it returns. This function only guarantees, that the traversal of | |
2040 the heap makes progress. The next cycle of incremental garbage | |
2041 collection happens automatically if the client allocates more than | |
2042 `gc-incremental-cons-threshold' bytes of Lisp data since previous | |
2043 garbage collection. | |
2044 */ | |
2045 ()) | |
2046 { | |
2047 gc_incremental (); | |
2048 return Qt; | |
2049 } | |
2050 #else /* not NEW_GC */ | |
2051 void garbage_collect_1 (void) | |
2052 { | |
2053 if (gc_in_progress | |
2054 || gc_currently_forbidden | |
2055 || in_display | |
2056 || preparing_for_armageddon) | |
2057 return; | |
2058 | |
2059 /* Very important to prevent GC during any of the following | |
2060 stuff that might run Lisp code; otherwise, we'll likely | |
2061 have infinite GC recursion. */ | |
2062 speccount = begin_gc_forbidden (); | |
2063 | |
3267 | 2064 show_gc_cursor_and_message (); |
2065 | |
3092 | 2066 gc_prepare (); |
2067 #ifdef USE_KKCC | |
2068 kkcc_gc_stack_init(); | |
2069 #ifdef DEBUG_XEMACS | |
2070 kkcc_bt_init (); | |
2071 #endif | |
2072 #endif /* USE_KKCC */ | |
2073 gc_mark_root_set (); | |
2074 #ifdef USE_KKCC | |
2075 kkcc_marking (0); | |
2076 #endif /* USE_KKCC */ | |
2077 gc_finish_mark (); | |
2078 #ifdef USE_KKCC | |
2079 kkcc_gc_stack_free (); | |
2080 #ifdef DEBUG_XEMACS | |
2081 kkcc_bt_free (); | |
2082 #endif | |
2083 #endif /* USE_KKCC */ | |
2084 gc_sweep_1 (); | |
2085 gc_finish (); | |
2086 | |
3267 | 2087 remove_gc_cursor_and_message (); |
2088 | |
3092 | 2089 /* now stop inhibiting GC */ |
2090 unbind_to (speccount); | |
2091 } | |
2092 #endif /* not NEW_GC */ | |
2093 | |
2094 | |
2095 /************************************************************************/ | |
2096 /* Initializations */ | |
2097 /************************************************************************/ | |
2098 | |
2099 /* Initialization */ | |
2100 static void | |
2101 common_init_gc_early (void) | |
2102 { | |
2103 Vgc_message = Qzero; | |
2104 | |
2105 gc_currently_forbidden = 0; | |
2106 gc_hooks_inhibited = 0; | |
2107 | |
2108 need_to_garbage_collect = always_gc; | |
2109 | |
2110 gc_cons_threshold = GC_CONS_THRESHOLD; | |
2111 gc_cons_percentage = 40; /* #### what is optimal? */ | |
2112 total_gc_usage_set = 0; | |
2113 #ifdef NEW_GC | |
2114 gc_cons_incremental_threshold = GC_CONS_INCREMENTAL_THRESHOLD; | |
2115 gc_incremental_traversal_threshold = GC_INCREMENTAL_TRAVERSAL_THRESHOLD; | |
3263 | 2116 #endif /* NEW_GC */ |
3092 | 2117 } |
2118 | |
2119 void | |
2120 init_gc_early (void) | |
2121 { | |
3263 | 2122 #ifdef NEW_GC |
2123 /* Reset the finalizers_to_run list after pdump_load. */ | |
2124 Vfinalizers_to_run = Qnil; | |
2125 #endif /* NEW_GC */ | |
3092 | 2126 } |
2127 | |
2128 void | |
2129 reinit_gc_early (void) | |
2130 { | |
2131 common_init_gc_early (); | |
2132 } | |
2133 | |
2134 void | |
2135 init_gc_once_early (void) | |
2136 { | |
2137 common_init_gc_early (); | |
2138 } | |
2139 | |
2140 void | |
2141 syms_of_gc (void) | |
2142 { | |
2143 DEFSYMBOL (Qpre_gc_hook); | |
2144 DEFSYMBOL (Qpost_gc_hook); | |
2145 #ifdef NEW_GC | |
2146 DEFSUBR (Fgc_full); | |
2147 DEFSUBR (Fgc_incremental); | |
2148 #ifdef ERROR_CHECK_GC | |
2149 DEFSUBR (Fgc_stats); | |
2150 #endif /* not ERROR_CHECK_GC */ | |
2151 #endif /* NEW_GC */ | |
2152 } | |
2153 | |
2154 void | |
2155 vars_of_gc (void) | |
2156 { | |
2157 staticpro_nodump (&pre_gc_cursor); | |
2158 | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4934
diff
changeset
|
2159 QSin_garbage_collection = build_defer_string ("(in garbage collection)"); |
3092 | 2160 staticpro (&QSin_garbage_collection); |
2161 | |
2162 DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold /* | |
2163 *Number of bytes of consing between full garbage collections. | |
2164 \"Consing\" is a misnomer in that this actually counts allocation | |
2165 of all different kinds of objects, not just conses. | |
2166 Garbage collection can happen automatically once this many bytes have been | |
2167 allocated since the last garbage collection. All data types count. | |
2168 | |
2169 Garbage collection happens automatically when `eval' or `funcall' are | |
2170 called. (Note that `funcall' is called implicitly as part of evaluation.) | |
2171 By binding this temporarily to a large number, you can effectively | |
2172 prevent garbage collection during a part of the program. | |
2173 | |
2174 Normally, you cannot set this value less than 10,000 (if you do, it is | |
2175 automatically reset during the next garbage collection). However, if | |
2176 XEmacs was compiled with DEBUG_XEMACS, this does not happen, allowing | |
2177 you to set this value very low to track down problems with insufficient | |
2178 GCPRO'ing. If you set this to a negative number, garbage collection will | |
2179 happen at *EVERY* call to `eval' or `funcall'. This is an extremely | |
2180 effective way to check GCPRO problems, but be warned that your XEmacs | |
2181 will be unusable! You almost certainly won't have the patience to wait | |
2182 long enough to be able to set it back. | |
2183 | |
2184 See also `consing-since-gc' and `gc-cons-percentage'. | |
2185 */ ); | |
2186 | |
2187 DEFVAR_INT ("gc-cons-percentage", &gc_cons_percentage /* | |
2188 *Percentage of memory allocated between garbage collections. | |
2189 | |
2190 Garbage collection will happen if this percentage of the total amount of | |
2191 memory used for data (see `lisp-object-memory-usage') has been allocated | |
2192 since the last garbage collection. However, it will not happen if less | |
2193 than `gc-cons-threshold' bytes have been allocated -- this sets an absolute | |
2194 minimum in case very little data has been allocated or the percentage is | |
2195 set very low. Set this to 0 to have garbage collection always happen after | |
2196 `gc-cons-threshold' bytes have been allocated, regardless of current memory | |
2197 usage. | |
2198 | |
2199 See also `consing-since-gc' and `gc-cons-threshold'. | |
2200 */ ); | |
2201 | |
2202 #ifdef NEW_GC | |
2203 DEFVAR_INT ("gc-cons-incremental-threshold", | |
2204 &gc_cons_incremental_threshold /* | |
2205 *Number of bytes of consing between cycles of incremental garbage | |
2206 collections. \"Consing\" is a misnomer in that this actually counts | |
2207 allocation of all different kinds of objects, not just conses. The | |
2208 next garbage collection cycle can happen automatically once this many | |
2209 bytes have been allocated since the last garbage collection cycle. | |
2210 All data types count. | |
2211 | |
2212 See also `gc-cons-threshold'. | |
2213 */ ); | |
2214 | |
2215 DEFVAR_INT ("gc-incremental-traversal-threshold", | |
2216 &gc_incremental_traversal_threshold /* | |
2217 *Number of elements processed in one cycle of incremental travesal. | |
2218 */ ); | |
2219 #endif /* NEW_GC */ | |
2220 | |
2221 DEFVAR_BOOL ("purify-flag", &purify_flag /* | |
2222 Non-nil means loading Lisp code in order to dump an executable. | |
2223 This means that certain objects should be allocated in readonly space. | |
2224 */ ); | |
2225 | |
2226 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages /* | |
4502
8748a3f7ceb4
Handle varalias chains, custom variables in #'user-variable-p.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4124
diff
changeset
|
2227 *Non-nil means display messages at start and end of garbage collection. |
3092 | 2228 */ ); |
2229 garbage_collection_messages = 0; | |
2230 | |
2231 DEFVAR_LISP ("pre-gc-hook", &Vpre_gc_hook /* | |
2232 Function or functions to be run just before each garbage collection. | |
2233 Interrupts, garbage collection, and errors are inhibited while this hook | |
2234 runs, so be extremely careful in what you add here. In particular, avoid | |
2235 consing, and do not interact with the user. | |
2236 */ ); | |
2237 Vpre_gc_hook = Qnil; | |
2238 | |
2239 DEFVAR_LISP ("post-gc-hook", &Vpost_gc_hook /* | |
2240 Function or functions to be run just after each garbage collection. | |
2241 Interrupts, garbage collection, and errors are inhibited while this hook | |
2242 runs. Each hook is called with one argument which is an alist with | |
2243 finalization data. | |
2244 */ ); | |
2245 Vpost_gc_hook = Qnil; | |
2246 | |
2247 DEFVAR_LISP ("gc-message", &Vgc_message /* | |
2248 String to print to indicate that a garbage collection is in progress. | |
2249 This is printed in the echo area. If the selected frame is on a | |
2250 window system and `gc-pointer-glyph' specifies a value (i.e. a pointer | |
2251 image instance) in the domain of the selected frame, the mouse pointer | |
2252 will change instead of this message being printed. | |
2253 */ ); | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4934
diff
changeset
|
2254 Vgc_message = build_defer_string (gc_default_message); |
3092 | 2255 |
2256 DEFVAR_LISP ("gc-pointer-glyph", &Vgc_pointer_glyph /* | |
2257 Pointer glyph used to indicate that a garbage collection is in progress. | |
2258 If the selected window is on a window system and this glyph specifies a | |
2259 value (i.e. a pointer image instance) in the domain of the selected | |
2260 window, the pointer will be changed as specified during garbage collection. | |
2261 Otherwise, a message will be printed in the echo area, as controlled | |
2262 by `gc-message'. | |
2263 */ ); | |
2264 | |
2265 #ifdef NEW_GC | |
2266 DEFVAR_BOOL ("allow-incremental-gc", &allow_incremental_gc /* | |
2267 *Non-nil means to allow incremental garbage collection. Nil prevents | |
2268 *incremental garbage collection, the garbage collector then only does | |
2269 *full collects (even if (gc-incremental) is called). | |
2270 */ ); | |
3263 | 2271 |
2272 Vfinalizers_to_run = Qnil; | |
2273 staticpro_nodump (&Vfinalizers_to_run); | |
3092 | 2274 #endif /* NEW_GC */ |
2275 } | |
2276 | |
2277 void | |
2278 complex_vars_of_gc (void) | |
2279 { | |
2280 Vgc_pointer_glyph = Fmake_glyph_internal (Qpointer); | |
2281 } |