summaryrefslogtreecommitdiff
path: root/src/alloc.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1992-10-01 23:07:09 +0000
committerRichard M. Stallman <rms@gnu.org>1992-10-01 23:07:09 +0000
commitc54ca9516b700408ed1d79819659dc886c370dc9 (patch)
tree6803c5fa9b54fa642d35ffdec02ac6fe7e1b5d0c /src/alloc.c
parent1f82d0e4d0d55db82cb70eb4f234c5bd1a018adb (diff)
downloademacs-c54ca9516b700408ed1d79819659dc886c370dc9.tar.gz
emacs-c54ca9516b700408ed1d79819659dc886c370dc9.tar.bz2
emacs-c54ca9516b700408ed1d79819659dc886c370dc9.zip
(mark_object): Avoid car recursion on cons with nil in cdr.
Avoid recursion on constants-vector of a compiled function.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 495c702d038..9cf149e51d1 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1332,7 +1332,6 @@ mark_object (objptr)
case Lisp_Window:
case Lisp_Process:
case Lisp_Window_Configuration:
- case Lisp_Compiled:
{
register struct Lisp_Vector *ptr = XVECTOR (obj);
register int size = ptr->size;
@@ -1350,6 +1349,30 @@ mark_object (objptr)
}
break;
+ case Lisp_Compiled:
+ /* We could treat this just like a vector, but it is better
+ to save the COMPILED_CONSTANTS element for last and avoid recursion
+ there. */
+ {
+ register struct Lisp_Vector *ptr = XVECTOR (obj);
+ register int size = ptr->size;
+ struct Lisp_Vector *volatile ptr1 = ptr;
+ register int i;
+
+ if (size & ARRAY_MARK_FLAG) break; /* Already marked */
+ ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
+ for (i = 0; i < size; i++) /* and then mark its elements */
+ {
+ if (ptr != ptr1)
+ abort ();
+ if (i != COMPILED_CONSTANTS)
+ mark_object (&ptr->contents[i]);
+ }
+ objptr = &ptr->contents[COMPILED_CONSTANTS];
+ obj = *objptr;
+ goto loop;
+ }
+
#ifdef MULTI_FRAME
case Lisp_Frame:
{
@@ -1371,19 +1394,6 @@ mark_object (objptr)
break;
#endif /* not MULTI_FRAME */
-#if 0
- case Lisp_Temp_Vector:
- {
- register struct Lisp_Vector *ptr = XVECTOR (obj);
- register int size = ptr->size;
- register int i;
-
- for (i = 0; i < size; i++) /* and then mark its elements */
- mark_object (&ptr->contents[i]);
- }
- break;
-#endif /* 0 */
-
case Lisp_Symbol:
{
register struct Lisp_Symbol *ptr = XSYMBOL (obj);
@@ -1410,7 +1420,7 @@ mark_object (objptr)
XMARK (XMARKER (obj)->chain);
/* DO NOT mark thru the marker's chain.
The buffer's markers chain does not preserve markers from gc;
- instead, markers are removed from the chain when they are freed by gc. */
+ instead, markers are removed from the chain when freed by gc. */
break;
case Lisp_Cons:
@@ -1420,6 +1430,14 @@ mark_object (objptr)
register struct Lisp_Cons *ptr = XCONS (obj);
if (XMARKBIT (ptr->car)) break;
XMARK (ptr->car);
+ /* If the cdr is nil, avoid recursion for the car. */
+ if (EQ (ptr->cdr, Qnil))
+ {
+ objptr = &ptr->car;
+ obj = ptr->car;
+ XUNMARK (obj);
+ goto loop;
+ }
mark_object (&ptr->car);
objptr = &ptr->cdr;
obj = ptr->cdr;