aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2012-07-04 10:38:02 -0400
committerStefan Monnier2012-07-04 10:38:02 -0400
commitee28be33a535e41c74f3a4d5c0f3878e44366942 (patch)
treeaea01076d95159b7559ec34cd47acd9245f46a7b /src
parent1a9746debdc8965edd84d27537ef9c55511ea04e (diff)
downloademacs-ee28be33a535e41c74f3a4d5c0f3878e44366942.tar.gz
emacs-ee28be33a535e41c74f3a4d5c0f3878e44366942.zip
Turn VECTOR_FREE_LIST_FLAG into PVEC_FREE.
* src/lisp.h (enum pvec_type): Use fewer bits. (PSEUDOVECTOR_SIZE_BITS): New constant. (PSEUDOVECTOR_SIZE_MASK, PVEC_TYPE_MASK): Use it. (XSETPVECTYPESIZE, XSETTYPED_PSEUDOVECTOR, DEFUN): Adapt code to change in pvec_type. (PSEUDOVECTOR_TYPEP): New macro. (TYPED_PSEUDOVECTORP): Use it. * src/fns.c (internal_equal): Adapt code to extract pvectype. * src/emacs.c (gdb_pvec_type): Update type. * src/alloc.c (PSEUDOVECTOR_NBYTES): New macro. (VECTOR_FREE_LIST_SIZE_MASK): Remove (=> PSEUDOVECTOR_SIZE_MASK). (VECTOR_FREE_LIST_FLAG): Remove (=> PVEC_FREE). (SETUP_ON_FREE_LIST): Use XSETPVECTYPESIZE. (sweep_vectors): Use it. Use local var `total_bytes' instead of abusing vector->header.next.nbytes. (live_vector_p): Use PVEC_TYPE. (mark_object): Adapt code to extract pvectype. Use switch.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog21
-rw-r--r--src/alloc.c184
-rw-r--r--src/emacs.c2
-rw-r--r--src/fns.c5
-rw-r--r--src/lisp.h98
5 files changed, 184 insertions, 126 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a600a0b2b6f..70f7fedf5ad 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,24 @@
12012-07-04 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 Turn VECTOR_FREE_LIST_FLAG into PVEC_FREE.
4 * lisp.h (enum pvec_type): Use fewer bits.
5 (PSEUDOVECTOR_SIZE_BITS): New constant.
6 (PSEUDOVECTOR_SIZE_MASK, PVEC_TYPE_MASK): Use it.
7 (XSETPVECTYPESIZE, XSETTYPED_PSEUDOVECTOR, DEFUN): Adapt code to
8 change in pvec_type.
9 (PSEUDOVECTOR_TYPEP): New macro.
10 (TYPED_PSEUDOVECTORP): Use it.
11 * fns.c (internal_equal): Adapt code to extract pvectype.
12 * emacs.c (gdb_pvec_type): Update type.
13 * alloc.c (PSEUDOVECTOR_NBYTES): New macro.
14 (VECTOR_FREE_LIST_SIZE_MASK): Remove (=> PSEUDOVECTOR_SIZE_MASK).
15 (VECTOR_FREE_LIST_FLAG): Remove (=> PVEC_FREE).
16 (SETUP_ON_FREE_LIST): Use XSETPVECTYPESIZE.
17 (sweep_vectors): Use it. Use local var `total_bytes' instead of
18 abusing vector->header.next.nbytes.
19 (live_vector_p): Use PVEC_TYPE.
20 (mark_object): Adapt code to extract pvectype. Use switch.
21
12012-07-04 Paul Eggert <eggert@cs.ucla.edu> 222012-07-04 Paul Eggert <eggert@cs.ucla.edu>
2 23
3 * doprnt.c (doprnt): Don't assume string length fits in 'int'. 24 * doprnt.c (doprnt): Don't assume string length fits in 'int'.
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
diff --git a/src/emacs.c b/src/emacs.c
index 72e280c7409..143a44e0847 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -119,7 +119,7 @@ ptrdiff_t PVEC_FLAG EXTERNALLY_VISIBLE = PSEUDOVECTOR_FLAG;
119ptrdiff_t gdb_array_mark_flag EXTERNALLY_VISIBLE = ARRAY_MARK_FLAG; 119ptrdiff_t gdb_array_mark_flag EXTERNALLY_VISIBLE = ARRAY_MARK_FLAG;
120/* GDB might say "No enum type named pvec_type" if we don't have at 120/* GDB might say "No enum type named pvec_type" if we don't have at
121 least one symbol with that type, and then xbacktrace could fail. */ 121 least one symbol with that type, and then xbacktrace could fail. */
122enum pvec_type gdb_pvec_type EXTERNALLY_VISIBLE = PVEC_TYPE_MASK; 122ptrdiff_t gdb_pvec_type EXTERNALLY_VISIBLE = PVEC_TYPE_MASK;
123 123
124/* Empty lisp strings. To avoid having to build any others. */ 124/* Empty lisp strings. To avoid having to build any others. */
125Lisp_Object empty_unibyte_string, empty_multibyte_string; 125Lisp_Object empty_unibyte_string, empty_multibyte_string;
diff --git a/src/fns.c b/src/fns.c
index 2c6e75e60c5..5ed283a8719 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2095,8 +2095,9 @@ internal_equal (register Lisp_Object o1, register Lisp_Object o2, int depth, int
2095 are sensible to compare, so eliminate the others now. */ 2095 are sensible to compare, so eliminate the others now. */
2096 if (size & PSEUDOVECTOR_FLAG) 2096 if (size & PSEUDOVECTOR_FLAG)
2097 { 2097 {
2098 if (!(size & (PVEC_COMPILED 2098 if (!(size & ((PVEC_COMPILED | PVEC_CHAR_TABLE
2099 | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE | PVEC_FONT))) 2099 | PVEC_SUB_CHAR_TABLE | PVEC_FONT)
2100 << PSEUDOVECTOR_SIZE_BITS)))
2100 return 0; 2101 return 0;
2101 size &= PSEUDOVECTOR_SIZE_MASK; 2102 size &= PSEUDOVECTOR_SIZE_MASK;
2102 } 2103 }
diff --git a/src/lisp.h b/src/lisp.h
index a0d6c6b3c0b..9b2dda244e9 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -341,28 +341,26 @@ typedef EMACS_INT Lisp_Object;
341 It is not crucial, but there are plenty of bits here, so why not do it? */ 341 It is not crucial, but there are plenty of bits here, so why not do it? */
342enum pvec_type 342enum pvec_type
343{ 343{
344 PVEC_NORMAL_VECTOR = 0, 344 PVEC_NORMAL_VECTOR = 0, /* Unused! */
345 PVEC_PROCESS = 0x200, 345 PVEC_FREE,
346 PVEC_FRAME = 0x400, 346 PVEC_PROCESS,
347 PVEC_COMPILED = 0x800, 347 PVEC_FRAME,
348 PVEC_WINDOW = 0x1000, 348 PVEC_WINDOW,
349 PVEC_WINDOW_CONFIGURATION = 0x2000, 349 PVEC_BOOL_VECTOR,
350 PVEC_SUBR = 0x4000, 350 PVEC_BUFFER,
351 PVEC_CHAR_TABLE = 0x8000, 351 PVEC_HASH_TABLE,
352 PVEC_BOOL_VECTOR = 0x10000, 352 PVEC_TERMINAL,
353 PVEC_BUFFER = 0x20000, 353 PVEC_WINDOW_CONFIGURATION,
354 PVEC_HASH_TABLE = 0x40000, 354 PVEC_SUBR,
355 PVEC_TERMINAL = 0x80000, 355 PVEC_OTHER,
356 PVEC_SUB_CHAR_TABLE = 0x100000, 356 /* These last 4 are special because we OR them in fns.c:internal_equal,
357 PVEC_FONT = 0x200000, 357 so they have to use a disjoint bit pattern:
358 PVEC_OTHER = 0x400000, 358 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE
359 PVEC_TYPE_MASK = 0x7ffe00 359 | PVEC_SUB_CHAR_TABLE | PVEC_FONT))) */
360 360 PVEC_COMPILED = 0x10,
361#if 0 /* This is used to make the value of PSEUDOVECTOR_FLAG available to 361 PVEC_CHAR_TABLE = 0x20,
362 GDB. It doesn't work on OS Alpha. Moved to a variable in 362 PVEC_SUB_CHAR_TABLE = 0x30,
363 emacs.c. */ 363 PVEC_FONT = 0x40
364 PVEC_FLAG = PSEUDOVECTOR_FLAG
365#endif
366}; 364};
367 365
368/* For convenience, we also store the number of elements in these bits. 366/* For convenience, we also store the number of elements in these bits.
@@ -370,7 +368,9 @@ enum pvec_type
370 only the number of Lisp_Object fields (that need to be traced by the GC). 368 only the number of Lisp_Object fields (that need to be traced by the GC).
371 The distinction is used e.g. by Lisp_Process which places extra 369 The distinction is used e.g. by Lisp_Process which places extra
372 non-Lisp_Object fields at the end of the structure. */ 370 non-Lisp_Object fields at the end of the structure. */
373#define PSEUDOVECTOR_SIZE_MASK 0x1ff 371#define PSEUDOVECTOR_SIZE_BITS 16
372#define PSEUDOVECTOR_SIZE_MASK ((1 << PSEUDOVECTOR_SIZE_BITS) - 1)
373#define PVEC_TYPE_MASK (0x0fff << PSEUDOVECTOR_SIZE_BITS)
374 374
375/* Number of bits to put in each character in the internal representation 375/* Number of bits to put in each character in the internal representation
376 of bool vectors. This should not vary across implementations. */ 376 of bool vectors. This should not vary across implementations. */
@@ -536,9 +536,11 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
536 536
537#define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE (v, header.size, code) 537#define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE (v, header.size, code)
538#define XSETTYPED_PVECTYPE(v, size_member, code) \ 538#define XSETTYPED_PVECTYPE(v, size_member, code) \
539 ((v)->size_member |= PSEUDOVECTOR_FLAG | (code)) 539 ((v)->size_member |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS))
540#define XSETPVECTYPESIZE(v, code, sizeval) \ 540#define XSETPVECTYPESIZE(v, code, sizeval) \
541 ((v)->header.size = PSEUDOVECTOR_FLAG | (code) | (sizeval)) 541 ((v)->header.size = (PSEUDOVECTOR_FLAG \
542 | ((code) << PSEUDOVECTOR_SIZE_BITS) \
543 | (sizeval)))
542 544
543/* The cast to struct vectorlike_header * avoids aliasing issues. */ 545/* The cast to struct vectorlike_header * avoids aliasing issues. */
544#define XSETPSEUDOVECTOR(a, b, code) \ 546#define XSETPSEUDOVECTOR(a, b, code) \
@@ -550,7 +552,7 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
550#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \ 552#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \
551 (XSETVECTOR (a, b), \ 553 (XSETVECTOR (a, b), \
552 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 554 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
553 == (PSEUDOVECTOR_FLAG | (code)))) 555 == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_SIZE_BITS))))
554 556
555#define XSETWINDOW_CONFIGURATION(a, b) \ 557#define XSETWINDOW_CONFIGURATION(a, b) \
556 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)) 558 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION))
@@ -730,13 +732,13 @@ extern ptrdiff_t string_bytes (struct Lisp_String *);
730/* Set text properties. */ 732/* Set text properties. */
731#define STRING_SET_INTERVALS(STR, INT) (XSTRING (STR)->intervals = (INT)) 733#define STRING_SET_INTERVALS(STR, INT) (XSTRING (STR)->intervals = (INT))
732 734
733/* In a string or vector, the sign bit of the `size' is the gc mark bit */ 735/* In a string or vector, the sign bit of the `size' is the gc mark bit. */
734 736
735struct Lisp_String 737struct Lisp_String
736 { 738 {
737 ptrdiff_t size; 739 ptrdiff_t size;
738 ptrdiff_t size_byte; 740 ptrdiff_t size_byte;
739 INTERVAL intervals; /* text properties in this string */ 741 INTERVAL intervals; /* Text properties in this string. */
740 unsigned char *data; 742 unsigned char *data;
741 }; 743 };
742 744
@@ -749,6 +751,20 @@ struct Lisp_String
749 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */ 751 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */
750struct vectorlike_header 752struct vectorlike_header
751 { 753 {
754 /* This field contains various pieces of information:
755 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
756 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
757 vector (0) or a pseudovector (1).
758 - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
759 of slots) of the vector.
760 - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into
761 a "pvec type" tag held in PVEC_TYPE_MASK and a size held in the lowest
762 PSEUDOVECTOR_SIZE_BITS. That size normally indicates the number of
763 Lisp_Object slots at the beginning of the object that need to be
764 traced by the GC, tho some types use it slightly differently.
765 - E.g. if the pvec type is PVEC_FREE it means this is an unallocated
766 vector on a free-list and PSEUDOVECTOR_SIZE_BITS indicates its size
767 in bytes. */
752 ptrdiff_t size; 768 ptrdiff_t size;
753 769
754 /* When the vector is allocated from a vector block, NBYTES is used 770 /* When the vector is allocated from a vector block, NBYTES is used
@@ -759,8 +775,17 @@ struct vectorlike_header
759 pointer: this way, one can write P->next.vector instead of ((struct 775 pointer: this way, one can write P->next.vector instead of ((struct
760 Lisp_Vector *) P->next). */ 776 Lisp_Vector *) P->next). */
761 union { 777 union {
778 /* This is only needed for small vectors that are not free because the
779 `size' field only gives us the number of Lisp_Object slots, whereas we
780 need to know the total size, including non-Lisp_Object data.
781 FIXME: figure out a way to store this info elsewhere so we can
782 finally get rid of this extra word of overhead. */
762 ptrdiff_t nbytes; 783 ptrdiff_t nbytes;
763 struct buffer *buffer; 784 struct buffer *buffer;
785 /* FIXME: This can be removed: For large vectors, this field could be
786 placed *before* the vector itself. And for small vectors on a free
787 list, this field could be stored in the vector's bytes, since the
788 empty vector is handled specially anyway. */
764 struct Lisp_Vector *vector; 789 struct Lisp_Vector *vector;
765 } next; 790 } next;
766 }; 791 };
@@ -775,7 +800,7 @@ struct Lisp_Vector
775 of the shortest vector that would hold that struct. */ 800 of the shortest vector that would hold that struct. */
776#define VECSIZE(type) ((sizeof (type) \ 801#define VECSIZE(type) ((sizeof (type) \
777 - offsetof (struct Lisp_Vector, contents[0]) \ 802 - offsetof (struct Lisp_Vector, contents[0]) \
778 + sizeof (Lisp_Object) - 1) /* round up */ \ 803 + sizeof (Lisp_Object) - 1) /* Round up. */ \
779 / sizeof (Lisp_Object)) 804 / sizeof (Lisp_Object))
780 805
781/* Like VECSIZE, but used when the pseudo-vector has non-Lisp_Object fields 806/* Like VECSIZE, but used when the pseudo-vector has non-Lisp_Object fields
@@ -1617,15 +1642,17 @@ typedef struct {
1617/* True if object X is a pseudovector whose code is CODE. The cast to struct 1642/* True if object X is a pseudovector whose code is CODE. The cast to struct
1618 vectorlike_header * avoids aliasing issues. */ 1643 vectorlike_header * avoids aliasing issues. */
1619#define PSEUDOVECTORP(x, code) \ 1644#define PSEUDOVECTORP(x, code) \
1620 TYPED_PSEUDOVECTORP(x, vectorlike_header, code) 1645 TYPED_PSEUDOVECTORP (x, vectorlike_header, code)
1646
1647#define PSEUDOVECTOR_TYPEP(v, code) \
1648 (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
1649 == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS)))
1621 1650
1622/* True if object X, with internal type struct T *, is a pseudovector whose 1651/* True if object X, with internal type struct T *, is a pseudovector whose
1623 code is CODE. */ 1652 code is CODE. */
1624#define TYPED_PSEUDOVECTORP(x, t, code) \ 1653#define TYPED_PSEUDOVECTORP(x, t, code) \
1625 (VECTORLIKEP (x) \ 1654 (VECTORLIKEP (x) \
1626 && (((((struct t *) XUNTAG (x, Lisp_Vectorlike))->size \ 1655 && PSEUDOVECTOR_TYPEP ((struct t *) XUNTAG (x, Lisp_Vectorlike), code))
1627 & (PSEUDOVECTOR_FLAG | (code)))) \
1628 == (PSEUDOVECTOR_FLAG | (code))))
1629 1656
1630/* Test for specific pseudovector types. */ 1657/* Test for specific pseudovector types. */
1631#define WINDOW_CONFIGURATIONP(x) PSEUDOVECTORP (x, PVEC_WINDOW_CONFIGURATION) 1658#define WINDOW_CONFIGURATIONP(x) PSEUDOVECTORP (x, PVEC_WINDOW_CONFIGURATION)
@@ -1818,7 +1845,8 @@ typedef struct {
1818#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1845#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1819 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1846 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1820 static DECL_ALIGN (struct Lisp_Subr, sname) = \ 1847 static DECL_ALIGN (struct Lisp_Subr, sname) = \
1821 { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \ 1848 { (PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS) \
1849 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \
1822 { (Lisp_Object (__cdecl *)(void))fnname }, \ 1850 { (Lisp_Object (__cdecl *)(void))fnname }, \
1823 minargs, maxargs, lname, intspec, 0}; \ 1851 minargs, maxargs, lname, intspec, 0}; \
1824 Lisp_Object fnname 1852 Lisp_Object fnname
@@ -1826,7 +1854,7 @@ typedef struct {
1826#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1854#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1827 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1855 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1828 static DECL_ALIGN (struct Lisp_Subr, sname) = \ 1856 static DECL_ALIGN (struct Lisp_Subr, sname) = \
1829 { PVEC_SUBR, \ 1857 { PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS, \
1830 { .a ## maxargs = fnname }, \ 1858 { .a ## maxargs = fnname }, \
1831 minargs, maxargs, lname, intspec, 0}; \ 1859 minargs, maxargs, lname, intspec, 0}; \
1832 Lisp_Object fnname 1860 Lisp_Object fnname