diff options
author | Richard M. Stallman <rms@gnu.org> | 1992-10-01 23:07:09 +0000 |
---|---|---|
committer | Richard M. Stallman <rms@gnu.org> | 1992-10-01 23:07:09 +0000 |
commit | c54ca9516b700408ed1d79819659dc886c370dc9 (patch) | |
tree | 6803c5fa9b54fa642d35ffdec02ac6fe7e1b5d0c /src/alloc.c | |
parent | 1f82d0e4d0d55db82cb70eb4f234c5bd1a018adb (diff) | |
download | emacs-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.c | 48 |
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; |