comparison src/alloc.c @ 5125:b5df3737028a ben-lisp-object

merge
author Ben Wing <ben@xemacs.org>
date Wed, 24 Feb 2010 01:58:04 -0600
parents 623d57b7fbe8 2ade80e8c640
children 2a462149bd6a
comparison
equal deleted inserted replaced
5124:623d57b7fbe8 5125:b5df3737028a
68 #endif /* NEW_GC */ 68 #endif /* NEW_GC */
69 #include "console-stream.h" 69 #include "console-stream.h"
70 70
71 #ifdef DOUG_LEA_MALLOC 71 #ifdef DOUG_LEA_MALLOC
72 #include <malloc.h> 72 #include <malloc.h>
73 #endif
74 #ifdef USE_VALGRIND
75 #include <valgrind/memcheck.h>
73 #endif 76 #endif
74 77
75 EXFUN (Fgarbage_collect, 0); 78 EXFUN (Fgarbage_collect, 0);
76 79
77 #if 0 /* this is _way_ too slow to be part of the standard debug options */ 80 #if 0 /* this is _way_ too slow to be part of the standard debug options */
224 { 227 {
225 if (breathing_space) 228 if (breathing_space)
226 { 229 {
227 void *tmp = breathing_space; 230 void *tmp = breathing_space;
228 breathing_space = 0; 231 breathing_space = 0;
229 xfree (tmp, void *); 232 xfree (tmp);
230 } 233 }
231 } 234 }
232 #endif /* not NEW_GC */ 235 #endif /* not NEW_GC */
233 236
234 static void 237 static void
267 do \ 270 do \
268 { \ 271 { \
269 /* Unbelievably, calling free() on 0xDEADBEEF doesn't cause an \ 272 /* Unbelievably, calling free() on 0xDEADBEEF doesn't cause an \
270 error until much later on for many system mallocs, such as \ 273 error until much later on for many system mallocs, such as \
271 the one that comes with Solaris 2.3. FMH!! */ \ 274 the one that comes with Solaris 2.3. FMH!! */ \
272 assert (block != (void *) 0xDEADBEEF); \ 275 assert (block != (void *) DEADBEEF_CONSTANT); \
273 MALLOC_BEGIN (); \ 276 MALLOC_BEGIN (); \
274 } \ 277 } \
275 while (0) 278 while (0)
276 #else /* not NEW_GC */ 279 #else /* not NEW_GC */
277 #define FREE_OR_REALLOC_BEGIN(block) \ 280 #define FREE_OR_REALLOC_BEGIN(block) \
278 do \ 281 do \
279 { \ 282 { \
280 /* Unbelievably, calling free() on 0xDEADBEEF doesn't cause an \ 283 /* Unbelievably, calling free() on 0xDEADBEEF doesn't cause an \
281 error until much later on for many system mallocs, such as \ 284 error until much later on for many system mallocs, such as \
282 the one that comes with Solaris 2.3. FMH!! */ \ 285 the one that comes with Solaris 2.3. FMH!! */ \
283 assert (block != (void *) 0xDEADBEEF); \ 286 assert (block != (void *) DEADBEEF_CONSTANT); \
284 /* You cannot free something within dumped space, because there is \ 287 /* You cannot free something within dumped space, because there is \
285 no longer any sort of malloc structure associated with the block. \ 288 no longer any sort of malloc structure associated with the block. \
286 If you are tripping this, you may need to conditionalize on \ 289 If you are tripping this, you may need to conditionalize on \
287 DUMPEDP. */ \ 290 DUMPEDP. */ \
288 assert (!DUMPEDP (block)); \ 291 assert (!DUMPEDP (block)); \
1253 mark_object (XCAR (obj)); 1256 mark_object (XCAR (obj));
1254 return XCDR (obj); 1257 return XCDR (obj);
1255 } 1258 }
1256 1259
1257 static int 1260 static int
1258 cons_equal (Lisp_Object ob1, Lisp_Object ob2, int depth) 1261 cons_equal (Lisp_Object ob1, Lisp_Object ob2, int depth, int foldcase)
1259 { 1262 {
1260 depth++; 1263 depth++;
1261 while (internal_equal (XCAR (ob1), XCAR (ob2), depth)) 1264 while (internal_equal_0 (XCAR (ob1), XCAR (ob2), depth, foldcase))
1262 { 1265 {
1263 ob1 = XCDR (ob1); 1266 ob1 = XCDR (ob1);
1264 ob2 = XCDR (ob2); 1267 ob2 = XCDR (ob2);
1265 if (! CONSP (ob1) || ! CONSP (ob2)) 1268 if (! CONSP (ob1) || ! CONSP (ob2))
1266 return internal_equal (ob1, ob2, depth); 1269 return internal_equal_0 (ob1, ob2, depth, foldcase);
1267 } 1270 }
1268 return 0; 1271 return 0;
1269 } 1272 }
1270 1273
1271 static const struct memory_description cons_description[] = { 1274 static const struct memory_description cons_description[] = {
1573 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, contents, 1576 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, contents,
1574 ((Lisp_Vector *) lheader)->size); 1577 ((Lisp_Vector *) lheader)->size);
1575 } 1578 }
1576 1579
1577 static int 1580 static int
1578 vector_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) 1581 vector_equal (Lisp_Object obj1, Lisp_Object obj2, int depth, int foldcase)
1579 { 1582 {
1580 int len = XVECTOR_LENGTH (obj1); 1583 int len = XVECTOR_LENGTH (obj1);
1581 if (len != XVECTOR_LENGTH (obj2)) 1584 if (len != XVECTOR_LENGTH (obj2))
1582 return 0; 1585 return 0;
1583 1586
1584 { 1587 {
1585 Lisp_Object *ptr1 = XVECTOR_DATA (obj1); 1588 Lisp_Object *ptr1 = XVECTOR_DATA (obj1);
1586 Lisp_Object *ptr2 = XVECTOR_DATA (obj2); 1589 Lisp_Object *ptr2 = XVECTOR_DATA (obj2);
1587 while (len--) 1590 while (len--)
1588 if (!internal_equal (*ptr1++, *ptr2++, depth + 1)) 1591 if (!internal_equal_0 (*ptr1++, *ptr2++, depth + 1, foldcase))
1589 return 0; 1592 return 0;
1590 } 1593 }
1591 return 1; 1594 return 1;
1592 } 1595 }
1593 1596
1955 1958
1956 CHECK_NATNUM (stack_depth); 1959 CHECK_NATNUM (stack_depth);
1957 f->stack_depth = (unsigned short) XINT (stack_depth); 1960 f->stack_depth = (unsigned short) XINT (stack_depth);
1958 1961
1959 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK 1962 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK
1960 if (!NILP (Vcurrent_compiled_function_annotation)) 1963 f->annotated = Vload_file_name_internal;
1961 f->annotated = Fcopy (Vcurrent_compiled_function_annotation);
1962 else if (!NILP (Vload_file_name_internal_the_purecopy))
1963 f->annotated = Vload_file_name_internal_the_purecopy;
1964 else if (!NILP (Vload_file_name_internal))
1965 {
1966 struct gcpro gcpro1;
1967 GCPRO1 (fun); /* don't let fun get reaped */
1968 Vload_file_name_internal_the_purecopy =
1969 Ffile_name_nondirectory (Vload_file_name_internal);
1970 f->annotated = Vload_file_name_internal_the_purecopy;
1971 UNGCPRO;
1972 }
1973 #endif /* COMPILED_FUNCTION_ANNOTATION_HACK */ 1964 #endif /* COMPILED_FUNCTION_ANNOTATION_HACK */
1974 1965
1975 /* doc_string may be nil, string, int, or a cons (string . int). 1966 /* doc_string may be nil, string, int, or a cons (string . int).
1976 interactive may be list or string (or unbound). */ 1967 interactive may be list or string (or unbound). */
1977 f->doc_and_interactive = Qunbound; 1968 f->doc_and_interactive = Qunbound;
2276 flush_cached_extent_info (XCAR (XSTRING_PLIST (obj))); 2267 flush_cached_extent_info (XCAR (XSTRING_PLIST (obj)));
2277 return XSTRING_PLIST (obj); 2268 return XSTRING_PLIST (obj);
2278 } 2269 }
2279 2270
2280 static int 2271 static int
2281 string_equal (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth)) 2272 string_equal (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth),
2273 int foldcase)
2282 { 2274 {
2283 Bytecount len; 2275 Bytecount len;
2284 return (((len = XSTRING_LENGTH (obj1)) == XSTRING_LENGTH (obj2)) && 2276 if (foldcase)
2285 !memcmp (XSTRING_DATA (obj1), XSTRING_DATA (obj2), len)); 2277 return !lisp_strcasecmp_i18n (obj1, obj2);
2278 else
2279 return (((len = XSTRING_LENGTH (obj1)) == XSTRING_LENGTH (obj2)) &&
2280 !memcmp (XSTRING_DATA (obj1), XSTRING_DATA (obj2), len));
2286 } 2281 }
2287 2282
2288 static const struct memory_description string_description[] = { 2283 static const struct memory_description string_description[] = {
2289 #ifdef NEW_GC 2284 #ifdef NEW_GC
2290 { XD_LISP_OBJECT, offsetof (Lisp_String, data_object) }, 2285 { XD_LISP_OBJECT, offsetof (Lisp_String, data_object) },
2678 memcpy (new_data, old_data, pos); 2673 memcpy (new_data, old_data, pos);
2679 memcpy (new_data + pos + delta, old_data + pos, 2674 memcpy (new_data + pos + delta, old_data + pos,
2680 XSTRING_LENGTH (s) + 1 - pos); 2675 XSTRING_LENGTH (s) + 1 - pos);
2681 } 2676 }
2682 XSET_STRING_DATA (s, new_data); 2677 XSET_STRING_DATA (s, new_data);
2683 xfree (old_data, Ibyte *); 2678 xfree (old_data);
2684 } 2679 }
2685 } 2680 }
2686 else /* old string is small */ 2681 else /* old string is small */
2687 { 2682 {
2688 if (oldfullsize == newfullsize) 2683 if (oldfullsize == newfullsize)
2896 } 2891 }
2897 2892
2898 /* Take some raw memory, encoded in some external data format, 2893 /* Take some raw memory, encoded in some external data format,
2899 and convert it into a Lisp string. */ 2894 and convert it into a Lisp string. */
2900 Lisp_Object 2895 Lisp_Object
2901 make_ext_string (const Extbyte *contents, EMACS_INT length, 2896 make_extstring (const Extbyte *contents, EMACS_INT length,
2902 Lisp_Object coding_system) 2897 Lisp_Object coding_system)
2903 { 2898 {
2904 Lisp_Object string; 2899 Lisp_Object string;
2905 TO_INTERNAL_FORMAT (DATA, (contents, length), 2900 TO_INTERNAL_FORMAT (DATA, (contents, length),
2906 LISP_STRING, string, 2901 LISP_STRING, string,
2907 coding_system); 2902 coding_system);
2908 return string; 2903 return string;
2909 } 2904 }
2910 2905
2911 Lisp_Object 2906 Lisp_Object
2912 build_intstring (const Ibyte *str) 2907 build_istring (const Ibyte *str)
2913 { 2908 {
2914 /* Some strlen's crash and burn if passed null. */ 2909 /* Some strlen's crash and burn if passed null. */
2915 return make_string (str, (str ? qxestrlen (str) : (Bytecount) 0)); 2910 return make_string (str, (str ? qxestrlen (str) : (Bytecount) 0));
2916 } 2911 }
2917 2912
2918 Lisp_Object 2913 Lisp_Object
2919 build_string (const CIbyte *str) 2914 build_cistring (const CIbyte *str)
2915 {
2916 return build_istring ((const Ibyte *) str);
2917 }
2918
2919 Lisp_Object
2920 build_ascstring (const Ascbyte *str)
2921 {
2922 ASSERT_ASCTEXT_ASCII (str);
2923 return build_istring ((const Ibyte *) str);
2924 }
2925
2926 Lisp_Object
2927 build_extstring (const Extbyte *str, Lisp_Object coding_system)
2920 { 2928 {
2921 /* Some strlen's crash and burn if passed null. */ 2929 /* Some strlen's crash and burn if passed null. */
2922 return make_string ((const Ibyte *) str, (str ? strlen (str) : 0)); 2930 return make_extstring ((const Extbyte *) str,
2923 }
2924
2925 Lisp_Object
2926 build_ext_string (const Extbyte *str, Lisp_Object coding_system)
2927 {
2928 /* Some strlen's crash and burn if passed null. */
2929 return make_ext_string ((const Extbyte *) str,
2930 (str ? dfc_external_data_len (str, coding_system) : 2931 (str ? dfc_external_data_len (str, coding_system) :
2931 0), 2932 0),
2932 coding_system); 2933 coding_system);
2933 } 2934 }
2934 2935
2935 Lisp_Object 2936 /* Build a string whose content is a translatable message, and translate
2936 build_msg_intstring (const Ibyte *str) 2937 the message according to the current language environment. */
2937 { 2938
2938 return build_intstring (GETTEXT (str)); 2939 Lisp_Object
2939 } 2940 build_msg_istring (const Ibyte *str)
2940 2941 {
2941 Lisp_Object 2942 return build_istring (IGETTEXT (str));
2942 build_msg_string (const CIbyte *str) 2943 }
2943 { 2944
2944 return build_string (CGETTEXT (str)); 2945 /* Build a string whose content is a translatable message, and translate
2946 the message according to the current language environment. */
2947
2948 Lisp_Object
2949 build_msg_cistring (const CIbyte *str)
2950 {
2951 return build_msg_istring ((const Ibyte *) str);
2952 }
2953
2954 /* Build a string whose content is a translatable message, and translate
2955 the message according to the current language environment.
2956 String must be pure-ASCII, and when compiled with error-checking,
2957 an abort will have if not pure-ASCII. */
2958
2959 Lisp_Object
2960 build_msg_ascstring (const Ascbyte *str)
2961 {
2962 ASSERT_ASCTEXT_ASCII (str);
2963 return build_msg_istring ((const Ibyte *) str);
2964 }
2965
2966 /* Build a string whose content is a translatable message, but don't
2967 translate the message immediately. Perhaps do something else instead,
2968 such as put a property on the string indicating that it needs to be
2969 translated.
2970
2971 This is useful for strings that are built at dump time or init time,
2972 rather than on-the-fly when the current language environment is set
2973 properly. */
2974
2975 Lisp_Object
2976 build_defer_istring (const Ibyte *str)
2977 {
2978 Lisp_Object retval = build_istring ((Ibyte *) str);
2979 /* Possibly do something to the return value */
2980 return retval;
2981 }
2982
2983 Lisp_Object
2984 build_defer_cistring (const CIbyte *str)
2985 {
2986 return build_defer_istring ((Ibyte *) str);
2987 }
2988
2989 Lisp_Object
2990 build_defer_ascstring (const Ascbyte *str)
2991 {
2992 ASSERT_ASCTEXT_ASCII (str);
2993 return build_defer_istring ((Ibyte *) str);
2945 } 2994 }
2946 2995
2947 Lisp_Object 2996 Lisp_Object
2948 make_string_nocopy (const Ibyte *contents, Bytecount length) 2997 make_string_nocopy (const Ibyte *contents, Bytecount length)
2949 { 2998 {
3130 struct free_lcrecord_header *free_header = 3179 struct free_lcrecord_header *free_header =
3131 (struct free_lcrecord_header *) XPNTR (lcrecord); 3180 (struct free_lcrecord_header *) XPNTR (lcrecord);
3132 struct lrecord_header *lheader = &free_header->lcheader.lheader; 3181 struct lrecord_header *lheader = &free_header->lcheader.lheader;
3133 const struct lrecord_implementation *implementation 3182 const struct lrecord_implementation *implementation
3134 = LHEADER_IMPLEMENTATION (lheader); 3183 = LHEADER_IMPLEMENTATION (lheader);
3184
3185 /* If we try to debug-print during GC, we'll likely get a crash on the
3186 following assert (called from Lstream_delete(), from prin1_to_string()).
3187 Instead, just don't do anything. Worst comes to worst, we have a
3188 small memory leak -- and programs being debugged usually won't be
3189 super long-lived afterwards, anyway. */
3190 if (gc_in_progress && in_debug_print)
3191 return;
3135 3192
3136 /* Finalizer methods may try to free objects within them, which typically 3193 /* Finalizer methods may try to free objects within them, which typically
3137 won't be marked and thus are scheduled for demolition. Putting them 3194 won't be marked and thus are scheduled for demolition. Putting them
3138 on the free list would be very bad, as we'd have xfree()d memory in 3195 on the free list would be very bad, as we'd have xfree()d memory in
3139 the list. Even if for some reason the objects are still live 3196 the list. Even if for some reason the objects are still live
3255 staticpros_description_1 3312 staticpros_description_1
3256 }; 3313 };
3257 3314
3258 #ifdef DEBUG_XEMACS 3315 #ifdef DEBUG_XEMACS
3259 3316
3260 static const struct memory_description staticpro_one_name_description_1[] = {
3261 { XD_ASCII_STRING, 0 },
3262 { XD_END }
3263 };
3264
3265 static const struct sized_memory_description staticpro_one_name_description = {
3266 sizeof (char *),
3267 staticpro_one_name_description_1
3268 };
3269
3270 static const struct memory_description staticpro_names_description_1[] = {
3271 XD_DYNARR_DESC (char_ptr_dynarr, &staticpro_one_name_description),
3272 { XD_END }
3273 };
3274
3275
3276 extern const struct sized_memory_description staticpro_names_description;
3277
3278 const struct sized_memory_description staticpro_names_description = {
3279 sizeof (char_ptr_dynarr),
3280 staticpro_names_description_1
3281 };
3282
3283 /* Help debug crashes gc-marking a staticpro'ed object. */ 3317 /* Help debug crashes gc-marking a staticpro'ed object. */
3284 3318
3285 Lisp_Object_ptr_dynarr *staticpros; 3319 Lisp_Object_ptr_dynarr *staticpros;
3286 char_ptr_dynarr *staticpro_names; 3320 const_Ascbyte_ptr_dynarr *staticpro_names;
3287 3321
3288 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for 3322 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for
3289 garbage collection, and for dumping. */ 3323 garbage collection, and for dumping. */
3290 void 3324 void
3291 staticpro_1 (Lisp_Object *varaddress, char *varname) 3325 staticpro_1 (Lisp_Object *varaddress, const Ascbyte *varname)
3292 { 3326 {
3293 Dynarr_add (staticpros, varaddress); 3327 Dynarr_add (staticpros, varaddress);
3294 Dynarr_add (staticpro_names, varname); 3328 Dynarr_add (staticpro_names, varname);
3295 dump_add_root_lisp_object (varaddress); 3329 dump_add_root_lisp_object (varaddress);
3296 } 3330 }
3297 3331
3332 const Ascbyte *staticpro_name (int count);
3333
3334 /* External debugging function: Return the name of the variable at offset
3335 COUNT. */
3336 const Ascbyte *
3337 staticpro_name (int count)
3338 {
3339 return Dynarr_at (staticpro_names, count);
3340 }
3298 3341
3299 Lisp_Object_ptr_dynarr *staticpros_nodump; 3342 Lisp_Object_ptr_dynarr *staticpros_nodump;
3300 char_ptr_dynarr *staticpro_nodump_names; 3343 const_Ascbyte_ptr_dynarr *staticpro_nodump_names;
3301 3344
3302 /* Mark the Lisp_Object at heap VARADDRESS as a root object for 3345 /* Mark the Lisp_Object at heap VARADDRESS as a root object for
3303 garbage collection, but not for dumping. (See below.) */ 3346 garbage collection, but not for dumping. (See below.) */
3304 void 3347 void
3305 staticpro_nodump_1 (Lisp_Object *varaddress, char *varname) 3348 staticpro_nodump_1 (Lisp_Object *varaddress, const Ascbyte *varname)
3306 { 3349 {
3307 Dynarr_add (staticpros_nodump, varaddress); 3350 Dynarr_add (staticpros_nodump, varaddress);
3308 Dynarr_add (staticpro_nodump_names, varname); 3351 Dynarr_add (staticpro_nodump_names, varname);
3352 }
3353
3354 const Ascbyte *staticpro_nodump_name (int count);
3355
3356 /* External debugging function: Return the name of the variable at offset
3357 COUNT. */
3358 const Ascbyte *
3359 staticpro_nodump_name (int count)
3360 {
3361 return Dynarr_at (staticpro_nodump_names, count);
3309 } 3362 }
3310 3363
3311 #ifdef HAVE_SHLIB 3364 #ifdef HAVE_SHLIB
3312 /* Stop treating the Lisp_Object at non-heap VARADDRESS as a root object 3365 /* Stop treating the Lisp_Object at non-heap VARADDRESS as a root object
3313 for garbage collection, but not for dumping. */ 3366 for garbage collection, but not for dumping. */
3314 void 3367 void
3315 unstaticpro_nodump_1 (Lisp_Object *varaddress, char *varname) 3368 unstaticpro_nodump_1 (Lisp_Object *varaddress, const Ascbyte *varname)
3316 { 3369 {
3317 Dynarr_delete_object (staticpros, varaddress); 3370 Dynarr_delete_object (staticpros, varaddress);
3318 Dynarr_delete_object (staticpro_names, varname); 3371 Dynarr_delete_object (staticpro_names, varname);
3319 } 3372 }
3320 #endif 3373 #endif
3394 mcpros_description_1 3447 mcpros_description_1
3395 }; 3448 };
3396 3449
3397 #ifdef DEBUG_XEMACS 3450 #ifdef DEBUG_XEMACS
3398 3451
3399 static const struct memory_description mcpro_one_name_description_1[] = {
3400 { XD_ASCII_STRING, 0 },
3401 { XD_END }
3402 };
3403
3404 static const struct sized_memory_description mcpro_one_name_description = {
3405 sizeof (char *),
3406 mcpro_one_name_description_1
3407 };
3408
3409 static const struct memory_description mcpro_names_description_1[] = {
3410 XD_DYNARR_DESC (char_ptr_dynarr, &mcpro_one_name_description),
3411 { XD_END }
3412 };
3413
3414 extern const struct sized_memory_description mcpro_names_description;
3415
3416 const struct sized_memory_description mcpro_names_description = {
3417 sizeof (char_ptr_dynarr),
3418 mcpro_names_description_1
3419 };
3420
3421 /* Help debug crashes gc-marking a mcpro'ed object. */ 3452 /* Help debug crashes gc-marking a mcpro'ed object. */
3422 3453
3423 Lisp_Object_dynarr *mcpros; 3454 Lisp_Object_dynarr *mcpros;
3424 char_ptr_dynarr *mcpro_names; 3455 const_Ascbyte_ptr_dynarr *mcpro_names;
3425 3456
3426 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for 3457 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for
3427 garbage collection, and for dumping. */ 3458 garbage collection, and for dumping. */
3428 void 3459 void
3429 mcpro_1 (Lisp_Object varaddress, char *varname) 3460 mcpro_1 (Lisp_Object varaddress, const Ascbyte *varname)
3430 { 3461 {
3431 Dynarr_add (mcpros, varaddress); 3462 Dynarr_add (mcpros, varaddress);
3432 Dynarr_add (mcpro_names, varname); 3463 Dynarr_add (mcpro_names, varname);
3464 }
3465
3466 /* External debugging function: Return the name of the variable at offset
3467 COUNT. */
3468 const Ascbyte *
3469 mcpro_name (int count)
3470 {
3471 return Dynarr_at (mcpro_names, count);
3433 } 3472 }
3434 3473
3435 #else /* not DEBUG_XEMACS */ 3474 #else /* not DEBUG_XEMACS */
3436 3475
3437 Lisp_Object_dynarr *mcpros; 3476 Lisp_Object_dynarr *mcpros;
3548 { 3587 {
3549 struct old_lcrecord_header *next = header->next; 3588 struct old_lcrecord_header *next = header->next;
3550 *prev = next; 3589 *prev = next;
3551 tick_lcrecord_stats (h, 1); 3590 tick_lcrecord_stats (h, 1);
3552 /* used to call finalizer right here. */ 3591 /* used to call finalizer right here. */
3553 xfree (header, struct old_lcrecord_header *); 3592 xfree (header);
3554 header = next; 3593 header = next;
3555 } 3594 }
3556 } 3595 }
3557 *used = num_used; 3596 *used = num_used;
3558 /* *total = total_size; */ 3597 /* *total = total_size; */
3672 current_##typename##_block_index \ 3711 current_##typename##_block_index \
3673 = countof (current_##typename##_block->block); \ 3712 = countof (current_##typename##_block->block); \
3674 SFTB_current = SFTB_current->prev; \ 3713 SFTB_current = SFTB_current->prev; \
3675 { \ 3714 { \
3676 *SFTB_prev = SFTB_current; \ 3715 *SFTB_prev = SFTB_current; \
3677 xfree (SFTB_victim_block, struct typename##_block *); \ 3716 xfree (SFTB_victim_block); \
3678 /* Restore free list to what it was before victim was swept */ \ 3717 /* Restore free list to what it was before victim was swept */ \
3679 typename##_free_list = SFTB_old_free_list; \ 3718 typename##_free_list = SFTB_old_free_list; \
3680 num_free -= SFTB_limit; \ 3719 num_free -= SFTB_limit; \
3681 } \ 3720 } \
3682 } \ 3721 } \
3778 static void 3817 static void
3779 sweep_compiled_functions (void) 3818 sweep_compiled_functions (void)
3780 { 3819 {
3781 #define UNMARK_compiled_function(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3820 #define UNMARK_compiled_function(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3782 #define ADDITIONAL_FREE_compiled_function(ptr) \ 3821 #define ADDITIONAL_FREE_compiled_function(ptr) \
3783 if (ptr->args_in_array) xfree (ptr->args, Lisp_Object *) 3822 if (ptr->args_in_array) xfree (ptr->args)
3784 3823
3785 SWEEP_FIXED_TYPE_BLOCK (compiled_function, Lisp_Compiled_Function); 3824 SWEEP_FIXED_TYPE_BLOCK (compiled_function, Lisp_Compiled_Function);
3786 } 3825 }
3787 3826
3788 static void 3827 static void
4124 #endif /* defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY) */ 4163 #endif /* defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY) */
4125 4164
4126 #ifndef NEW_GC 4165 #ifndef NEW_GC
4127 /* Compactify string chars, relocating the reference to each -- 4166 /* Compactify string chars, relocating the reference to each --
4128 free any empty string_chars_block we see. */ 4167 free any empty string_chars_block we see. */
4129 void 4168 static void
4130 compact_string_chars (void) 4169 compact_string_chars (void)
4131 { 4170 {
4132 struct string_chars_block *to_sb = first_string_chars_block; 4171 struct string_chars_block *to_sb = first_string_chars_block;
4133 int to_pos = 0; 4172 int to_pos = 0;
4134 struct string_chars_block *from_sb; 4173 struct string_chars_block *from_sb;
4211 struct string_chars_block *victim; 4250 struct string_chars_block *victim;
4212 4251
4213 for (victim = to_sb->next; victim; ) 4252 for (victim = to_sb->next; victim; )
4214 { 4253 {
4215 struct string_chars_block *next = victim->next; 4254 struct string_chars_block *next = victim->next;
4216 xfree (victim, struct string_chars_block *); 4255 xfree (victim);
4217 victim = next; 4256 victim = next;
4218 } 4257 }
4219 4258
4220 current_string_chars_block = to_sb; 4259 current_string_chars_block = to_sb;
4221 current_string_chars_block->pos = to_pos; 4260 current_string_chars_block->pos = to_pos;
4271 debug_string_purity_print (wrap_string (p)); \ 4310 debug_string_purity_print (wrap_string (p)); \
4272 } while (0) 4311 } while (0)
4273 #define ADDITIONAL_FREE_string(ptr) do { \ 4312 #define ADDITIONAL_FREE_string(ptr) do { \
4274 Bytecount size = ptr->size_; \ 4313 Bytecount size = ptr->size_; \
4275 if (BIG_STRING_SIZE_P (size)) \ 4314 if (BIG_STRING_SIZE_P (size)) \
4276 xfree (ptr->data_, Ibyte *); \ 4315 xfree (ptr->data_); \
4277 } while (0) 4316 } while (0)
4278 4317
4279 SWEEP_FIXED_TYPE_BLOCK_1 (string, Lisp_String, u.lheader); 4318 SWEEP_FIXED_TYPE_BLOCK_1 (string, Lisp_String, u.lheader);
4280 4319
4281 gc_count_num_short_string_in_use = num_small_used; 4320 gc_count_num_short_string_in_use = num_small_used;
4461 4500
4462 for (i = 0; i < countof (lrecord_implementations_table); i++) 4501 for (i = 0; i < countof (lrecord_implementations_table); i++)
4463 { 4502 {
4464 if (lrecord_stats[i].instances_in_use != 0) 4503 if (lrecord_stats[i].instances_in_use != 0)
4465 { 4504 {
4466 char buf [255]; 4505 Ascbyte buf[255];
4467 const char *name = lrecord_implementations_table[i]->name; 4506 const Ascbyte *name = lrecord_implementations_table[i]->name;
4468 int len = strlen (name); 4507 int len = strlen (name);
4469 4508
4470 if (lrecord_stats[i].bytes_in_use_including_overhead != 4509 if (lrecord_stats[i].bytes_in_use_including_overhead !=
4471 lrecord_stats[i].bytes_in_use) 4510 lrecord_stats[i].bytes_in_use)
4472 { 4511 {
4505 { 4544 {
4506 if (lcrecord_stats[i].bytes_in_use != 0 4545 if (lcrecord_stats[i].bytes_in_use != 0
4507 || lcrecord_stats[i].bytes_freed != 0 4546 || lcrecord_stats[i].bytes_freed != 0
4508 || lcrecord_stats[i].instances_on_free_list != 0) 4547 || lcrecord_stats[i].instances_on_free_list != 0)
4509 { 4548 {
4510 char buf [255]; 4549 Ascbyte buf[255];
4511 const char *name = lrecord_implementations_table[i]->name; 4550 const Ascbyte *name = lrecord_implementations_table[i]->name;
4512 int len = strlen (name); 4551 int len = strlen (name);
4513 4552
4514 sprintf (buf, "%s-storage", name); 4553 sprintf (buf, "%s-storage", name);
4515 pl = gc_plist_hack (buf, lcrecord_stats[i].bytes_in_use, pl); 4554 pl = gc_plist_hack (buf, lcrecord_stats[i].bytes_in_use, pl);
4516 tgu_val += lcrecord_stats[i].bytes_in_use; 4555 tgu_val += lcrecord_stats[i].bytes_in_use;
4722 { 4761 {
4723 return make_int (total_gc_usage + consing_since_gc); 4762 return make_int (total_gc_usage + consing_since_gc);
4724 } 4763 }
4725 #endif /* ALLOC_TYPE_STATS */ 4764 #endif /* ALLOC_TYPE_STATS */
4726 4765
4766 #ifdef USE_VALGRIND
4767 DEFUN ("valgrind-leak-check", Fvalgrind_leak_check, 0, 0, "", /*
4768 Ask valgrind to perform a memory leak check.
4769 The results of the leak check are sent to stderr.
4770 */
4771 ())
4772 {
4773 VALGRIND_DO_LEAK_CHECK;
4774 return Qnil;
4775 }
4776
4777 DEFUN ("valgrind-quick-leak-check", Fvalgrind_quick_leak_check, 0, 0, "", /*
4778 Ask valgrind to perform a quick memory leak check.
4779 This just prints a summary of leaked memory, rather than all the details.
4780 The results of the leak check are sent to stderr.
4781 */
4782 ())
4783 {
4784 VALGRIND_DO_QUICK_LEAK_CHECK;
4785 return Qnil;
4786 }
4787 #endif /* USE_VALGRIND */
4788
4727 void 4789 void
4728 recompute_funcall_allocation_flag (void) 4790 recompute_funcall_allocation_flag (void)
4729 { 4791 {
4730 funcall_allocation_flag = 4792 funcall_allocation_flag =
4731 need_to_garbage_collect || 4793 need_to_garbage_collect ||
4925 staticpros_nodump = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); 4987 staticpros_nodump = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *);
4926 Dynarr_resize (staticpros_nodump, 100); /* merely a small optimization */ 4988 Dynarr_resize (staticpros_nodump, 100); /* merely a small optimization */
4927 #ifdef DEBUG_XEMACS 4989 #ifdef DEBUG_XEMACS
4928 if (staticpro_nodump_names) 4990 if (staticpro_nodump_names)
4929 Dynarr_free (staticpro_nodump_names); 4991 Dynarr_free (staticpro_nodump_names);
4930 staticpro_nodump_names = Dynarr_new2 (char_ptr_dynarr, char *); 4992 staticpro_nodump_names = Dynarr_new2 (const_Ascbyte_ptr_dynarr,
4993 const Ascbyte *);
4931 Dynarr_resize (staticpro_nodump_names, 100); /* ditto */ 4994 Dynarr_resize (staticpro_nodump_names, 100); /* ditto */
4932 #endif 4995 #endif
4933 4996
4934 #ifdef NEW_GC 4997 #ifdef NEW_GC
4935 mcpros = Dynarr_new2 (Lisp_Object_dynarr, Lisp_Object); 4998 mcpros = Dynarr_new2 (Lisp_Object_dynarr, Lisp_Object);
4936 Dynarr_resize (mcpros, 1410); /* merely a small optimization */ 4999 Dynarr_resize (mcpros, 1410); /* merely a small optimization */
4937 dump_add_root_block_ptr (&mcpros, &mcpros_description); 5000 dump_add_root_block_ptr (&mcpros, &mcpros_description);
4938 #ifdef DEBUG_XEMACS 5001 #ifdef DEBUG_XEMACS
4939 mcpro_names = Dynarr_new2 (char_ptr_dynarr, char *); 5002 mcpro_names = Dynarr_new2 (const_Ascbyte_ptr_dynarr, const Ascbyte *);
4940 Dynarr_resize (mcpro_names, 1410); /* merely a small optimization */ 5003 Dynarr_resize (mcpro_names, 1410); /* merely a small optimization */
4941 dump_add_root_block_ptr (&mcpro_names, &mcpro_names_description); 5004 dump_add_root_block_ptr (&mcpro_names,
5005 &const_Ascbyte_ptr_dynarr_description);
4942 #endif 5006 #endif
4943 #endif /* NEW_GC */ 5007 #endif /* NEW_GC */
4944 5008
4945 consing_since_gc = 0; 5009 consing_since_gc = 0;
4946 need_to_check_c_alloca = 0; 5010 need_to_check_c_alloca = 0;
5029 5093
5030 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); 5094 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *);
5031 Dynarr_resize (staticpros, 1410); /* merely a small optimization */ 5095 Dynarr_resize (staticpros, 1410); /* merely a small optimization */
5032 dump_add_root_block_ptr (&staticpros, &staticpros_description); 5096 dump_add_root_block_ptr (&staticpros, &staticpros_description);
5033 #ifdef DEBUG_XEMACS 5097 #ifdef DEBUG_XEMACS
5034 staticpro_names = Dynarr_new2 (char_ptr_dynarr, char *); 5098 staticpro_names = Dynarr_new2 (const_Ascbyte_ptr_dynarr, const Ascbyte *);
5035 Dynarr_resize (staticpro_names, 1410); /* merely a small optimization */ 5099 Dynarr_resize (staticpro_names, 1410); /* merely a small optimization */
5036 dump_add_root_block_ptr (&staticpro_names, &staticpro_names_description); 5100 dump_add_root_block_ptr (&staticpro_names,
5101 &const_Ascbyte_ptr_dynarr_description);
5037 #endif 5102 #endif
5038 5103
5039 #ifdef NEW_GC 5104 #ifdef NEW_GC
5040 mcpros = Dynarr_new2 (Lisp_Object_dynarr, Lisp_Object); 5105 mcpros = Dynarr_new2 (Lisp_Object_dynarr, Lisp_Object);
5041 Dynarr_resize (mcpros, 1410); /* merely a small optimization */ 5106 Dynarr_resize (mcpros, 1410); /* merely a small optimization */
5042 dump_add_root_block_ptr (&mcpros, &mcpros_description); 5107 dump_add_root_block_ptr (&mcpros, &mcpros_description);
5043 #ifdef DEBUG_XEMACS 5108 #ifdef DEBUG_XEMACS
5044 mcpro_names = Dynarr_new2 (char_ptr_dynarr, char *); 5109 mcpro_names = Dynarr_new2 (const_Ascbyte_ptr_dynarr, const Ascbyte *);
5045 Dynarr_resize (mcpro_names, 1410); /* merely a small optimization */ 5110 Dynarr_resize (mcpro_names, 1410); /* merely a small optimization */
5046 dump_add_root_block_ptr (&mcpro_names, &mcpro_names_description); 5111 dump_add_root_block_ptr (&mcpro_names,
5112 &const_Ascbyte_ptr_dynarr_description);
5047 #endif 5113 #endif
5048 #else /* not NEW_GC */ 5114 #else /* not NEW_GC */
5049 init_lcrecord_lists (); 5115 init_lcrecord_lists ();
5050 #endif /* not NEW_GC */ 5116 #endif /* not NEW_GC */
5051 } 5117 }
5076 #if 0 5142 #if 0
5077 DEFSUBR (Fmemory_limit); 5143 DEFSUBR (Fmemory_limit);
5078 #endif 5144 #endif
5079 DEFSUBR (Ftotal_memory_usage); 5145 DEFSUBR (Ftotal_memory_usage);
5080 DEFSUBR (Fconsing_since_gc); 5146 DEFSUBR (Fconsing_since_gc);
5147 #ifdef USE_VALGRIND
5148 DEFSUBR (Fvalgrind_leak_check);
5149 DEFSUBR (Fvalgrind_quick_leak_check);
5150 #endif
5081 } 5151 }
5082 5152
5083 void 5153 void
5084 vars_of_alloc (void) 5154 vars_of_alloc (void)
5085 { 5155 {