diff options
| author | Gerd Moellmann | 2000-09-26 11:12:19 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-09-26 11:12:19 +0000 |
| commit | 31d929e56d19e9f6610a69b921742ef570a3ce95 (patch) | |
| tree | 1b00ce6c20906669a24ea11e7966412226643373 /src/alloc.c | |
| parent | cd3b81be39042964eca4f36f334ab28168f1588e (diff) | |
| download | emacs-31d929e56d19e9f6610a69b921742ef570a3ce95.tar.gz emacs-31d929e56d19e9f6610a69b921742ef570a3ce95.zip | |
(GC_CHECK_STRING_BYTES): Temporarily define, for bug
hunting.
(struct sdata) [GC_CHECK_STRING_BYTES]: Always record the string's
size in the sdata structure.
(SDATA_NBYTES, SDATA_DATA): New macros.
(SDATA_OF_STRING, SDATA_SIZE) [GC_CHECK_STRING_BYTES]: Define
differently for the different layout of the sdata structure.
(allocate_string_data) [GC_CHECK_STRING_BYTES]: Record string size
in sdata.
(sweep_strings, compact_small_strings) [GC_CHECK_STRING_BYTES]:
Check that size recorded in the string size and size recorded in
the sdata structure agree.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c index eaf883a7821..fc8787670e6 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -26,6 +26,12 @@ Boston, MA 02111-1307, USA. */ | |||
| 26 | 26 | ||
| 27 | #include <signal.h> | 27 | #include <signal.h> |
| 28 | 28 | ||
| 29 | /* Define this temporarily to hunt a bug. If defined, the size of | ||
| 30 | strings is always recorded in sdata structures so that it can be | ||
| 31 | compared to the sizes recorded in Lisp strings. */ | ||
| 32 | |||
| 33 | #define GC_CHECK_STRING_BYTES 1 | ||
| 34 | |||
| 29 | /* This file is part of the core Lisp implementation, and thus must | 35 | /* This file is part of the core Lisp implementation, and thus must |
| 30 | deal with the real data structures. If the Lisp implementation is | 36 | deal with the real data structures. If the Lisp implementation is |
| 31 | replaced, this file likely will not be used. */ | 37 | replaced, this file likely will not be used. */ |
| @@ -868,6 +874,16 @@ struct sdata | |||
| 868 | contents. */ | 874 | contents. */ |
| 869 | struct Lisp_String *string; | 875 | struct Lisp_String *string; |
| 870 | 876 | ||
| 877 | #ifdef GC_CHECK_STRING_BYTES | ||
| 878 | |||
| 879 | EMACS_INT nbytes; | ||
| 880 | unsigned char data[1]; | ||
| 881 | |||
| 882 | #define SDATA_NBYTES(S) (S)->nbytes | ||
| 883 | #define SDATA_DATA(S) (S)->data | ||
| 884 | |||
| 885 | #else /* not GC_CHECK_STRING_BYTES */ | ||
| 886 | |||
| 871 | union | 887 | union |
| 872 | { | 888 | { |
| 873 | /* When STRING in non-null. */ | 889 | /* When STRING in non-null. */ |
| @@ -876,8 +892,15 @@ struct sdata | |||
| 876 | /* When STRING is null. */ | 892 | /* When STRING is null. */ |
| 877 | EMACS_INT nbytes; | 893 | EMACS_INT nbytes; |
| 878 | } u; | 894 | } u; |
| 895 | |||
| 896 | |||
| 897 | #define SDATA_NBYTES(S) (S)->u.nbytes | ||
| 898 | #define SDATA_DATA(S) (S)->u.data | ||
| 899 | |||
| 900 | #endif /* not GC_CHECK_STRING_BYTES */ | ||
| 879 | }; | 901 | }; |
| 880 | 902 | ||
| 903 | |||
| 881 | /* Structure describing a block of memory which is sub-allocated to | 904 | /* Structure describing a block of memory which is sub-allocated to |
| 882 | obtain string data memory for strings. Blocks for small strings | 905 | obtain string data memory for strings. Blocks for small strings |
| 883 | are of fixed size SBLOCK_SIZE. Blocks for large strings are made | 906 | are of fixed size SBLOCK_SIZE. Blocks for large strings are made |
| @@ -949,19 +972,41 @@ static int total_string_size; | |||
| 949 | a pointer to the `u.data' member of its sdata structure; the | 972 | a pointer to the `u.data' member of its sdata structure; the |
| 950 | structure starts at a constant offset in front of that. */ | 973 | structure starts at a constant offset in front of that. */ |
| 951 | 974 | ||
| 975 | #ifdef GC_CHECK_STRING_BYTES | ||
| 976 | |||
| 977 | #define SDATA_OF_STRING(S) \ | ||
| 978 | ((struct sdata *) ((S)->data - sizeof (struct Lisp_String *) \ | ||
| 979 | - sizeof (EMACS_INT))) | ||
| 980 | |||
| 981 | #else /* not GC_CHECK_STRING_BYTES */ | ||
| 982 | |||
| 952 | #define SDATA_OF_STRING(S) \ | 983 | #define SDATA_OF_STRING(S) \ |
| 953 | ((struct sdata *) ((S)->data - sizeof (struct Lisp_String *))) | 984 | ((struct sdata *) ((S)->data - sizeof (struct Lisp_String *))) |
| 954 | 985 | ||
| 986 | #endif /* not GC_CHECK_STRING_BYTES */ | ||
| 987 | |||
| 955 | /* Value is the size of an sdata structure large enough to hold NBYTES | 988 | /* Value is the size of an sdata structure large enough to hold NBYTES |
| 956 | bytes of string data. The value returned includes a terminating | 989 | bytes of string data. The value returned includes a terminating |
| 957 | NUL byte, the size of the sdata structure, and padding. */ | 990 | NUL byte, the size of the sdata structure, and padding. */ |
| 958 | 991 | ||
| 992 | #ifdef GC_CHECK_STRING_BYTES | ||
| 993 | |||
| 994 | #define SDATA_SIZE(NBYTES) \ | ||
| 995 | ((sizeof (struct Lisp_String *) \ | ||
| 996 | + (NBYTES) + 1 \ | ||
| 997 | + sizeof (EMACS_INT) \ | ||
| 998 | + sizeof (EMACS_INT) - 1) \ | ||
| 999 | & ~(sizeof (EMACS_INT) - 1)) | ||
| 1000 | |||
| 1001 | #else /* not GC_CHECK_STRING_BYTES */ | ||
| 1002 | |||
| 959 | #define SDATA_SIZE(NBYTES) \ | 1003 | #define SDATA_SIZE(NBYTES) \ |
| 960 | ((sizeof (struct Lisp_String *) \ | 1004 | ((sizeof (struct Lisp_String *) \ |
| 961 | + (NBYTES) + 1 \ | 1005 | + (NBYTES) + 1 \ |
| 962 | + sizeof (EMACS_INT) - 1) \ | 1006 | + sizeof (EMACS_INT) - 1) \ |
| 963 | & ~(sizeof (EMACS_INT) - 1)) | 1007 | & ~(sizeof (EMACS_INT) - 1)) |
| 964 | 1008 | ||
| 1009 | #endif /* not GC_CHECK_STRING_BYTES */ | ||
| 965 | 1010 | ||
| 966 | /* Initialize string allocation. Called from init_alloc_once. */ | 1011 | /* Initialize string allocation. Called from init_alloc_once. */ |
| 967 | 1012 | ||
| @@ -1090,7 +1135,10 @@ allocate_string_data (s, nchars, nbytes) | |||
| 1090 | 1135 | ||
| 1091 | data = b->next_free; | 1136 | data = b->next_free; |
| 1092 | data->string = s; | 1137 | data->string = s; |
| 1093 | s->data = data->u.data; | 1138 | s->data = SDATA_DATA (data); |
| 1139 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1140 | SDATA_NBYTES (data) = nbytes; | ||
| 1141 | #endif | ||
| 1094 | s->size = nchars; | 1142 | s->size = nchars; |
| 1095 | s->size_byte = nbytes; | 1143 | s->size_byte = nbytes; |
| 1096 | s->data[nbytes] = '\0'; | 1144 | s->data[nbytes] = '\0'; |
| @@ -1101,7 +1149,7 @@ allocate_string_data (s, nchars, nbytes) | |||
| 1101 | in it. */ | 1149 | in it. */ |
| 1102 | if (old_data) | 1150 | if (old_data) |
| 1103 | { | 1151 | { |
| 1104 | old_data->u.nbytes = old_nbytes; | 1152 | SDATA_NBYTES (old_data) = old_nbytes; |
| 1105 | old_data->string = NULL; | 1153 | old_data->string = NULL; |
| 1106 | } | 1154 | } |
| 1107 | 1155 | ||
| @@ -1155,7 +1203,12 @@ sweep_strings () | |||
| 1155 | /* Save the size of S in its sdata so that we know | 1203 | /* Save the size of S in its sdata so that we know |
| 1156 | how large that is. Reset the sdata's string | 1204 | how large that is. Reset the sdata's string |
| 1157 | back-pointer so that we know it's free. */ | 1205 | back-pointer so that we know it's free. */ |
| 1206 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1207 | if (GC_STRING_BYTES (s) != SDATA_NBYTES (data)) | ||
| 1208 | abort (); | ||
| 1209 | #else | ||
| 1158 | data->u.nbytes = GC_STRING_BYTES (s); | 1210 | data->u.nbytes = GC_STRING_BYTES (s); |
| 1211 | #endif | ||
| 1159 | data->string = NULL; | 1212 | data->string = NULL; |
| 1160 | 1213 | ||
| 1161 | /* Reset the strings's `data' member so that we | 1214 | /* Reset the strings's `data' member so that we |
| @@ -1255,10 +1308,18 @@ compact_small_strings () | |||
| 1255 | overwrite data we need to compute it. */ | 1308 | overwrite data we need to compute it. */ |
| 1256 | int nbytes; | 1309 | int nbytes; |
| 1257 | 1310 | ||
| 1311 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1312 | /* Check that the string size recorded in the string is the | ||
| 1313 | same as the one recorded in the sdata structure. */ | ||
| 1314 | if (from->string | ||
| 1315 | && GC_STRING_BYTES (from->string) != SDATA_NBYTES (from)) | ||
| 1316 | abort (); | ||
| 1317 | #endif /* GC_CHECK_STRING_BYTES */ | ||
| 1318 | |||
| 1258 | if (from->string) | 1319 | if (from->string) |
| 1259 | nbytes = GC_STRING_BYTES (from->string); | 1320 | nbytes = GC_STRING_BYTES (from->string); |
| 1260 | else | 1321 | else |
| 1261 | nbytes = from->u.nbytes; | 1322 | nbytes = SDATA_NBYTES (from); |
| 1262 | 1323 | ||
| 1263 | nbytes = SDATA_SIZE (nbytes); | 1324 | nbytes = SDATA_SIZE (nbytes); |
| 1264 | from_end = (struct sdata *) ((char *) from + nbytes); | 1325 | from_end = (struct sdata *) ((char *) from + nbytes); |
| @@ -1282,7 +1343,7 @@ compact_small_strings () | |||
| 1282 | { | 1343 | { |
| 1283 | xassert (tb != b || to <= from); | 1344 | xassert (tb != b || to <= from); |
| 1284 | safe_bcopy ((char *) from, (char *) to, nbytes); | 1345 | safe_bcopy ((char *) from, (char *) to, nbytes); |
| 1285 | to->string->data = to->u.data; | 1346 | to->string->data = SDATA_DATA (to); |
| 1286 | } | 1347 | } |
| 1287 | 1348 | ||
| 1288 | /* Advance past the sdata we copied to. */ | 1349 | /* Advance past the sdata we copied to. */ |
| @@ -2934,6 +2995,7 @@ mark_maybe_object (obj) | |||
| 2934 | break; | 2995 | break; |
| 2935 | 2996 | ||
| 2936 | case Lisp_Int: | 2997 | case Lisp_Int: |
| 2998 | case Lisp_Type_Limit: | ||
| 2937 | break; | 2999 | break; |
| 2938 | } | 3000 | } |
| 2939 | 3001 | ||