aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorRichard M. Stallman1992-10-01 23:07:09 +0000
committerRichard M. Stallman1992-10-01 23:07:09 +0000
commitc54ca9516b700408ed1d79819659dc886c370dc9 (patch)
tree6803c5fa9b54fa642d35ffdec02ac6fe7e1b5d0c /src/alloc.c
parent1f82d0e4d0d55db82cb70eb4f234c5bd1a018adb (diff)
downloademacs-c54ca9516b700408ed1d79819659dc886c370dc9.tar.gz
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)
1332 case Lisp_Window: 1332 case Lisp_Window:
1333 case Lisp_Process: 1333 case Lisp_Process:
1334 case Lisp_Window_Configuration: 1334 case Lisp_Window_Configuration:
1335 case Lisp_Compiled:
1336 { 1335 {
1337 register struct Lisp_Vector *ptr = XVECTOR (obj); 1336 register struct Lisp_Vector *ptr = XVECTOR (obj);
1338 register int size = ptr->size; 1337 register int size = ptr->size;
@@ -1350,6 +1349,30 @@ mark_object (objptr)
1350 } 1349 }
1351 break; 1350 break;
1352 1351
1352 case Lisp_Compiled:
1353 /* We could treat this just like a vector, but it is better
1354 to save the COMPILED_CONSTANTS element for last and avoid recursion
1355 there. */
1356 {
1357 register struct Lisp_Vector *ptr = XVECTOR (obj);
1358 register int size = ptr->size;
1359 struct Lisp_Vector *volatile ptr1 = ptr;
1360 register int i;
1361
1362 if (size & ARRAY_MARK_FLAG) break; /* Already marked */
1363 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
1364 for (i = 0; i < size; i++) /* and then mark its elements */
1365 {
1366 if (ptr != ptr1)
1367 abort ();
1368 if (i != COMPILED_CONSTANTS)
1369 mark_object (&ptr->contents[i]);
1370 }
1371 objptr = &ptr->contents[COMPILED_CONSTANTS];
1372 obj = *objptr;
1373 goto loop;
1374 }
1375
1353#ifdef MULTI_FRAME 1376#ifdef MULTI_FRAME
1354 case Lisp_Frame: 1377 case Lisp_Frame:
1355 { 1378 {
@@ -1371,19 +1394,6 @@ mark_object (objptr)
1371 break; 1394 break;
1372#endif /* not MULTI_FRAME */ 1395#endif /* not MULTI_FRAME */
1373 1396
1374#if 0
1375 case Lisp_Temp_Vector:
1376 {
1377 register struct Lisp_Vector *ptr = XVECTOR (obj);
1378 register int size = ptr->size;
1379 register int i;
1380
1381 for (i = 0; i < size; i++) /* and then mark its elements */
1382 mark_object (&ptr->contents[i]);
1383 }
1384 break;
1385#endif /* 0 */
1386
1387 case Lisp_Symbol: 1397 case Lisp_Symbol:
1388 { 1398 {
1389 register struct Lisp_Symbol *ptr = XSYMBOL (obj); 1399 register struct Lisp_Symbol *ptr = XSYMBOL (obj);
@@ -1410,7 +1420,7 @@ mark_object (objptr)
1410 XMARK (XMARKER (obj)->chain); 1420 XMARK (XMARKER (obj)->chain);
1411 /* DO NOT mark thru the marker's chain. 1421 /* DO NOT mark thru the marker's chain.
1412 The buffer's markers chain does not preserve markers from gc; 1422 The buffer's markers chain does not preserve markers from gc;
1413 instead, markers are removed from the chain when they are freed by gc. */ 1423 instead, markers are removed from the chain when freed by gc. */
1414 break; 1424 break;
1415 1425
1416 case Lisp_Cons: 1426 case Lisp_Cons:
@@ -1420,6 +1430,14 @@ mark_object (objptr)
1420 register struct Lisp_Cons *ptr = XCONS (obj); 1430 register struct Lisp_Cons *ptr = XCONS (obj);
1421 if (XMARKBIT (ptr->car)) break; 1431 if (XMARKBIT (ptr->car)) break;
1422 XMARK (ptr->car); 1432 XMARK (ptr->car);
1433 /* If the cdr is nil, avoid recursion for the car. */
1434 if (EQ (ptr->cdr, Qnil))
1435 {
1436 objptr = &ptr->car;
1437 obj = ptr->car;
1438 XUNMARK (obj);
1439 goto loop;
1440 }
1423 mark_object (&ptr->car); 1441 mark_object (&ptr->car);
1424 objptr = &ptr->cdr; 1442 objptr = &ptr->cdr;
1425 obj = ptr->cdr; 1443 obj = ptr->cdr;