diff options
| author | Paul Eggert | 2019-05-13 12:43:13 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-05-14 11:10:02 -0700 |
| commit | cf5457764c1288ee34e01d82deb596950fc9f885 (patch) | |
| tree | 5cb2e0ebca40ab00f292c744149ac894ed76bbc5 | |
| parent | 202ff53da267f9fa15f438e9c38603bbead6e890 (diff) | |
| download | emacs-cf5457764c1288ee34e01d82deb596950fc9f885.tar.gz emacs-cf5457764c1288ee34e01d82deb596950fc9f885.zip | |
Backport: fix broken build on m68k
The GCC + valgrind fix caused the m68k build to fail (Bug#35711).
Simplify string allocation a bit to make similar problems less
likely in the future.
* src/alloc.c (sdata, SDATA_NBYTES, SDATA_DATA) [GC_CHECK_STRING_BYTES]:
Use the same implementation as with !GC_CHECK_STRING_BYTES,
as the special case is no longer needed.
(SDATA_ALIGN): New constant.
(SDATA_SIZE): Remove this macro, replacing with ...
(sdata_size): ... this new function. All uses changed.
Properly account for sizes and alignments even in the m68k case,
and even if GC_CHECK_STRING_BYTES is not defined.
| -rw-r--r-- | src/alloc.c | 77 |
1 files changed, 25 insertions, 52 deletions
diff --git a/src/alloc.c b/src/alloc.c index 6fd78188a0c..6aeac140ca0 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -1607,9 +1607,7 @@ mark_interval (INTERVAL i, void *dummy) | |||
| 1607 | 1607 | ||
| 1608 | #define LARGE_STRING_BYTES 1024 | 1608 | #define LARGE_STRING_BYTES 1024 |
| 1609 | 1609 | ||
| 1610 | /* The SDATA typedef is a struct or union describing string memory | 1610 | /* The layout of a nonnull string. */ |
| 1611 | sub-allocated from an sblock. This is where the contents of Lisp | ||
| 1612 | strings are stored. */ | ||
| 1613 | 1611 | ||
| 1614 | struct sdata | 1612 | struct sdata |
| 1615 | { | 1613 | { |
| @@ -1628,13 +1626,8 @@ struct sdata | |||
| 1628 | unsigned char data[FLEXIBLE_ARRAY_MEMBER]; | 1626 | unsigned char data[FLEXIBLE_ARRAY_MEMBER]; |
| 1629 | }; | 1627 | }; |
| 1630 | 1628 | ||
| 1631 | #ifdef GC_CHECK_STRING_BYTES | 1629 | /* A union describing string memory sub-allocated from an sblock. |
| 1632 | 1630 | This is where the contents of Lisp strings are stored. */ | |
| 1633 | typedef struct sdata sdata; | ||
| 1634 | #define SDATA_NBYTES(S) (S)->nbytes | ||
| 1635 | #define SDATA_DATA(S) (S)->data | ||
| 1636 | |||
| 1637 | #else | ||
| 1638 | 1631 | ||
| 1639 | typedef union | 1632 | typedef union |
| 1640 | { | 1633 | { |
| @@ -1662,8 +1655,6 @@ typedef union | |||
| 1662 | #define SDATA_NBYTES(S) (S)->n.nbytes | 1655 | #define SDATA_NBYTES(S) (S)->n.nbytes |
| 1663 | #define SDATA_DATA(S) ((struct sdata *) (S))->data | 1656 | #define SDATA_DATA(S) ((struct sdata *) (S))->data |
| 1664 | 1657 | ||
| 1665 | #endif /* not GC_CHECK_STRING_BYTES */ | ||
| 1666 | |||
| 1667 | enum { SDATA_DATA_OFFSET = offsetof (struct sdata, data) }; | 1658 | enum { SDATA_DATA_OFFSET = offsetof (struct sdata, data) }; |
| 1668 | 1659 | ||
| 1669 | /* Structure describing a block of memory which is sub-allocated to | 1660 | /* Structure describing a block of memory which is sub-allocated to |
| @@ -1754,31 +1745,20 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | |||
| 1754 | #define GC_STRING_OVERRUN_COOKIE_SIZE 0 | 1745 | #define GC_STRING_OVERRUN_COOKIE_SIZE 0 |
| 1755 | #endif | 1746 | #endif |
| 1756 | 1747 | ||
| 1757 | /* Value is the size of an sdata structure large enough to hold NBYTES | 1748 | /* Return the size of an sdata structure large enough to hold N bytes |
| 1758 | bytes of string data. The value returned includes a terminating | 1749 | of string data. This counts the sdata structure, the N bytes, a |
| 1759 | NUL byte, the size of the sdata structure, and padding. */ | 1750 | terminating NUL byte, and alignment padding. */ |
| 1760 | |||
| 1761 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1762 | |||
| 1763 | #define SDATA_SIZE(NBYTES) FLEXSIZEOF (struct sdata, data, (NBYTES) + 1) | ||
| 1764 | |||
| 1765 | #else /* not GC_CHECK_STRING_BYTES */ | ||
| 1766 | |||
| 1767 | /* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is | ||
| 1768 | less than the size of that member. The 'max' is not needed when | ||
| 1769 | SDATA_DATA_OFFSET is a multiple of FLEXALIGNOF (struct sdata), | ||
| 1770 | because then the alignment code reserves enough space. */ | ||
| 1771 | |||
| 1772 | #define SDATA_SIZE(NBYTES) \ | ||
| 1773 | ((SDATA_DATA_OFFSET \ | ||
| 1774 | + (SDATA_DATA_OFFSET % FLEXALIGNOF (struct sdata) == 0 \ | ||
| 1775 | ? NBYTES \ | ||
| 1776 | : max (NBYTES, FLEXALIGNOF (struct sdata) - 1)) \ | ||
| 1777 | + 1 \ | ||
| 1778 | + FLEXALIGNOF (struct sdata) - 1) \ | ||
| 1779 | & ~(FLEXALIGNOF (struct sdata) - 1)) | ||
| 1780 | 1751 | ||
| 1781 | #endif /* not GC_CHECK_STRING_BYTES */ | 1752 | static ptrdiff_t |
| 1753 | sdata_size (ptrdiff_t n) | ||
| 1754 | { | ||
| 1755 | /* Reserve space for the nbytes union member even when N + 1 is less | ||
| 1756 | than the size of that member. */ | ||
| 1757 | ptrdiff_t unaligned_size = max (SDATA_DATA_OFFSET + n + 1, | ||
| 1758 | sizeof (sdata)); | ||
| 1759 | int sdata_align = max (FLEXALIGNOF (struct sdata), alignof (sdata)); | ||
| 1760 | return (unaligned_size + sdata_align - 1) & ~(sdata_align - 1); | ||
| 1761 | } | ||
| 1782 | 1762 | ||
| 1783 | /* Extra bytes to allocate for each string. */ | 1763 | /* Extra bytes to allocate for each string. */ |
| 1784 | 1764 | ||
| @@ -1831,21 +1811,14 @@ string_bytes (struct Lisp_String *s) | |||
| 1831 | static void | 1811 | static void |
| 1832 | check_sblock (struct sblock *b) | 1812 | check_sblock (struct sblock *b) |
| 1833 | { | 1813 | { |
| 1834 | sdata *from, *end, *from_end; | 1814 | sdata *end = b->next_free; |
| 1835 | |||
| 1836 | end = b->next_free; | ||
| 1837 | 1815 | ||
| 1838 | for (from = b->data; from < end; from = from_end) | 1816 | for (sdata *from = b->data; from < end; ) |
| 1839 | { | 1817 | { |
| 1840 | /* Compute the next FROM here because copying below may | 1818 | ptrdiff_t nbytes = sdata_size (from->string |
| 1841 | overwrite data we need to compute it. */ | 1819 | ? string_bytes (from->string) |
| 1842 | ptrdiff_t nbytes; | 1820 | : SDATA_NBYTES (from)); |
| 1843 | 1821 | from = (sdata *) ((char *) from + nbytes + GC_STRING_EXTRA); | |
| 1844 | /* Check that the string size recorded in the string is the | ||
| 1845 | same as the one recorded in the sdata structure. */ | ||
| 1846 | nbytes = SDATA_SIZE (from->string ? string_bytes (from->string) | ||
| 1847 | : SDATA_NBYTES (from)); | ||
| 1848 | from_end = (sdata *) ((char *) from + nbytes + GC_STRING_EXTRA); | ||
| 1849 | } | 1822 | } |
| 1850 | } | 1823 | } |
| 1851 | 1824 | ||
| @@ -1977,14 +1950,14 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1977 | { | 1950 | { |
| 1978 | sdata *data, *old_data; | 1951 | sdata *data, *old_data; |
| 1979 | struct sblock *b; | 1952 | struct sblock *b; |
| 1980 | ptrdiff_t needed, old_nbytes; | 1953 | ptrdiff_t old_nbytes; |
| 1981 | 1954 | ||
| 1982 | if (STRING_BYTES_MAX < nbytes) | 1955 | if (STRING_BYTES_MAX < nbytes) |
| 1983 | string_overflow (); | 1956 | string_overflow (); |
| 1984 | 1957 | ||
| 1985 | /* Determine the number of bytes needed to store NBYTES bytes | 1958 | /* Determine the number of bytes needed to store NBYTES bytes |
| 1986 | of string data. */ | 1959 | of string data. */ |
| 1987 | needed = SDATA_SIZE (nbytes); | 1960 | ptrdiff_t needed = sdata_size (nbytes); |
| 1988 | if (s->u.s.data) | 1961 | if (s->u.s.data) |
| 1989 | { | 1962 | { |
| 1990 | old_data = SDATA_OF_STRING (s); | 1963 | old_data = SDATA_OF_STRING (s); |
| @@ -2234,7 +2207,7 @@ compact_small_strings (void) | |||
| 2234 | nbytes = s ? STRING_BYTES (s) : SDATA_NBYTES (from); | 2207 | nbytes = s ? STRING_BYTES (s) : SDATA_NBYTES (from); |
| 2235 | eassert (nbytes <= LARGE_STRING_BYTES); | 2208 | eassert (nbytes <= LARGE_STRING_BYTES); |
| 2236 | 2209 | ||
| 2237 | nbytes = SDATA_SIZE (nbytes); | 2210 | nbytes = sdata_size (nbytes); |
| 2238 | sdata *from_end = (sdata *) ((char *) from | 2211 | sdata *from_end = (sdata *) ((char *) from |
| 2239 | + nbytes + GC_STRING_EXTRA); | 2212 | + nbytes + GC_STRING_EXTRA); |
| 2240 | 2213 | ||