aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorDmitry Antipov2012-11-08 18:10:28 +0400
committerDmitry Antipov2012-11-08 18:10:28 +0400
commit914adc427f7d1159356e465ec616c65a2ea902af (patch)
treea4af121088abea87624dd93640d1deb1dd54ea95 /src/alloc.c
parentd14bb752ea51331ce2fb459c6ffacd8b11f80bb0 (diff)
downloademacs-914adc427f7d1159356e465ec616c65a2ea902af.tar.gz
emacs-914adc427f7d1159356e465ec616c65a2ea902af.zip
Shrink struct vectorlike_header to the only size field.
* lisp.h (enum pvec_type): Avoid explicit enum member values. Adjust comment. (enum More_Lisp_Bits): Change PSEUDOVECTOR_SIZE_BITS and PVEC_TYPE_MASK to arrange new bitfield in the vector header. (PSEUDOVECTOR_REST_BITS, PSEUDOVECTOR_REST_MASK): New members. (PSEUDOVECTOR_AREA_BITS): New member used to extract subtype information from the vector header. Adjust comment. (XSETPVECTYPE, XSETPVECTYPESIZE, XSETTYPED_PSEUDOVECTOR) (PSEUDOVECTOR_TYPEP, DEFUN): Adjust to match new vector header layout. (XSETSUBR, SUBRP): Adjust to match new Lisp_Subr layout. (struct vectorlike_header): Remove next member. Adjust comment. (struct Lisp_Subr): Add convenient header. Adjust comment. (allocate_pseudovector): Adjust prototype. * alloc.c (mark_glyph_matrix, mark_face_cache, allocate_string) (sweep_string, lisp_malloc): Remove useless prototypes. (enum mem_type): Adjust comment. (NEXT_IN_FREE_LIST): New macro. (SETUP_ON_FREE_LIST): Adjust XSETPVECTYPESIZE usage. (Fmake_bool_vector): Likewise. (struct large_vector): New type to represent allocation unit for the vectors with the memory footprint more than VBLOOCK_BYTES_MAX. (large_vectors): Change type to struct large_vector. (allocate_vector_from_block): Simplify. (PSEUDOVECTOR_NBYTES): Replace with... (vector_nbytes): ...new function. Adjust users. (sweep_vectors): Adjust processing of large vectors. (allocate_vectorlike): Likewise. (allocate_pseudovector): Change type of 3rd arg to enum pvec_type. Add easserts. Adjust XSETPVECTYPESIZE usage. (allocate_buffer): Use BUFFER_PVEC_INIT. (live_vector_p): Adjust to match large vector. * buffer.c (init_buffer_once): Use BUFFER_PVEC_INIT. * buffer.h (struct buffer): Add next member. (BUFFER_LISP_SIZE, BUFFER_REST_SIZE, BUFFER_PVEC_INIT): New macros. (FOR_EACH_BUFFER): Adjust to match struct buffer change. * fns.c (internal_equal): Adjust to match enum pvec_type change. (copy_hash_table): Adjust to match vector header change. * lread.c (defsubr): Use XSETPVECTYPE. * .gdbinit (xpr, xbacktrace): Adjust to match vector header change. (xvectype): Likewise. Print PVEC_NORMAL_VECTOR for regular vectors. (xvecsize): New command.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c185
1 files changed, 114 insertions, 71 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 5bb528c64ab..557c68ca5af 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -216,23 +216,19 @@ static Lisp_Object Qpost_gc_hook;
216static void mark_terminals (void); 216static void mark_terminals (void);
217static void gc_sweep (void); 217static void gc_sweep (void);
218static Lisp_Object make_pure_vector (ptrdiff_t); 218static Lisp_Object make_pure_vector (ptrdiff_t);
219static void mark_glyph_matrix (struct glyph_matrix *);
220static void mark_face_cache (struct face_cache *);
221static void mark_buffer (struct buffer *); 219static void mark_buffer (struct buffer *);
222 220
223#if !defined REL_ALLOC || defined SYSTEM_MALLOC 221#if !defined REL_ALLOC || defined SYSTEM_MALLOC
224static void refill_memory_reserve (void); 222static void refill_memory_reserve (void);
225#endif 223#endif
226static struct Lisp_String *allocate_string (void);
227static void compact_small_strings (void); 224static void compact_small_strings (void);
228static void free_large_strings (void); 225static void free_large_strings (void);
229static void sweep_strings (void);
230static void free_misc (Lisp_Object); 226static void free_misc (Lisp_Object);
231extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; 227extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE;
232 228
233/* When scanning the C stack for live Lisp objects, Emacs keeps track 229/* When scanning the C stack for live Lisp objects, Emacs keeps track of
234 of what memory allocated via lisp_malloc is intended for what 230 what memory allocated via lisp_malloc and lisp_align_malloc is intended
235 purpose. This enumeration specifies the type of memory. */ 231 for what purpose. This enumeration specifies the type of memory. */
236 232
237enum mem_type 233enum mem_type
238{ 234{
@@ -243,10 +239,9 @@ enum mem_type
243 MEM_TYPE_MISC, 239 MEM_TYPE_MISC,
244 MEM_TYPE_SYMBOL, 240 MEM_TYPE_SYMBOL,
245 MEM_TYPE_FLOAT, 241 MEM_TYPE_FLOAT,
246 /* We used to keep separate mem_types for subtypes of vectors such as 242 /* Since all non-bool pseudovectors are small enough to be
247 process, hash_table, frame, terminal, and window, but we never made 243 allocated from vector blocks, this memory type denotes
248 use of the distinction, so it only caused source-code complexity 244 large regular vectors and large bool pseudovectors. */
249 and runtime slowdown. Minor but pointless. */
250 MEM_TYPE_VECTORLIKE, 245 MEM_TYPE_VECTORLIKE,
251 /* Special type to denote vector blocks. */ 246 /* Special type to denote vector blocks. */
252 MEM_TYPE_VECTOR_BLOCK, 247 MEM_TYPE_VECTOR_BLOCK,
@@ -254,9 +249,6 @@ enum mem_type
254 MEM_TYPE_SPARE 249 MEM_TYPE_SPARE
255}; 250};
256 251
257static void *lisp_malloc (size_t, enum mem_type);
258
259
260#if GC_MARK_STACK || defined GC_MALLOC_CHECK 252#if GC_MARK_STACK || defined GC_MALLOC_CHECK
261 253
262#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 254#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
@@ -2040,7 +2032,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2040 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil); 2032 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil);
2041 2033
2042 /* No Lisp_Object to trace in there. */ 2034 /* No Lisp_Object to trace in there. */
2043 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0); 2035 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2044 2036
2045 p = XBOOL_VECTOR (val); 2037 p = XBOOL_VECTOR (val);
2046 p->size = XFASTINT (length); 2038 p->size = XFASTINT (length);
@@ -2619,19 +2611,49 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2619 2611
2620#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) 2612#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
2621 2613
2614/* When V is on the free list, first word after header is used as a pointer
2615 to next vector on the free list. It might be done in a better way with:
2616
2617 (*(struct Lisp_Vector **)&(v->contents[0]))
2618
2619 but this breaks GCC's strict-aliasing rules (which looks more relaxed
2620 for char and void pointers). */
2621
2622#define NEXT_IN_FREE_LIST(v) \
2623 (*(struct Lisp_Vector **)((char *) v + header_size))
2624
2622/* Common shortcut to setup vector on a free list. */ 2625/* Common shortcut to setup vector on a free list. */
2623 2626
2624#define SETUP_ON_FREE_LIST(v, nbytes, index) \ 2627#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \
2625 do { \ 2628 do { \
2626 XSETPVECTYPESIZE (v, PVEC_FREE, nbytes); \ 2629 (tmp) = ((nbytes - header_size) / word_size); \
2627 eassert ((nbytes) % roundup_size == 0); \ 2630 XSETPVECTYPESIZE (v, PVEC_FREE, 0, (tmp)); \
2628 (index) = VINDEX (nbytes); \ 2631 eassert ((nbytes) % roundup_size == 0); \
2629 eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ 2632 (tmp) = VINDEX (nbytes); \
2630 (v)->header.next.vector = vector_free_lists[index]; \ 2633 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
2631 vector_free_lists[index] = (v); \ 2634 NEXT_IN_FREE_LIST (v) = vector_free_lists[tmp]; \
2632 total_free_vector_slots += (nbytes) / word_size; \ 2635 vector_free_lists[tmp] = (v); \
2636 total_free_vector_slots += (nbytes) / word_size; \
2633 } while (0) 2637 } while (0)
2634 2638
2639/* This internal type is used to maintain the list of large vectors
2640 which are allocated at their own, e.g. outside of vector blocks. */
2641
2642struct large_vector
2643{
2644 union {
2645 struct large_vector *vector;
2646#if USE_LSB_TAG
2647 /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */
2648 unsigned char c[vroundup (sizeof (struct large_vector *))];
2649#endif
2650 } next;
2651 struct Lisp_Vector v;
2652};
2653
2654/* This internal type is used to maintain an underlying storage
2655 for small vectors. */
2656
2635struct vector_block 2657struct vector_block
2636{ 2658{
2637 char data[VECTOR_BLOCK_BYTES]; 2659 char data[VECTOR_BLOCK_BYTES];
@@ -2649,7 +2671,7 @@ static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX];
2649 2671
2650/* Singly-linked list of large vectors. */ 2672/* Singly-linked list of large vectors. */
2651 2673
2652static struct Lisp_Vector *large_vectors; 2674static struct large_vector *large_vectors;
2653 2675
2654/* The only vector with 0 slots, allocated from pure space. */ 2676/* The only vector with 0 slots, allocated from pure space. */
2655 2677
@@ -2693,7 +2715,7 @@ init_vectors (void)
2693static struct Lisp_Vector * 2715static struct Lisp_Vector *
2694allocate_vector_from_block (size_t nbytes) 2716allocate_vector_from_block (size_t nbytes)
2695{ 2717{
2696 struct Lisp_Vector *vector, *rest; 2718 struct Lisp_Vector *vector;
2697 struct vector_block *block; 2719 struct vector_block *block;
2698 size_t index, restbytes; 2720 size_t index, restbytes;
2699 2721
@@ -2706,8 +2728,7 @@ allocate_vector_from_block (size_t nbytes)
2706 if (vector_free_lists[index]) 2728 if (vector_free_lists[index])
2707 { 2729 {
2708 vector = vector_free_lists[index]; 2730 vector = vector_free_lists[index];
2709 vector_free_lists[index] = vector->header.next.vector; 2731 vector_free_lists[index] = NEXT_IN_FREE_LIST (vector);
2710 vector->header.next.nbytes = nbytes;
2711 total_free_vector_slots -= nbytes / word_size; 2732 total_free_vector_slots -= nbytes / word_size;
2712 return vector; 2733 return vector;
2713 } 2734 }
@@ -2721,16 +2742,14 @@ allocate_vector_from_block (size_t nbytes)
2721 { 2742 {
2722 /* This vector is larger than requested. */ 2743 /* This vector is larger than requested. */
2723 vector = vector_free_lists[index]; 2744 vector = vector_free_lists[index];
2724 vector_free_lists[index] = vector->header.next.vector; 2745 vector_free_lists[index] = NEXT_IN_FREE_LIST (vector);
2725 vector->header.next.nbytes = nbytes;
2726 total_free_vector_slots -= nbytes / word_size; 2746 total_free_vector_slots -= nbytes / word_size;
2727 2747
2728 /* Excess bytes are used for the smaller vector, 2748 /* Excess bytes are used for the smaller vector,
2729 which should be set on an appropriate free list. */ 2749 which should be set on an appropriate free list. */
2730 restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; 2750 restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes;
2731 eassert (restbytes % roundup_size == 0); 2751 eassert (restbytes % roundup_size == 0);
2732 rest = ADVANCE (vector, nbytes); 2752 SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index);
2733 SETUP_ON_FREE_LIST (rest, restbytes, index);
2734 return vector; 2753 return vector;
2735 } 2754 }
2736 2755
@@ -2739,7 +2758,6 @@ allocate_vector_from_block (size_t nbytes)
2739 2758
2740 /* New vector will be at the beginning of this block. */ 2759 /* New vector will be at the beginning of this block. */
2741 vector = (struct Lisp_Vector *) block->data; 2760 vector = (struct Lisp_Vector *) block->data;
2742 vector->header.next.nbytes = nbytes;
2743 2761
2744 /* If the rest of space from this block is large enough 2762 /* If the rest of space from this block is large enough
2745 for one-slot vector at least, set up it on a free list. */ 2763 for one-slot vector at least, set up it on a free list. */
@@ -2747,11 +2765,10 @@ allocate_vector_from_block (size_t nbytes)
2747 if (restbytes >= VBLOCK_BYTES_MIN) 2765 if (restbytes >= VBLOCK_BYTES_MIN)
2748 { 2766 {
2749 eassert (restbytes % roundup_size == 0); 2767 eassert (restbytes % roundup_size == 0);
2750 rest = ADVANCE (vector, nbytes); 2768 SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index);
2751 SETUP_ON_FREE_LIST (rest, restbytes, index);
2752 } 2769 }
2753 return vector; 2770 return vector;
2754 } 2771}
2755 2772
2756/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ 2773/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */
2757 2774
@@ -2759,15 +2776,30 @@ allocate_vector_from_block (size_t nbytes)
2759 ((char *) (vector) <= (block)->data \ 2776 ((char *) (vector) <= (block)->data \
2760 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) 2777 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN)
2761 2778
2762/* Number of bytes used by vector-block-allocated object. This is the only 2779/* Return the memory footprint of V in bytes. */
2763 place where we actually use the `nbytes' field of the vector-header.
2764 I.e. we could get rid of the `nbytes' field by computing it based on the
2765 vector-type. */
2766 2780
2767#define PSEUDOVECTOR_NBYTES(vector) \ 2781static ptrdiff_t
2768 (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \ 2782vector_nbytes (struct Lisp_Vector *v)
2769 ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \ 2783{
2770 : vector->header.next.nbytes) 2784 ptrdiff_t size = v->header.size & ~ARRAY_MARK_FLAG;
2785
2786 if (size & PSEUDOVECTOR_FLAG)
2787 {
2788 if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR))
2789 size = (bool_header_size
2790 + (((struct Lisp_Bool_Vector *) v)->size
2791 + BOOL_VECTOR_BITS_PER_CHAR - 1)
2792 / BOOL_VECTOR_BITS_PER_CHAR);
2793 else
2794 size = (header_size
2795 + ((size & PSEUDOVECTOR_SIZE_MASK)
2796 + ((size & PSEUDOVECTOR_REST_MASK)
2797 >> PSEUDOVECTOR_SIZE_BITS)) * word_size);
2798 }
2799 else
2800 size = header_size + size * word_size;
2801 return vroundup (size);
2802}
2771 2803
2772/* Reclaim space used by unmarked vectors. */ 2804/* Reclaim space used by unmarked vectors. */
2773 2805
@@ -2775,7 +2807,8 @@ static void
2775sweep_vectors (void) 2807sweep_vectors (void)
2776{ 2808{
2777 struct vector_block *block = vector_blocks, **bprev = &vector_blocks; 2809 struct vector_block *block = vector_blocks, **bprev = &vector_blocks;
2778 struct Lisp_Vector *vector, *next, **vprev = &large_vectors; 2810 struct large_vector *lv, **lvprev = &large_vectors;
2811 struct Lisp_Vector *vector, *next;
2779 2812
2780 total_vectors = total_vector_slots = total_free_vector_slots = 0; 2813 total_vectors = total_vector_slots = total_free_vector_slots = 0;
2781 memset (vector_free_lists, 0, sizeof (vector_free_lists)); 2814 memset (vector_free_lists, 0, sizeof (vector_free_lists));
@@ -2785,6 +2818,7 @@ sweep_vectors (void)
2785 for (block = vector_blocks; block; block = *bprev) 2818 for (block = vector_blocks; block; block = *bprev)
2786 { 2819 {
2787 bool free_this_block = 0; 2820 bool free_this_block = 0;
2821 ptrdiff_t nbytes;
2788 2822
2789 for (vector = (struct Lisp_Vector *) block->data; 2823 for (vector = (struct Lisp_Vector *) block->data;
2790 VECTOR_IN_BLOCK (vector, block); vector = next) 2824 VECTOR_IN_BLOCK (vector, block); vector = next)
@@ -2793,14 +2827,16 @@ sweep_vectors (void)
2793 { 2827 {
2794 VECTOR_UNMARK (vector); 2828 VECTOR_UNMARK (vector);
2795 total_vectors++; 2829 total_vectors++;
2796 total_vector_slots += vector->header.next.nbytes / word_size; 2830 nbytes = vector_nbytes (vector);
2797 next = ADVANCE (vector, vector->header.next.nbytes); 2831 total_vector_slots += nbytes / word_size;
2832 next = ADVANCE (vector, nbytes);
2798 } 2833 }
2799 else 2834 else
2800 { 2835 {
2801 ptrdiff_t nbytes = PSEUDOVECTOR_NBYTES (vector); 2836 ptrdiff_t total_bytes;
2802 ptrdiff_t total_bytes = nbytes;
2803 2837
2838 nbytes = vector_nbytes (vector);
2839 total_bytes = nbytes;
2804 next = ADVANCE (vector, nbytes); 2840 next = ADVANCE (vector, nbytes);
2805 2841
2806 /* While NEXT is not marked, try to coalesce with VECTOR, 2842 /* While NEXT is not marked, try to coalesce with VECTOR,
@@ -2810,7 +2846,7 @@ sweep_vectors (void)
2810 { 2846 {
2811 if (VECTOR_MARKED_P (next)) 2847 if (VECTOR_MARKED_P (next))
2812 break; 2848 break;
2813 nbytes = PSEUDOVECTOR_NBYTES (next); 2849 nbytes = vector_nbytes (next);
2814 total_bytes += nbytes; 2850 total_bytes += nbytes;
2815 next = ADVANCE (next, nbytes); 2851 next = ADVANCE (next, nbytes);
2816 } 2852 }
@@ -2844,8 +2880,9 @@ sweep_vectors (void)
2844 2880
2845 /* Sweep large vectors. */ 2881 /* Sweep large vectors. */
2846 2882
2847 for (vector = large_vectors; vector; vector = *vprev) 2883 for (lv = large_vectors; lv; lv = *lvprev)
2848 { 2884 {
2885 vector = &lv->v;
2849 if (VECTOR_MARKED_P (vector)) 2886 if (VECTOR_MARKED_P (vector))
2850 { 2887 {
2851 VECTOR_UNMARK (vector); 2888 VECTOR_UNMARK (vector);
@@ -2867,12 +2904,12 @@ sweep_vectors (void)
2867 else 2904 else
2868 total_vector_slots 2905 total_vector_slots
2869 += header_size / word_size + vector->header.size; 2906 += header_size / word_size + vector->header.size;
2870 vprev = &vector->header.next.vector; 2907 lvprev = &lv->next.vector;
2871 } 2908 }
2872 else 2909 else
2873 { 2910 {
2874 *vprev = vector->header.next.vector; 2911 *lvprev = lv->next.vector;
2875 lisp_free (vector); 2912 lisp_free (lv);
2876 } 2913 }
2877 } 2914 }
2878} 2915}
@@ -2904,9 +2941,12 @@ allocate_vectorlike (ptrdiff_t len)
2904 p = allocate_vector_from_block (vroundup (nbytes)); 2941 p = allocate_vector_from_block (vroundup (nbytes));
2905 else 2942 else
2906 { 2943 {
2907 p = lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); 2944 struct large_vector *lv
2908 p->header.next.vector = large_vectors; 2945 = lisp_malloc (sizeof (*lv) + (len - 1) * word_size,
2909 large_vectors = p; 2946 MEM_TYPE_VECTORLIKE);
2947 lv->next.vector = large_vectors;
2948 large_vectors = lv;
2949 p = &lv->v;
2910 } 2950 }
2911 2951
2912#ifdef DOUG_LEA_MALLOC 2952#ifdef DOUG_LEA_MALLOC
@@ -2943,16 +2983,21 @@ allocate_vector (EMACS_INT len)
2943/* Allocate other vector-like structures. */ 2983/* Allocate other vector-like structures. */
2944 2984
2945struct Lisp_Vector * 2985struct Lisp_Vector *
2946allocate_pseudovector (int memlen, int lisplen, int tag) 2986allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
2947{ 2987{
2948 struct Lisp_Vector *v = allocate_vectorlike (memlen); 2988 struct Lisp_Vector *v = allocate_vectorlike (memlen);
2949 int i; 2989 int i;
2950 2990
2991 /* Catch bogus values. */
2992 eassert (tag <= PVEC_FONT);
2993 eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1);
2994 eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
2995
2951 /* Only the first lisplen slots will be traced normally by the GC. */ 2996 /* Only the first lisplen slots will be traced normally by the GC. */
2952 for (i = 0; i < lisplen; ++i) 2997 for (i = 0; i < lisplen; ++i)
2953 v->contents[i] = Qnil; 2998 v->contents[i] = Qnil;
2954 2999
2955 XSETPVECTYPESIZE (v, tag, lisplen); 3000 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
2956 return v; 3001 return v;
2957} 3002}
2958 3003
@@ -2961,10 +3006,9 @@ allocate_buffer (void)
2961{ 3006{
2962 struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER); 3007 struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER);
2963 3008
2964 XSETPVECTYPESIZE (b, PVEC_BUFFER, (offsetof (struct buffer, own_text) 3009 BUFFER_PVEC_INIT (b);
2965 - header_size) / word_size);
2966 /* Put B on the chain of all buffers including killed ones. */ 3010 /* Put B on the chain of all buffers including killed ones. */
2967 b->header.next.buffer = all_buffers; 3011 b->next = all_buffers;
2968 all_buffers = b; 3012 all_buffers = b;
2969 /* Note that the rest fields of B are not initialized. */ 3013 /* Note that the rest fields of B are not initialized. */
2970 return b; 3014 return b;
@@ -4068,16 +4112,15 @@ live_vector_p (struct mem_node *m, void *p)
4068 while (VECTOR_IN_BLOCK (vector, block) 4112 while (VECTOR_IN_BLOCK (vector, block)
4069 && vector <= (struct Lisp_Vector *) p) 4113 && vector <= (struct Lisp_Vector *) p)
4070 { 4114 {
4071 if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) 4115 if (!PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) && vector == p)
4072 vector = ADVANCE (vector, (vector->header.size
4073 & PSEUDOVECTOR_SIZE_MASK));
4074 else if (vector == p)
4075 return 1; 4116 return 1;
4076 else 4117 else
4077 vector = ADVANCE (vector, vector->header.next.nbytes); 4118 vector = ADVANCE (vector, vector_nbytes (vector));
4078 } 4119 }
4079 } 4120 }
4080 else if (m->type == MEM_TYPE_VECTORLIKE && p == m->start) 4121 else if (m->type == MEM_TYPE_VECTORLIKE
4122 && (char *) p == ((char *) m->start
4123 + offsetof (struct large_vector, v)))
4081 /* This memory node corresponds to a large vector. */ 4124 /* This memory node corresponds to a large vector. */
4082 return 1; 4125 return 1;
4083 return 0; 4126 return 0;
@@ -5687,7 +5730,7 @@ mark_object (Lisp_Object arg)
5687 5730
5688 if (ptr->header.size & PSEUDOVECTOR_FLAG) 5731 if (ptr->header.size & PSEUDOVECTOR_FLAG)
5689 pvectype = ((ptr->header.size & PVEC_TYPE_MASK) 5732 pvectype = ((ptr->header.size & PVEC_TYPE_MASK)
5690 >> PSEUDOVECTOR_SIZE_BITS); 5733 >> PSEUDOVECTOR_AREA_BITS);
5691 else 5734 else
5692 pvectype = PVEC_NORMAL_VECTOR; 5735 pvectype = PVEC_NORMAL_VECTOR;
5693 5736
@@ -6317,7 +6360,7 @@ gc_sweep (void)
6317 for (buffer = all_buffers; buffer; buffer = *bprev) 6360 for (buffer = all_buffers; buffer; buffer = *bprev)
6318 if (!VECTOR_MARKED_P (buffer)) 6361 if (!VECTOR_MARKED_P (buffer))
6319 { 6362 {
6320 *bprev = buffer->header.next.buffer; 6363 *bprev = buffer->next;
6321 lisp_free (buffer); 6364 lisp_free (buffer);
6322 } 6365 }
6323 else 6366 else
@@ -6326,7 +6369,7 @@ gc_sweep (void)
6326 /* Do not use buffer_(set|get)_intervals here. */ 6369 /* Do not use buffer_(set|get)_intervals here. */
6327 buffer->text->intervals = balance_intervals (buffer->text->intervals); 6370 buffer->text->intervals = balance_intervals (buffer->text->intervals);
6328 total_buffers++; 6371 total_buffers++;
6329 bprev = &buffer->header.next.buffer; 6372 bprev = &buffer->next;
6330 } 6373 }
6331 } 6374 }
6332 6375