Mercurial > hg > xemacs-beta
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 { |