Mercurial > emacs
comparison src/alloc.c @ 4494:15b073a6c860
(mark_object): Declare ptr volatile, or don't use it
after a recursive call. Delete the aborts if ptr is clobbered.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 08 Aug 1993 23:19:24 +0000 |
parents | a696547fb51e |
children | 1fc792473491 |
comparison
equal
deleted
inserted
replaced
4493:d0143beb12f0 | 4494:15b073a6c860 |
---|---|
1467 mark_object (objptr) | 1467 mark_object (objptr) |
1468 Lisp_Object *objptr; | 1468 Lisp_Object *objptr; |
1469 { | 1469 { |
1470 register Lisp_Object obj; | 1470 register Lisp_Object obj; |
1471 | 1471 |
1472 #ifdef DEBUG_MOLE | |
1473 if (*(int *) ((char *)__builtin_frame_address (0) - 16) == 0) | |
1474 abort (); | |
1475 #endif | |
1476 | |
1477 obj = *objptr; | 1472 obj = *objptr; |
1478 XUNMARK (obj); | 1473 XUNMARK (obj); |
1479 | 1474 |
1480 loop: | 1475 loop: |
1481 | 1476 |
1529 case Lisp_Process: | 1524 case Lisp_Process: |
1530 case Lisp_Window_Configuration: | 1525 case Lisp_Window_Configuration: |
1531 { | 1526 { |
1532 register struct Lisp_Vector *ptr = XVECTOR (obj); | 1527 register struct Lisp_Vector *ptr = XVECTOR (obj); |
1533 register int size = ptr->size; | 1528 register int size = ptr->size; |
1529 /* The reason we use ptr1 is to avoid an apparent hardware bug | |
1530 that happens occasionally on the FSF's HP 300s. | |
1531 The bug is that a2 gets clobbered by recursive calls to mark_object. | |
1532 The clobberage seems to happen during function entry, | |
1533 perhaps in the moveml instruction. | |
1534 Yes, this is a crock, but we have to do it. */ | |
1534 struct Lisp_Vector *volatile ptr1 = ptr; | 1535 struct Lisp_Vector *volatile ptr1 = ptr; |
1535 register int i; | 1536 register int i; |
1536 | 1537 |
1537 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | 1538 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ |
1538 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | 1539 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
1539 for (i = 0; i < size; i++) /* and then mark its elements */ | 1540 for (i = 0; i < size; i++) /* and then mark its elements */ |
1540 { | 1541 mark_object (&ptr1->contents[i]); |
1541 if (ptr != ptr1) | |
1542 abort (); | |
1543 mark_object (&ptr->contents[i]); | |
1544 } | |
1545 } | 1542 } |
1546 break; | 1543 break; |
1547 | 1544 |
1548 case Lisp_Compiled: | 1545 case Lisp_Compiled: |
1549 /* We could treat this just like a vector, but it is better | 1546 /* We could treat this just like a vector, but it is better |
1550 to save the COMPILED_CONSTANTS element for last and avoid recursion | 1547 to save the COMPILED_CONSTANTS element for last and avoid recursion |
1551 there. */ | 1548 there. */ |
1552 { | 1549 { |
1553 register struct Lisp_Vector *ptr = XVECTOR (obj); | 1550 register struct Lisp_Vector *ptr = XVECTOR (obj); |
1554 register int size = ptr->size; | 1551 register int size = ptr->size; |
1552 /* See comment above under Lisp_Vector. */ | |
1555 struct Lisp_Vector *volatile ptr1 = ptr; | 1553 struct Lisp_Vector *volatile ptr1 = ptr; |
1556 register int i; | 1554 register int i; |
1557 | 1555 |
1558 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | 1556 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ |
1559 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | 1557 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
1560 for (i = 0; i < size; i++) /* and then mark its elements */ | 1558 for (i = 0; i < size; i++) /* and then mark its elements */ |
1561 { | 1559 { |
1562 if (ptr != ptr1) | |
1563 abort (); | |
1564 if (i != COMPILED_CONSTANTS) | 1560 if (i != COMPILED_CONSTANTS) |
1565 mark_object (&ptr->contents[i]); | 1561 mark_object (&ptr1->contents[i]); |
1566 } | 1562 } |
1567 objptr = &ptr->contents[COMPILED_CONSTANTS]; | 1563 objptr = &ptr1->contents[COMPILED_CONSTANTS]; |
1568 obj = *objptr; | 1564 obj = *objptr; |
1569 goto loop; | 1565 goto loop; |
1570 } | 1566 } |
1571 | 1567 |
1572 #ifdef MULTI_FRAME | 1568 #ifdef MULTI_FRAME |
1573 case Lisp_Frame: | 1569 case Lisp_Frame: |
1574 { | 1570 { |
1575 register struct frame *ptr = XFRAME (obj); | 1571 /* See comment above under Lisp_Vector for why this is volatile. */ |
1572 register struct frame *volatile ptr = XFRAME (obj); | |
1576 register int size = ptr->size; | 1573 register int size = ptr->size; |
1577 | 1574 |
1578 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | 1575 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ |
1579 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | 1576 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
1580 | 1577 |
1593 break; | 1590 break; |
1594 #endif /* MULTI_FRAME */ | 1591 #endif /* MULTI_FRAME */ |
1595 | 1592 |
1596 case Lisp_Symbol: | 1593 case Lisp_Symbol: |
1597 { | 1594 { |
1598 register struct Lisp_Symbol *ptr = XSYMBOL (obj); | 1595 /* See comment above under Lisp_Vector for why this is volatile. */ |
1596 register struct Lisp_Symbol *volatile ptr = XSYMBOL (obj); | |
1599 struct Lisp_Symbol *ptrx; | 1597 struct Lisp_Symbol *ptrx; |
1600 | 1598 |
1601 if (XMARKBIT (ptr->plist)) break; | 1599 if (XMARKBIT (ptr->plist)) break; |
1602 XMARK (ptr->plist); | 1600 XMARK (ptr->plist); |
1603 mark_object ((Lisp_Object *) &ptr->value); | 1601 mark_object ((Lisp_Object *) &ptr->value); |
1604 if ((unsigned int) ptr <= 4) | |
1605 abort (); | |
1606 mark_object (&ptr->function); | 1602 mark_object (&ptr->function); |
1607 if ((unsigned int) ptr <= 4) | |
1608 abort (); | |
1609 mark_object (&ptr->plist); | 1603 mark_object (&ptr->plist); |
1610 if ((unsigned int) ptr <= 4) | |
1611 abort (); | |
1612 XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String); | 1604 XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String); |
1613 mark_object (&ptr->name); | 1605 mark_object (&ptr->name); |
1614 if ((unsigned int) ptr <= 4) | |
1615 abort (); | |
1616 ptr = ptr->next; | 1606 ptr = ptr->next; |
1617 if (ptr) | 1607 if (ptr) |
1618 { | 1608 { |
1619 ptrx = ptr; /* Use of ptrx avoids compiler bug on Sun */ | 1609 ptrx = ptr; /* Use of ptrx avoids compiler bug on Sun */ |
1620 XSETSYMBOL (obj, ptrx); | 1610 XSETSYMBOL (obj, ptrx); |
1644 objptr = &ptr->car; | 1634 objptr = &ptr->car; |
1645 obj = ptr->car; | 1635 obj = ptr->car; |
1646 XUNMARK (obj); | 1636 XUNMARK (obj); |
1647 goto loop; | 1637 goto loop; |
1648 } | 1638 } |
1649 if (ptr == 0) | |
1650 abort (); | |
1651 mark_object (&ptr->car); | 1639 mark_object (&ptr->car); |
1652 if (ptr == 0) | 1640 /* See comment above under Lisp_Vector for why not use ptr here. */ |
1653 abort (); | 1641 objptr = &XCONS (obj)->cdr; |
1654 objptr = &ptr->cdr; | |
1655 obj = ptr->cdr; | 1642 obj = ptr->cdr; |
1656 goto loop; | 1643 goto loop; |
1657 } | 1644 } |
1658 | 1645 |
1659 #ifdef LISP_FLOAT_TYPE | 1646 #ifdef LISP_FLOAT_TYPE |