Mercurial > emacs
changeset 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 | 91bed9994bc1 |
children | b0b446f1087b |
files | src/alloc.c |
diffstat | 1 files changed, 36 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/src/alloc.c Fri May 21 23:35:24 2004 +0000 +++ b/src/alloc.c Fri May 21 23:36:10 2004 +0000 @@ -2334,7 +2334,6 @@ cons_free_list = ptr; } - DEFUN ("cons", Fcons, Scons, 2, 2, 0, doc: /* Create a new cons, give it CAR and CDR as components, and return it. */) (car, cdr) @@ -4286,6 +4285,8 @@ /* If nargs is UNEVALLED, args points to slot holding list of unevalled args. */ char evalargs; + /* Nonzero means call value of debugger when done with this operation. */ + char debug_on_exit; }; @@ -4476,34 +4477,42 @@ } #endif - /* Look thru every buffer's undo list - for elements that update markers that were not marked, - and delete them. */ + gc_sweep (); + + /* Look thru every buffer's undo list for elements that used to + contain update markers that were changed to Lisp_Misc_Free + objects and delete them. This may leave a few cons cells + unchained, but we will get those on the next sweep. */ { register struct buffer *nextb = all_buffers; while (nextb) { /* If a buffer's undo list is Qt, that means that undo is - turned off in that buffer. Calling truncate_undo_list on - Qt tends to return NULL, which effectively turns undo back on. - So don't call truncate_undo_list if undo_list is Qt. */ + turned off in that buffer. */ if (! EQ (nextb->undo_list, Qt)) { - Lisp_Object tail, prev; + Lisp_Object tail, prev, elt, car; tail = nextb->undo_list; prev = Qnil; while (CONSP (tail)) { - if (GC_CONSP (XCAR (tail)) - && GC_MARKERP (XCAR (XCAR (tail))) - && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) + if ((elt = XCAR (tail), GC_CONSP (elt)) + && (car = XCAR (elt), GC_MISCP (car)) + && XMISCTYPE (car) == Lisp_Misc_Free) { + Lisp_Object cdr = XCDR (tail); + /* Do not use free_cons here, as we don't know if + anybody else has a pointer to these conses. */ + XSETCAR (elt, Qnil); + XSETCDR (elt, Qnil); + XSETCAR (tail, Qnil); + XSETCDR (tail, Qnil); if (NILP (prev)) - nextb->undo_list = tail = XCDR (tail); + nextb->undo_list = tail = cdr; else { - tail = XCDR (tail); + tail = cdr; XSETCDR (prev, tail); } } @@ -4519,8 +4528,6 @@ } } - gc_sweep (); - /* Clear the mark bits that we set in certain root slots. */ unmark_byte_stack (); @@ -4976,14 +4983,6 @@ break; case Lisp_Misc: - if (XMISCTYPE (obj) == Lisp_Misc_Free) - { - /* This is (probably) a freed marker which may still exist on - a buffer undo list, so accept it here, as check below will - fail (not live). KFS 2004-05-17 */ - XMARKER (obj)->gcmarkbit = 1; - break; - } CHECK_ALLOCATED_AND_LIVE (live_misc_p); if (XMARKER (obj)->gcmarkbit) break; @@ -5209,16 +5208,6 @@ static void gc_sweep () { - /* Remove or mark entries in weak hash tables. - This must be done before any object is unmarked. */ - sweep_weak_hash_tables (); - - sweep_strings (); -#ifdef GC_CHECK_STRING_BYTES - if (!noninteractive) - check_string_bytes (1); -#endif - /* Put all unmarked conses on free list */ { register struct cons_block *cblk; @@ -5269,6 +5258,16 @@ total_free_conses = num_free; } + /* Remove or mark entries in weak hash tables. + This must be done before any object is unmarked. */ + sweep_weak_hash_tables (); + + sweep_strings (); +#ifdef GC_CHECK_STRING_BYTES + if (!noninteractive) + check_string_bytes (1); +#endif + /* Put all unmarked floats on free list */ { register struct float_block *fblk; @@ -5467,6 +5466,9 @@ /* If this block contains only free markers and we have already seen more than two blocks worth of free markers then deallocate this block. */ +#if 0 + /* There may still be pointers to these markers from a buffer's + undo list, so don't free them. KFS 2004-05-21 / if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE) { *mprev = mblk->next; @@ -5476,6 +5478,7 @@ n_marker_blocks--; } else +#endif { num_free += this_free; mprev = &mblk->next;