aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorKim F. Storm2004-05-21 23:36:10 +0000
committerKim F. Storm2004-05-21 23:36:10 +0000
commit0dbaecd24aeac801d6d49cdd5f0b4bee5f2c9e05 (patch)
treeba74dde57269fb53a7d5fcb42cdb1b67daccfa43 /src/alloc.c
parent4d12067c77083dbacb34366b576825ca7315531c (diff)
downloademacs-0dbaecd24aeac801d6d49cdd5f0b4bee5f2c9e05.tar.gz
emacs-0dbaecd24aeac801d6d49cdd5f0b4bee5f2c9e05.zip
(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.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 3dc21ca30e0..fb424e6aee6 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2334,7 +2334,6 @@ free_cons (ptr)
2334 cons_free_list = ptr; 2334 cons_free_list = ptr;
2335} 2335}
2336 2336
2337
2338DEFUN ("cons", Fcons, Scons, 2, 2, 0, 2337DEFUN ("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)
@@ -4286,6 +4285,8 @@ struct backtrace
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
@@ -4476,34 +4477,42 @@ returns nil, because real GC can't be done. */)
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 }
@@ -4519,8 +4528,6 @@ returns nil, because real GC can't be done. */)
4519 } 4528 }
4520 } 4529 }
4521 4530
4522 gc_sweep ();
4523
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 ();
@@ -4976,14 +4983,6 @@ mark_object (arg)
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;
@@ -5209,16 +5208,6 @@ survives_gc_p (obj)
5209static void 5208static void
5210gc_sweep () 5209gc_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;
@@ -5269,6 +5258,16 @@ gc_sweep ()
5269 total_free_conses = num_free; 5258 total_free_conses = num_free;
5270 } 5259 }
5271 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
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;
@@ -5467,6 +5466,9 @@ gc_sweep ()
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;
@@ -5476,6 +5478,7 @@ gc_sweep ()
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;