aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c184
1 files changed, 96 insertions, 88 deletions
diff --git a/src/alloc.c b/src/alloc.c
index b1e2ed0a2ed..bd68f2b31f2 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1529,7 +1529,7 @@ make_interval (void)
1529} 1529}
1530 1530
1531 1531
1532/* Mark Lisp objects in interval I. */ 1532/* Mark Lisp objects in interval I. */
1533 1533
1534static void 1534static void
1535mark_interval (register INTERVAL i, Lisp_Object dummy) 1535mark_interval (register INTERVAL i, Lisp_Object dummy)
@@ -1836,7 +1836,7 @@ check_sblock (struct sblock *b)
1836 ptrdiff_t nbytes; 1836 ptrdiff_t nbytes;
1837 1837
1838 /* Check that the string size recorded in the string is the 1838 /* Check that the string size recorded in the string is the
1839 same as the one recorded in the sdata structure. */ 1839 same as the one recorded in the sdata structure. */
1840 if (from->string) 1840 if (from->string)
1841 CHECK_STRING_BYTES (from->string); 1841 CHECK_STRING_BYTES (from->string);
1842 1842
@@ -2869,12 +2869,6 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0,
2869 2869
2870#define VECTOR_BLOCK_SIZE 4096 2870#define VECTOR_BLOCK_SIZE 4096
2871 2871
2872/* This special value is used to calculate vector size when the vector is
2873 on a free list. It should be VECTOR_BLOCK_SIZE rounded up to nearest
2874 power of two, minus one. */
2875
2876#define VECTOR_FREE_LIST_SIZE_MASK 4095
2877
2878/* Handy constants for vectorlike objects. */ 2872/* Handy constants for vectorlike objects. */
2879enum 2873enum
2880 { 2874 {
@@ -2889,8 +2883,7 @@ verify ((roundup_size & (roundup_size - 1)) == 0);
2889 2883
2890/* Verify assumptions described above. */ 2884/* Verify assumptions described above. */
2891verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); 2885verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0);
2892verify ((VECTOR_FREE_LIST_SIZE_MASK + 1) >= VECTOR_BLOCK_SIZE); 2886verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2893verify ((VECTOR_FREE_LIST_SIZE_MASK & (VECTOR_FREE_LIST_SIZE_MASK + 1)) == 0);
2894 2887
2895/* Round up X to nearest mult-of-ROUNDUP_SIZE. */ 2888/* Round up X to nearest mult-of-ROUNDUP_SIZE. */
2896 2889
@@ -2915,12 +2908,6 @@ verify ((VECTOR_FREE_LIST_SIZE_MASK & (VECTOR_FREE_LIST_SIZE_MASK + 1)) == 0);
2915#define VECTOR_MAX_FREE_LIST_INDEX \ 2908#define VECTOR_MAX_FREE_LIST_INDEX \
2916 ((VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1) 2909 ((VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1)
2917 2910
2918/* When the vector is on a free list, vectorlike_header.SIZE is set to
2919 this special value ORed with vector's memory footprint size. */
2920
2921#define VECTOR_FREE_LIST_FLAG (~(ARRAY_MARK_FLAG | PSEUDOVECTOR_FLAG \
2922 | VECTOR_FREE_LIST_SIZE_MASK))
2923
2924/* Common shortcut to advance vector pointer over a block data. */ 2911/* Common shortcut to advance vector pointer over a block data. */
2925 2912
2926#define ADVANCE(v, nbytes) ((struct Lisp_Vector *) ((char *) (v) + (nbytes))) 2913#define ADVANCE(v, nbytes) ((struct Lisp_Vector *) ((char *) (v) + (nbytes)))
@@ -2933,7 +2920,7 @@ verify ((VECTOR_FREE_LIST_SIZE_MASK & (VECTOR_FREE_LIST_SIZE_MASK + 1)) == 0);
2933 2920
2934#define SETUP_ON_FREE_LIST(v, nbytes, index) \ 2921#define SETUP_ON_FREE_LIST(v, nbytes, index) \
2935 do { \ 2922 do { \
2936 (v)->header.size = VECTOR_FREE_LIST_FLAG | (nbytes); \ 2923 XSETPVECTYPESIZE (v, PVEC_FREE, nbytes); \
2937 eassert ((nbytes) % roundup_size == 0); \ 2924 eassert ((nbytes) % roundup_size == 0); \
2938 (index) = VINDEX (nbytes); \ 2925 (index) = VINDEX (nbytes); \
2939 eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ 2926 eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \
@@ -3065,6 +3052,16 @@ allocate_vector_from_block (size_t nbytes)
3065 ((char *) (vector) <= (block)->data \ 3052 ((char *) (vector) <= (block)->data \
3066 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) 3053 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN)
3067 3054
3055/* Number of bytes used by vector-block-allocated object. This is the only
3056 place where we actually use the `nbytes' field of the vector-header.
3057 I.e. we could get rid of the `nbytes' field by computing it based on the
3058 vector-type. */
3059
3060#define PSEUDOVECTOR_NBYTES(vector) \
3061 (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \
3062 ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \
3063 : vector->header.next.nbytes);
3064
3068/* Reclaim space used by unmarked vectors. */ 3065/* Reclaim space used by unmarked vectors. */
3069 3066
3070static void 3067static void
@@ -3093,14 +3090,10 @@ sweep_vectors (void)
3093 } 3090 }
3094 else 3091 else
3095 { 3092 {
3096 ptrdiff_t nbytes; 3093 ptrdiff_t nbytes = PSEUDOVECTOR_NBYTES (vector);
3094 ptrdiff_t total_bytes = nbytes;
3097 3095
3098 if ((vector->header.size & VECTOR_FREE_LIST_FLAG) 3096 next = ADVANCE (vector, nbytes);
3099 == VECTOR_FREE_LIST_FLAG)
3100 vector->header.next.nbytes =
3101 vector->header.size & VECTOR_FREE_LIST_SIZE_MASK;
3102
3103 next = ADVANCE (vector, vector->header.next.nbytes);
3104 3097
3105 /* While NEXT is not marked, try to coalesce with VECTOR, 3098 /* While NEXT is not marked, try to coalesce with VECTOR,
3106 thus making VECTOR of the largest possible size. */ 3099 thus making VECTOR of the largest possible size. */
@@ -3109,16 +3102,12 @@ sweep_vectors (void)
3109 { 3102 {
3110 if (VECTOR_MARKED_P (next)) 3103 if (VECTOR_MARKED_P (next))
3111 break; 3104 break;
3112 if ((next->header.size & VECTOR_FREE_LIST_FLAG) 3105 nbytes = PSEUDOVECTOR_NBYTES (next);
3113 == VECTOR_FREE_LIST_FLAG) 3106 total_bytes += nbytes;
3114 nbytes = next->header.size & VECTOR_FREE_LIST_SIZE_MASK;
3115 else
3116 nbytes = next->header.next.nbytes;
3117 vector->header.next.nbytes += nbytes;
3118 next = ADVANCE (next, nbytes); 3107 next = ADVANCE (next, nbytes);
3119 } 3108 }
3120 3109
3121 eassert (vector->header.next.nbytes % roundup_size == 0); 3110 eassert (total_bytes % roundup_size == 0);
3122 3111
3123 if (vector == (struct Lisp_Vector *) block->data 3112 if (vector == (struct Lisp_Vector *) block->data
3124 && !VECTOR_IN_BLOCK (next, block)) 3113 && !VECTOR_IN_BLOCK (next, block))
@@ -3126,7 +3115,10 @@ sweep_vectors (void)
3126 space was coalesced into the only free vector. */ 3115 space was coalesced into the only free vector. */
3127 free_this_block = 1; 3116 free_this_block = 1;
3128 else 3117 else
3129 SETUP_ON_FREE_LIST (vector, vector->header.next.nbytes, nbytes); 3118 {
3119 int tmp;
3120 SETUP_ON_FREE_LIST (vector, total_bytes, tmp);
3121 }
3130 } 3122 }
3131 } 3123 }
3132 3124
@@ -4342,10 +4334,9 @@ live_vector_p (struct mem_node *m, void *p)
4342 while (VECTOR_IN_BLOCK (vector, block) 4334 while (VECTOR_IN_BLOCK (vector, block)
4343 && vector <= (struct Lisp_Vector *) p) 4335 && vector <= (struct Lisp_Vector *) p)
4344 { 4336 {
4345 if ((vector->header.size & VECTOR_FREE_LIST_FLAG) 4337 if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE))
4346 == VECTOR_FREE_LIST_FLAG)
4347 vector = ADVANCE (vector, (vector->header.size 4338 vector = ADVANCE (vector, (vector->header.size
4348 & VECTOR_FREE_LIST_SIZE_MASK)); 4339 & PSEUDOVECTOR_SIZE_MASK));
4349 else if (vector == p) 4340 else if (vector == p)
4350 return 1; 4341 return 1;
4351 else 4342 else
@@ -5913,15 +5904,17 @@ mark_object (Lisp_Object arg)
5913#endif /* GC_CHECK_MARKED_OBJECTS */ 5904#endif /* GC_CHECK_MARKED_OBJECTS */
5914 5905
5915 if (ptr->header.size & PSEUDOVECTOR_FLAG) 5906 if (ptr->header.size & PSEUDOVECTOR_FLAG)
5916 pvectype = ptr->header.size & PVEC_TYPE_MASK; 5907 pvectype = ((ptr->header.size & PVEC_TYPE_MASK)
5908 >> PSEUDOVECTOR_SIZE_BITS);
5917 else 5909 else
5918 pvectype = 0; 5910 pvectype = 0;
5919 5911
5920 if (pvectype != PVEC_SUBR && pvectype != PVEC_BUFFER) 5912 if (pvectype != PVEC_SUBR && pvectype != PVEC_BUFFER)
5921 CHECK_LIVE (live_vector_p); 5913 CHECK_LIVE (live_vector_p);
5922 5914
5923 if (pvectype == PVEC_BUFFER) 5915 switch (pvectype)
5924 { 5916 {
5917 case PVEC_BUFFER:
5925#ifdef GC_CHECK_MARKED_OBJECTS 5918#ifdef GC_CHECK_MARKED_OBJECTS
5926 if (po != &buffer_defaults && po != &buffer_local_symbols) 5919 if (po != &buffer_defaults && po != &buffer_local_symbols)
5927 { 5920 {
@@ -5933,67 +5926,82 @@ mark_object (Lisp_Object arg)
5933 } 5926 }
5934#endif /* GC_CHECK_MARKED_OBJECTS */ 5927#endif /* GC_CHECK_MARKED_OBJECTS */
5935 mark_buffer ((struct buffer *) ptr); 5928 mark_buffer ((struct buffer *) ptr);
5936 } 5929 break;
5937 5930
5938 else if (pvectype == PVEC_COMPILED) 5931 case PVEC_COMPILED:
5939 /* We could treat this just like a vector, but it is better 5932 { /* We could treat this just like a vector, but it is better
5940 to save the COMPILED_CONSTANTS element for last and avoid 5933 to save the COMPILED_CONSTANTS element for last and avoid
5941 recursion there. */ 5934 recursion there. */
5942 { 5935 int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK;
5943 int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; 5936 int i;
5944 int i; 5937
5938 VECTOR_MARK (ptr);
5939 for (i = 0; i < size; i++)
5940 if (i != COMPILED_CONSTANTS)
5941 mark_object (ptr->contents[i]);
5942 if (size > COMPILED_CONSTANTS)
5943 {
5944 obj = ptr->contents[COMPILED_CONSTANTS];
5945 goto loop;
5946 }
5947 }
5948 break;
5945 5949
5946 VECTOR_MARK (ptr); 5950 case PVEC_FRAME:
5947 for (i = 0; i < size; i++) 5951 {
5948 if (i != COMPILED_CONSTANTS) 5952 mark_vectorlike (ptr);
5949 mark_object (ptr->contents[i]); 5953 mark_face_cache (((struct frame *) ptr)->face_cache);
5950 obj = ptr->contents[COMPILED_CONSTANTS]; 5954 }
5951 goto loop; 5955 break;
5952 }
5953 5956
5954 else if (pvectype == PVEC_FRAME) 5957 case PVEC_WINDOW:
5955 { 5958 {
5956 mark_vectorlike (ptr); 5959 struct window *w = (struct window *) ptr;
5957 mark_face_cache (((struct frame *) ptr)->face_cache);
5958 }
5959 5960
5960 else if (pvectype == PVEC_WINDOW) 5961 mark_vectorlike (ptr);
5961 { 5962 /* Mark glyphs for leaf windows. Marking window
5962 struct window *w = (struct window *) ptr; 5963 matrices is sufficient because frame matrices
5964 use the same glyph memory. */
5965 if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix)
5966 {
5967 mark_glyph_matrix (w->current_matrix);
5968 mark_glyph_matrix (w->desired_matrix);
5969 }
5970 }
5971 break;
5963 5972
5964 mark_vectorlike (ptr); 5973 case PVEC_HASH_TABLE:
5965 /* Mark glyphs for leaf windows. Marking window 5974 {
5966 matrices is sufficient because frame matrices 5975 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr;
5967 use the same glyph memory. */
5968 if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix)
5969 {
5970 mark_glyph_matrix (w->current_matrix);
5971 mark_glyph_matrix (w->desired_matrix);
5972 }
5973 }
5974 5976
5975 else if (pvectype == PVEC_HASH_TABLE) 5977 mark_vectorlike (ptr);
5976 { 5978 /* If hash table is not weak, mark all keys and values.
5977 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; 5979 For weak tables, mark only the vector. */
5980 if (NILP (h->weak))
5981 mark_object (h->key_and_value);
5982 else
5983 VECTOR_MARK (XVECTOR (h->key_and_value));
5984 }
5985 break;
5978 5986
5979 mark_vectorlike (ptr); 5987 case PVEC_CHAR_TABLE:
5980 /* If hash table is not weak, mark all keys and values. 5988 mark_char_table (ptr);
5981 For weak tables, mark only the vector. */ 5989 break;
5982 if (NILP (h->weak)) 5990
5983 mark_object (h->key_and_value); 5991 case PVEC_BOOL_VECTOR:
5984 else 5992 /* No Lisp_Objects to mark in a bool vector. */
5985 VECTOR_MARK (XVECTOR (h->key_and_value)); 5993 VECTOR_MARK (ptr);
5986 } 5994 break;
5987 5995
5988 else if (pvectype == PVEC_CHAR_TABLE) 5996 case PVEC_SUBR:
5989 mark_char_table (ptr); 5997 break;
5990 5998
5991 else if (pvectype == PVEC_BOOL_VECTOR) 5999 case PVEC_FREE:
5992 /* No Lisp_Objects to mark in a bool vector. */ 6000 abort ();
5993 VECTOR_MARK (ptr);
5994 6001
5995 else if (pvectype != PVEC_SUBR) 6002 default:
5996 mark_vectorlike (ptr); 6003 mark_vectorlike (ptr);
6004 }
5997 } 6005 }
5998 break; 6006 break;
5999 6007