diff options
| author | Gerd Moellmann | 2001-01-09 20:10:50 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2001-01-09 20:10:50 +0000 |
| commit | 676a72518a2d168ba02311922e6d5cf8f3504f76 (patch) | |
| tree | 80a2ff9a4677cece6ac940e57ab63d7ef020d7e3 /src/alloc.c | |
| parent | 2bef3a39ac12364efa7ce6dec26a92f2afd3940d (diff) | |
| download | emacs-676a72518a2d168ba02311922e6d5cf8f3504f76.tar.gz emacs-676a72518a2d168ba02311922e6d5cf8f3504f76.zip | |
(CHECK_STRING_BYTES) [GC_CHECK_STRING_BYTES]: New macro.
(check_sblock, string_bytes) [GC_CHECK_STRING_BYTES]: New functions.
(check_string_bytes) [GC_CHECK_STRING_BYTES]: Add parameter ALL_P.
(allocate_string) [GC_CHECK_STRING_BYTES]: Always check strings in
the current sblock.
(mark_object) [GC_CHECK_STRING_BYTES]: Use CHECK_STRING_BYTES.
(gc_sweep) [GC_CHECK_STRING_BYTES]: Call check_string_bytes
after sweeping strings, and at the end.
(GC_CHECK_STRING_BYTES): Moved to lisp.h.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 138 |
1 files changed, 88 insertions, 50 deletions
diff --git a/src/alloc.c b/src/alloc.c index 8685496a515..b516695c0dd 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -26,12 +26,6 @@ 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 redundantly recorded in sdata structures so that it can | ||
| 31 | be compared to the sizes recorded in Lisp strings. */ | ||
| 32 | |||
| 33 | #define GC_CHECK_STRING_BYTES 1 | ||
| 34 | |||
| 35 | /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd | 29 | /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd |
| 36 | memory. Can do this only if using gmalloc.c. */ | 30 | memory. Can do this only if using gmalloc.c. */ |
| 37 | 31 | ||
| @@ -1201,50 +1195,84 @@ init_strings () | |||
| 1201 | 1195 | ||
| 1202 | #ifdef GC_CHECK_STRING_BYTES | 1196 | #ifdef GC_CHECK_STRING_BYTES |
| 1203 | 1197 | ||
| 1204 | /* Check validity of all live Lisp strings' string_bytes member. | ||
| 1205 | Used for hunting a bug. */ | ||
| 1206 | |||
| 1207 | static int check_string_bytes_count; | 1198 | static int check_string_bytes_count; |
| 1208 | 1199 | ||
| 1200 | void check_string_bytes P_ ((int)); | ||
| 1201 | void check_sblock P_ ((struct sblock *)); | ||
| 1202 | |||
| 1203 | #define CHECK_STRING_BYTES(S) STRING_BYTES (S) | ||
| 1204 | |||
| 1205 | |||
| 1206 | /* Like GC_STRING_BYTES, but with debugging check. */ | ||
| 1207 | |||
| 1208 | int | ||
| 1209 | string_bytes (s) | ||
| 1210 | struct Lisp_String *s; | ||
| 1211 | { | ||
| 1212 | int nbytes = (s->size_byte < 0 ? s->size : s->size_byte) & ~MARKBIT; | ||
| 1213 | if (!PURE_POINTER_P (s) | ||
| 1214 | && s->data | ||
| 1215 | && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) | ||
| 1216 | abort (); | ||
| 1217 | return nbytes; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | /* Check validity Lisp strings' string_bytes member in B. */ | ||
| 1221 | |||
| 1209 | void | 1222 | void |
| 1210 | check_string_bytes () | 1223 | check_sblock (b) |
| 1224 | struct sblock *b; | ||
| 1211 | { | 1225 | { |
| 1212 | struct sblock *b; | 1226 | struct sdata *from, *end, *from_end; |
| 1213 | |||
| 1214 | for (b = large_sblocks; b; b = b->next) | ||
| 1215 | { | ||
| 1216 | struct Lisp_String *s = b->first_data.string; | ||
| 1217 | if (s && GC_STRING_BYTES (s) != SDATA_NBYTES (SDATA_OF_STRING (s))) | ||
| 1218 | abort (); | ||
| 1219 | } | ||
| 1220 | 1227 | ||
| 1221 | for (b = oldest_sblock; b; b = b->next) | 1228 | end = b->next_free; |
| 1229 | |||
| 1230 | for (from = &b->first_data; from < end; from = from_end) | ||
| 1222 | { | 1231 | { |
| 1223 | struct sdata *from, *end, *from_end; | 1232 | /* Compute the next FROM here because copying below may |
| 1233 | overwrite data we need to compute it. */ | ||
| 1234 | int nbytes; | ||
| 1224 | 1235 | ||
| 1225 | end = b->next_free; | 1236 | /* Check that the string size recorded in the string is the |
| 1237 | same as the one recorded in the sdata structure. */ | ||
| 1238 | if (from->string) | ||
| 1239 | CHECK_STRING_BYTES (from->string); | ||
| 1226 | 1240 | ||
| 1227 | for (from = &b->first_data; from < end; from = from_end) | 1241 | if (from->string) |
| 1228 | { | 1242 | nbytes = GC_STRING_BYTES (from->string); |
| 1229 | /* Compute the next FROM here because copying below may | 1243 | else |
| 1230 | overwrite data we need to compute it. */ | 1244 | nbytes = SDATA_NBYTES (from); |
| 1231 | int nbytes; | 1245 | |
| 1246 | nbytes = SDATA_SIZE (nbytes); | ||
| 1247 | from_end = (struct sdata *) ((char *) from + nbytes); | ||
| 1248 | } | ||
| 1249 | } | ||
| 1232 | 1250 | ||
| 1233 | /* Check that the string size recorded in the string is the | 1251 | |
| 1234 | same as the one recorded in the sdata structure. */ | 1252 | /* Check validity of Lisp strings' string_bytes member. ALL_P |
| 1235 | if (from->string | 1253 | non-zero means check all strings, otherwise check only most |
| 1236 | && GC_STRING_BYTES (from->string) != SDATA_NBYTES (from)) | 1254 | recently allocated strings. Used for hunting a bug. */ |
| 1237 | abort (); | 1255 | |
| 1238 | 1256 | void | |
| 1239 | if (from->string) | 1257 | check_string_bytes (all_p) |
| 1240 | nbytes = GC_STRING_BYTES (from->string); | 1258 | int all_p; |
| 1241 | else | 1259 | { |
| 1242 | nbytes = SDATA_NBYTES (from); | 1260 | if (all_p) |
| 1243 | 1261 | { | |
| 1244 | nbytes = SDATA_SIZE (nbytes); | 1262 | struct sblock *b; |
| 1245 | from_end = (struct sdata *) ((char *) from + nbytes); | 1263 | |
| 1264 | for (b = large_sblocks; b; b = b->next) | ||
| 1265 | { | ||
| 1266 | struct Lisp_String *s = b->first_data.string; | ||
| 1267 | if (s) | ||
| 1268 | CHECK_STRING_BYTES (s); | ||
| 1246 | } | 1269 | } |
| 1270 | |||
| 1271 | for (b = oldest_sblock; b; b = b->next) | ||
| 1272 | check_sblock (b); | ||
| 1247 | } | 1273 | } |
| 1274 | else | ||
| 1275 | check_sblock (current_sblock); | ||
| 1248 | } | 1276 | } |
| 1249 | 1277 | ||
| 1250 | #endif /* GC_CHECK_STRING_BYTES */ | 1278 | #endif /* GC_CHECK_STRING_BYTES */ |
| @@ -1294,12 +1322,17 @@ allocate_string () | |||
| 1294 | consing_since_gc += sizeof *s; | 1322 | consing_since_gc += sizeof *s; |
| 1295 | 1323 | ||
| 1296 | #ifdef GC_CHECK_STRING_BYTES | 1324 | #ifdef GC_CHECK_STRING_BYTES |
| 1297 | if (!noninteractive && ++check_string_bytes_count == 50) | 1325 | if (!noninteractive) |
| 1298 | { | 1326 | { |
| 1299 | check_string_bytes_count = 0; | 1327 | if (++check_string_bytes_count == 200) |
| 1300 | check_string_bytes (); | 1328 | { |
| 1329 | check_string_bytes_count = 0; | ||
| 1330 | check_string_bytes (1); | ||
| 1331 | } | ||
| 1332 | else | ||
| 1333 | check_string_bytes (0); | ||
| 1301 | } | 1334 | } |
| 1302 | #endif | 1335 | #endif /* GC_CHECK_STRING_BYTES */ |
| 1303 | 1336 | ||
| 1304 | return s; | 1337 | return s; |
| 1305 | } | 1338 | } |
| @@ -4111,13 +4144,9 @@ mark_object (argptr) | |||
| 4111 | MARK_INTERVAL_TREE (ptr->intervals); | 4144 | MARK_INTERVAL_TREE (ptr->intervals); |
| 4112 | MARK_STRING (ptr); | 4145 | MARK_STRING (ptr); |
| 4113 | #ifdef GC_CHECK_STRING_BYTES | 4146 | #ifdef GC_CHECK_STRING_BYTES |
| 4114 | { | 4147 | /* Check that the string size recorded in the string is the |
| 4115 | /* Check that the string size recorded in the string is the | 4148 | same as the one recorded in the sdata structure. */ |
| 4116 | same as the one recorded in the sdata structure. */ | 4149 | CHECK_STRING_BYTES (ptr); |
| 4117 | struct sdata *p = SDATA_OF_STRING (ptr); | ||
| 4118 | if (GC_STRING_BYTES (ptr) != SDATA_NBYTES (p)) | ||
| 4119 | abort (); | ||
| 4120 | } | ||
| 4121 | #endif /* GC_CHECK_STRING_BYTES */ | 4150 | #endif /* GC_CHECK_STRING_BYTES */ |
| 4122 | } | 4151 | } |
| 4123 | break; | 4152 | break; |
| @@ -4608,6 +4637,10 @@ gc_sweep () | |||
| 4608 | sweep_weak_hash_tables (); | 4637 | sweep_weak_hash_tables (); |
| 4609 | 4638 | ||
| 4610 | sweep_strings (); | 4639 | sweep_strings (); |
| 4640 | #ifdef GC_CHECK_STRING_BYTES | ||
| 4641 | if (!noninteractive) | ||
| 4642 | check_string_bytes (1); | ||
| 4643 | #endif | ||
| 4611 | 4644 | ||
| 4612 | /* Put all unmarked conses on free list */ | 4645 | /* Put all unmarked conses on free list */ |
| 4613 | { | 4646 | { |
| @@ -4960,6 +4993,11 @@ gc_sweep () | |||
| 4960 | prev = vector, vector = vector->next; | 4993 | prev = vector, vector = vector->next; |
| 4961 | } | 4994 | } |
| 4962 | } | 4995 | } |
| 4996 | |||
| 4997 | #ifdef GC_CHECK_STRING_BYTES | ||
| 4998 | if (!noninteractive) | ||
| 4999 | check_string_bytes (1); | ||
| 5000 | #endif | ||
| 4963 | } | 5001 | } |
| 4964 | 5002 | ||
| 4965 | 5003 | ||