comparison src/alloc.c @ 55720:1a56baecf37d

(struct backtrace): Add debug_on_exit member. (Fgarbage_collect): Clear out buffer undo_list markers after gc_sweep. Identify those markers as Lisp_Misc_Free objects. Clear car and cdr of the removed cons cells. (mark_object): Undo previous change - disallow Lisp_Misc_Free objects. (gc_sweep): Clear cons_blocks before sweeping strings, so we don't have any cons cells pointing to unallocated stings. Do not lisp_free any marker blocks, as there may still be pointers to them from buffer undo lists at this stage of GC.
author Kim F. Storm <storm@cua.dk>
date Fri, 21 May 2004 23:36:10 +0000
parents 57f4a242e8f4
children 1c3b8ce97c63
comparison
equal deleted inserted replaced
55719:91bed9994bc1 55720:1a56baecf37d
2331 #if GC_MARK_STACK 2331 #if GC_MARK_STACK
2332 ptr->car = Vdead; 2332 ptr->car = Vdead;
2333 #endif 2333 #endif
2334 cons_free_list = ptr; 2334 cons_free_list = ptr;
2335 } 2335 }
2336
2337 2336
2338 DEFUN ("cons", Fcons, Scons, 2, 2, 0, 2337 DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2339 doc: /* Create a new cons, give it CAR and CDR as components, and return it. */) 2338 doc: /* Create a new cons, give it CAR and CDR as components, and return it. */)
2340 (car, cdr) 2339 (car, cdr)
2341 Lisp_Object car, cdr; 2340 Lisp_Object car, cdr;
4284 Lisp_Object *args; /* Points to vector of args. */ 4283 Lisp_Object *args; /* Points to vector of args. */
4285 int nargs; /* Length of vector. */ 4284 int nargs; /* Length of vector. */
4286 /* If nargs is UNEVALLED, args points to slot holding list of 4285 /* If nargs is UNEVALLED, args points to slot holding list of
4287 unevalled args. */ 4286 unevalled args. */
4288 char evalargs; 4287 char evalargs;
4288 /* Nonzero means call value of debugger when done with this operation. */
4289 char debug_on_exit;
4289 }; 4290 };
4290 4291
4291 4292
4292 4293
4293 /*********************************************************************** 4294 /***********************************************************************
4474 extern void xg_mark_data (); 4475 extern void xg_mark_data ();
4475 xg_mark_data (); 4476 xg_mark_data ();
4476 } 4477 }
4477 #endif 4478 #endif
4478 4479
4479 /* Look thru every buffer's undo list 4480 gc_sweep ();
4480 for elements that update markers that were not marked, 4481
4481 and delete them. */ 4482 /* Look thru every buffer's undo list for elements that used to
4483 contain update markers that were changed to Lisp_Misc_Free
4484 objects and delete them. This may leave a few cons cells
4485 unchained, but we will get those on the next sweep. */
4482 { 4486 {
4483 register struct buffer *nextb = all_buffers; 4487 register struct buffer *nextb = all_buffers;
4484 4488
4485 while (nextb) 4489 while (nextb)
4486 { 4490 {
4487 /* If a buffer's undo list is Qt, that means that undo is 4491 /* If a buffer's undo list is Qt, that means that undo is
4488 turned off in that buffer. Calling truncate_undo_list on 4492 turned off in that buffer. */
4489 Qt tends to return NULL, which effectively turns undo back on.
4490 So don't call truncate_undo_list if undo_list is Qt. */
4491 if (! EQ (nextb->undo_list, Qt)) 4493 if (! EQ (nextb->undo_list, Qt))
4492 { 4494 {
4493 Lisp_Object tail, prev; 4495 Lisp_Object tail, prev, elt, car;
4494 tail = nextb->undo_list; 4496 tail = nextb->undo_list;
4495 prev = Qnil; 4497 prev = Qnil;
4496 while (CONSP (tail)) 4498 while (CONSP (tail))
4497 { 4499 {
4498 if (GC_CONSP (XCAR (tail)) 4500 if ((elt = XCAR (tail), GC_CONSP (elt))
4499 && GC_MARKERP (XCAR (XCAR (tail))) 4501 && (car = XCAR (elt), GC_MISCP (car))
4500 && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) 4502 && XMISCTYPE (car) == Lisp_Misc_Free)
4501 { 4503 {
4504 Lisp_Object cdr = XCDR (tail);
4505 /* Do not use free_cons here, as we don't know if
4506 anybody else has a pointer to these conses. */
4507 XSETCAR (elt, Qnil);
4508 XSETCDR (elt, Qnil);
4509 XSETCAR (tail, Qnil);
4510 XSETCDR (tail, Qnil);
4502 if (NILP (prev)) 4511 if (NILP (prev))
4503 nextb->undo_list = tail = XCDR (tail); 4512 nextb->undo_list = tail = cdr;
4504 else 4513 else
4505 { 4514 {
4506 tail = XCDR (tail); 4515 tail = cdr;
4507 XSETCDR (prev, tail); 4516 XSETCDR (prev, tail);
4508 } 4517 }
4509 } 4518 }
4510 else 4519 else
4511 { 4520 {
4516 } 4525 }
4517 4526
4518 nextb = nextb->next; 4527 nextb = nextb->next;
4519 } 4528 }
4520 } 4529 }
4521
4522 gc_sweep ();
4523 4530
4524 /* Clear the mark bits that we set in certain root slots. */ 4531 /* Clear the mark bits that we set in certain root slots. */
4525 4532
4526 unmark_byte_stack (); 4533 unmark_byte_stack ();
4527 VECTOR_UNMARK (&buffer_defaults); 4534 VECTOR_UNMARK (&buffer_defaults);
4974 } 4981 }
4975 } 4982 }
4976 break; 4983 break;
4977 4984
4978 case Lisp_Misc: 4985 case Lisp_Misc:
4979 if (XMISCTYPE (obj) == Lisp_Misc_Free)
4980 {
4981 /* This is (probably) a freed marker which may still exist on
4982 a buffer undo list, so accept it here, as check below will
4983 fail (not live). KFS 2004-05-17 */
4984 XMARKER (obj)->gcmarkbit = 1;
4985 break;
4986 }
4987 CHECK_ALLOCATED_AND_LIVE (live_misc_p); 4986 CHECK_ALLOCATED_AND_LIVE (live_misc_p);
4988 if (XMARKER (obj)->gcmarkbit) 4987 if (XMARKER (obj)->gcmarkbit)
4989 break; 4988 break;
4990 XMARKER (obj)->gcmarkbit = 1; 4989 XMARKER (obj)->gcmarkbit = 1;
4991 switch (XMISCTYPE (obj)) 4990 switch (XMISCTYPE (obj))
5207 /* Sweep: find all structures not marked, and free them. */ 5206 /* Sweep: find all structures not marked, and free them. */
5208 5207
5209 static void 5208 static void
5210 gc_sweep () 5209 gc_sweep ()
5211 { 5210 {
5212 /* Remove or mark entries in weak hash tables.
5213 This must be done before any object is unmarked. */
5214 sweep_weak_hash_tables ();
5215
5216 sweep_strings ();
5217 #ifdef GC_CHECK_STRING_BYTES
5218 if (!noninteractive)
5219 check_string_bytes (1);
5220 #endif
5221
5222 /* Put all unmarked conses on free list */ 5211 /* Put all unmarked conses on free list */
5223 { 5212 {
5224 register struct cons_block *cblk; 5213 register struct cons_block *cblk;
5225 struct cons_block **cprev = &cons_block; 5214 struct cons_block **cprev = &cons_block;
5226 register int lim = cons_block_index; 5215 register int lim = cons_block_index;
5266 } 5255 }
5267 } 5256 }
5268 total_conses = num_used; 5257 total_conses = num_used;
5269 total_free_conses = num_free; 5258 total_free_conses = num_free;
5270 } 5259 }
5260
5261 /* Remove or mark entries in weak hash tables.
5262 This must be done before any object is unmarked. */
5263 sweep_weak_hash_tables ();
5264
5265 sweep_strings ();
5266 #ifdef GC_CHECK_STRING_BYTES
5267 if (!noninteractive)
5268 check_string_bytes (1);
5269 #endif
5271 5270
5272 /* Put all unmarked floats on free list */ 5271 /* Put all unmarked floats on free list */
5273 { 5272 {
5274 register struct float_block *fblk; 5273 register struct float_block *fblk;
5275 struct float_block **fprev = &float_block; 5274 struct float_block **fprev = &float_block;
5465 } 5464 }
5466 lim = MARKER_BLOCK_SIZE; 5465 lim = MARKER_BLOCK_SIZE;
5467 /* If this block contains only free markers and we have already 5466 /* If this block contains only free markers and we have already
5468 seen more than two blocks worth of free markers then deallocate 5467 seen more than two blocks worth of free markers then deallocate
5469 this block. */ 5468 this block. */
5469 #if 0
5470 /* There may still be pointers to these markers from a buffer's
5471 undo list, so don't free them. KFS 2004-05-21 /
5470 if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE) 5472 if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE)
5471 { 5473 {
5472 *mprev = mblk->next; 5474 *mprev = mblk->next;
5473 /* Unhook from the free list. */ 5475 /* Unhook from the free list. */
5474 marker_free_list = mblk->markers[0].u_free.chain; 5476 marker_free_list = mblk->markers[0].u_free.chain;
5475 lisp_free (mblk); 5477 lisp_free (mblk);
5476 n_marker_blocks--; 5478 n_marker_blocks--;
5477 } 5479 }
5478 else 5480 else
5481 #endif
5479 { 5482 {
5480 num_free += this_free; 5483 num_free += this_free;
5481 mprev = &mblk->next; 5484 mprev = &mblk->next;
5482 } 5485 }
5483 } 5486 }