aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorEli Zaretskii2013-09-26 10:37:16 +0300
committerEli Zaretskii2013-09-26 10:37:16 +0300
commitb87c4ff2817e71ca71b028792200b1e069a95e04 (patch)
treebfe00c0655fa02078a9ab2c633ea06d90c4a2064 /src/alloc.c
parentbbc108377873aa6ed7cf21c731770103096eea39 (diff)
parentba355de014b75ed104da4777f909db70d62f2357 (diff)
downloademacs-b87c4ff2817e71ca71b028792200b1e069a95e04.tar.gz
emacs-b87c4ff2817e71ca71b028792200b1e069a95e04.zip
Merge from trunk.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c186
1 files changed, 113 insertions, 73 deletions
diff --git a/src/alloc.c b/src/alloc.c
index a8cbee1cf36..621693fc096 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -20,8 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22 22
23#define LISP_INLINE EXTERN_INLINE
24
25#include <stdio.h> 23#include <stdio.h>
26#include <limits.h> /* For CHAR_BIT. */ 24#include <limits.h> /* For CHAR_BIT. */
27 25
@@ -47,6 +45,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
47 45
48#include <verify.h> 46#include <verify.h>
49 47
48#if (defined ENABLE_CHECKING \
49 && defined HAVE_VALGRIND_VALGRIND_H \
50 && !defined USE_VALGRIND)
51# define USE_VALGRIND 1
52#endif
53
54#if USE_VALGRIND
55#include <valgrind/valgrind.h>
56#include <valgrind/memcheck.h>
57static bool valgrind_p;
58#endif
59
50/* GC_CHECK_MARKED_OBJECTS means do sanity checks on allocated objects. 60/* GC_CHECK_MARKED_OBJECTS means do sanity checks on allocated objects.
51 Doable only if GC_MARK_STACK. */ 61 Doable only if GC_MARK_STACK. */
52#if ! GC_MARK_STACK 62#if ! GC_MARK_STACK
@@ -971,7 +981,7 @@ struct ablocks
971#define ABLOCKS_BASE(abase) (abase) 981#define ABLOCKS_BASE(abase) (abase)
972#else 982#else
973#define ABLOCKS_BASE(abase) \ 983#define ABLOCKS_BASE(abase) \
974 (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) 984 (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **)abase)[-1])
975#endif 985#endif
976 986
977/* The list of free ablock. */ 987/* The list of free ablock. */
@@ -1026,7 +1036,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1026 1036
1027 aligned = (base == abase); 1037 aligned = (base == abase);
1028 if (!aligned) 1038 if (!aligned)
1029 ((void**)abase)[-1] = base; 1039 ((void **) abase)[-1] = base;
1030 1040
1031#ifdef DOUG_LEA_MALLOC 1041#ifdef DOUG_LEA_MALLOC
1032 /* Back to a reasonable maximum of mmap'ed areas. */ 1042 /* Back to a reasonable maximum of mmap'ed areas. */
@@ -2003,6 +2013,34 @@ INIT must be an integer that represents a character. */)
2003 return val; 2013 return val;
2004} 2014}
2005 2015
2016verify (sizeof (size_t) * CHAR_BIT == BITS_PER_SIZE_T);
2017verify ((BITS_PER_SIZE_T & (BITS_PER_SIZE_T - 1)) == 0);
2018
2019static ptrdiff_t
2020bool_vector_payload_bytes (ptrdiff_t nr_bits,
2021 ptrdiff_t *exact_needed_bytes_out)
2022{
2023 ptrdiff_t exact_needed_bytes;
2024 ptrdiff_t needed_bytes;
2025
2026 eassert_and_assume (nr_bits >= 0);
2027
2028 exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT;
2029 needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_SIZE_T) / CHAR_BIT;
2030
2031 if (needed_bytes == 0)
2032 {
2033 /* Always allocate at least one machine word of payload so that
2034 bool-vector operations in data.c don't need a special case
2035 for empty vectors. */
2036 needed_bytes = sizeof (size_t);
2037 }
2038
2039 if (exact_needed_bytes_out != NULL)
2040 *exact_needed_bytes_out = exact_needed_bytes;
2041
2042 return needed_bytes;
2043}
2006 2044
2007DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0, 2045DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0,
2008 doc: /* Return a new bool-vector of length LENGTH, using INIT for each element. 2046 doc: /* Return a new bool-vector of length LENGTH, using INIT for each element.
@@ -2011,37 +2049,43 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2011{ 2049{
2012 register Lisp_Object val; 2050 register Lisp_Object val;
2013 struct Lisp_Bool_Vector *p; 2051 struct Lisp_Bool_Vector *p;
2014 ptrdiff_t length_in_chars; 2052 ptrdiff_t exact_payload_bytes;
2015 EMACS_INT length_in_elts; 2053 ptrdiff_t total_payload_bytes;
2016 int bits_per_value; 2054 ptrdiff_t needed_elements;
2017 int extra_bool_elts = ((bool_header_size - header_size + word_size - 1)
2018 / word_size);
2019 2055
2020 CHECK_NATNUM (length); 2056 CHECK_NATNUM (length);
2057 if (PTRDIFF_MAX < XFASTINT (length))
2058 memory_full (SIZE_MAX);
2021 2059
2022 bits_per_value = sizeof (EMACS_INT) * BOOL_VECTOR_BITS_PER_CHAR; 2060 total_payload_bytes = bool_vector_payload_bytes
2061 (XFASTINT (length), &exact_payload_bytes);
2023 2062
2024 length_in_elts = (XFASTINT (length) + bits_per_value - 1) / bits_per_value; 2063 eassert_and_assume (exact_payload_bytes <= total_payload_bytes);
2064 eassert_and_assume (0 <= exact_payload_bytes);
2025 2065
2026 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil); 2066 needed_elements = ROUNDUP ((size_t) ((bool_header_size - header_size)
2067 + total_payload_bytes),
2068 word_size) / word_size;
2027 2069
2028 /* No Lisp_Object to trace in there. */ 2070 p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
2071 XSETVECTOR (val, p);
2029 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); 2072 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2030 2073
2031 p = XBOOL_VECTOR (val);
2032 p->size = XFASTINT (length); 2074 p->size = XFASTINT (length);
2033 2075 if (exact_payload_bytes)
2034 length_in_chars = ((XFASTINT (length) + BOOL_VECTOR_BITS_PER_CHAR - 1)
2035 / BOOL_VECTOR_BITS_PER_CHAR);
2036 if (length_in_chars)
2037 { 2076 {
2038 memset (p->data, ! NILP (init) ? -1 : 0, length_in_chars); 2077 memset (p->data, ! NILP (init) ? -1 : 0, exact_payload_bytes);
2039 2078
2040 /* Clear any extraneous bits in the last byte. */ 2079 /* Clear any extraneous bits in the last byte. */
2041 p->data[length_in_chars - 1] 2080 p->data[exact_payload_bytes - 1]
2042 &= (1 << ((XFASTINT (length) - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1)) - 1; 2081 &= (1 << ((XFASTINT (length) - 1) % BOOL_VECTOR_BITS_PER_CHAR + 1)) - 1;
2043 } 2082 }
2044 2083
2084 /* Clear padding at the end. */
2085 memset (p->data + exact_payload_bytes,
2086 0,
2087 total_payload_bytes - exact_payload_bytes);
2088
2045 return val; 2089 return val;
2046} 2090}
2047 2091
@@ -2567,24 +2611,22 @@ enum
2567 roundup_size = COMMON_MULTIPLE (word_size, USE_LSB_TAG ? GCALIGNMENT : 1) 2611 roundup_size = COMMON_MULTIPLE (word_size, USE_LSB_TAG ? GCALIGNMENT : 1)
2568 }; 2612 };
2569 2613
2570/* ROUNDUP_SIZE must be a power of 2. */
2571verify ((roundup_size & (roundup_size - 1)) == 0);
2572
2573/* Verify assumptions described above. */ 2614/* Verify assumptions described above. */
2574verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); 2615verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0);
2575verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); 2616verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2576 2617
2577/* Round up X to nearest mult-of-ROUNDUP_SIZE. */ 2618/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time. */
2578 2619#define vroundup_ct(x) ROUNDUP ((size_t) (x), roundup_size)
2579#define vroundup(x) (((x) + (roundup_size - 1)) & ~(roundup_size - 1)) 2620/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at runtime. */
2621#define vroundup(x) (assume ((x) >= 0), vroundup_ct (x))
2580 2622
2581/* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */ 2623/* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */
2582 2624
2583#define VECTOR_BLOCK_BYTES (VECTOR_BLOCK_SIZE - vroundup (sizeof (void *))) 2625#define VECTOR_BLOCK_BYTES (VECTOR_BLOCK_SIZE - vroundup_ct (sizeof (void *)))
2584 2626
2585/* Size of the minimal vector allocated from block. */ 2627/* Size of the minimal vector allocated from block. */
2586 2628
2587#define VBLOCK_BYTES_MIN vroundup (header_size + sizeof (Lisp_Object)) 2629#define VBLOCK_BYTES_MIN vroundup_ct (header_size + sizeof (Lisp_Object))
2588 2630
2589/* Size of the largest vector allocated from block. */ 2631/* Size of the largest vector allocated from block. */
2590 2632
@@ -2605,22 +2647,6 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2605 2647
2606#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) 2648#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
2607 2649
2608/* Get and set the next field in block-allocated vectorlike objects on
2609 the free list. Doing it this way respects C's aliasing rules.
2610 We could instead make 'contents' a union, but that would mean
2611 changes everywhere that the code uses 'contents'. */
2612static struct Lisp_Vector *
2613next_in_free_list (struct Lisp_Vector *v)
2614{
2615 intptr_t i = XLI (v->contents[0]);
2616 return (struct Lisp_Vector *) i;
2617}
2618static void
2619set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
2620{
2621 v->contents[0] = XIL ((intptr_t) next);
2622}
2623
2624/* Common shortcut to setup vector on a free list. */ 2650/* Common shortcut to setup vector on a free list. */
2625 2651
2626#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \ 2652#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \
@@ -2630,7 +2656,7 @@ set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
2630 eassert ((nbytes) % roundup_size == 0); \ 2656 eassert ((nbytes) % roundup_size == 0); \
2631 (tmp) = VINDEX (nbytes); \ 2657 (tmp) = VINDEX (nbytes); \
2632 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ 2658 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
2633 set_next_in_free_list (v, vector_free_lists[tmp]); \ 2659 v->u.next = vector_free_lists[tmp]; \
2634 vector_free_lists[tmp] = (v); \ 2660 vector_free_lists[tmp] = (v); \
2635 total_free_vector_slots += (nbytes) / word_size; \ 2661 total_free_vector_slots += (nbytes) / word_size; \
2636 } while (0) 2662 } while (0)
@@ -2644,7 +2670,7 @@ struct large_vector
2644 struct large_vector *vector; 2670 struct large_vector *vector;
2645#if USE_LSB_TAG 2671#if USE_LSB_TAG
2646 /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */ 2672 /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */
2647 unsigned char c[vroundup (sizeof (struct large_vector *))]; 2673 unsigned char c[vroundup_ct (sizeof (struct large_vector *))];
2648#endif 2674#endif
2649 } next; 2675 } next;
2650 struct Lisp_Vector v; 2676 struct Lisp_Vector v;
@@ -2727,7 +2753,7 @@ allocate_vector_from_block (size_t nbytes)
2727 if (vector_free_lists[index]) 2753 if (vector_free_lists[index])
2728 { 2754 {
2729 vector = vector_free_lists[index]; 2755 vector = vector_free_lists[index];
2730 vector_free_lists[index] = next_in_free_list (vector); 2756 vector_free_lists[index] = vector->u.next;
2731 total_free_vector_slots -= nbytes / word_size; 2757 total_free_vector_slots -= nbytes / word_size;
2732 return vector; 2758 return vector;
2733 } 2759 }
@@ -2741,7 +2767,7 @@ allocate_vector_from_block (size_t nbytes)
2741 { 2767 {
2742 /* This vector is larger than requested. */ 2768 /* This vector is larger than requested. */
2743 vector = vector_free_lists[index]; 2769 vector = vector_free_lists[index];
2744 vector_free_lists[index] = next_in_free_list (vector); 2770 vector_free_lists[index] = vector->u.next;
2745 total_free_vector_slots -= nbytes / word_size; 2771 total_free_vector_slots -= nbytes / word_size;
2746 2772
2747 /* Excess bytes are used for the smaller vector, 2773 /* Excess bytes are used for the smaller vector,
@@ -2785,10 +2811,14 @@ vector_nbytes (struct Lisp_Vector *v)
2785 if (size & PSEUDOVECTOR_FLAG) 2811 if (size & PSEUDOVECTOR_FLAG)
2786 { 2812 {
2787 if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR)) 2813 if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR))
2788 size = (bool_header_size 2814 {
2789 + (((struct Lisp_Bool_Vector *) v)->size 2815 struct Lisp_Bool_Vector *bv = (struct Lisp_Bool_Vector *) v;
2790 + BOOL_VECTOR_BITS_PER_CHAR - 1) 2816 ptrdiff_t payload_bytes =
2791 / BOOL_VECTOR_BITS_PER_CHAR); 2817 bool_vector_payload_bytes (bv->size, NULL);
2818
2819 eassert_and_assume (payload_bytes >= 0);
2820 size = bool_header_size + ROUNDUP (payload_bytes, word_size);
2821 }
2792 else 2822 else
2793 size = (header_size 2823 size = (header_size
2794 + ((size & PSEUDOVECTOR_SIZE_MASK) 2824 + ((size & PSEUDOVECTOR_SIZE_MASK)
@@ -2859,7 +2889,7 @@ sweep_vectors (void)
2859 free_this_block = 1; 2889 free_this_block = 1;
2860 else 2890 else
2861 { 2891 {
2862 int tmp; 2892 size_t tmp;
2863 SETUP_ON_FREE_LIST (vector, total_bytes, tmp); 2893 SETUP_ON_FREE_LIST (vector, total_bytes, tmp);
2864 } 2894 }
2865 } 2895 }
@@ -2888,17 +2918,11 @@ sweep_vectors (void)
2888 total_vectors++; 2918 total_vectors++;
2889 if (vector->header.size & PSEUDOVECTOR_FLAG) 2919 if (vector->header.size & PSEUDOVECTOR_FLAG)
2890 { 2920 {
2891 struct Lisp_Bool_Vector *b = (struct Lisp_Bool_Vector *) vector;
2892
2893 /* All non-bool pseudovectors are small enough to be allocated 2921 /* All non-bool pseudovectors are small enough to be allocated
2894 from vector blocks. This code should be redesigned if some 2922 from vector blocks. This code should be redesigned if some
2895 pseudovector type grows beyond VBLOCK_BYTES_MAX. */ 2923 pseudovector type grows beyond VBLOCK_BYTES_MAX. */
2896 eassert (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BOOL_VECTOR)); 2924 eassert (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BOOL_VECTOR));
2897 2925 total_vector_slots += vector_nbytes (vector) / word_size;
2898 total_vector_slots
2899 += (bool_header_size
2900 + ((b->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
2901 / BOOL_VECTOR_BITS_PER_CHAR)) / word_size;
2902 } 2926 }
2903 else 2927 else
2904 total_vector_slots 2928 total_vector_slots
@@ -2941,7 +2965,7 @@ allocate_vectorlike (ptrdiff_t len)
2941 else 2965 else
2942 { 2966 {
2943 struct large_vector *lv 2967 struct large_vector *lv
2944 = lisp_malloc ((offsetof (struct large_vector, v.contents) 2968 = lisp_malloc ((offsetof (struct large_vector, v.u.contents)
2945 + len * word_size), 2969 + len * word_size),
2946 MEM_TYPE_VECTORLIKE); 2970 MEM_TYPE_VECTORLIKE);
2947 lv->next.vector = large_vectors; 2971 lv->next.vector = large_vectors;
@@ -2995,7 +3019,7 @@ allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
2995 3019
2996 /* Only the first lisplen slots will be traced normally by the GC. */ 3020 /* Only the first lisplen slots will be traced normally by the GC. */
2997 for (i = 0; i < lisplen; ++i) 3021 for (i = 0; i < lisplen; ++i)
2998 v->contents[i] = Qnil; 3022 v->u.contents[i] = Qnil;
2999 3023
3000 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); 3024 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
3001 return v; 3025 return v;
@@ -3083,7 +3107,7 @@ See also the function `vector'. */)
3083 p = allocate_vector (XFASTINT (length)); 3107 p = allocate_vector (XFASTINT (length));
3084 sizei = XFASTINT (length); 3108 sizei = XFASTINT (length);
3085 for (i = 0; i < sizei; i++) 3109 for (i = 0; i < sizei; i++)
3086 p->contents[i] = init; 3110 p->u.contents[i] = init;
3087 3111
3088 XSETVECTOR (vector, p); 3112 XSETVECTOR (vector, p);
3089 return vector; 3113 return vector;
@@ -3101,21 +3125,23 @@ usage: (vector &rest OBJECTS) */)
3101 register struct Lisp_Vector *p = XVECTOR (val); 3125 register struct Lisp_Vector *p = XVECTOR (val);
3102 3126
3103 for (i = 0; i < nargs; i++) 3127 for (i = 0; i < nargs; i++)
3104 p->contents[i] = args[i]; 3128 p->u.contents[i] = args[i];
3105 return val; 3129 return val;
3106} 3130}
3107 3131
3108void 3132void
3109make_byte_code (struct Lisp_Vector *v) 3133make_byte_code (struct Lisp_Vector *v)
3110{ 3134{
3111 if (v->header.size > 1 && STRINGP (v->contents[1]) 3135 /* Don't allow the global zero_vector to become a byte code object. */
3112 && STRING_MULTIBYTE (v->contents[1])) 3136 eassert(0 < v->header.size);
3137 if (v->header.size > 1 && STRINGP (v->u.contents[1])
3138 && STRING_MULTIBYTE (v->u.contents[1]))
3113 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the 3139 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the
3114 earlier because they produced a raw 8-bit string for byte-code 3140 earlier because they produced a raw 8-bit string for byte-code
3115 and now such a byte-code string is loaded as multibyte while 3141 and now such a byte-code string is loaded as multibyte while
3116 raw 8-bit characters converted to multibyte form. Thus, now we 3142 raw 8-bit characters converted to multibyte form. Thus, now we
3117 must convert them back to the original unibyte form. */ 3143 must convert them back to the original unibyte form. */
3118 v->contents[1] = Fstring_as_unibyte (v->contents[1]); 3144 v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]);
3119 XSETPVECTYPE (v, PVEC_COMPILED); 3145 XSETPVECTYPE (v, PVEC_COMPILED);
3120} 3146}
3121 3147
@@ -3150,7 +3176,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3150 to be setcar'd). */ 3176 to be setcar'd). */
3151 3177
3152 for (i = 0; i < nargs; i++) 3178 for (i = 0; i < nargs; i++)
3153 p->contents[i] = args[i]; 3179 p->u.contents[i] = args[i];
3154 make_byte_code (p); 3180 make_byte_code (p);
3155 XSETCOMPILED (val, p); 3181 XSETCOMPILED (val, p);
3156 return val; 3182 return val;
@@ -4296,6 +4322,11 @@ mark_maybe_object (Lisp_Object obj)
4296 void *po; 4322 void *po;
4297 struct mem_node *m; 4323 struct mem_node *m;
4298 4324
4325#if USE_VALGRIND
4326 if (valgrind_p)
4327 VALGRIND_MAKE_MEM_DEFINED (&obj, sizeof (obj));
4328#endif
4329
4299 if (INTEGERP (obj)) 4330 if (INTEGERP (obj))
4300 return; 4331 return;
4301 4332
@@ -4364,6 +4395,11 @@ mark_maybe_pointer (void *p)
4364{ 4395{
4365 struct mem_node *m; 4396 struct mem_node *m;
4366 4397
4398#if USE_VALGRIND
4399 if (valgrind_p)
4400 VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p));
4401#endif
4402
4367 /* Quickly rule out some values which can't point to Lisp data. 4403 /* Quickly rule out some values which can't point to Lisp data.
4368 USE_LSB_TAG needs Lisp data to be aligned on multiples of GCALIGNMENT. 4404 USE_LSB_TAG needs Lisp data to be aligned on multiples of GCALIGNMENT.
4369 Otherwise, assume that Lisp data is aligned on even addresses. */ 4405 Otherwise, assume that Lisp data is aligned on even addresses. */
@@ -5131,7 +5167,7 @@ Does not copy symbols. Copies strings without text properties. */)
5131 size &= PSEUDOVECTOR_SIZE_MASK; 5167 size &= PSEUDOVECTOR_SIZE_MASK;
5132 vec = XVECTOR (make_pure_vector (size)); 5168 vec = XVECTOR (make_pure_vector (size));
5133 for (i = 0; i < size; i++) 5169 for (i = 0; i < size; i++)
5134 vec->contents[i] = Fpurecopy (AREF (obj, i)); 5170 vec->u.contents[i] = Fpurecopy (AREF (obj, i));
5135 if (COMPILEDP (obj)) 5171 if (COMPILEDP (obj))
5136 { 5172 {
5137 XSETPVECTYPE (vec, PVEC_COMPILED); 5173 XSETPVECTYPE (vec, PVEC_COMPILED);
@@ -5622,7 +5658,7 @@ mark_vectorlike (struct Lisp_Vector *ptr)
5622 The distinction is used e.g. by Lisp_Process which places extra 5658 The distinction is used e.g. by Lisp_Process which places extra
5623 non-Lisp_Object fields at the end of the structure... */ 5659 non-Lisp_Object fields at the end of the structure... */
5624 for (i = 0; i < size; i++) /* ...and then mark its elements. */ 5660 for (i = 0; i < size; i++) /* ...and then mark its elements. */
5625 mark_object (ptr->contents[i]); 5661 mark_object (ptr->u.contents[i]);
5626} 5662}
5627 5663
5628/* Like mark_vectorlike but optimized for char-tables (and 5664/* Like mark_vectorlike but optimized for char-tables (and
@@ -5639,7 +5675,7 @@ mark_char_table (struct Lisp_Vector *ptr)
5639 VECTOR_MARK (ptr); 5675 VECTOR_MARK (ptr);
5640 for (i = 0; i < size; i++) 5676 for (i = 0; i < size; i++)
5641 { 5677 {
5642 Lisp_Object val = ptr->contents[i]; 5678 Lisp_Object val = ptr->u.contents[i];
5643 5679
5644 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) 5680 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit))
5645 continue; 5681 continue;
@@ -5844,10 +5880,10 @@ mark_object (Lisp_Object arg)
5844 VECTOR_MARK (ptr); 5880 VECTOR_MARK (ptr);
5845 for (i = 0; i < size; i++) 5881 for (i = 0; i < size; i++)
5846 if (i != COMPILED_CONSTANTS) 5882 if (i != COMPILED_CONSTANTS)
5847 mark_object (ptr->contents[i]); 5883 mark_object (ptr->u.contents[i]);
5848 if (size > COMPILED_CONSTANTS) 5884 if (size > COMPILED_CONSTANTS)
5849 { 5885 {
5850 obj = ptr->contents[COMPILED_CONSTANTS]; 5886 obj = ptr->u.contents[COMPILED_CONSTANTS];
5851 goto loop; 5887 goto loop;
5852 } 5888 }
5853 } 5889 }
@@ -6612,6 +6648,10 @@ init_alloc (void)
6612#endif 6648#endif
6613 Vgc_elapsed = make_float (0.0); 6649 Vgc_elapsed = make_float (0.0);
6614 gcs_done = 0; 6650 gcs_done = 0;
6651
6652#if USE_VALGRIND
6653 valgrind_p = RUNNING_ON_VALGRIND != 0;
6654#endif
6615} 6655}
6616 6656
6617void 6657void