Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 647:b39c14581166
[xemacs-hg @ 2001-08-13 04:45:47 by ben]
removal of unsigned, size_t, etc.
author | ben |
---|---|
date | Mon, 13 Aug 2001 04:46:48 +0000 |
parents | af57a77cbc92 |
children | fdefd0186b75 |
comparison
equal
deleted
inserted
replaced
646:00c54252fe4f | 647:b39c14581166 |
---|---|
241 | 241 |
242 /* like malloc and realloc but check for no memory left, and block input. */ | 242 /* like malloc and realloc but check for no memory left, and block input. */ |
243 | 243 |
244 #undef xmalloc | 244 #undef xmalloc |
245 void * | 245 void * |
246 xmalloc (size_t size) | 246 xmalloc (Memory_Count size) |
247 { | 247 { |
248 void *val = malloc (size); | 248 void *val = malloc (size); |
249 | 249 |
250 if (!val && (size != 0)) memory_full (); | 250 if (!val && (size != 0)) memory_full (); |
251 return val; | 251 return val; |
252 } | 252 } |
253 | 253 |
254 #undef xcalloc | 254 #undef xcalloc |
255 static void * | 255 static void * |
256 xcalloc (size_t nelem, size_t elsize) | 256 xcalloc (Element_Count nelem, Memory_Count elsize) |
257 { | 257 { |
258 void *val = calloc (nelem, elsize); | 258 void *val = calloc (nelem, elsize); |
259 | 259 |
260 if (!val && (nelem != 0)) memory_full (); | 260 if (!val && (nelem != 0)) memory_full (); |
261 return val; | 261 return val; |
262 } | 262 } |
263 | 263 |
264 void * | 264 void * |
265 xmalloc_and_zero (size_t size) | 265 xmalloc_and_zero (Memory_Count size) |
266 { | 266 { |
267 return xcalloc (size, sizeof (char)); | 267 return xcalloc (size, sizeof (char)); |
268 } | 268 } |
269 | 269 |
270 #undef xrealloc | 270 #undef xrealloc |
271 void * | 271 void * |
272 xrealloc (void *block, size_t size) | 272 xrealloc (void *block, Memory_Count size) |
273 { | 273 { |
274 block = realloc (block, size); | 274 block = realloc (block, size); |
275 | 275 |
276 if (!block && (size != 0)) memory_full (); | 276 if (!block && (size != 0)) memory_full (); |
277 return block; | 277 return block; |
305 #else | 305 #else |
306 What kind of strange-ass system are we running on? | 306 What kind of strange-ass system are we running on? |
307 #endif | 307 #endif |
308 | 308 |
309 static void | 309 static void |
310 deadbeef_memory (void *ptr, size_t size) | 310 deadbeef_memory (void *ptr, Memory_Count size) |
311 { | 311 { |
312 four_byte_t *ptr4 = (four_byte_t *) ptr; | 312 four_byte_t *ptr4 = (four_byte_t *) ptr; |
313 size_t beefs = size >> 2; | 313 Memory_Count beefs = size >> 2; |
314 | 314 |
315 /* In practice, size will always be a multiple of four. */ | 315 /* In practice, size will always be a multiple of four. */ |
316 while (beefs--) | 316 while (beefs--) |
317 (*ptr4++) = 0xDEADBEEF; | 317 (*ptr4++) = 0xDEADBEEF; |
318 } | 318 } |
343 } | 343 } |
344 #endif /* NEED_STRDUP */ | 344 #endif /* NEED_STRDUP */ |
345 | 345 |
346 | 346 |
347 static void * | 347 static void * |
348 allocate_lisp_storage (size_t size) | 348 allocate_lisp_storage (Memory_Count size) |
349 { | 349 { |
350 return xmalloc (size); | 350 return xmalloc (size); |
351 } | 351 } |
352 | 352 |
353 | 353 |
355 After doing the mark phase, GC will walk this linked list | 355 After doing the mark phase, GC will walk this linked list |
356 and free any lcrecord which hasn't been marked. */ | 356 and free any lcrecord which hasn't been marked. */ |
357 static struct lcrecord_header *all_lcrecords; | 357 static struct lcrecord_header *all_lcrecords; |
358 | 358 |
359 void * | 359 void * |
360 alloc_lcrecord (size_t size, const struct lrecord_implementation *implementation) | 360 alloc_lcrecord (Memory_Count size, const struct lrecord_implementation *implementation) |
361 { | 361 { |
362 struct lcrecord_header *lcheader; | 362 struct lcrecord_header *lcheader; |
363 | 363 |
364 type_checking_assert | 364 type_checking_assert |
365 ((implementation->static_size == 0 ? | 365 ((implementation->static_size == 0 ? |
995 { | 995 { |
996 CHECK_NATNUM (length); | 996 CHECK_NATNUM (length); |
997 | 997 |
998 { | 998 { |
999 Lisp_Object val = Qnil; | 999 Lisp_Object val = Qnil; |
1000 size_t size = XINT (length); | 1000 EMACS_INT size = XINT (length); |
1001 | 1001 |
1002 while (size--) | 1002 while (size--) |
1003 val = Fcons (object, val); | 1003 val = Fcons (object, val); |
1004 return val; | 1004 return val; |
1005 } | 1005 } |
1050 for (i = 0; i < len - 1; i++) | 1050 for (i = 0; i < len - 1; i++) |
1051 mark_object (ptr->contents[i]); | 1051 mark_object (ptr->contents[i]); |
1052 return (len > 0) ? ptr->contents[len - 1] : Qnil; | 1052 return (len > 0) ? ptr->contents[len - 1] : Qnil; |
1053 } | 1053 } |
1054 | 1054 |
1055 static size_t | 1055 static Memory_Count |
1056 size_vector (const void *lheader) | 1056 size_vector (const void *lheader) |
1057 { | 1057 { |
1058 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, contents, | 1058 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, contents, |
1059 ((Lisp_Vector *) lheader)->size); | 1059 ((Lisp_Vector *) lheader)->size); |
1060 } | 1060 } |
1074 return 0; | 1074 return 0; |
1075 } | 1075 } |
1076 return 1; | 1076 return 1; |
1077 } | 1077 } |
1078 | 1078 |
1079 static hashcode_t | 1079 static Hash_Code |
1080 vector_hash (Lisp_Object obj, int depth) | 1080 vector_hash (Lisp_Object obj, int depth) |
1081 { | 1081 { |
1082 return HASH2 (XVECTOR_LENGTH (obj), | 1082 return HASH2 (XVECTOR_LENGTH (obj), |
1083 internal_array_hash (XVECTOR_DATA (obj), | 1083 internal_array_hash (XVECTOR_DATA (obj), |
1084 XVECTOR_LENGTH (obj), | 1084 XVECTOR_LENGTH (obj), |
1098 vector_description, | 1098 vector_description, |
1099 size_vector, Lisp_Vector); | 1099 size_vector, Lisp_Vector); |
1100 | 1100 |
1101 /* #### should allocate `small' vectors from a frob-block */ | 1101 /* #### should allocate `small' vectors from a frob-block */ |
1102 static Lisp_Vector * | 1102 static Lisp_Vector * |
1103 make_vector_internal (size_t sizei) | 1103 make_vector_internal (Element_Count sizei) |
1104 { | 1104 { |
1105 /* no vector_next */ | 1105 /* no vector_next */ |
1106 size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, | 1106 Memory_Count sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, |
1107 contents, sizei); | 1107 contents, sizei); |
1108 Lisp_Vector *p = (Lisp_Vector *) alloc_lcrecord (sizem, &lrecord_vector); | 1108 Lisp_Vector *p = (Lisp_Vector *) alloc_lcrecord (sizem, &lrecord_vector); |
1109 | 1109 |
1110 p->size = sizei; | 1110 p->size = sizei; |
1111 return p; | 1111 return p; |
1112 } | 1112 } |
1113 | 1113 |
1114 Lisp_Object | 1114 Lisp_Object |
1115 make_vector (size_t length, Lisp_Object object) | 1115 make_vector (Element_Count length, Lisp_Object object) |
1116 { | 1116 { |
1117 Lisp_Vector *vecp = make_vector_internal (length); | 1117 Lisp_Vector *vecp = make_vector_internal (length); |
1118 Lisp_Object *p = vector_data (vecp); | 1118 Lisp_Object *p = vector_data (vecp); |
1119 | 1119 |
1120 while (length--) | 1120 while (length--) |
1262 | 1262 |
1263 static Lisp_Object all_bit_vectors; | 1263 static Lisp_Object all_bit_vectors; |
1264 | 1264 |
1265 /* #### should allocate `small' bit vectors from a frob-block */ | 1265 /* #### should allocate `small' bit vectors from a frob-block */ |
1266 static Lisp_Bit_Vector * | 1266 static Lisp_Bit_Vector * |
1267 make_bit_vector_internal (size_t sizei) | 1267 make_bit_vector_internal (Element_Count sizei) |
1268 { | 1268 { |
1269 size_t num_longs = BIT_VECTOR_LONG_STORAGE (sizei); | 1269 Element_Count num_longs = BIT_VECTOR_LONG_STORAGE (sizei); |
1270 size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, unsigned long, | 1270 Memory_Count sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, |
1271 bits, num_longs); | 1271 unsigned long, |
1272 bits, num_longs); | |
1272 Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) allocate_lisp_storage (sizem); | 1273 Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) allocate_lisp_storage (sizem); |
1273 set_lheader_implementation (&p->lheader, &lrecord_bit_vector); | 1274 set_lheader_implementation (&p->lheader, &lrecord_bit_vector); |
1274 | 1275 |
1275 INCREMENT_CONS_COUNTER (sizem, "bit-vector"); | 1276 INCREMENT_CONS_COUNTER (sizem, "bit-vector"); |
1276 | 1277 |
1282 XSETBIT_VECTOR (all_bit_vectors, p); | 1283 XSETBIT_VECTOR (all_bit_vectors, p); |
1283 return p; | 1284 return p; |
1284 } | 1285 } |
1285 | 1286 |
1286 Lisp_Object | 1287 Lisp_Object |
1287 make_bit_vector (size_t length, Lisp_Object bit) | 1288 make_bit_vector (Element_Count length, Lisp_Object bit) |
1288 { | 1289 { |
1289 Lisp_Bit_Vector *p = make_bit_vector_internal (length); | 1290 Lisp_Bit_Vector *p = make_bit_vector_internal (length); |
1290 size_t num_longs = BIT_VECTOR_LONG_STORAGE (length); | 1291 Element_Count num_longs = BIT_VECTOR_LONG_STORAGE (length); |
1291 | 1292 |
1292 CHECK_BIT (bit); | 1293 CHECK_BIT (bit); |
1293 | 1294 |
1294 if (ZEROP (bit)) | 1295 if (ZEROP (bit)) |
1295 memset (p->bits, 0, num_longs * sizeof (long)); | 1296 memset (p->bits, 0, num_longs * sizeof (long)); |
1296 else | 1297 else |
1297 { | 1298 { |
1298 size_t bits_in_last = length & (LONGBITS_POWER_OF_2 - 1); | 1299 Element_Count bits_in_last = length & (LONGBITS_POWER_OF_2 - 1); |
1299 memset (p->bits, ~0, num_longs * sizeof (long)); | 1300 memset (p->bits, ~0, num_longs * sizeof (long)); |
1300 /* But we have to make sure that the unused bits in the | 1301 /* But we have to make sure that the unused bits in the |
1301 last long are 0, so that equal/hash is easy. */ | 1302 last long are 0, so that equal/hash is easy. */ |
1302 if (bits_in_last) | 1303 if (bits_in_last) |
1303 p->bits[num_longs - 1] &= (1 << bits_in_last) - 1; | 1304 p->bits[num_longs - 1] &= (1 << bits_in_last) - 1; |
1309 return bit_vector; | 1310 return bit_vector; |
1310 } | 1311 } |
1311 } | 1312 } |
1312 | 1313 |
1313 Lisp_Object | 1314 Lisp_Object |
1314 make_bit_vector_from_byte_vector (unsigned char *bytevec, size_t length) | 1315 make_bit_vector_from_byte_vector (unsigned char *bytevec, Element_Count length) |
1315 { | 1316 { |
1316 size_t i; | 1317 Element_Count i; |
1317 Lisp_Bit_Vector *p = make_bit_vector_internal (length); | 1318 Lisp_Bit_Vector *p = make_bit_vector_internal (length); |
1318 | 1319 |
1319 for (i = 0; i < length; i++) | 1320 for (i = 0; i < length; i++) |
1320 set_bit_vector_bit (p, i, bytevec[i]); | 1321 set_bit_vector_bit (p, i, bytevec[i]); |
1321 | 1322 |
2039 if (len == 1) | 2040 if (len == 1) |
2040 /* Optimize the single-byte case */ | 2041 /* Optimize the single-byte case */ |
2041 memset (XSTRING_DATA (val), XCHAR (character), XSTRING_LENGTH (val)); | 2042 memset (XSTRING_DATA (val), XCHAR (character), XSTRING_LENGTH (val)); |
2042 else | 2043 else |
2043 { | 2044 { |
2044 size_t i; | 2045 EMACS_INT i; |
2045 Bufbyte *ptr = XSTRING_DATA (val); | 2046 Bufbyte *ptr = XSTRING_DATA (val); |
2046 | 2047 |
2047 for (i = XINT (length); i; i--) | 2048 for (i = XINT (length); i; i--) |
2048 { | 2049 { |
2049 Bufbyte *init_ptr = init_str; | 2050 Bufbyte *init_ptr = init_str; |
2224 | 2225 |
2225 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list, | 2226 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list, |
2226 mark_lcrecord_list, internal_object_printer, | 2227 mark_lcrecord_list, internal_object_printer, |
2227 0, 0, 0, 0, struct lcrecord_list); | 2228 0, 0, 0, 0, struct lcrecord_list); |
2228 Lisp_Object | 2229 Lisp_Object |
2229 make_lcrecord_list (size_t size, | 2230 make_lcrecord_list (Element_Count size, |
2230 const struct lrecord_implementation *implementation) | 2231 const struct lrecord_implementation *implementation) |
2231 { | 2232 { |
2232 struct lcrecord_list *p = alloc_lcrecord_type (struct lcrecord_list, | 2233 struct lcrecord_list *p = alloc_lcrecord_type (struct lcrecord_list, |
2233 &lrecord_lcrecord_list); | 2234 &lrecord_lcrecord_list); |
2234 Lisp_Object val; | 2235 Lisp_Object val; |
2324 /************************************************************************/ | 2325 /************************************************************************/ |
2325 | 2326 |
2326 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. | 2327 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. |
2327 Additional ones may be defined by a module (none yet). We leave some | 2328 Additional ones may be defined by a module (none yet). We leave some |
2328 room in `lrecord_implementations_table' for such new lisp object types. */ | 2329 room in `lrecord_implementations_table' for such new lisp object types. */ |
2329 const struct lrecord_implementation *lrecord_implementations_table[(unsigned int)lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT]; | 2330 const struct lrecord_implementation *lrecord_implementations_table[(int)lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT]; |
2330 unsigned int lrecord_type_count = (unsigned int)lrecord_type_last_built_in_type; | 2331 int lrecord_type_count = lrecord_type_last_built_in_type; |
2331 /* Object marker functions are in the lrecord_implementation structure. | 2332 /* Object marker functions are in the lrecord_implementation structure. |
2332 But copying them to a parallel array is much more cache-friendly. | 2333 But copying them to a parallel array is much more cache-friendly. |
2333 This hack speeds up (garbage-collect) by about 5%. */ | 2334 This hack speeds up (garbage-collect) by about 5%. */ |
2334 Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object); | 2335 Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object); |
2335 | 2336 |
2380 | 2381 |
2381 #ifdef ERROR_CHECK_GC | 2382 #ifdef ERROR_CHECK_GC |
2382 #define GC_CHECK_LHEADER_INVARIANTS(lheader) do { \ | 2383 #define GC_CHECK_LHEADER_INVARIANTS(lheader) do { \ |
2383 struct lrecord_header * GCLI_lh = (lheader); \ | 2384 struct lrecord_header * GCLI_lh = (lheader); \ |
2384 assert (GCLI_lh != 0); \ | 2385 assert (GCLI_lh != 0); \ |
2385 assert (GCLI_lh->type < lrecord_type_count); \ | 2386 assert (GCLI_lh->type < (unsigned int) lrecord_type_count); \ |
2386 assert (! C_READONLY_RECORD_HEADER_P (GCLI_lh) || \ | 2387 assert (! C_READONLY_RECORD_HEADER_P (GCLI_lh) || \ |
2387 (MARKED_RECORD_HEADER_P (GCLI_lh) && \ | 2388 (MARKED_RECORD_HEADER_P (GCLI_lh) && \ |
2388 LISP_READONLY_RECORD_HEADER_P (GCLI_lh))); \ | 2389 LISP_READONLY_RECORD_HEADER_P (GCLI_lh))); \ |
2389 } while (0) | 2390 } while (0) |
2390 #else | 2391 #else |
2454 /* Find all structures not marked, and free them. */ | 2455 /* Find all structures not marked, and free them. */ |
2455 | 2456 |
2456 static int gc_count_num_bit_vector_used, gc_count_bit_vector_total_size; | 2457 static int gc_count_num_bit_vector_used, gc_count_bit_vector_total_size; |
2457 static int gc_count_bit_vector_storage; | 2458 static int gc_count_bit_vector_storage; |
2458 static int gc_count_num_short_string_in_use; | 2459 static int gc_count_num_short_string_in_use; |
2459 static int gc_count_string_total_size; | 2460 static Bytecount gc_count_string_total_size; |
2460 static int gc_count_short_string_total_size; | 2461 static Bytecount gc_count_short_string_total_size; |
2461 | 2462 |
2462 /* static int gc_count_total_records_used, gc_count_records_total_size; */ | 2463 /* static int gc_count_total_records_used, gc_count_records_total_size; */ |
2463 | 2464 |
2464 | 2465 |
2465 /* stats on lcrecords in use - kinda kludgy */ | 2466 /* stats on lcrecords in use - kinda kludgy */ |
2474 } lcrecord_stats [countof (lrecord_implementations_table)]; | 2475 } lcrecord_stats [countof (lrecord_implementations_table)]; |
2475 | 2476 |
2476 static void | 2477 static void |
2477 tick_lcrecord_stats (const struct lrecord_header *h, int free_p) | 2478 tick_lcrecord_stats (const struct lrecord_header *h, int free_p) |
2478 { | 2479 { |
2479 unsigned int type_index = h->type; | 2480 int type_index = h->type; |
2480 | 2481 |
2481 if (((struct lcrecord_header *) h)->free) | 2482 if (((struct lcrecord_header *) h)->free) |
2482 { | 2483 { |
2483 gc_checking_assert (!free_p); | 2484 gc_checking_assert (!free_p); |
2484 lcrecord_stats[type_index].instances_on_free_list++; | 2485 lcrecord_stats[type_index].instances_on_free_list++; |
2486 else | 2487 else |
2487 { | 2488 { |
2488 const struct lrecord_implementation *implementation = | 2489 const struct lrecord_implementation *implementation = |
2489 LHEADER_IMPLEMENTATION (h); | 2490 LHEADER_IMPLEMENTATION (h); |
2490 | 2491 |
2491 size_t sz = (implementation->size_in_bytes_method ? | 2492 Memory_Count sz = (implementation->size_in_bytes_method ? |
2492 implementation->size_in_bytes_method (h) : | 2493 implementation->size_in_bytes_method (h) : |
2493 implementation->static_size); | 2494 implementation->static_size); |
2494 if (free_p) | 2495 if (free_p) |
2495 { | 2496 { |
2496 lcrecord_stats[type_index].instances_freed++; | 2497 lcrecord_stats[type_index].instances_freed++; |
3053 | 3054 |
3054 | 3055 |
3055 static void | 3056 static void |
3056 sweep_strings (void) | 3057 sweep_strings (void) |
3057 { | 3058 { |
3058 int num_small_used = 0, num_small_bytes = 0, num_bytes = 0; | 3059 int num_small_used = 0; |
3060 Bytecount num_small_bytes = 0, num_bytes = 0; | |
3059 int debug = debug_string_purity; | 3061 int debug = debug_string_purity; |
3060 | 3062 |
3061 #define UNMARK_string(ptr) do { \ | 3063 #define UNMARK_string(ptr) do { \ |
3062 Lisp_String *p = (ptr); \ | 3064 Lisp_String *p = (ptr); \ |
3063 size_t size = string_length (p); \ | 3065 Bytecount size = string_length (p); \ |
3064 UNMARK_RECORD_HEADER (&(p->lheader)); \ | 3066 UNMARK_RECORD_HEADER (&(p->lheader)); \ |
3065 num_bytes += size; \ | 3067 num_bytes += size; \ |
3066 if (!BIG_STRING_SIZE_P (size)) \ | 3068 if (!BIG_STRING_SIZE_P (size)) \ |
3067 { \ | 3069 { \ |
3068 num_small_bytes += size; \ | 3070 num_small_bytes += size; \ |
3070 } \ | 3072 } \ |
3071 if (debug) \ | 3073 if (debug) \ |
3072 debug_string_purity_print (p); \ | 3074 debug_string_purity_print (p); \ |
3073 } while (0) | 3075 } while (0) |
3074 #define ADDITIONAL_FREE_string(ptr) do { \ | 3076 #define ADDITIONAL_FREE_string(ptr) do { \ |
3075 size_t size = string_length (ptr); \ | 3077 Bytecount size = string_length (ptr); \ |
3076 if (BIG_STRING_SIZE_P (size)) \ | 3078 if (BIG_STRING_SIZE_P (size)) \ |
3077 xfree (ptr->data); \ | 3079 xfree (ptr->data); \ |
3078 } while (0) | 3080 } while (0) |
3079 | 3081 |
3080 SWEEP_FIXED_TYPE_BLOCK (string, Lisp_String); | 3082 SWEEP_FIXED_TYPE_BLOCK (string, Lisp_String); |
3392 /* Save a copy of the contents of the stack, for debugging. */ | 3394 /* Save a copy of the contents of the stack, for debugging. */ |
3393 if (!purify_flag) | 3395 if (!purify_flag) |
3394 { | 3396 { |
3395 /* Static buffer in which we save a copy of the C stack at each GC. */ | 3397 /* Static buffer in which we save a copy of the C stack at each GC. */ |
3396 static char *stack_copy; | 3398 static char *stack_copy; |
3397 static size_t stack_copy_size; | 3399 static Memory_Count stack_copy_size; |
3398 | 3400 |
3399 ptrdiff_t stack_diff = &stack_top_variable - stack_bottom; | 3401 ptrdiff_t stack_diff = &stack_top_variable - stack_bottom; |
3400 size_t stack_size = (stack_diff > 0 ? stack_diff : -stack_diff); | 3402 Memory_Count stack_size = (stack_diff > 0 ? stack_diff : -stack_diff); |
3401 if (stack_size < MAX_SAVE_STACK) | 3403 if (stack_size < MAX_SAVE_STACK) |
3402 { | 3404 { |
3403 if (stack_copy_size < stack_size) | 3405 if (stack_copy_size < stack_size) |
3404 { | 3406 { |
3405 stack_copy = (char *) xrealloc (stack_copy, stack_size); | 3407 stack_copy = (char *) xrealloc (stack_copy, stack_size); |
3420 | 3422 |
3421 /* Mark all the special slots that serve as the roots of accessibility. */ | 3423 /* Mark all the special slots that serve as the roots of accessibility. */ |
3422 | 3424 |
3423 { /* staticpro() */ | 3425 { /* staticpro() */ |
3424 Lisp_Object **p = Dynarr_begin (staticpros); | 3426 Lisp_Object **p = Dynarr_begin (staticpros); |
3425 size_t count; | 3427 Element_Count count; |
3426 for (count = Dynarr_length (staticpros); count; count--) | 3428 for (count = Dynarr_length (staticpros); count; count--) |
3427 mark_object (**p++); | 3429 mark_object (**p++); |
3428 } | 3430 } |
3429 | 3431 |
3430 { /* staticpro_nodump() */ | 3432 { /* staticpro_nodump() */ |
3431 Lisp_Object **p = Dynarr_begin (staticpros_nodump); | 3433 Lisp_Object **p = Dynarr_begin (staticpros_nodump); |
3432 size_t count; | 3434 Element_Count count; |
3433 for (count = Dynarr_length (staticpros_nodump); count; count--) | 3435 for (count = Dynarr_length (staticpros_nodump); count; count--) |
3434 mark_object (**p++); | 3436 mark_object (**p++); |
3435 } | 3437 } |
3436 | 3438 |
3437 { /* GCPRO() */ | 3439 { /* GCPRO() */ |
3585 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. | 3587 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. |
3586 */ | 3588 */ |
3587 ()) | 3589 ()) |
3588 { | 3590 { |
3589 Lisp_Object pl = Qnil; | 3591 Lisp_Object pl = Qnil; |
3590 unsigned int i; | 3592 int i; |
3591 int gc_count_vector_total_size = 0; | 3593 int gc_count_vector_total_size = 0; |
3592 | 3594 |
3593 garbage_collect_1 (); | 3595 garbage_collect_1 (); |
3594 | 3596 |
3595 for (i = 0; i < lrecord_type_count; i++) | 3597 for (i = 0; i < lrecord_type_count; i++) |
3760 for want of better data is that sizeof (void *), or maybe | 3762 for want of better data is that sizeof (void *), or maybe |
3761 2 * sizeof (void *), is required as overhead and that | 3763 2 * sizeof (void *), is required as overhead and that |
3762 blocks are allocated in the minimum required size except | 3764 blocks are allocated in the minimum required size except |
3763 that some minimum block size is imposed (e.g. 16 bytes). */ | 3765 that some minimum block size is imposed (e.g. 16 bytes). */ |
3764 | 3766 |
3765 size_t | 3767 Memory_Count |
3766 malloced_storage_size (void *ptr, size_t claimed_size, | 3768 malloced_storage_size (void *ptr, Memory_Count claimed_size, |
3767 struct overhead_stats *stats) | 3769 struct overhead_stats *stats) |
3768 { | 3770 { |
3769 size_t orig_claimed_size = claimed_size; | 3771 Memory_Count orig_claimed_size = claimed_size; |
3770 | 3772 |
3771 #ifdef GNU_MALLOC | 3773 #ifdef GNU_MALLOC |
3772 | 3774 if (claimed_size < (Memory_Count) (2 * sizeof (void *))) |
3773 if (claimed_size < 2 * sizeof (void *)) | |
3774 claimed_size = 2 * sizeof (void *); | 3775 claimed_size = 2 * sizeof (void *); |
3775 # ifdef SUNOS_LOCALTIME_BUG | 3776 # ifdef SUNOS_LOCALTIME_BUG |
3776 if (claimed_size < 16) | 3777 if (claimed_size < 16) |
3777 claimed_size = 16; | 3778 claimed_size = 16; |
3778 # endif | 3779 # endif |
3793 claimed_size *= 2; | 3794 claimed_size *= 2; |
3794 log--; | 3795 log--; |
3795 } | 3796 } |
3796 /* We have to come up with some average about the amount of | 3797 /* We have to come up with some average about the amount of |
3797 blocks used. */ | 3798 blocks used. */ |
3798 if ((size_t) (rand () & 4095) < claimed_size) | 3799 if ((Memory_Count) (rand () & 4095) < claimed_size) |
3799 claimed_size += 3 * sizeof (void *); | 3800 claimed_size += 3 * sizeof (void *); |
3800 } | 3801 } |
3801 else | 3802 else |
3802 { | 3803 { |
3803 claimed_size += 4095; | 3804 claimed_size += 4095; |
3844 stats->malloc_overhead += claimed_size - orig_claimed_size; | 3845 stats->malloc_overhead += claimed_size - orig_claimed_size; |
3845 } | 3846 } |
3846 return claimed_size; | 3847 return claimed_size; |
3847 } | 3848 } |
3848 | 3849 |
3849 size_t | 3850 Memory_Count |
3850 fixed_type_block_overhead (size_t size) | 3851 fixed_type_block_overhead (Memory_Count size) |
3851 { | 3852 { |
3852 size_t per_block = TYPE_ALLOC_SIZE (cons, unsigned char); | 3853 Memory_Count per_block = TYPE_ALLOC_SIZE (cons, unsigned char); |
3853 size_t overhead = 0; | 3854 Memory_Count overhead = 0; |
3854 size_t storage_size = malloced_storage_size (0, per_block, 0); | 3855 Memory_Count storage_size = malloced_storage_size (0, per_block, 0); |
3855 while (size >= per_block) | 3856 while (size >= per_block) |
3856 { | 3857 { |
3857 size -= per_block; | 3858 size -= per_block; |
3858 overhead += sizeof (void *) + per_block - storage_size; | 3859 overhead += sizeof (void *) + per_block - storage_size; |
3859 } | 3860 } |