aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorKaroly Lorentey <[email protected]>2004-05-30 21:11:48 +0000
committerKaroly Lorentey <[email protected]>2004-05-30 21:11:48 +0000
commita596810c6c3c3c2fd450717f5083a5ff5207d243 (patch)
treee84b4a480f6b5bdfb232a384c4c77472950be2a8 /src/alloc.c
parent3de8a2533978f2e296b418a1ab0ae41deb00fa40 (diff)
parent9dd5e8d7c1e0cb26cc75f8cdf91eeaa170b48a6a (diff)
Merged in changes from CVS trunk.
Patches applied: * [email protected]/emacs--cvs-trunk--0--patch-344 Update from CVS * [email protected]/emacs--cvs-trunk--0--patch-345 Tweak source regexps so that building in place won't cause problems * [email protected]/emacs--cvs-trunk--0--patch-346 Update from CVS * [email protected]/emacs--cvs-trunk--0--patch-347 Update from CVS * [email protected]/emacs--cvs-trunk--0--patch-348 Update from CVS * [email protected]/emacs--cvs-trunk--0--patch-349 Update from CVS * [email protected]/emacs--cvs-trunk--0--patch-350 Update from CVS * [email protected]/emacs--cvs-trunk--0--patch-351 Update from CVS * [email protected]/emacs--cvs-trunk--0--patch-352 Update from CVS: lisp/flymake.el: New file. git-archimport-id: [email protected]/emacs--multi-tty--0--patch-182
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c148
1 files changed, 34 insertions, 114 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 1d50f19e92..adedb414aa 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -257,6 +257,7 @@ EMACS_INT gcs_done; /* accumulated GCs */
static void mark_buffer P_ ((Lisp_Object));
extern void mark_kboards P_ ((void));
extern void mark_ttys P_ ((void));
+extern void mark_backtrace P_ ((void));
static void gc_sweep P_ ((void));
static void mark_glyph_matrix P_ ((struct glyph_matrix *));
static void mark_face_cache P_ ((struct face_cache *));
@@ -2866,10 +2867,6 @@ int marker_block_index;
union Lisp_Misc *marker_free_list;
-/* Marker blocks which should be freed at end of GC. */
-
-struct marker_block *marker_blocks_pending_free;
-
/* Total number of marker blocks now in use. */
int n_marker_blocks;
@@ -2880,7 +2877,6 @@ init_marker ()
marker_block = NULL;
marker_block_index = MARKER_BLOCK_SIZE;
marker_free_list = 0;
- marker_blocks_pending_free = 0;
n_marker_blocks = 0;
}
@@ -4283,20 +4279,6 @@ struct catchtag
struct catchtag *next;
};
-struct backtrace
-{
- struct backtrace *next;
- Lisp_Object *function;
- Lisp_Object *args; /* Points to vector of args. */
- int nargs; /* Length of vector. */
- /* 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;
-};
-
-
/***********************************************************************
Protection from GC
@@ -4331,7 +4313,6 @@ returns nil, because real GC can't be done. */)
register struct specbinding *bind;
struct catchtag *catch;
struct handler *handler;
- register struct backtrace *backlist;
char stack_top_variable;
register int i;
int message_p;
@@ -4460,17 +4441,7 @@ returns nil, because real GC can't be done. */)
mark_object (handler->handler);
mark_object (handler->var);
}
- for (backlist = backtrace_list; backlist; backlist = backlist->next)
- {
- mark_object (*backlist->function);
-
- if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
- i = 0;
- else
- i = backlist->nargs - 1;
- for (; i >= 0; i--)
- mark_object (backlist->args[i]);
- }
+ mark_backtrace ();
mark_kboards ();
mark_ttys ();
@@ -4485,42 +4456,36 @@ returns nil, because real GC can't be done. */)
}
#endif
- 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. */
+ /* Everything is now marked, except for the things that require special
+ finalization, i.e. the undo_list.
+ Look thru every buffer's undo list
+ for elements that update markers that were not marked,
+ and delete them. */
{
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. */
+ 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. */
if (! EQ (nextb->undo_list, Qt))
{
- Lisp_Object tail, prev, elt, car;
+ Lisp_Object tail, prev;
tail = nextb->undo_list;
prev = Qnil;
while (CONSP (tail))
{
- if ((elt = XCAR (tail), GC_CONSP (elt))
- && (car = XCAR (elt), GC_MISCP (car))
- && XMISCTYPE (car) == Lisp_Misc_Free)
+ if (GC_CONSP (XCAR (tail))
+ && GC_MARKERP (XCAR (XCAR (tail)))
+ && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
{
- 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 = cdr;
+ nextb->undo_list = tail = XCDR (tail);
else
{
- tail = cdr;
+ tail = XCDR (tail);
XSETCDR (prev, tail);
}
}
@@ -4531,22 +4496,15 @@ returns nil, because real GC can't be done. */)
}
}
}
+ /* Now that we have stripped the elements that need not be in the
+ undo_list any more, we can finally mark the list. */
+ mark_object (nextb->undo_list);
nextb = nextb->next;
}
}
- /* Undo lists have been cleaned up, so we can free marker blocks now. */
-
- {
- struct marker_block *mblk;
-
- while ((mblk = marker_blocks_pending_free) != 0)
- {
- marker_blocks_pending_free = mblk->next;
- lisp_free (mblk);
- }
- }
+ gc_sweep ();
/* Clear the mark bits that we set in certain root slots. */
@@ -5114,41 +5072,9 @@ mark_buffer (buf)
MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
- if (CONSP (buffer->undo_list))
- {
- Lisp_Object tail;
- tail = buffer->undo_list;
-
- /* We mark the undo list specially because
- its pointers to markers should be weak. */
-
- while (CONSP (tail))
- {
- register struct Lisp_Cons *ptr = XCONS (tail);
-
- if (CONS_MARKED_P (ptr))
- break;
- CONS_MARK (ptr);
- if (GC_CONSP (ptr->car)
- && !CONS_MARKED_P (XCONS (ptr->car))
- && GC_MARKERP (XCAR (ptr->car)))
- {
- CONS_MARK (XCONS (ptr->car));
- mark_object (XCDR (ptr->car));
- }
- else
- mark_object (ptr->car);
-
- if (CONSP (ptr->cdr))
- tail = ptr->cdr;
- else
- break;
- }
-
- mark_object (XCDR (tail));
- }
- else
- mark_object (buffer->undo_list);
+ /* For now, we just don't mark the undo_list. It's done later in
+ a special way just before the sweep phase, and after stripping
+ some of its elements that are not needed any more. */
if (buffer->overlays_before)
{
@@ -5228,6 +5154,16 @@ survives_gc_p (obj)
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;
@@ -5278,16 +5214,6 @@ gc_sweep ()
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;
@@ -5456,7 +5382,6 @@ gc_sweep ()
register int num_free = 0, num_used = 0;
marker_free_list = 0;
- marker_blocks_pending_free = 0;
for (mblk = marker_block; mblk; mblk = *mprev)
{
@@ -5492,13 +5417,8 @@ gc_sweep ()
*mprev = mblk->next;
/* Unhook from the free list. */
marker_free_list = mblk->markers[0].u_free.chain;
+ lisp_free (mblk);
n_marker_blocks--;
-
- /* It is not safe to free the marker block at this stage,
- since there may still be pointers to these markers from
- a buffer's undo list. KFS 2004-05-25. */
- mblk->next = marker_blocks_pending_free;
- marker_blocks_pending_free = mblk;
}
else
{