diff options
| author | Eli Zaretskii | 2013-09-26 10:37:16 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-09-26 10:37:16 +0300 |
| commit | b87c4ff2817e71ca71b028792200b1e069a95e04 (patch) | |
| tree | bfe00c0655fa02078a9ab2c633ea06d90c4a2064 /src/alloc.c | |
| parent | bbc108377873aa6ed7cf21c731770103096eea39 (diff) | |
| parent | ba355de014b75ed104da4777f909db70d62f2357 (diff) | |
| download | emacs-b87c4ff2817e71ca71b028792200b1e069a95e04.tar.gz emacs-b87c4ff2817e71ca71b028792200b1e069a95e04.zip | |
Merge from trunk.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 186 |
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> | ||
| 57 | static 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 | ||
| 2016 | verify (sizeof (size_t) * CHAR_BIT == BITS_PER_SIZE_T); | ||
| 2017 | verify ((BITS_PER_SIZE_T & (BITS_PER_SIZE_T - 1)) == 0); | ||
| 2018 | |||
| 2019 | static ptrdiff_t | ||
| 2020 | bool_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 | ||
| 2007 | DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0, | 2045 | DEFUN ("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. */ | ||
| 2571 | verify ((roundup_size & (roundup_size - 1)) == 0); | ||
| 2572 | |||
| 2573 | /* Verify assumptions described above. */ | 2614 | /* Verify assumptions described above. */ |
| 2574 | verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); | 2615 | verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); |
| 2575 | verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); | 2616 | verify (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'. */ | ||
| 2612 | static struct Lisp_Vector * | ||
| 2613 | next_in_free_list (struct Lisp_Vector *v) | ||
| 2614 | { | ||
| 2615 | intptr_t i = XLI (v->contents[0]); | ||
| 2616 | return (struct Lisp_Vector *) i; | ||
| 2617 | } | ||
| 2618 | static void | ||
| 2619 | set_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 | ||
| 3108 | void | 3132 | void |
| 3109 | make_byte_code (struct Lisp_Vector *v) | 3133 | make_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 | ||
| 6617 | void | 6657 | void |