Mercurial > emacs
comparison src/alloc.c @ 83142:62cf3d6337a0
Merged in changes from CVS trunk.
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-344
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-345
Tweak source regexps so that building in place won't cause problems
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-346
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-347
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-348
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-349
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-350
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-351
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-352
Update from CVS: lisp/flymake.el: New file.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-182
| author | Karoly Lorentey <lorentey@elte.hu> |
|---|---|
| date | Sun, 30 May 2004 21:11:48 +0000 |
| parents | 85232760f917 a4fe04f4d9c2 |
| children | 9fb10038ca55 |
comparison
equal
deleted
inserted
replaced
| 83141:8d02e70dd3cc | 83142:62cf3d6337a0 |
|---|---|
| 255 EMACS_INT gcs_done; /* accumulated GCs */ | 255 EMACS_INT gcs_done; /* accumulated GCs */ |
| 256 | 256 |
| 257 static void mark_buffer P_ ((Lisp_Object)); | 257 static void mark_buffer P_ ((Lisp_Object)); |
| 258 extern void mark_kboards P_ ((void)); | 258 extern void mark_kboards P_ ((void)); |
| 259 extern void mark_ttys P_ ((void)); | 259 extern void mark_ttys P_ ((void)); |
| 260 extern void mark_backtrace P_ ((void)); | |
| 260 static void gc_sweep P_ ((void)); | 261 static void gc_sweep P_ ((void)); |
| 261 static void mark_glyph_matrix P_ ((struct glyph_matrix *)); | 262 static void mark_glyph_matrix P_ ((struct glyph_matrix *)); |
| 262 static void mark_face_cache P_ ((struct face_cache *)); | 263 static void mark_face_cache P_ ((struct face_cache *)); |
| 263 | 264 |
| 264 #ifdef HAVE_WINDOW_SYSTEM | 265 #ifdef HAVE_WINDOW_SYSTEM |
| 2864 struct marker_block *marker_block; | 2865 struct marker_block *marker_block; |
| 2865 int marker_block_index; | 2866 int marker_block_index; |
| 2866 | 2867 |
| 2867 union Lisp_Misc *marker_free_list; | 2868 union Lisp_Misc *marker_free_list; |
| 2868 | 2869 |
| 2869 /* Marker blocks which should be freed at end of GC. */ | |
| 2870 | |
| 2871 struct marker_block *marker_blocks_pending_free; | |
| 2872 | |
| 2873 /* Total number of marker blocks now in use. */ | 2870 /* Total number of marker blocks now in use. */ |
| 2874 | 2871 |
| 2875 int n_marker_blocks; | 2872 int n_marker_blocks; |
| 2876 | 2873 |
| 2877 void | 2874 void |
| 2878 init_marker () | 2875 init_marker () |
| 2879 { | 2876 { |
| 2880 marker_block = NULL; | 2877 marker_block = NULL; |
| 2881 marker_block_index = MARKER_BLOCK_SIZE; | 2878 marker_block_index = MARKER_BLOCK_SIZE; |
| 2882 marker_free_list = 0; | 2879 marker_free_list = 0; |
| 2883 marker_blocks_pending_free = 0; | |
| 2884 n_marker_blocks = 0; | 2880 n_marker_blocks = 0; |
| 2885 } | 2881 } |
| 2886 | 2882 |
| 2887 /* Return a newly allocated Lisp_Misc object, with no substructure. */ | 2883 /* Return a newly allocated Lisp_Misc object, with no substructure. */ |
| 2888 | 2884 |
| 4281 Lisp_Object tag; | 4277 Lisp_Object tag; |
| 4282 Lisp_Object val; | 4278 Lisp_Object val; |
| 4283 struct catchtag *next; | 4279 struct catchtag *next; |
| 4284 }; | 4280 }; |
| 4285 | 4281 |
| 4286 struct backtrace | |
| 4287 { | |
| 4288 struct backtrace *next; | |
| 4289 Lisp_Object *function; | |
| 4290 Lisp_Object *args; /* Points to vector of args. */ | |
| 4291 int nargs; /* Length of vector. */ | |
| 4292 /* If nargs is UNEVALLED, args points to slot holding list of | |
| 4293 unevalled args. */ | |
| 4294 char evalargs; | |
| 4295 /* Nonzero means call value of debugger when done with this operation. */ | |
| 4296 char debug_on_exit; | |
| 4297 }; | |
| 4298 | |
| 4299 | |
| 4300 | 4282 |
| 4301 /*********************************************************************** | 4283 /*********************************************************************** |
| 4302 Protection from GC | 4284 Protection from GC |
| 4303 ***********************************************************************/ | 4285 ***********************************************************************/ |
| 4304 | 4286 |
| 4329 () | 4311 () |
| 4330 { | 4312 { |
| 4331 register struct specbinding *bind; | 4313 register struct specbinding *bind; |
| 4332 struct catchtag *catch; | 4314 struct catchtag *catch; |
| 4333 struct handler *handler; | 4315 struct handler *handler; |
| 4334 register struct backtrace *backlist; | |
| 4335 char stack_top_variable; | 4316 char stack_top_variable; |
| 4336 register int i; | 4317 register int i; |
| 4337 int message_p; | 4318 int message_p; |
| 4338 Lisp_Object total[8]; | 4319 Lisp_Object total[8]; |
| 4339 int count = SPECPDL_INDEX (); | 4320 int count = SPECPDL_INDEX (); |
| 4458 for (handler = handlerlist; handler; handler = handler->next) | 4439 for (handler = handlerlist; handler; handler = handler->next) |
| 4459 { | 4440 { |
| 4460 mark_object (handler->handler); | 4441 mark_object (handler->handler); |
| 4461 mark_object (handler->var); | 4442 mark_object (handler->var); |
| 4462 } | 4443 } |
| 4463 for (backlist = backtrace_list; backlist; backlist = backlist->next) | 4444 mark_backtrace (); |
| 4464 { | |
| 4465 mark_object (*backlist->function); | |
| 4466 | |
| 4467 if (backlist->nargs == UNEVALLED || backlist->nargs == MANY) | |
| 4468 i = 0; | |
| 4469 else | |
| 4470 i = backlist->nargs - 1; | |
| 4471 for (; i >= 0; i--) | |
| 4472 mark_object (backlist->args[i]); | |
| 4473 } | |
| 4474 mark_kboards (); | 4445 mark_kboards (); |
| 4475 mark_ttys (); | 4446 mark_ttys (); |
| 4476 | 4447 |
| 4477 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 4448 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 4478 mark_stack (); | 4449 mark_stack (); |
| 4483 extern void xg_mark_data (); | 4454 extern void xg_mark_data (); |
| 4484 xg_mark_data (); | 4455 xg_mark_data (); |
| 4485 } | 4456 } |
| 4486 #endif | 4457 #endif |
| 4487 | 4458 |
| 4488 gc_sweep (); | 4459 /* Everything is now marked, except for the things that require special |
| 4489 | 4460 finalization, i.e. the undo_list. |
| 4490 /* Look thru every buffer's undo list for elements that used to | 4461 Look thru every buffer's undo list |
| 4491 contain update markers that were changed to Lisp_Misc_Free | 4462 for elements that update markers that were not marked, |
| 4492 objects and delete them. This may leave a few cons cells | 4463 and delete them. */ |
| 4493 unchained, but we will get those on the next sweep. */ | |
| 4494 { | 4464 { |
| 4495 register struct buffer *nextb = all_buffers; | 4465 register struct buffer *nextb = all_buffers; |
| 4496 | 4466 |
| 4497 while (nextb) | 4467 while (nextb) |
| 4498 { | 4468 { |
| 4499 /* If a buffer's undo list is Qt, that means that undo is | 4469 /* If a buffer's undo list is Qt, that means that undo is |
| 4500 turned off in that buffer. */ | 4470 turned off in that buffer. Calling truncate_undo_list on |
| 4471 Qt tends to return NULL, which effectively turns undo back on. | |
| 4472 So don't call truncate_undo_list if undo_list is Qt. */ | |
| 4501 if (! EQ (nextb->undo_list, Qt)) | 4473 if (! EQ (nextb->undo_list, Qt)) |
| 4502 { | 4474 { |
| 4503 Lisp_Object tail, prev, elt, car; | 4475 Lisp_Object tail, prev; |
| 4504 tail = nextb->undo_list; | 4476 tail = nextb->undo_list; |
| 4505 prev = Qnil; | 4477 prev = Qnil; |
| 4506 while (CONSP (tail)) | 4478 while (CONSP (tail)) |
| 4507 { | 4479 { |
| 4508 if ((elt = XCAR (tail), GC_CONSP (elt)) | 4480 if (GC_CONSP (XCAR (tail)) |
| 4509 && (car = XCAR (elt), GC_MISCP (car)) | 4481 && GC_MARKERP (XCAR (XCAR (tail))) |
| 4510 && XMISCTYPE (car) == Lisp_Misc_Free) | 4482 && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) |
| 4511 { | 4483 { |
| 4512 Lisp_Object cdr = XCDR (tail); | |
| 4513 /* Do not use free_cons here, as we don't know if | |
| 4514 anybody else has a pointer to these conses. */ | |
| 4515 XSETCAR (elt, Qnil); | |
| 4516 XSETCDR (elt, Qnil); | |
| 4517 XSETCAR (tail, Qnil); | |
| 4518 XSETCDR (tail, Qnil); | |
| 4519 if (NILP (prev)) | 4484 if (NILP (prev)) |
| 4520 nextb->undo_list = tail = cdr; | 4485 nextb->undo_list = tail = XCDR (tail); |
| 4521 else | 4486 else |
| 4522 { | 4487 { |
| 4523 tail = cdr; | 4488 tail = XCDR (tail); |
| 4524 XSETCDR (prev, tail); | 4489 XSETCDR (prev, tail); |
| 4525 } | 4490 } |
| 4526 } | 4491 } |
| 4527 else | 4492 else |
| 4528 { | 4493 { |
| 4529 prev = tail; | 4494 prev = tail; |
| 4530 tail = XCDR (tail); | 4495 tail = XCDR (tail); |
| 4531 } | 4496 } |
| 4532 } | 4497 } |
| 4533 } | 4498 } |
| 4499 /* Now that we have stripped the elements that need not be in the | |
| 4500 undo_list any more, we can finally mark the list. */ | |
| 4501 mark_object (nextb->undo_list); | |
| 4534 | 4502 |
| 4535 nextb = nextb->next; | 4503 nextb = nextb->next; |
| 4536 } | 4504 } |
| 4537 } | 4505 } |
| 4538 | 4506 |
| 4539 /* Undo lists have been cleaned up, so we can free marker blocks now. */ | 4507 gc_sweep (); |
| 4540 | |
| 4541 { | |
| 4542 struct marker_block *mblk; | |
| 4543 | |
| 4544 while ((mblk = marker_blocks_pending_free) != 0) | |
| 4545 { | |
| 4546 marker_blocks_pending_free = mblk->next; | |
| 4547 lisp_free (mblk); | |
| 4548 } | |
| 4549 } | |
| 4550 | 4508 |
| 4551 /* Clear the mark bits that we set in certain root slots. */ | 4509 /* Clear the mark bits that we set in certain root slots. */ |
| 4552 | 4510 |
| 4553 unmark_byte_stack (); | 4511 unmark_byte_stack (); |
| 4554 VECTOR_UNMARK (&buffer_defaults); | 4512 VECTOR_UNMARK (&buffer_defaults); |
| 5112 | 5070 |
| 5113 VECTOR_MARK (buffer); | 5071 VECTOR_MARK (buffer); |
| 5114 | 5072 |
| 5115 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); | 5073 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); |
| 5116 | 5074 |
| 5117 if (CONSP (buffer->undo_list)) | 5075 /* For now, we just don't mark the undo_list. It's done later in |
| 5118 { | 5076 a special way just before the sweep phase, and after stripping |
| 5119 Lisp_Object tail; | 5077 some of its elements that are not needed any more. */ |
| 5120 tail = buffer->undo_list; | |
| 5121 | |
| 5122 /* We mark the undo list specially because | |
| 5123 its pointers to markers should be weak. */ | |
| 5124 | |
| 5125 while (CONSP (tail)) | |
| 5126 { | |
| 5127 register struct Lisp_Cons *ptr = XCONS (tail); | |
| 5128 | |
| 5129 if (CONS_MARKED_P (ptr)) | |
| 5130 break; | |
| 5131 CONS_MARK (ptr); | |
| 5132 if (GC_CONSP (ptr->car) | |
| 5133 && !CONS_MARKED_P (XCONS (ptr->car)) | |
| 5134 && GC_MARKERP (XCAR (ptr->car))) | |
| 5135 { | |
| 5136 CONS_MARK (XCONS (ptr->car)); | |
| 5137 mark_object (XCDR (ptr->car)); | |
| 5138 } | |
| 5139 else | |
| 5140 mark_object (ptr->car); | |
| 5141 | |
| 5142 if (CONSP (ptr->cdr)) | |
| 5143 tail = ptr->cdr; | |
| 5144 else | |
| 5145 break; | |
| 5146 } | |
| 5147 | |
| 5148 mark_object (XCDR (tail)); | |
| 5149 } | |
| 5150 else | |
| 5151 mark_object (buffer->undo_list); | |
| 5152 | 5078 |
| 5153 if (buffer->overlays_before) | 5079 if (buffer->overlays_before) |
| 5154 { | 5080 { |
| 5155 XSETMISC (tmp, buffer->overlays_before); | 5081 XSETMISC (tmp, buffer->overlays_before); |
| 5156 mark_object (tmp); | 5082 mark_object (tmp); |
| 5226 /* Sweep: find all structures not marked, and free them. */ | 5152 /* Sweep: find all structures not marked, and free them. */ |
| 5227 | 5153 |
| 5228 static void | 5154 static void |
| 5229 gc_sweep () | 5155 gc_sweep () |
| 5230 { | 5156 { |
| 5157 /* Remove or mark entries in weak hash tables. | |
| 5158 This must be done before any object is unmarked. */ | |
| 5159 sweep_weak_hash_tables (); | |
| 5160 | |
| 5161 sweep_strings (); | |
| 5162 #ifdef GC_CHECK_STRING_BYTES | |
| 5163 if (!noninteractive) | |
| 5164 check_string_bytes (1); | |
| 5165 #endif | |
| 5166 | |
| 5231 /* Put all unmarked conses on free list */ | 5167 /* Put all unmarked conses on free list */ |
| 5232 { | 5168 { |
| 5233 register struct cons_block *cblk; | 5169 register struct cons_block *cblk; |
| 5234 struct cons_block **cprev = &cons_block; | 5170 struct cons_block **cprev = &cons_block; |
| 5235 register int lim = cons_block_index; | 5171 register int lim = cons_block_index; |
| 5275 } | 5211 } |
| 5276 } | 5212 } |
| 5277 total_conses = num_used; | 5213 total_conses = num_used; |
| 5278 total_free_conses = num_free; | 5214 total_free_conses = num_free; |
| 5279 } | 5215 } |
| 5280 | |
| 5281 /* Remove or mark entries in weak hash tables. | |
| 5282 This must be done before any object is unmarked. */ | |
| 5283 sweep_weak_hash_tables (); | |
| 5284 | |
| 5285 sweep_strings (); | |
| 5286 #ifdef GC_CHECK_STRING_BYTES | |
| 5287 if (!noninteractive) | |
| 5288 check_string_bytes (1); | |
| 5289 #endif | |
| 5290 | 5216 |
| 5291 /* Put all unmarked floats on free list */ | 5217 /* Put all unmarked floats on free list */ |
| 5292 { | 5218 { |
| 5293 register struct float_block *fblk; | 5219 register struct float_block *fblk; |
| 5294 struct float_block **fprev = &float_block; | 5220 struct float_block **fprev = &float_block; |
| 5454 struct marker_block **mprev = &marker_block; | 5380 struct marker_block **mprev = &marker_block; |
| 5455 register int lim = marker_block_index; | 5381 register int lim = marker_block_index; |
| 5456 register int num_free = 0, num_used = 0; | 5382 register int num_free = 0, num_used = 0; |
| 5457 | 5383 |
| 5458 marker_free_list = 0; | 5384 marker_free_list = 0; |
| 5459 marker_blocks_pending_free = 0; | |
| 5460 | 5385 |
| 5461 for (mblk = marker_block; mblk; mblk = *mprev) | 5386 for (mblk = marker_block; mblk; mblk = *mprev) |
| 5462 { | 5387 { |
| 5463 register int i; | 5388 register int i; |
| 5464 int this_free = 0; | 5389 int this_free = 0; |
| 5490 if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE) | 5415 if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE) |
| 5491 { | 5416 { |
| 5492 *mprev = mblk->next; | 5417 *mprev = mblk->next; |
| 5493 /* Unhook from the free list. */ | 5418 /* Unhook from the free list. */ |
| 5494 marker_free_list = mblk->markers[0].u_free.chain; | 5419 marker_free_list = mblk->markers[0].u_free.chain; |
| 5420 lisp_free (mblk); | |
| 5495 n_marker_blocks--; | 5421 n_marker_blocks--; |
| 5496 | |
| 5497 /* It is not safe to free the marker block at this stage, | |
| 5498 since there may still be pointers to these markers from | |
| 5499 a buffer's undo list. KFS 2004-05-25. */ | |
| 5500 mblk->next = marker_blocks_pending_free; | |
| 5501 marker_blocks_pending_free = mblk; | |
| 5502 } | 5422 } |
| 5503 else | 5423 else |
| 5504 { | 5424 { |
| 5505 num_free += this_free; | 5425 num_free += this_free; |
| 5506 mprev = &mblk->next; | 5426 mprev = &mblk->next; |
