aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorEli Zaretskii2013-11-18 18:45:48 +0200
committerEli Zaretskii2013-11-18 18:45:48 +0200
commit18b35e2c7a3ff95fb4a07e58c3f57c70c65c0701 (patch)
tree7a837a755a7c22d3258408cb384d01479ad88232 /src/alloc.c
parentdf87c56cdf6c8c13e8760bdc409e2eb0fda55b0b (diff)
parent37c790b38599cc80a16c6a76152abbf8160fe2a1 (diff)
downloademacs-18b35e2c7a3ff95fb4a07e58c3f57c70c65c0701.tar.gz
emacs-18b35e2c7a3ff95fb4a07e58c3f57c70c65c0701.zip
Merge from mainline.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c559
1 files changed, 337 insertions, 222 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 02deaa94af1..f12fdc5c861 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -361,13 +361,21 @@ static int staticidx;
361 361
362static void *pure_alloc (size_t, int); 362static void *pure_alloc (size_t, int);
363 363
364/* Return X rounded to the next multiple of Y. Arguments should not
365 have side effects, as they are evaluated more than once. Assume X
366 + Y - 1 does not overflow. Tune for Y being a power of 2. */
364 367
365/* Value is SZ rounded up to the next multiple of ALIGNMENT. 368#define ROUNDUP(x, y) ((y) & ((y) - 1) \
366 ALIGNMENT must be a power of 2. */ 369 ? ((x) + (y) - 1) - ((x) + (y) - 1) % (y) \
370 : ((x) + (y) - 1) & ~ ((y) - 1))
367 371
368#define ALIGN(ptr, ALIGNMENT) \ 372/* Return PTR rounded up to the next multiple of ALIGNMENT. */
369 ((void *) (((uintptr_t) (ptr) + (ALIGNMENT) - 1) \ 373
370 & ~ ((ALIGNMENT) - 1))) 374static void *
375ALIGN (void *ptr, int alignment)
376{
377 return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
378}
371 379
372static void 380static void
373XFLOAT_INIT (Lisp_Object f, double n) 381XFLOAT_INIT (Lisp_Object f, double n)
@@ -912,8 +920,20 @@ lisp_free (void *block)
912/* The entry point is lisp_align_malloc which returns blocks of at most 920/* The entry point is lisp_align_malloc which returns blocks of at most
913 BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ 921 BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */
914 922
915#if defined (HAVE_POSIX_MEMALIGN) && defined (SYSTEM_MALLOC) 923#if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
916#define USE_POSIX_MEMALIGN 1 924# define USE_ALIGNED_ALLOC 1
925/* Defined in gmalloc.c. */
926void *aligned_alloc (size_t, size_t);
927#elif defined HAVE_ALIGNED_ALLOC
928# define USE_ALIGNED_ALLOC 1
929#elif defined HAVE_POSIX_MEMALIGN
930# define USE_ALIGNED_ALLOC 1
931static void *
932aligned_alloc (size_t alignment, size_t size)
933{
934 void *p;
935 return posix_memalign (&p, alignment, size) == 0 ? p : 0;
936}
917#endif 937#endif
918 938
919/* BLOCK_ALIGN has to be a power of 2. */ 939/* BLOCK_ALIGN has to be a power of 2. */
@@ -923,7 +943,7 @@ lisp_free (void *block)
923 malloc a chance to minimize the amount of memory wasted to alignment. 943 malloc a chance to minimize the amount of memory wasted to alignment.
924 It should be tuned to the particular malloc library used. 944 It should be tuned to the particular malloc library used.
925 On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best. 945 On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best.
926 posix_memalign on the other hand would ideally prefer a value of 4 946 aligned_alloc on the other hand would ideally prefer a value of 4
927 because otherwise, there's 1020 bytes wasted between each ablocks. 947 because otherwise, there's 1020 bytes wasted between each ablocks.
928 In Emacs, testing shows that those 1020 can most of the time be 948 In Emacs, testing shows that those 1020 can most of the time be
929 efficiently used by malloc to place other objects, so a value of 0 can 949 efficiently used by malloc to place other objects, so a value of 0 can
@@ -968,7 +988,7 @@ struct ablocks
968 struct ablock blocks[ABLOCKS_SIZE]; 988 struct ablock blocks[ABLOCKS_SIZE];
969}; 989};
970 990
971/* Size of the block requested from malloc or posix_memalign. */ 991/* Size of the block requested from malloc or aligned_alloc. */
972#define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) 992#define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING)
973 993
974#define ABLOCK_ABASE(block) \ 994#define ABLOCK_ABASE(block) \
@@ -980,7 +1000,7 @@ struct ablocks
980#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) 1000#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase)
981 1001
982/* Pointer to the (not necessarily aligned) malloc block. */ 1002/* Pointer to the (not necessarily aligned) malloc block. */
983#ifdef USE_POSIX_MEMALIGN 1003#ifdef USE_ALIGNED_ALLOC
984#define ABLOCKS_BASE(abase) (abase) 1004#define ABLOCKS_BASE(abase) (abase)
985#else 1005#else
986#define ABLOCKS_BASE(abase) \ 1006#define ABLOCKS_BASE(abase) \
@@ -1019,13 +1039,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1019 mallopt (M_MMAP_MAX, 0); 1039 mallopt (M_MMAP_MAX, 0);
1020#endif 1040#endif
1021 1041
1022#ifdef USE_POSIX_MEMALIGN 1042#ifdef USE_ALIGNED_ALLOC
1023 { 1043 abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES);
1024 int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES);
1025 if (err)
1026 base = NULL;
1027 abase = base;
1028 }
1029#else 1044#else
1030 base = malloc (ABLOCKS_BYTES); 1045 base = malloc (ABLOCKS_BYTES);
1031 abase = ALIGN (base, BLOCK_ALIGN); 1046 abase = ALIGN (base, BLOCK_ALIGN);
@@ -1280,28 +1295,32 @@ mark_interval (register INTERVAL i, Lisp_Object dummy)
1280 1295
1281#define LARGE_STRING_BYTES 1024 1296#define LARGE_STRING_BYTES 1024
1282 1297
1283/* Struct or union describing string memory sub-allocated from an sblock. 1298/* The SDATA typedef is a struct or union describing string memory
1284 This is where the contents of Lisp strings are stored. */ 1299 sub-allocated from an sblock. This is where the contents of Lisp
1285 1300 strings are stored. */
1286#ifdef GC_CHECK_STRING_BYTES
1287 1301
1288typedef struct 1302struct sdata
1289{ 1303{
1290 /* Back-pointer to the string this sdata belongs to. If null, this 1304 /* Back-pointer to the string this sdata belongs to. If null, this
1291 structure is free, and the NBYTES member of the union below 1305 structure is free, and NBYTES (in this structure or in the union below)
1292 contains the string's byte size (the same value that STRING_BYTES 1306 contains the string's byte size (the same value that STRING_BYTES
1293 would return if STRING were non-null). If non-null, STRING_BYTES 1307 would return if STRING were non-null). If non-null, STRING_BYTES
1294 (STRING) is the size of the data, and DATA contains the string's 1308 (STRING) is the size of the data, and DATA contains the string's
1295 contents. */ 1309 contents. */
1296 struct Lisp_String *string; 1310 struct Lisp_String *string;
1297 1311
1312#ifdef GC_CHECK_STRING_BYTES
1298 ptrdiff_t nbytes; 1313 ptrdiff_t nbytes;
1314#endif
1315
1299 unsigned char data[FLEXIBLE_ARRAY_MEMBER]; 1316 unsigned char data[FLEXIBLE_ARRAY_MEMBER];
1300} sdata; 1317};
1301 1318
1319#ifdef GC_CHECK_STRING_BYTES
1320
1321typedef struct sdata sdata;
1302#define SDATA_NBYTES(S) (S)->nbytes 1322#define SDATA_NBYTES(S) (S)->nbytes
1303#define SDATA_DATA(S) (S)->data 1323#define SDATA_DATA(S) (S)->data
1304#define SDATA_SELECTOR(member) member
1305 1324
1306#else 1325#else
1307 1326
@@ -1309,12 +1328,16 @@ typedef union
1309{ 1328{
1310 struct Lisp_String *string; 1329 struct Lisp_String *string;
1311 1330
1312 /* When STRING is non-null. */ 1331 /* When STRING is nonnull, this union is actually of type 'struct sdata',
1313 struct 1332 which has a flexible array member. However, if implemented by
1314 { 1333 giving this union a member of type 'struct sdata', the union
1315 struct Lisp_String *string; 1334 could not be the last (flexible) member of 'struct sblock',
1316 unsigned char data[FLEXIBLE_ARRAY_MEMBER]; 1335 because C99 prohibits a flexible array member from having a type
1317 } u; 1336 that is itself a flexible array. So, comment this member out here,
1337 but remember that the option's there when using this union. */
1338#if 0
1339 struct sdata u;
1340#endif
1318 1341
1319 /* When STRING is null. */ 1342 /* When STRING is null. */
1320 struct 1343 struct
@@ -1325,13 +1348,11 @@ typedef union
1325} sdata; 1348} sdata;
1326 1349
1327#define SDATA_NBYTES(S) (S)->n.nbytes 1350#define SDATA_NBYTES(S) (S)->n.nbytes
1328#define SDATA_DATA(S) (S)->u.data 1351#define SDATA_DATA(S) ((struct sdata *) (S))->data
1329#define SDATA_SELECTOR(member) u.member
1330 1352
1331#endif /* not GC_CHECK_STRING_BYTES */ 1353#endif /* not GC_CHECK_STRING_BYTES */
1332 1354
1333#define SDATA_DATA_OFFSET offsetof (sdata, SDATA_SELECTOR (data)) 1355enum { SDATA_DATA_OFFSET = offsetof (struct sdata, data) };
1334
1335 1356
1336/* Structure describing a block of memory which is sub-allocated to 1357/* Structure describing a block of memory which is sub-allocated to
1337 obtain string data memory for strings. Blocks for small strings 1358 obtain string data memory for strings. Blocks for small strings
@@ -1347,8 +1368,8 @@ struct sblock
1347 of the sblock if there isn't any space left in this block. */ 1368 of the sblock if there isn't any space left in this block. */
1348 sdata *next_free; 1369 sdata *next_free;
1349 1370
1350 /* Start of data. */ 1371 /* String data. */
1351 sdata first_data; 1372 sdata data[FLEXIBLE_ARRAY_MEMBER];
1352}; 1373};
1353 1374
1354/* Number of Lisp strings in a string_block structure. The 1020 is 1375/* Number of Lisp strings in a string_block structure. The 1020 is
@@ -1464,7 +1485,7 @@ static ptrdiff_t const STRING_BYTES_MAX =
1464 min (STRING_BYTES_BOUND, 1485 min (STRING_BYTES_BOUND,
1465 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD 1486 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD
1466 - GC_STRING_EXTRA 1487 - GC_STRING_EXTRA
1467 - offsetof (struct sblock, first_data) 1488 - offsetof (struct sblock, data)
1468 - SDATA_DATA_OFFSET) 1489 - SDATA_DATA_OFFSET)
1469 & ~(sizeof (EMACS_INT) - 1))); 1490 & ~(sizeof (EMACS_INT) - 1)));
1470 1491
@@ -1507,7 +1528,7 @@ check_sblock (struct sblock *b)
1507 1528
1508 end = b->next_free; 1529 end = b->next_free;
1509 1530
1510 for (from = &b->first_data; from < end; from = from_end) 1531 for (from = b->data; from < end; from = from_end)
1511 { 1532 {
1512 /* Compute the next FROM here because copying below may 1533 /* Compute the next FROM here because copying below may
1513 overwrite data we need to compute it. */ 1534 overwrite data we need to compute it. */
@@ -1535,7 +1556,7 @@ check_string_bytes (bool all_p)
1535 1556
1536 for (b = large_sblocks; b; b = b->next) 1557 for (b = large_sblocks; b; b = b->next)
1537 { 1558 {
1538 struct Lisp_String *s = b->first_data.string; 1559 struct Lisp_String *s = b->data[0].string;
1539 if (s) 1560 if (s)
1540 string_bytes (s); 1561 string_bytes (s);
1541 } 1562 }
@@ -1669,7 +1690,7 @@ allocate_string_data (struct Lisp_String *s,
1669 1690
1670 if (nbytes > LARGE_STRING_BYTES) 1691 if (nbytes > LARGE_STRING_BYTES)
1671 { 1692 {
1672 size_t size = offsetof (struct sblock, first_data) + needed; 1693 size_t size = offsetof (struct sblock, data) + needed;
1673 1694
1674#ifdef DOUG_LEA_MALLOC 1695#ifdef DOUG_LEA_MALLOC
1675 /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed 1696 /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed
@@ -1691,8 +1712,8 @@ allocate_string_data (struct Lisp_String *s,
1691 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); 1712 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
1692#endif 1713#endif
1693 1714
1694 b->next_free = &b->first_data; 1715 b->next_free = b->data;
1695 b->first_data.string = NULL; 1716 b->data[0].string = NULL;
1696 b->next = large_sblocks; 1717 b->next = large_sblocks;
1697 large_sblocks = b; 1718 large_sblocks = b;
1698 } 1719 }
@@ -1703,8 +1724,8 @@ allocate_string_data (struct Lisp_String *s,
1703 { 1724 {
1704 /* Not enough room in the current sblock. */ 1725 /* Not enough room in the current sblock. */
1705 b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP); 1726 b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP);
1706 b->next_free = &b->first_data; 1727 b->next_free = b->data;
1707 b->first_data.string = NULL; 1728 b->data[0].string = NULL;
1708 b->next = NULL; 1729 b->next = NULL;
1709 1730
1710 if (current_sblock) 1731 if (current_sblock)
@@ -1858,7 +1879,7 @@ free_large_strings (void)
1858 { 1879 {
1859 next = b->next; 1880 next = b->next;
1860 1881
1861 if (b->first_data.string == NULL) 1882 if (b->data[0].string == NULL)
1862 lisp_free (b); 1883 lisp_free (b);
1863 else 1884 else
1864 { 1885 {
@@ -1885,7 +1906,7 @@ compact_small_strings (void)
1885 to, and TB_END is the end of TB. */ 1906 to, and TB_END is the end of TB. */
1886 tb = oldest_sblock; 1907 tb = oldest_sblock;
1887 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); 1908 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE);
1888 to = &tb->first_data; 1909 to = tb->data;
1889 1910
1890 /* Step through the blocks from the oldest to the youngest. We 1911 /* Step through the blocks from the oldest to the youngest. We
1891 expect that old blocks will stabilize over time, so that less 1912 expect that old blocks will stabilize over time, so that less
@@ -1895,7 +1916,7 @@ compact_small_strings (void)
1895 end = b->next_free; 1916 end = b->next_free;
1896 eassert ((char *) end <= (char *) b + SBLOCK_SIZE); 1917 eassert ((char *) end <= (char *) b + SBLOCK_SIZE);
1897 1918
1898 for (from = &b->first_data; from < end; from = from_end) 1919 for (from = b->data; from < end; from = from_end)
1899 { 1920 {
1900 /* Compute the next FROM here because copying below may 1921 /* Compute the next FROM here because copying below may
1901 overwrite data we need to compute it. */ 1922 overwrite data we need to compute it. */
@@ -1932,7 +1953,7 @@ compact_small_strings (void)
1932 tb->next_free = to; 1953 tb->next_free = to;
1933 tb = tb->next; 1954 tb = tb->next;
1934 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); 1955 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE);
1935 to = &tb->first_data; 1956 to = tb->data;
1936 to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); 1957 to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA);
1937 } 1958 }
1938 1959
@@ -2020,82 +2041,61 @@ INIT must be an integer that represents a character. */)
2020 return val; 2041 return val;
2021} 2042}
2022 2043
2023verify (sizeof (size_t) * CHAR_BIT == BITS_PER_BITS_WORD); 2044/* Fill A with 1 bits if INIT is non-nil, and with 0 bits otherwise.
2024verify ((BITS_PER_BITS_WORD & (BITS_PER_BITS_WORD - 1)) == 0); 2045 Return A. */
2025 2046
2026static ptrdiff_t 2047Lisp_Object
2027bool_vector_payload_bytes (ptrdiff_t nr_bits, 2048bool_vector_fill (Lisp_Object a, Lisp_Object init)
2028 ptrdiff_t *exact_needed_bytes_out)
2029{ 2049{
2030 ptrdiff_t exact_needed_bytes; 2050 EMACS_INT nbits = bool_vector_size (a);
2031 ptrdiff_t needed_bytes; 2051 if (0 < nbits)
2032
2033 eassume (nr_bits >= 0);
2034
2035 exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT;
2036 needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_BITS_WORD) / CHAR_BIT;
2037
2038 if (needed_bytes == 0)
2039 { 2052 {
2040 /* Always allocate at least one machine word of payload so that 2053 unsigned char *data = bool_vector_uchar_data (a);
2041 bool-vector operations in data.c don't need a special case 2054 int pattern = NILP (init) ? 0 : (1 << BOOL_VECTOR_BITS_PER_CHAR) - 1;
2042 for empty vectors. */ 2055 ptrdiff_t nbytes = bool_vector_bytes (nbits);
2043 needed_bytes = sizeof (bits_word); 2056 int last_mask = ~ (~0 << ((nbits - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1));
2057 memset (data, pattern, nbytes - 1);
2058 data[nbytes - 1] = pattern & last_mask;
2044 } 2059 }
2045 2060 return a;
2046 if (exact_needed_bytes_out != NULL)
2047 *exact_needed_bytes_out = exact_needed_bytes;
2048
2049 return needed_bytes;
2050} 2061}
2051 2062
2052DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0, 2063/* Return a newly allocated, uninitialized bool vector of size NBITS. */
2053 doc: /* Return a new bool-vector of length LENGTH, using INIT for each element. 2064
2054LENGTH must be a number. INIT matters only in whether it is t or nil. */) 2065Lisp_Object
2055 (Lisp_Object length, Lisp_Object init) 2066make_uninit_bool_vector (EMACS_INT nbits)
2056{ 2067{
2057 register Lisp_Object val; 2068 Lisp_Object val;
2058 struct Lisp_Bool_Vector *p; 2069 struct Lisp_Bool_Vector *p;
2059 ptrdiff_t exact_payload_bytes; 2070 EMACS_INT word_bytes, needed_elements;
2060 ptrdiff_t total_payload_bytes; 2071 word_bytes = bool_vector_words (nbits) * sizeof (bits_word);
2061 ptrdiff_t needed_elements; 2072 needed_elements = ((bool_header_size - header_size + word_bytes
2062 2073 + word_size - 1)
2063 CHECK_NATNUM (length); 2074 / word_size);
2064 if (PTRDIFF_MAX < XFASTINT (length))
2065 memory_full (SIZE_MAX);
2066
2067 total_payload_bytes = bool_vector_payload_bytes
2068 (XFASTINT (length), &exact_payload_bytes);
2069
2070 eassume (exact_payload_bytes <= total_payload_bytes);
2071 eassume (0 <= exact_payload_bytes);
2072
2073 needed_elements = ROUNDUP ((size_t) ((bool_header_size - header_size)
2074 + total_payload_bytes),
2075 word_size) / word_size;
2076
2077 p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements); 2075 p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
2078 XSETVECTOR (val, p); 2076 XSETVECTOR (val, p);
2079 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); 2077 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2080 2078 p->size = nbits;
2081 p->size = XFASTINT (length);
2082 if (exact_payload_bytes)
2083 {
2084 memset (p->data, ! NILP (init) ? -1 : 0, exact_payload_bytes);
2085
2086 /* Clear any extraneous bits in the last byte. */
2087 p->data[exact_payload_bytes - 1]
2088 &= (1 << ((XFASTINT (length) - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1)) - 1;
2089 }
2090 2079
2091 /* Clear padding at the end. */ 2080 /* Clear padding at the end. */
2092 memset (p->data + exact_payload_bytes, 2081 if (nbits)
2093 0, 2082 p->data[bool_vector_words (nbits) - 1] = 0;
2094 total_payload_bytes - exact_payload_bytes);
2095 2083
2096 return val; 2084 return val;
2097} 2085}
2098 2086
2087DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0,
2088 doc: /* Return a new bool-vector of length LENGTH, using INIT for each element.
2089LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2090 (Lisp_Object length, Lisp_Object init)
2091{
2092 Lisp_Object val;
2093
2094 CHECK_NATNUM (length);
2095 val = make_uninit_bool_vector (XFASTINT (length));
2096 return bool_vector_fill (val, init);
2097}
2098
2099 2099
2100/* Make a string from NBYTES bytes at CONTENTS, and compute the number 2100/* Make a string from NBYTES bytes at CONTENTS, and compute the number
2101 of characters from the contents. This string may be unibyte or 2101 of characters from the contents. This string may be unibyte or
@@ -2606,16 +2606,35 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
2606 Vector Allocation 2606 Vector Allocation
2607 ***********************************************************************/ 2607 ***********************************************************************/
2608 2608
2609/* Sometimes a vector's contents are merely a pointer internally used
2610 in vector allocation code. Usually you don't want to touch this. */
2611
2612static struct Lisp_Vector *
2613next_vector (struct Lisp_Vector *v)
2614{
2615 return XUNTAG (v->contents[0], 0);
2616}
2617
2618static void
2619set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p)
2620{
2621 v->contents[0] = make_lisp_ptr (p, 0);
2622}
2623
2609/* This value is balanced well enough to avoid too much internal overhead 2624/* This value is balanced well enough to avoid too much internal overhead
2610 for the most common cases; it's not required to be a power of two, but 2625 for the most common cases; it's not required to be a power of two, but
2611 it's expected to be a mult-of-ROUNDUP_SIZE (see below). */ 2626 it's expected to be a mult-of-ROUNDUP_SIZE (see below). */
2612 2627
2613#define VECTOR_BLOCK_SIZE 4096 2628#define VECTOR_BLOCK_SIZE 4096
2614 2629
2615/* Align allocation request sizes to be a multiple of ROUNDUP_SIZE. */
2616enum 2630enum
2617 { 2631 {
2618 roundup_size = COMMON_MULTIPLE (word_size, USE_LSB_TAG ? GCALIGNMENT : 1) 2632 /* Alignment of struct Lisp_Vector objects. */
2633 vector_alignment = COMMON_MULTIPLE (ALIGNOF_STRUCT_LISP_VECTOR,
2634 USE_LSB_TAG ? GCALIGNMENT : 1),
2635
2636 /* Vector size requests are a multiple of this. */
2637 roundup_size = COMMON_MULTIPLE (vector_alignment, word_size)
2619 }; 2638 };
2620 2639
2621/* Verify assumptions described above. */ 2640/* Verify assumptions described above. */
@@ -2623,7 +2642,7 @@ verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0);
2623verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); 2642verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2624 2643
2625/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time. */ 2644/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time. */
2626#define vroundup_ct(x) ROUNDUP ((size_t) (x), roundup_size) 2645#define vroundup_ct(x) ROUNDUP (x, roundup_size)
2627/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at runtime. */ 2646/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at runtime. */
2628#define vroundup(x) (eassume ((x) >= 0), vroundup_ct (x)) 2647#define vroundup(x) (eassume ((x) >= 0), vroundup_ct (x))
2629 2648
@@ -2663,26 +2682,37 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2663 eassert ((nbytes) % roundup_size == 0); \ 2682 eassert ((nbytes) % roundup_size == 0); \
2664 (tmp) = VINDEX (nbytes); \ 2683 (tmp) = VINDEX (nbytes); \
2665 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ 2684 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
2666 v->u.next = vector_free_lists[tmp]; \ 2685 set_next_vector (v, vector_free_lists[tmp]); \
2667 vector_free_lists[tmp] = (v); \ 2686 vector_free_lists[tmp] = (v); \
2668 total_free_vector_slots += (nbytes) / word_size; \ 2687 total_free_vector_slots += (nbytes) / word_size; \
2669 } while (0) 2688 } while (0)
2670 2689
2671/* This internal type is used to maintain the list of large vectors 2690/* This internal type is used to maintain the list of large vectors
2672 which are allocated at their own, e.g. outside of vector blocks. */ 2691 which are allocated at their own, e.g. outside of vector blocks.
2692
2693 struct large_vector itself cannot contain a struct Lisp_Vector, as
2694 the latter contains a flexible array member and C99 does not allow
2695 such structs to be nested. Instead, each struct large_vector
2696 object LV is followed by a struct Lisp_Vector, which is at offset
2697 large_vector_offset from LV, and whose address is therefore
2698 large_vector_vec (&LV). */
2673 2699
2674struct large_vector 2700struct large_vector
2675{ 2701{
2676 union { 2702 struct large_vector *next;
2677 struct large_vector *vector;
2678#if USE_LSB_TAG
2679 /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */
2680 unsigned char c[vroundup_ct (sizeof (struct large_vector *))];
2681#endif
2682 } next;
2683 struct Lisp_Vector v;
2684}; 2703};
2685 2704
2705enum
2706{
2707 large_vector_offset = ROUNDUP (sizeof (struct large_vector), vector_alignment)
2708};
2709
2710static struct Lisp_Vector *
2711large_vector_vec (struct large_vector *p)
2712{
2713 return (struct Lisp_Vector *) ((char *) p + large_vector_offset);
2714}
2715
2686/* This internal type is used to maintain an underlying storage 2716/* This internal type is used to maintain an underlying storage
2687 for small vectors. */ 2717 for small vectors. */
2688 2718
@@ -2760,7 +2790,7 @@ allocate_vector_from_block (size_t nbytes)
2760 if (vector_free_lists[index]) 2790 if (vector_free_lists[index])
2761 { 2791 {
2762 vector = vector_free_lists[index]; 2792 vector = vector_free_lists[index];
2763 vector_free_lists[index] = vector->u.next; 2793 vector_free_lists[index] = next_vector (vector);
2764 total_free_vector_slots -= nbytes / word_size; 2794 total_free_vector_slots -= nbytes / word_size;
2765 return vector; 2795 return vector;
2766 } 2796 }
@@ -2774,7 +2804,7 @@ allocate_vector_from_block (size_t nbytes)
2774 { 2804 {
2775 /* This vector is larger than requested. */ 2805 /* This vector is larger than requested. */
2776 vector = vector_free_lists[index]; 2806 vector = vector_free_lists[index];
2777 vector_free_lists[index] = vector->u.next; 2807 vector_free_lists[index] = next_vector (vector);
2778 total_free_vector_slots -= nbytes / word_size; 2808 total_free_vector_slots -= nbytes / word_size;
2779 2809
2780 /* Excess bytes are used for the smaller vector, 2810 /* Excess bytes are used for the smaller vector,
@@ -2814,27 +2844,40 @@ static ptrdiff_t
2814vector_nbytes (struct Lisp_Vector *v) 2844vector_nbytes (struct Lisp_Vector *v)
2815{ 2845{
2816 ptrdiff_t size = v->header.size & ~ARRAY_MARK_FLAG; 2846 ptrdiff_t size = v->header.size & ~ARRAY_MARK_FLAG;
2847 ptrdiff_t nwords;
2817 2848
2818 if (size & PSEUDOVECTOR_FLAG) 2849 if (size & PSEUDOVECTOR_FLAG)
2819 { 2850 {
2820 if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR)) 2851 if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR))
2821 { 2852 {
2822 struct Lisp_Bool_Vector *bv = (struct Lisp_Bool_Vector *) v; 2853 struct Lisp_Bool_Vector *bv = (struct Lisp_Bool_Vector *) v;
2823 ptrdiff_t payload_bytes = 2854 ptrdiff_t word_bytes = (bool_vector_words (bv->size)
2824 bool_vector_payload_bytes (bv->size, NULL); 2855 * sizeof (bits_word));
2825 2856 ptrdiff_t boolvec_bytes = bool_header_size + word_bytes;
2826 eassume (payload_bytes >= 0); 2857 verify (header_size <= bool_header_size);
2827 size = bool_header_size + ROUNDUP (payload_bytes, word_size); 2858 nwords = (boolvec_bytes - header_size + word_size - 1) / word_size;
2828 } 2859 }
2829 else 2860 else
2830 size = (header_size 2861 nwords = ((size & PSEUDOVECTOR_SIZE_MASK)
2831 + ((size & PSEUDOVECTOR_SIZE_MASK) 2862 + ((size & PSEUDOVECTOR_REST_MASK)
2832 + ((size & PSEUDOVECTOR_REST_MASK) 2863 >> PSEUDOVECTOR_SIZE_BITS));
2833 >> PSEUDOVECTOR_SIZE_BITS)) * word_size);
2834 } 2864 }
2835 else 2865 else
2836 size = header_size + size * word_size; 2866 nwords = size;
2837 return vroundup (size); 2867 return vroundup (header_size + word_size * nwords);
2868}
2869
2870/* Release extra resources still in use by VECTOR, which may be any
2871 vector-like object. For now, this is used just to free data in
2872 font objects. */
2873
2874static void
2875cleanup_vector (struct Lisp_Vector *vector)
2876{
2877 if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT)
2878 && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK)
2879 == FONT_OBJECT_MAX))
2880 ((struct font *) vector)->driver->close ((struct font *) vector);
2838} 2881}
2839 2882
2840/* Reclaim space used by unmarked vectors. */ 2883/* Reclaim space used by unmarked vectors. */
@@ -2871,6 +2914,7 @@ sweep_vectors (void)
2871 { 2914 {
2872 ptrdiff_t total_bytes; 2915 ptrdiff_t total_bytes;
2873 2916
2917 cleanup_vector (vector);
2874 nbytes = vector_nbytes (vector); 2918 nbytes = vector_nbytes (vector);
2875 total_bytes = nbytes; 2919 total_bytes = nbytes;
2876 next = ADVANCE (vector, nbytes); 2920 next = ADVANCE (vector, nbytes);
@@ -2882,6 +2926,7 @@ sweep_vectors (void)
2882 { 2926 {
2883 if (VECTOR_MARKED_P (next)) 2927 if (VECTOR_MARKED_P (next))
2884 break; 2928 break;
2929 cleanup_vector (next);
2885 nbytes = vector_nbytes (next); 2930 nbytes = vector_nbytes (next);
2886 total_bytes += nbytes; 2931 total_bytes += nbytes;
2887 next = ADVANCE (next, nbytes); 2932 next = ADVANCE (next, nbytes);
@@ -2918,7 +2963,7 @@ sweep_vectors (void)
2918 2963
2919 for (lv = large_vectors; lv; lv = *lvprev) 2964 for (lv = large_vectors; lv; lv = *lvprev)
2920 { 2965 {
2921 vector = &lv->v; 2966 vector = large_vector_vec (lv);
2922 if (VECTOR_MARKED_P (vector)) 2967 if (VECTOR_MARKED_P (vector))
2923 { 2968 {
2924 VECTOR_UNMARK (vector); 2969 VECTOR_UNMARK (vector);
@@ -2934,11 +2979,11 @@ sweep_vectors (void)
2934 else 2979 else
2935 total_vector_slots 2980 total_vector_slots
2936 += header_size / word_size + vector->header.size; 2981 += header_size / word_size + vector->header.size;
2937 lvprev = &lv->next.vector; 2982 lvprev = &lv->next;
2938 } 2983 }
2939 else 2984 else
2940 { 2985 {
2941 *lvprev = lv->next.vector; 2986 *lvprev = lv->next;
2942 lisp_free (lv); 2987 lisp_free (lv);
2943 } 2988 }
2944 } 2989 }
@@ -2972,12 +3017,12 @@ allocate_vectorlike (ptrdiff_t len)
2972 else 3017 else
2973 { 3018 {
2974 struct large_vector *lv 3019 struct large_vector *lv
2975 = lisp_malloc ((offsetof (struct large_vector, v.u.contents) 3020 = lisp_malloc ((large_vector_offset + header_size
2976 + len * word_size), 3021 + len * word_size),
2977 MEM_TYPE_VECTORLIKE); 3022 MEM_TYPE_VECTORLIKE);
2978 lv->next.vector = large_vectors; 3023 lv->next = large_vectors;
2979 large_vectors = lv; 3024 large_vectors = lv;
2980 p = &lv->v; 3025 p = large_vector_vec (lv);
2981 } 3026 }
2982 3027
2983#ifdef DOUG_LEA_MALLOC 3028#ifdef DOUG_LEA_MALLOC
@@ -3026,7 +3071,7 @@ allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
3026 3071
3027 /* Only the first lisplen slots will be traced normally by the GC. */ 3072 /* Only the first lisplen slots will be traced normally by the GC. */
3028 for (i = 0; i < lisplen; ++i) 3073 for (i = 0; i < lisplen; ++i)
3029 v->u.contents[i] = Qnil; 3074 v->contents[i] = Qnil;
3030 3075
3031 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); 3076 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
3032 return v; 3077 return v;
@@ -3114,7 +3159,7 @@ See also the function `vector'. */)
3114 p = allocate_vector (XFASTINT (length)); 3159 p = allocate_vector (XFASTINT (length));
3115 sizei = XFASTINT (length); 3160 sizei = XFASTINT (length);
3116 for (i = 0; i < sizei; i++) 3161 for (i = 0; i < sizei; i++)
3117 p->u.contents[i] = init; 3162 p->contents[i] = init;
3118 3163
3119 XSETVECTOR (vector, p); 3164 XSETVECTOR (vector, p);
3120 return vector; 3165 return vector;
@@ -3132,7 +3177,7 @@ usage: (vector &rest OBJECTS) */)
3132 register struct Lisp_Vector *p = XVECTOR (val); 3177 register struct Lisp_Vector *p = XVECTOR (val);
3133 3178
3134 for (i = 0; i < nargs; i++) 3179 for (i = 0; i < nargs; i++)
3135 p->u.contents[i] = args[i]; 3180 p->contents[i] = args[i];
3136 return val; 3181 return val;
3137} 3182}
3138 3183
@@ -3141,14 +3186,14 @@ make_byte_code (struct Lisp_Vector *v)
3141{ 3186{
3142 /* Don't allow the global zero_vector to become a byte code object. */ 3187 /* Don't allow the global zero_vector to become a byte code object. */
3143 eassert(0 < v->header.size); 3188 eassert(0 < v->header.size);
3144 if (v->header.size > 1 && STRINGP (v->u.contents[1]) 3189 if (v->header.size > 1 && STRINGP (v->contents[1])
3145 && STRING_MULTIBYTE (v->u.contents[1])) 3190 && STRING_MULTIBYTE (v->contents[1]))
3146 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the 3191 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the
3147 earlier because they produced a raw 8-bit string for byte-code 3192 earlier because they produced a raw 8-bit string for byte-code
3148 and now such a byte-code string is loaded as multibyte while 3193 and now such a byte-code string is loaded as multibyte while
3149 raw 8-bit characters converted to multibyte form. Thus, now we 3194 raw 8-bit characters converted to multibyte form. Thus, now we
3150 must convert them back to the original unibyte form. */ 3195 must convert them back to the original unibyte form. */
3151 v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]); 3196 v->contents[1] = Fstring_as_unibyte (v->contents[1]);
3152 XSETPVECTYPE (v, PVEC_COMPILED); 3197 XSETPVECTYPE (v, PVEC_COMPILED);
3153} 3198}
3154 3199
@@ -3183,7 +3228,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3183 to be setcar'd). */ 3228 to be setcar'd). */
3184 3229
3185 for (i = 0; i < nargs; i++) 3230 for (i = 0; i < nargs; i++)
3186 p->u.contents[i] = args[i]; 3231 p->contents[i] = args[i];
3187 make_byte_code (p); 3232 make_byte_code (p);
3188 XSETCOMPILED (val, p); 3233 XSETCOMPILED (val, p);
3189 return val; 3234 return val;
@@ -4241,9 +4286,7 @@ live_vector_p (struct mem_node *m, void *p)
4241 vector = ADVANCE (vector, vector_nbytes (vector)); 4286 vector = ADVANCE (vector, vector_nbytes (vector));
4242 } 4287 }
4243 } 4288 }
4244 else if (m->type == MEM_TYPE_VECTORLIKE 4289 else if (m->type == MEM_TYPE_VECTORLIKE && p == large_vector_vec (m->start))
4245 && (char *) p == ((char *) m->start
4246 + offsetof (struct large_vector, v)))
4247 /* This memory node corresponds to a large vector. */ 4290 /* This memory node corresponds to a large vector. */
4248 return 1; 4291 return 1;
4249 return 0; 4292 return 0;
@@ -5174,7 +5217,7 @@ Does not copy symbols. Copies strings without text properties. */)
5174 size &= PSEUDOVECTOR_SIZE_MASK; 5217 size &= PSEUDOVECTOR_SIZE_MASK;
5175 vec = XVECTOR (make_pure_vector (size)); 5218 vec = XVECTOR (make_pure_vector (size));
5176 for (i = 0; i < size; i++) 5219 for (i = 0; i < size; i++)
5177 vec->u.contents[i] = Fpurecopy (AREF (obj, i)); 5220 vec->contents[i] = Fpurecopy (AREF (obj, i));
5178 if (COMPILEDP (obj)) 5221 if (COMPILEDP (obj))
5179 { 5222 {
5180 XSETPVECTYPE (vec, PVEC_COMPILED); 5223 XSETPVECTYPE (vec, PVEC_COMPILED);
@@ -5254,6 +5297,95 @@ total_bytes_of_live_objects (void)
5254 return tot; 5297 return tot;
5255} 5298}
5256 5299
5300#ifdef HAVE_WINDOW_SYSTEM
5301
5302/* Remove unmarked font-spec and font-entity objects from ENTRY, which is
5303 (DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...), and return changed entry. */
5304
5305static Lisp_Object
5306compact_font_cache_entry (Lisp_Object entry)
5307{
5308 Lisp_Object tail, *prev = &entry;
5309
5310 for (tail = entry; CONSP (tail); tail = XCDR (tail))
5311 {
5312 bool drop = 0;
5313 Lisp_Object obj = XCAR (tail);
5314
5315 /* Consider OBJ if it is (font-spec . [font-entity font-entity ...]). */
5316 if (CONSP (obj) && FONT_SPEC_P (XCAR (obj))
5317 && !VECTOR_MARKED_P (XFONT_SPEC (XCAR (obj)))
5318 && VECTORP (XCDR (obj)))
5319 {
5320 ptrdiff_t i, size = ASIZE (XCDR (obj)) & ~ARRAY_MARK_FLAG;
5321
5322 /* If font-spec is not marked, most likely all font-entities
5323 are not marked too. But we must be sure that nothing is
5324 marked within OBJ before we really drop it. */
5325 for (i = 0; i < size; i++)
5326 if (VECTOR_MARKED_P (XFONT_ENTITY (AREF (XCDR (obj), i))))
5327 break;
5328
5329 if (i == size)
5330 drop = 1;
5331 }
5332 if (drop)
5333 *prev = XCDR (tail);
5334 else
5335 prev = xcdr_addr (tail);
5336 }
5337 return entry;
5338}
5339
5340/* Compact font caches on all terminals and mark
5341 everything which is still here after compaction. */
5342
5343static void
5344compact_font_caches (void)
5345{
5346 struct terminal *t;
5347
5348 for (t = terminal_list; t; t = t->next_terminal)
5349 {
5350 Lisp_Object cache = TERMINAL_FONT_CACHE (t);
5351
5352 if (CONSP (cache))
5353 {
5354 Lisp_Object entry;
5355
5356 for (entry = XCDR (cache); CONSP (entry); entry = XCDR (entry))
5357 XSETCAR (entry, compact_font_cache_entry (XCAR (entry)));
5358 }
5359 mark_object (cache);
5360 }
5361}
5362
5363#else /* not HAVE_WINDOW_SYSTEM */
5364
5365#define compact_font_caches() (void)(0)
5366
5367#endif /* HAVE_WINDOW_SYSTEM */
5368
5369/* Remove (MARKER . DATA) entries with unmarked MARKER
5370 from buffer undo LIST and return changed list. */
5371
5372static Lisp_Object
5373compact_undo_list (Lisp_Object list)
5374{
5375 Lisp_Object tail, *prev = &list;
5376
5377 for (tail = list; CONSP (tail); tail = XCDR (tail))
5378 {
5379 if (CONSP (XCAR (tail))
5380 && MARKERP (XCAR (XCAR (tail)))
5381 && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
5382 *prev = XCDR (tail);
5383 else
5384 prev = xcdr_addr (tail);
5385 }
5386 return list;
5387}
5388
5257DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", 5389DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
5258 doc: /* Reclaim storage for Lisp objects no longer needed. 5390 doc: /* Reclaim storage for Lisp objects no longer needed.
5259Garbage collection happens automatically if you cons more than 5391Garbage collection happens automatically if you cons more than
@@ -5392,46 +5524,19 @@ See Info node `(elisp)Garbage Collection'. */)
5392 mark_stack (); 5524 mark_stack ();
5393#endif 5525#endif
5394 5526
5395 /* Everything is now marked, except for the things that require special 5527 /* Everything is now marked, except for the data in font caches
5396 finalization, i.e. the undo_list. 5528 and undo lists. They're compacted by removing an items which
5397 Look thru every buffer's undo list 5529 aren't reachable otherwise. */
5398 for elements that update markers that were not marked, 5530
5399 and delete them. */ 5531 compact_font_caches ();
5532
5400 FOR_EACH_BUFFER (nextb) 5533 FOR_EACH_BUFFER (nextb)
5401 { 5534 {
5402 /* If a buffer's undo list is Qt, that means that undo is 5535 if (!EQ (BVAR (nextb, undo_list), Qt))
5403 turned off in that buffer. Calling truncate_undo_list on 5536 bset_undo_list (nextb, compact_undo_list (BVAR (nextb, undo_list)));
5404 Qt tends to return NULL, which effectively turns undo back on. 5537 /* Now that we have stripped the elements that need not be
5405 So don't call truncate_undo_list if undo_list is Qt. */ 5538 in the undo_list any more, we can finally mark the list. */
5406 if (! EQ (nextb->INTERNAL_FIELD (undo_list), Qt)) 5539 mark_object (BVAR (nextb, undo_list));
5407 {
5408 Lisp_Object tail, prev;
5409 tail = nextb->INTERNAL_FIELD (undo_list);
5410 prev = Qnil;
5411 while (CONSP (tail))
5412 {
5413 if (CONSP (XCAR (tail))
5414 && MARKERP (XCAR (XCAR (tail)))
5415 && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
5416 {
5417 if (NILP (prev))
5418 nextb->INTERNAL_FIELD (undo_list) = tail = XCDR (tail);
5419 else
5420 {
5421 tail = XCDR (tail);
5422 XSETCDR (prev, tail);
5423 }
5424 }
5425 else
5426 {
5427 prev = tail;
5428 tail = XCDR (tail);
5429 }
5430 }
5431 }
5432 /* Now that we have stripped the elements that need not be in the
5433 undo_list any more, we can finally mark the list. */
5434 mark_object (nextb->INTERNAL_FIELD (undo_list));
5435 } 5540 }
5436 5541
5437 gc_sweep (); 5542 gc_sweep ();
@@ -5603,30 +5708,6 @@ mark_glyph_matrix (struct glyph_matrix *matrix)
5603 } 5708 }
5604} 5709}
5605 5710
5606
5607/* Mark Lisp faces in the face cache C. */
5608
5609static void
5610mark_face_cache (struct face_cache *c)
5611{
5612 if (c)
5613 {
5614 int i, j;
5615 for (i = 0; i < c->used; ++i)
5616 {
5617 struct face *face = FACE_FROM_ID (c->f, i);
5618
5619 if (face)
5620 {
5621 for (j = 0; j < LFACE_VECTOR_SIZE; ++j)
5622 mark_object (face->lface[j]);
5623 }
5624 }
5625 }
5626}
5627
5628
5629
5630/* Mark reference to a Lisp_Object. 5711/* Mark reference to a Lisp_Object.
5631 If the object referred to has not been seen yet, recursively mark 5712 If the object referred to has not been seen yet, recursively mark
5632 all the references contained in it. */ 5713 all the references contained in it. */
@@ -5657,7 +5738,7 @@ mark_vectorlike (struct Lisp_Vector *ptr)
5657 The distinction is used e.g. by Lisp_Process which places extra 5738 The distinction is used e.g. by Lisp_Process which places extra
5658 non-Lisp_Object fields at the end of the structure... */ 5739 non-Lisp_Object fields at the end of the structure... */
5659 for (i = 0; i < size; i++) /* ...and then mark its elements. */ 5740 for (i = 0; i < size; i++) /* ...and then mark its elements. */
5660 mark_object (ptr->u.contents[i]); 5741 mark_object (ptr->contents[i]);
5661} 5742}
5662 5743
5663/* Like mark_vectorlike but optimized for char-tables (and 5744/* Like mark_vectorlike but optimized for char-tables (and
@@ -5674,7 +5755,7 @@ mark_char_table (struct Lisp_Vector *ptr)
5674 VECTOR_MARK (ptr); 5755 VECTOR_MARK (ptr);
5675 for (i = 0; i < size; i++) 5756 for (i = 0; i < size; i++)
5676 { 5757 {
5677 Lisp_Object val = ptr->u.contents[i]; 5758 Lisp_Object val = ptr->contents[i];
5678 5759
5679 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) 5760 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit))
5680 continue; 5761 continue;
@@ -5726,6 +5807,30 @@ mark_buffer (struct buffer *buffer)
5726 mark_buffer (buffer->base_buffer); 5807 mark_buffer (buffer->base_buffer);
5727} 5808}
5728 5809
5810/* Mark Lisp faces in the face cache C. */
5811
5812static void
5813mark_face_cache (struct face_cache *c)
5814{
5815 if (c)
5816 {
5817 int i, j;
5818 for (i = 0; i < c->used; ++i)
5819 {
5820 struct face *face = FACE_FROM_ID (c->f, i);
5821
5822 if (face)
5823 {
5824 if (face->font && !VECTOR_MARKED_P (face->font))
5825 mark_vectorlike ((struct Lisp_Vector *) face->font);
5826
5827 for (j = 0; j < LFACE_VECTOR_SIZE; ++j)
5828 mark_object (face->lface[j]);
5829 }
5830 }
5831 }
5832}
5833
5729/* Remove killed buffers or items whose car is a killed buffer from 5834/* Remove killed buffers or items whose car is a killed buffer from
5730 LIST, and mark other items. Return changed LIST, which is marked. */ 5835 LIST, and mark other items. Return changed LIST, which is marked. */
5731 5836
@@ -5879,18 +5984,31 @@ mark_object (Lisp_Object arg)
5879 VECTOR_MARK (ptr); 5984 VECTOR_MARK (ptr);
5880 for (i = 0; i < size; i++) 5985 for (i = 0; i < size; i++)
5881 if (i != COMPILED_CONSTANTS) 5986 if (i != COMPILED_CONSTANTS)
5882 mark_object (ptr->u.contents[i]); 5987 mark_object (ptr->contents[i]);
5883 if (size > COMPILED_CONSTANTS) 5988 if (size > COMPILED_CONSTANTS)
5884 { 5989 {
5885 obj = ptr->u.contents[COMPILED_CONSTANTS]; 5990 obj = ptr->contents[COMPILED_CONSTANTS];
5886 goto loop; 5991 goto loop;
5887 } 5992 }
5888 } 5993 }
5889 break; 5994 break;
5890 5995
5891 case PVEC_FRAME: 5996 case PVEC_FRAME:
5892 mark_vectorlike (ptr); 5997 {
5893 mark_face_cache (((struct frame *) ptr)->face_cache); 5998 struct frame *f = (struct frame *) ptr;
5999
6000 mark_vectorlike (ptr);
6001 mark_face_cache (f->face_cache);
6002#ifdef HAVE_WINDOW_SYSTEM
6003 if (FRAME_WINDOW_P (f) && FRAME_X_OUTPUT (f))
6004 {
6005 struct font *font = FRAME_FONT (f);
6006
6007 if (font && !VECTOR_MARKED_P (font))
6008 mark_vectorlike ((struct Lisp_Vector *) font);
6009 }
6010#endif
6011 }
5894 break; 6012 break;
5895 6013
5896 case PVEC_WINDOW: 6014 case PVEC_WINDOW:
@@ -6118,9 +6236,6 @@ mark_terminals (void)
6118 it might have been marked already. Make sure the image cache 6236 it might have been marked already. Make sure the image cache
6119 gets marked. */ 6237 gets marked. */
6120 mark_image_cache (t->image_cache); 6238 mark_image_cache (t->image_cache);
6121 /* FIXME: currently font cache may grow too large
6122 and probably needs special finalization. */
6123 mark_object (TERMINAL_FONT_CACHE (t));
6124#endif /* HAVE_WINDOW_SYSTEM */ 6239#endif /* HAVE_WINDOW_SYSTEM */
6125 if (!VECTOR_MARKED_P (t)) 6240 if (!VECTOR_MARKED_P (t))
6126 mark_vectorlike ((struct Lisp_Vector *)t); 6241 mark_vectorlike ((struct Lisp_Vector *)t);