aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2013-06-21 13:11:44 -0700
committerPaul Eggert2013-06-21 13:11:44 -0700
commitfbe9e0b9fb6a250674e7619e9ba794e74ff5f0bc (patch)
tree7b1836faca02f39413afec531c2ae467898523f5 /src/alloc.c
parentcad5d1cb5af7210154814b60825576d14740158f (diff)
downloademacs-fbe9e0b9fb6a250674e7619e9ba794e74ff5f0bc.tar.gz
emacs-fbe9e0b9fb6a250674e7619e9ba794e74ff5f0bc.zip
Use C99-style flexible array members if available.
This avoids some subtle aliasing issues, which typically aren't a problem with GCC but may be a problem elsewhere. * lib-src/ebrowse.c (struct member, struct alias, struct sym): Use FLEXIBLE_ARRAY_MEMBER. (add_sym, add_member, make_namespace, register_namespace_alias): Use offsetof (struct, flex_array_member), not sizeof (struct), as that ports better to pre-C99 non-GCC. * src/alloc.c (sdata): New typedef, replacing the old struct sdata. It is a struct if GC_CHECK_STRING_BYTES, a union otherwise. In either case, it uses a flexible array member rather than the old struct hack. All uses changed. (SDATA_NBYTES, sweep_strings) [!GC_CHECK_STRING_BYTES]: Adjust to sdata reorganization. * src/alloc.c (VBLOCK_BYTES_MIN, allocate_vectorlike, Fgarbage_collect): Use offsetof (struct, flex_array_member), not sizeof (struct), as that ports better to pre-C99 non-GCC. * src/chartab.c (Fmake_char_table, make_sub_char_table, copy_char_table): Use CHAR_TABLE_STANDARD_SLOTS rather than its definition, as the latter has changed. * src/conf_post.h (FLEXIBLE_ARRAY_MEMBER): Move here from w32.c, and port better to pre-C99 GCC. * src/image.c (struct xpm_cached_color): * src/lisp.h (struct Lisp_Vector, struct Lisp_Bool_Vector) (struct Lisp_Char_Table, struct Lisp_Sub_Char_Table): Use FLEXIBLE_ARRAY_MEMBER. * src/lisp.h (string_bytes) [GC_CHECK_STRING_BYTES]: Move decl to top level so it gets checked against implementation. (CHAR_TABLE_STANDARD_SLOTS): Adjust to struct Lisp_Char_Table change. * src/w32.c (FLEXIBLE_ARRAY_MEMBER): Move to conf_post.h.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/src/alloc.c b/src/alloc.c
index d277dd2419b..eaef0d4b797 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1260,7 +1260,7 @@ mark_interval (register INTERVAL i, Lisp_Object dummy)
1260 When a Lisp_String is freed during GC, it is put back on 1260 When a Lisp_String is freed during GC, it is put back on
1261 string_free_list, and its `data' member and its sdata's `string' 1261 string_free_list, and its `data' member and its sdata's `string'
1262 pointer is set to null. The size of the string is recorded in the 1262 pointer is set to null. The size of the string is recorded in the
1263 `u.nbytes' member of the sdata. So, sdata structures that are no 1263 `n.nbytes' member of the sdata. So, sdata structures that are no
1264 longer used, can be easily recognized, and it's easy to compact the 1264 longer used, can be easily recognized, and it's easy to compact the
1265 sblocks of small strings which we do in compact_small_strings. */ 1265 sblocks of small strings which we do in compact_small_strings. */
1266 1266
@@ -1274,10 +1274,12 @@ mark_interval (register INTERVAL i, Lisp_Object dummy)
1274 1274
1275#define LARGE_STRING_BYTES 1024 1275#define LARGE_STRING_BYTES 1024
1276 1276
1277/* Structure describing string memory sub-allocated from an sblock. 1277/* Struct or union describing string memory sub-allocated from an sblock.
1278 This is where the contents of Lisp strings are stored. */ 1278 This is where the contents of Lisp strings are stored. */
1279 1279
1280struct sdata 1280#ifdef GC_CHECK_STRING_BYTES
1281
1282typedef struct
1281{ 1283{
1282 /* Back-pointer to the string this sdata belongs to. If null, this 1284 /* Back-pointer to the string this sdata belongs to. If null, this
1283 structure is free, and the NBYTES member of the union below 1285 structure is free, and the NBYTES member of the union below
@@ -1287,34 +1289,42 @@ struct sdata
1287 contents. */ 1289 contents. */
1288 struct Lisp_String *string; 1290 struct Lisp_String *string;
1289 1291
1290#ifdef GC_CHECK_STRING_BYTES
1291
1292 ptrdiff_t nbytes; 1292 ptrdiff_t nbytes;
1293 unsigned char data[1]; 1293 unsigned char data[FLEXIBLE_ARRAY_MEMBER];
1294} sdata;
1294 1295
1295#define SDATA_NBYTES(S) (S)->nbytes 1296#define SDATA_NBYTES(S) (S)->nbytes
1296#define SDATA_DATA(S) (S)->data 1297#define SDATA_DATA(S) (S)->data
1297#define SDATA_SELECTOR(member) member 1298#define SDATA_SELECTOR(member) member
1298 1299
1299#else /* not GC_CHECK_STRING_BYTES */ 1300#else
1300 1301
1301 union 1302typedef union
1303{
1304 struct Lisp_String *string;
1305
1306 /* When STRING is non-null. */
1307 struct
1302 { 1308 {
1303 /* When STRING is non-null. */ 1309 struct Lisp_String *string;
1304 unsigned char data[1]; 1310 unsigned char data[FLEXIBLE_ARRAY_MEMBER];
1311 } u;
1305 1312
1306 /* When STRING is null. */ 1313 /* When STRING is null. */
1314 struct
1315 {
1316 struct Lisp_String *string;
1307 ptrdiff_t nbytes; 1317 ptrdiff_t nbytes;
1308 } u; 1318 } n;
1319} sdata;
1309 1320
1310#define SDATA_NBYTES(S) (S)->u.nbytes 1321#define SDATA_NBYTES(S) (S)->n.nbytes
1311#define SDATA_DATA(S) (S)->u.data 1322#define SDATA_DATA(S) (S)->u.data
1312#define SDATA_SELECTOR(member) u.member 1323#define SDATA_SELECTOR(member) u.member
1313 1324
1314#endif /* not GC_CHECK_STRING_BYTES */ 1325#endif /* not GC_CHECK_STRING_BYTES */
1315 1326
1316#define SDATA_DATA_OFFSET offsetof (struct sdata, SDATA_SELECTOR (data)) 1327#define SDATA_DATA_OFFSET offsetof (sdata, SDATA_SELECTOR (data))
1317};
1318 1328
1319 1329
1320/* Structure describing a block of memory which is sub-allocated to 1330/* Structure describing a block of memory which is sub-allocated to
@@ -1329,10 +1339,10 @@ struct sblock
1329 1339
1330 /* Pointer to the next free sdata block. This points past the end 1340 /* Pointer to the next free sdata block. This points past the end
1331 of the sblock if there isn't any space left in this block. */ 1341 of the sblock if there isn't any space left in this block. */
1332 struct sdata *next_free; 1342 sdata *next_free;
1333 1343
1334 /* Start of data. */ 1344 /* Start of data. */
1335 struct sdata first_data; 1345 sdata first_data;
1336}; 1346};
1337 1347
1338/* Number of Lisp strings in a string_block structure. The 1020 is 1348/* Number of Lisp strings in a string_block structure. The 1020 is
@@ -1388,7 +1398,7 @@ static EMACS_INT total_string_bytes;
1388 a pointer to the `u.data' member of its sdata structure; the 1398 a pointer to the `u.data' member of its sdata structure; the
1389 structure starts at a constant offset in front of that. */ 1399 structure starts at a constant offset in front of that. */
1390 1400
1391#define SDATA_OF_STRING(S) ((struct sdata *) ((S)->data - SDATA_DATA_OFFSET)) 1401#define SDATA_OF_STRING(S) ((sdata *) ((S)->data - SDATA_DATA_OFFSET))
1392 1402
1393 1403
1394#ifdef GC_CHECK_STRING_OVERRUN 1404#ifdef GC_CHECK_STRING_OVERRUN
@@ -1487,7 +1497,7 @@ string_bytes (struct Lisp_String *s)
1487static void 1497static void
1488check_sblock (struct sblock *b) 1498check_sblock (struct sblock *b)
1489{ 1499{
1490 struct sdata *from, *end, *from_end; 1500 sdata *from, *end, *from_end;
1491 1501
1492 end = b->next_free; 1502 end = b->next_free;
1493 1503
@@ -1501,7 +1511,7 @@ check_sblock (struct sblock *b)
1501 same as the one recorded in the sdata structure. */ 1511 same as the one recorded in the sdata structure. */
1502 nbytes = SDATA_SIZE (from->string ? string_bytes (from->string) 1512 nbytes = SDATA_SIZE (from->string ? string_bytes (from->string)
1503 : SDATA_NBYTES (from)); 1513 : SDATA_NBYTES (from));
1504 from_end = (struct sdata *) ((char *) from + nbytes + GC_STRING_EXTRA); 1514 from_end = (sdata *) ((char *) from + nbytes + GC_STRING_EXTRA);
1505 } 1515 }
1506} 1516}
1507 1517
@@ -1631,7 +1641,7 @@ void
1631allocate_string_data (struct Lisp_String *s, 1641allocate_string_data (struct Lisp_String *s,
1632 EMACS_INT nchars, EMACS_INT nbytes) 1642 EMACS_INT nchars, EMACS_INT nbytes)
1633{ 1643{
1634 struct sdata *data, *old_data; 1644 sdata *data, *old_data;
1635 struct sblock *b; 1645 struct sblock *b;
1636 ptrdiff_t needed, old_nbytes; 1646 ptrdiff_t needed, old_nbytes;
1637 1647
@@ -1701,7 +1711,7 @@ allocate_string_data (struct Lisp_String *s,
1701 b = current_sblock; 1711 b = current_sblock;
1702 1712
1703 data = b->next_free; 1713 data = b->next_free;
1704 b->next_free = (struct sdata *) ((char *) data + needed + GC_STRING_EXTRA); 1714 b->next_free = (sdata *) ((char *) data + needed + GC_STRING_EXTRA);
1705 1715
1706 MALLOC_UNBLOCK_INPUT; 1716 MALLOC_UNBLOCK_INPUT;
1707 1717
@@ -1772,7 +1782,7 @@ sweep_strings (void)
1772 else 1782 else
1773 { 1783 {
1774 /* String is dead. Put it on the free-list. */ 1784 /* String is dead. Put it on the free-list. */
1775 struct sdata *data = SDATA_OF_STRING (s); 1785 sdata *data = SDATA_OF_STRING (s);
1776 1786
1777 /* Save the size of S in its sdata so that we know 1787 /* Save the size of S in its sdata so that we know
1778 how large that is. Reset the sdata's string 1788 how large that is. Reset the sdata's string
@@ -1781,7 +1791,7 @@ sweep_strings (void)
1781 if (string_bytes (s) != SDATA_NBYTES (data)) 1791 if (string_bytes (s) != SDATA_NBYTES (data))
1782 emacs_abort (); 1792 emacs_abort ();
1783#else 1793#else
1784 data->u.nbytes = STRING_BYTES (s); 1794 data->n.nbytes = STRING_BYTES (s);
1785#endif 1795#endif
1786 data->string = NULL; 1796 data->string = NULL;
1787 1797
@@ -1862,13 +1872,13 @@ static void
1862compact_small_strings (void) 1872compact_small_strings (void)
1863{ 1873{
1864 struct sblock *b, *tb, *next; 1874 struct sblock *b, *tb, *next;
1865 struct sdata *from, *to, *end, *tb_end; 1875 sdata *from, *to, *end, *tb_end;
1866 struct sdata *to_end, *from_end; 1876 sdata *to_end, *from_end;
1867 1877
1868 /* TB is the sblock we copy to, TO is the sdata within TB we copy 1878 /* TB is the sblock we copy to, TO is the sdata within TB we copy
1869 to, and TB_END is the end of TB. */ 1879 to, and TB_END is the end of TB. */
1870 tb = oldest_sblock; 1880 tb = oldest_sblock;
1871 tb_end = (struct sdata *) ((char *) tb + SBLOCK_SIZE); 1881 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE);
1872 to = &tb->first_data; 1882 to = &tb->first_data;
1873 1883
1874 /* Step through the blocks from the oldest to the youngest. We 1884 /* Step through the blocks from the oldest to the youngest. We
@@ -1897,7 +1907,7 @@ compact_small_strings (void)
1897 eassert (nbytes <= LARGE_STRING_BYTES); 1907 eassert (nbytes <= LARGE_STRING_BYTES);
1898 1908
1899 nbytes = SDATA_SIZE (nbytes); 1909 nbytes = SDATA_SIZE (nbytes);
1900 from_end = (struct sdata *) ((char *) from + nbytes + GC_STRING_EXTRA); 1910 from_end = (sdata *) ((char *) from + nbytes + GC_STRING_EXTRA);
1901 1911
1902#ifdef GC_CHECK_STRING_OVERRUN 1912#ifdef GC_CHECK_STRING_OVERRUN
1903 if (memcmp (string_overrun_cookie, 1913 if (memcmp (string_overrun_cookie,
@@ -1910,14 +1920,14 @@ compact_small_strings (void)
1910 if (s) 1920 if (s)
1911 { 1921 {
1912 /* If TB is full, proceed with the next sblock. */ 1922 /* If TB is full, proceed with the next sblock. */
1913 to_end = (struct sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); 1923 to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA);
1914 if (to_end > tb_end) 1924 if (to_end > tb_end)
1915 { 1925 {
1916 tb->next_free = to; 1926 tb->next_free = to;
1917 tb = tb->next; 1927 tb = tb->next;
1918 tb_end = (struct sdata *) ((char *) tb + SBLOCK_SIZE); 1928 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE);
1919 to = &tb->first_data; 1929 to = &tb->first_data;
1920 to_end = (struct sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); 1930 to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA);
1921 } 1931 }
1922 1932
1923 /* Copy, and update the string's `data' pointer. */ 1933 /* Copy, and update the string's `data' pointer. */
@@ -2581,7 +2591,7 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2581 2591
2582/* Size of the minimal vector allocated from block. */ 2592/* Size of the minimal vector allocated from block. */
2583 2593
2584#define VBLOCK_BYTES_MIN vroundup (sizeof (struct Lisp_Vector)) 2594#define VBLOCK_BYTES_MIN vroundup (header_size + sizeof (Lisp_Object))
2585 2595
2586/* Size of the largest vector allocated from block. */ 2596/* Size of the largest vector allocated from block. */
2587 2597
@@ -2938,7 +2948,8 @@ allocate_vectorlike (ptrdiff_t len)
2938 else 2948 else
2939 { 2949 {
2940 struct large_vector *lv 2950 struct large_vector *lv
2941 = lisp_malloc (sizeof (*lv) + (len - 1) * word_size, 2951 = lisp_malloc ((offsetof (struct large_vector, v.contents)
2952 + len * word_size),
2942 MEM_TYPE_VECTORLIKE); 2953 MEM_TYPE_VECTORLIKE);
2943 lv->next.vector = large_vectors; 2954 lv->next.vector = large_vectors;
2944 large_vectors = lv; 2955 large_vectors = lv;
@@ -5416,7 +5427,8 @@ See Info node `(elisp)Garbage Collection'. */)
5416 total[4] = list3 (Qstring_bytes, make_number (1), 5427 total[4] = list3 (Qstring_bytes, make_number (1),
5417 bounded_number (total_string_bytes)); 5428 bounded_number (total_string_bytes));
5418 5429
5419 total[5] = list3 (Qvectors, make_number (sizeof (struct Lisp_Vector)), 5430 total[5] = list3 (Qvectors,
5431 make_number (header_size + sizeof (Lisp_Object)),
5420 bounded_number (total_vectors)); 5432 bounded_number (total_vectors));
5421 5433
5422 total[6] = list4 (Qvector_slots, make_number (word_size), 5434 total[6] = list4 (Qvector_slots, make_number (word_size),