aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c168
1 files changed, 101 insertions, 67 deletions
diff --git a/src/alloc.c b/src/alloc.c
index f57e22d9cc0..b35f7c4333f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1280,28 +1280,32 @@ mark_interval (register INTERVAL i, Lisp_Object dummy)
1280 1280
1281#define LARGE_STRING_BYTES 1024 1281#define LARGE_STRING_BYTES 1024
1282 1282
1283/* Struct or union describing string memory sub-allocated from an sblock. 1283/* The SDATA typedef is a struct or union describing string memory
1284 This is where the contents of Lisp strings are stored. */ 1284 sub-allocated from an sblock. This is where the contents of Lisp
1285 strings are stored. */
1285 1286
1286#ifdef GC_CHECK_STRING_BYTES 1287struct sdata
1287
1288typedef struct
1289{ 1288{
1290 /* Back-pointer to the string this sdata belongs to. If null, this 1289 /* Back-pointer to the string this sdata belongs to. If null, this
1291 structure is free, and the NBYTES member of the union below 1290 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 1291 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 1292 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 1293 (STRING) is the size of the data, and DATA contains the string's
1295 contents. */ 1294 contents. */
1296 struct Lisp_String *string; 1295 struct Lisp_String *string;
1297 1296
1297#ifdef GC_CHECK_STRING_BYTES
1298 ptrdiff_t nbytes; 1298 ptrdiff_t nbytes;
1299#endif
1300
1299 unsigned char data[FLEXIBLE_ARRAY_MEMBER]; 1301 unsigned char data[FLEXIBLE_ARRAY_MEMBER];
1300} sdata; 1302};
1303
1304#ifdef GC_CHECK_STRING_BYTES
1301 1305
1306typedef struct sdata sdata;
1302#define SDATA_NBYTES(S) (S)->nbytes 1307#define SDATA_NBYTES(S) (S)->nbytes
1303#define SDATA_DATA(S) (S)->data 1308#define SDATA_DATA(S) (S)->data
1304#define SDATA_SELECTOR(member) member
1305 1309
1306#else 1310#else
1307 1311
@@ -1309,12 +1313,16 @@ typedef union
1309{ 1313{
1310 struct Lisp_String *string; 1314 struct Lisp_String *string;
1311 1315
1312 /* When STRING is non-null. */ 1316 /* When STRING is nonnull, this union is actually of type 'struct sdata',
1313 struct 1317 which has a flexible array member. However, if implemented by
1314 { 1318 giving this union a member of type 'struct sdata', the union
1315 struct Lisp_String *string; 1319 could not be the last (flexible) member of 'struct sblock',
1316 unsigned char data[FLEXIBLE_ARRAY_MEMBER]; 1320 because C99 prohibits a flexible array member from having a type
1317 } u; 1321 that is itself a flexible array. So, comment this member out here,
1322 but remember that the option's there when using this union. */
1323#if 0
1324 struct sdata u;
1325#endif
1318 1326
1319 /* When STRING is null. */ 1327 /* When STRING is null. */
1320 struct 1328 struct
@@ -1325,13 +1333,11 @@ typedef union
1325} sdata; 1333} sdata;
1326 1334
1327#define SDATA_NBYTES(S) (S)->n.nbytes 1335#define SDATA_NBYTES(S) (S)->n.nbytes
1328#define SDATA_DATA(S) (S)->u.data 1336#define SDATA_DATA(S) ((struct sdata *) (S))->data
1329#define SDATA_SELECTOR(member) u.member
1330 1337
1331#endif /* not GC_CHECK_STRING_BYTES */ 1338#endif /* not GC_CHECK_STRING_BYTES */
1332 1339
1333#define SDATA_DATA_OFFSET offsetof (sdata, SDATA_SELECTOR (data)) 1340enum { SDATA_DATA_OFFSET = offsetof (struct sdata, data) };
1334
1335 1341
1336/* Structure describing a block of memory which is sub-allocated to 1342/* Structure describing a block of memory which is sub-allocated to
1337 obtain string data memory for strings. Blocks for small strings 1343 obtain string data memory for strings. Blocks for small strings
@@ -1347,8 +1353,8 @@ struct sblock
1347 of the sblock if there isn't any space left in this block. */ 1353 of the sblock if there isn't any space left in this block. */
1348 sdata *next_free; 1354 sdata *next_free;
1349 1355
1350 /* Start of data. */ 1356 /* String data. */
1351 sdata first_data; 1357 sdata data[FLEXIBLE_ARRAY_MEMBER];
1352}; 1358};
1353 1359
1354/* Number of Lisp strings in a string_block structure. The 1020 is 1360/* Number of Lisp strings in a string_block structure. The 1020 is
@@ -1464,7 +1470,7 @@ static ptrdiff_t const STRING_BYTES_MAX =
1464 min (STRING_BYTES_BOUND, 1470 min (STRING_BYTES_BOUND,
1465 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD 1471 ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD
1466 - GC_STRING_EXTRA 1472 - GC_STRING_EXTRA
1467 - offsetof (struct sblock, first_data) 1473 - offsetof (struct sblock, data)
1468 - SDATA_DATA_OFFSET) 1474 - SDATA_DATA_OFFSET)
1469 & ~(sizeof (EMACS_INT) - 1))); 1475 & ~(sizeof (EMACS_INT) - 1)));
1470 1476
@@ -1507,7 +1513,7 @@ check_sblock (struct sblock *b)
1507 1513
1508 end = b->next_free; 1514 end = b->next_free;
1509 1515
1510 for (from = &b->first_data; from < end; from = from_end) 1516 for (from = b->data; from < end; from = from_end)
1511 { 1517 {
1512 /* Compute the next FROM here because copying below may 1518 /* Compute the next FROM here because copying below may
1513 overwrite data we need to compute it. */ 1519 overwrite data we need to compute it. */
@@ -1535,7 +1541,7 @@ check_string_bytes (bool all_p)
1535 1541
1536 for (b = large_sblocks; b; b = b->next) 1542 for (b = large_sblocks; b; b = b->next)
1537 { 1543 {
1538 struct Lisp_String *s = b->first_data.string; 1544 struct Lisp_String *s = b->data[0].string;
1539 if (s) 1545 if (s)
1540 string_bytes (s); 1546 string_bytes (s);
1541 } 1547 }
@@ -1669,7 +1675,7 @@ allocate_string_data (struct Lisp_String *s,
1669 1675
1670 if (nbytes > LARGE_STRING_BYTES) 1676 if (nbytes > LARGE_STRING_BYTES)
1671 { 1677 {
1672 size_t size = offsetof (struct sblock, first_data) + needed; 1678 size_t size = offsetof (struct sblock, data) + needed;
1673 1679
1674#ifdef DOUG_LEA_MALLOC 1680#ifdef DOUG_LEA_MALLOC
1675 /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed 1681 /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed
@@ -1691,8 +1697,8 @@ allocate_string_data (struct Lisp_String *s,
1691 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); 1697 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
1692#endif 1698#endif
1693 1699
1694 b->next_free = &b->first_data; 1700 b->next_free = b->data;
1695 b->first_data.string = NULL; 1701 b->data[0].string = NULL;
1696 b->next = large_sblocks; 1702 b->next = large_sblocks;
1697 large_sblocks = b; 1703 large_sblocks = b;
1698 } 1704 }
@@ -1703,8 +1709,8 @@ allocate_string_data (struct Lisp_String *s,
1703 { 1709 {
1704 /* Not enough room in the current sblock. */ 1710 /* Not enough room in the current sblock. */
1705 b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP); 1711 b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP);
1706 b->next_free = &b->first_data; 1712 b->next_free = b->data;
1707 b->first_data.string = NULL; 1713 b->data[0].string = NULL;
1708 b->next = NULL; 1714 b->next = NULL;
1709 1715
1710 if (current_sblock) 1716 if (current_sblock)
@@ -1858,7 +1864,7 @@ free_large_strings (void)
1858 { 1864 {
1859 next = b->next; 1865 next = b->next;
1860 1866
1861 if (b->first_data.string == NULL) 1867 if (b->data[0].string == NULL)
1862 lisp_free (b); 1868 lisp_free (b);
1863 else 1869 else
1864 { 1870 {
@@ -1885,7 +1891,7 @@ compact_small_strings (void)
1885 to, and TB_END is the end of TB. */ 1891 to, and TB_END is the end of TB. */
1886 tb = oldest_sblock; 1892 tb = oldest_sblock;
1887 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); 1893 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE);
1888 to = &tb->first_data; 1894 to = tb->data;
1889 1895
1890 /* Step through the blocks from the oldest to the youngest. We 1896 /* Step through the blocks from the oldest to the youngest. We
1891 expect that old blocks will stabilize over time, so that less 1897 expect that old blocks will stabilize over time, so that less
@@ -1895,7 +1901,7 @@ compact_small_strings (void)
1895 end = b->next_free; 1901 end = b->next_free;
1896 eassert ((char *) end <= (char *) b + SBLOCK_SIZE); 1902 eassert ((char *) end <= (char *) b + SBLOCK_SIZE);
1897 1903
1898 for (from = &b->first_data; from < end; from = from_end) 1904 for (from = b->data; from < end; from = from_end)
1899 { 1905 {
1900 /* Compute the next FROM here because copying below may 1906 /* Compute the next FROM here because copying below may
1901 overwrite data we need to compute it. */ 1907 overwrite data we need to compute it. */
@@ -1932,7 +1938,7 @@ compact_small_strings (void)
1932 tb->next_free = to; 1938 tb->next_free = to;
1933 tb = tb->next; 1939 tb = tb->next;
1934 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); 1940 tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE);
1935 to = &tb->first_data; 1941 to = tb->data;
1936 to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); 1942 to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA);
1937 } 1943 }
1938 1944
@@ -2606,16 +2612,35 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
2606 Vector Allocation 2612 Vector Allocation
2607 ***********************************************************************/ 2613 ***********************************************************************/
2608 2614
2615/* Sometimes a vector's contents are merely a pointer internally used
2616 in vector allocation code. Usually you don't want to touch this. */
2617
2618static struct Lisp_Vector *
2619next_vector (struct Lisp_Vector *v)
2620{
2621 return XUNTAG (v->contents[0], 0);
2622}
2623
2624static void
2625set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p)
2626{
2627 v->contents[0] = make_lisp_ptr (p, 0);
2628}
2629
2609/* This value is balanced well enough to avoid too much internal overhead 2630/* 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 2631 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). */ 2632 it's expected to be a mult-of-ROUNDUP_SIZE (see below). */
2612 2633
2613#define VECTOR_BLOCK_SIZE 4096 2634#define VECTOR_BLOCK_SIZE 4096
2614 2635
2615/* Align allocation request sizes to be a multiple of ROUNDUP_SIZE. */
2616enum 2636enum
2617 { 2637 {
2618 roundup_size = COMMON_MULTIPLE (word_size, USE_LSB_TAG ? GCALIGNMENT : 1) 2638 /* Alignment of struct Lisp_Vector objects. */
2639 vector_alignment = COMMON_MULTIPLE (ALIGNOF_STRUCT_LISP_VECTOR,
2640 USE_LSB_TAG ? GCALIGNMENT : 1),
2641
2642 /* Vector size requests are a multiple of this. */
2643 roundup_size = COMMON_MULTIPLE (vector_alignment, word_size)
2619 }; 2644 };
2620 2645
2621/* Verify assumptions described above. */ 2646/* Verify assumptions described above. */
@@ -2663,26 +2688,37 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2663 eassert ((nbytes) % roundup_size == 0); \ 2688 eassert ((nbytes) % roundup_size == 0); \
2664 (tmp) = VINDEX (nbytes); \ 2689 (tmp) = VINDEX (nbytes); \
2665 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ 2690 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
2666 v->u.next = vector_free_lists[tmp]; \ 2691 set_next_vector (v, vector_free_lists[tmp]); \
2667 vector_free_lists[tmp] = (v); \ 2692 vector_free_lists[tmp] = (v); \
2668 total_free_vector_slots += (nbytes) / word_size; \ 2693 total_free_vector_slots += (nbytes) / word_size; \
2669 } while (0) 2694 } while (0)
2670 2695
2671/* This internal type is used to maintain the list of large vectors 2696/* 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. */ 2697 which are allocated at their own, e.g. outside of vector blocks.
2698
2699 struct large_vector itself cannot contain a struct Lisp_Vector, as
2700 the latter contains a flexible array member and C99 does not allow
2701 such structs to be nested. Instead, each struct large_vector
2702 object LV is followed by a struct Lisp_Vector, which is at offset
2703 large_vector_offset from LV, and whose address is therefore
2704 large_vector_vec (&LV). */
2673 2705
2674struct large_vector 2706struct large_vector
2675{ 2707{
2676 union { 2708 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}; 2709};
2685 2710
2711enum
2712{
2713 large_vector_offset = ROUNDUP (sizeof (struct large_vector), vector_alignment)
2714};
2715
2716static struct Lisp_Vector *
2717large_vector_vec (struct large_vector *p)
2718{
2719 return (struct Lisp_Vector *) ((char *) p + large_vector_offset);
2720}
2721
2686/* This internal type is used to maintain an underlying storage 2722/* This internal type is used to maintain an underlying storage
2687 for small vectors. */ 2723 for small vectors. */
2688 2724
@@ -2760,7 +2796,7 @@ allocate_vector_from_block (size_t nbytes)
2760 if (vector_free_lists[index]) 2796 if (vector_free_lists[index])
2761 { 2797 {
2762 vector = vector_free_lists[index]; 2798 vector = vector_free_lists[index];
2763 vector_free_lists[index] = vector->u.next; 2799 vector_free_lists[index] = next_vector (vector);
2764 total_free_vector_slots -= nbytes / word_size; 2800 total_free_vector_slots -= nbytes / word_size;
2765 return vector; 2801 return vector;
2766 } 2802 }
@@ -2774,7 +2810,7 @@ allocate_vector_from_block (size_t nbytes)
2774 { 2810 {
2775 /* This vector is larger than requested. */ 2811 /* This vector is larger than requested. */
2776 vector = vector_free_lists[index]; 2812 vector = vector_free_lists[index];
2777 vector_free_lists[index] = vector->u.next; 2813 vector_free_lists[index] = next_vector (vector);
2778 total_free_vector_slots -= nbytes / word_size; 2814 total_free_vector_slots -= nbytes / word_size;
2779 2815
2780 /* Excess bytes are used for the smaller vector, 2816 /* Excess bytes are used for the smaller vector,
@@ -2933,7 +2969,7 @@ sweep_vectors (void)
2933 2969
2934 for (lv = large_vectors; lv; lv = *lvprev) 2970 for (lv = large_vectors; lv; lv = *lvprev)
2935 { 2971 {
2936 vector = &lv->v; 2972 vector = large_vector_vec (lv);
2937 if (VECTOR_MARKED_P (vector)) 2973 if (VECTOR_MARKED_P (vector))
2938 { 2974 {
2939 VECTOR_UNMARK (vector); 2975 VECTOR_UNMARK (vector);
@@ -2949,11 +2985,11 @@ sweep_vectors (void)
2949 else 2985 else
2950 total_vector_slots 2986 total_vector_slots
2951 += header_size / word_size + vector->header.size; 2987 += header_size / word_size + vector->header.size;
2952 lvprev = &lv->next.vector; 2988 lvprev = &lv->next;
2953 } 2989 }
2954 else 2990 else
2955 { 2991 {
2956 *lvprev = lv->next.vector; 2992 *lvprev = lv->next;
2957 lisp_free (lv); 2993 lisp_free (lv);
2958 } 2994 }
2959 } 2995 }
@@ -2987,12 +3023,12 @@ allocate_vectorlike (ptrdiff_t len)
2987 else 3023 else
2988 { 3024 {
2989 struct large_vector *lv 3025 struct large_vector *lv
2990 = lisp_malloc ((offsetof (struct large_vector, v.u.contents) 3026 = lisp_malloc ((large_vector_offset + header_size
2991 + len * word_size), 3027 + len * word_size),
2992 MEM_TYPE_VECTORLIKE); 3028 MEM_TYPE_VECTORLIKE);
2993 lv->next.vector = large_vectors; 3029 lv->next = large_vectors;
2994 large_vectors = lv; 3030 large_vectors = lv;
2995 p = &lv->v; 3031 p = large_vector_vec (lv);
2996 } 3032 }
2997 3033
2998#ifdef DOUG_LEA_MALLOC 3034#ifdef DOUG_LEA_MALLOC
@@ -3041,7 +3077,7 @@ allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
3041 3077
3042 /* Only the first lisplen slots will be traced normally by the GC. */ 3078 /* Only the first lisplen slots will be traced normally by the GC. */
3043 for (i = 0; i < lisplen; ++i) 3079 for (i = 0; i < lisplen; ++i)
3044 v->u.contents[i] = Qnil; 3080 v->contents[i] = Qnil;
3045 3081
3046 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); 3082 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
3047 return v; 3083 return v;
@@ -3129,7 +3165,7 @@ See also the function `vector'. */)
3129 p = allocate_vector (XFASTINT (length)); 3165 p = allocate_vector (XFASTINT (length));
3130 sizei = XFASTINT (length); 3166 sizei = XFASTINT (length);
3131 for (i = 0; i < sizei; i++) 3167 for (i = 0; i < sizei; i++)
3132 p->u.contents[i] = init; 3168 p->contents[i] = init;
3133 3169
3134 XSETVECTOR (vector, p); 3170 XSETVECTOR (vector, p);
3135 return vector; 3171 return vector;
@@ -3147,7 +3183,7 @@ usage: (vector &rest OBJECTS) */)
3147 register struct Lisp_Vector *p = XVECTOR (val); 3183 register struct Lisp_Vector *p = XVECTOR (val);
3148 3184
3149 for (i = 0; i < nargs; i++) 3185 for (i = 0; i < nargs; i++)
3150 p->u.contents[i] = args[i]; 3186 p->contents[i] = args[i];
3151 return val; 3187 return val;
3152} 3188}
3153 3189
@@ -3156,14 +3192,14 @@ make_byte_code (struct Lisp_Vector *v)
3156{ 3192{
3157 /* Don't allow the global zero_vector to become a byte code object. */ 3193 /* Don't allow the global zero_vector to become a byte code object. */
3158 eassert(0 < v->header.size); 3194 eassert(0 < v->header.size);
3159 if (v->header.size > 1 && STRINGP (v->u.contents[1]) 3195 if (v->header.size > 1 && STRINGP (v->contents[1])
3160 && STRING_MULTIBYTE (v->u.contents[1])) 3196 && STRING_MULTIBYTE (v->contents[1]))
3161 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the 3197 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the
3162 earlier because they produced a raw 8-bit string for byte-code 3198 earlier because they produced a raw 8-bit string for byte-code
3163 and now such a byte-code string is loaded as multibyte while 3199 and now such a byte-code string is loaded as multibyte while
3164 raw 8-bit characters converted to multibyte form. Thus, now we 3200 raw 8-bit characters converted to multibyte form. Thus, now we
3165 must convert them back to the original unibyte form. */ 3201 must convert them back to the original unibyte form. */
3166 v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]); 3202 v->contents[1] = Fstring_as_unibyte (v->contents[1]);
3167 XSETPVECTYPE (v, PVEC_COMPILED); 3203 XSETPVECTYPE (v, PVEC_COMPILED);
3168} 3204}
3169 3205
@@ -3198,7 +3234,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3198 to be setcar'd). */ 3234 to be setcar'd). */
3199 3235
3200 for (i = 0; i < nargs; i++) 3236 for (i = 0; i < nargs; i++)
3201 p->u.contents[i] = args[i]; 3237 p->contents[i] = args[i];
3202 make_byte_code (p); 3238 make_byte_code (p);
3203 XSETCOMPILED (val, p); 3239 XSETCOMPILED (val, p);
3204 return val; 3240 return val;
@@ -4256,9 +4292,7 @@ live_vector_p (struct mem_node *m, void *p)
4256 vector = ADVANCE (vector, vector_nbytes (vector)); 4292 vector = ADVANCE (vector, vector_nbytes (vector));
4257 } 4293 }
4258 } 4294 }
4259 else if (m->type == MEM_TYPE_VECTORLIKE 4295 else if (m->type == MEM_TYPE_VECTORLIKE && p == large_vector_vec (m->start))
4260 && (char *) p == ((char *) m->start
4261 + offsetof (struct large_vector, v)))
4262 /* This memory node corresponds to a large vector. */ 4296 /* This memory node corresponds to a large vector. */
4263 return 1; 4297 return 1;
4264 return 0; 4298 return 0;
@@ -5189,7 +5223,7 @@ Does not copy symbols. Copies strings without text properties. */)
5189 size &= PSEUDOVECTOR_SIZE_MASK; 5223 size &= PSEUDOVECTOR_SIZE_MASK;
5190 vec = XVECTOR (make_pure_vector (size)); 5224 vec = XVECTOR (make_pure_vector (size));
5191 for (i = 0; i < size; i++) 5225 for (i = 0; i < size; i++)
5192 vec->u.contents[i] = Fpurecopy (AREF (obj, i)); 5226 vec->contents[i] = Fpurecopy (AREF (obj, i));
5193 if (COMPILEDP (obj)) 5227 if (COMPILEDP (obj))
5194 { 5228 {
5195 XSETPVECTYPE (vec, PVEC_COMPILED); 5229 XSETPVECTYPE (vec, PVEC_COMPILED);
@@ -5710,7 +5744,7 @@ mark_vectorlike (struct Lisp_Vector *ptr)
5710 The distinction is used e.g. by Lisp_Process which places extra 5744 The distinction is used e.g. by Lisp_Process which places extra
5711 non-Lisp_Object fields at the end of the structure... */ 5745 non-Lisp_Object fields at the end of the structure... */
5712 for (i = 0; i < size; i++) /* ...and then mark its elements. */ 5746 for (i = 0; i < size; i++) /* ...and then mark its elements. */
5713 mark_object (ptr->u.contents[i]); 5747 mark_object (ptr->contents[i]);
5714} 5748}
5715 5749
5716/* Like mark_vectorlike but optimized for char-tables (and 5750/* Like mark_vectorlike but optimized for char-tables (and
@@ -5727,7 +5761,7 @@ mark_char_table (struct Lisp_Vector *ptr)
5727 VECTOR_MARK (ptr); 5761 VECTOR_MARK (ptr);
5728 for (i = 0; i < size; i++) 5762 for (i = 0; i < size; i++)
5729 { 5763 {
5730 Lisp_Object val = ptr->u.contents[i]; 5764 Lisp_Object val = ptr->contents[i];
5731 5765
5732 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) 5766 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit))
5733 continue; 5767 continue;
@@ -5956,10 +5990,10 @@ mark_object (Lisp_Object arg)
5956 VECTOR_MARK (ptr); 5990 VECTOR_MARK (ptr);
5957 for (i = 0; i < size; i++) 5991 for (i = 0; i < size; i++)
5958 if (i != COMPILED_CONSTANTS) 5992 if (i != COMPILED_CONSTANTS)
5959 mark_object (ptr->u.contents[i]); 5993 mark_object (ptr->contents[i]);
5960 if (size > COMPILED_CONSTANTS) 5994 if (size > COMPILED_CONSTANTS)
5961 { 5995 {
5962 obj = ptr->u.contents[COMPILED_CONSTANTS]; 5996 obj = ptr->contents[COMPILED_CONSTANTS];
5963 goto loop; 5997 goto loop;
5964 } 5998 }
5965 } 5999 }