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;