diff options
| author | Richard M. Stallman | 1992-10-01 23:07:09 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 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.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) | |||
| 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; |