Mercurial > emacs
comparison src/alloc.c @ 90261:7beb78bc1f8e
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 616-696)
- Add lisp/mh-e/.arch-inventory
- Update from CVS
- Merge from gnus--rel--5.10
- Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords.
- lisp/gnus/ChangeLog: Remove duplicate entry
* gnus--rel--5.10 (patch 147-181)
- Update from CVS
- Merge from emacs--cvs-trunk--0
- Update from CVS: lisp/mml.el (mml-preview): Doc fix.
- Update from CVS: texi/message.texi: Fix default values.
- Update from CVS: texi/gnus.texi (RSS): Addition.
| author | Miles Bader <miles@gnu.org> |
|---|---|
| date | Mon, 16 Jan 2006 08:37:27 +0000 |
| parents | aa89c814f853 28fd92314a04 |
| children | 5b7d410e31f9 |
comparison
equal
deleted
inserted
replaced
| 90260:0ca0d9181b5e | 90261:7beb78bc1f8e |
|---|---|
| 62 | 62 |
| 63 #ifdef HAVE_UNISTD_H | 63 #ifdef HAVE_UNISTD_H |
| 64 #include <unistd.h> | 64 #include <unistd.h> |
| 65 #else | 65 #else |
| 66 extern POINTER_TYPE *sbrk (); | 66 extern POINTER_TYPE *sbrk (); |
| 67 #endif | |
| 68 | |
| 69 #ifdef HAVE_FCNTL_H | |
| 70 #define INCLUDED_FCNTL | |
| 71 #include <fcntl.h> | |
| 72 #endif | |
| 73 #ifndef O_WRONLY | |
| 74 #define O_WRONLY 1 | |
| 67 #endif | 75 #endif |
| 68 | 76 |
| 69 #ifdef DOUG_LEA_MALLOC | 77 #ifdef DOUG_LEA_MALLOC |
| 70 | 78 |
| 71 #include <malloc.h> | 79 #include <malloc.h> |
| 136 | 144 |
| 137 /* Value of _bytes_used, when spare_memory was freed. */ | 145 /* Value of _bytes_used, when spare_memory was freed. */ |
| 138 | 146 |
| 139 static __malloc_size_t bytes_used_when_full; | 147 static __malloc_size_t bytes_used_when_full; |
| 140 | 148 |
| 149 static __malloc_size_t bytes_used_when_reconsidered; | |
| 150 | |
| 141 /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer | 151 /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer |
| 142 to a struct Lisp_String. */ | 152 to a struct Lisp_String. */ |
| 143 | 153 |
| 144 #define MARK_STRING(S) ((S)->size |= ARRAY_MARK_FLAG) | 154 #define MARK_STRING(S) ((S)->size |= ARRAY_MARK_FLAG) |
| 145 #define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) | 155 #define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) |
| 180 | 190 |
| 181 EMACS_INT gc_relative_threshold; | 191 EMACS_INT gc_relative_threshold; |
| 182 | 192 |
| 183 static Lisp_Object Vgc_cons_percentage; | 193 static Lisp_Object Vgc_cons_percentage; |
| 184 | 194 |
| 195 /* Minimum number of bytes of consing since GC before next GC, | |
| 196 when memory is full. */ | |
| 197 | |
| 198 EMACS_INT memory_full_cons_threshold; | |
| 199 | |
| 185 /* Nonzero during GC. */ | 200 /* Nonzero during GC. */ |
| 186 | 201 |
| 187 int gc_in_progress; | 202 int gc_in_progress; |
| 188 | 203 |
| 189 /* Nonzero means abort if try to GC. | 204 /* Nonzero means abort if try to GC. |
| 211 static int total_conses, total_markers, total_symbols, total_vector_size; | 226 static int total_conses, total_markers, total_symbols, total_vector_size; |
| 212 static int total_free_conses, total_free_markers, total_free_symbols; | 227 static int total_free_conses, total_free_markers, total_free_symbols; |
| 213 static int total_free_floats, total_floats; | 228 static int total_free_floats, total_floats; |
| 214 | 229 |
| 215 /* Points to memory space allocated as "spare", to be freed if we run | 230 /* Points to memory space allocated as "spare", to be freed if we run |
| 216 out of memory. */ | 231 out of memory. We keep one large block, four cons-blocks, and |
| 217 | 232 two string blocks. */ |
| 218 static char *spare_memory; | 233 |
| 219 | 234 char *spare_memory[7]; |
| 220 /* Amount of spare memory to keep in reserve. */ | 235 |
| 236 /* Amount of spare memory to keep in large reserve block. */ | |
| 221 | 237 |
| 222 #define SPARE_MEMORY (1 << 14) | 238 #define SPARE_MEMORY (1 << 14) |
| 223 | 239 |
| 224 /* Number of extra blocks malloc should get when it needs more core. */ | 240 /* Number of extra blocks malloc should get when it needs more core. */ |
| 225 | 241 |
| 347 MEM_TYPE_PROCESS, | 363 MEM_TYPE_PROCESS, |
| 348 MEM_TYPE_HASH_TABLE, | 364 MEM_TYPE_HASH_TABLE, |
| 349 MEM_TYPE_FRAME, | 365 MEM_TYPE_FRAME, |
| 350 MEM_TYPE_WINDOW | 366 MEM_TYPE_WINDOW |
| 351 }; | 367 }; |
| 368 | |
| 369 static POINTER_TYPE *lisp_align_malloc P_ ((size_t, enum mem_type)); | |
| 370 static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); | |
| 371 void refill_memory_reserve (); | |
| 372 | |
| 352 | 373 |
| 353 #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 374 #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 354 | 375 |
| 355 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 376 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 356 #include <stdio.h> /* For fprintf. */ | 377 #include <stdio.h> /* For fprintf. */ |
| 448 static void mem_rotate_right P_ ((struct mem_node *)); | 469 static void mem_rotate_right P_ ((struct mem_node *)); |
| 449 static void mem_delete P_ ((struct mem_node *)); | 470 static void mem_delete P_ ((struct mem_node *)); |
| 450 static void mem_delete_fixup P_ ((struct mem_node *)); | 471 static void mem_delete_fixup P_ ((struct mem_node *)); |
| 451 static INLINE struct mem_node *mem_find P_ ((void *)); | 472 static INLINE struct mem_node *mem_find P_ ((void *)); |
| 452 | 473 |
| 474 | |
| 453 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 475 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
| 454 static void check_gcpros P_ ((void)); | 476 static void check_gcpros P_ ((void)); |
| 455 #endif | 477 #endif |
| 456 | 478 |
| 457 #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ | 479 #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ |
| 508 pending_malloc_warning = 0; | 530 pending_malloc_warning = 0; |
| 509 } | 531 } |
| 510 | 532 |
| 511 | 533 |
| 512 #ifdef DOUG_LEA_MALLOC | 534 #ifdef DOUG_LEA_MALLOC |
| 513 # define BYTES_USED (mallinfo ().arena) | 535 # define BYTES_USED (mallinfo ().uordblks) |
| 514 #else | 536 #else |
| 515 # define BYTES_USED _bytes_used | 537 # define BYTES_USED _bytes_used |
| 516 #endif | 538 #endif |
| 517 | |
| 518 | |
| 519 /* Called if malloc returns zero. */ | |
| 520 | |
| 521 void | |
| 522 memory_full () | |
| 523 { | |
| 524 Vmemory_full = Qt; | |
| 525 | |
| 526 #ifndef SYSTEM_MALLOC | |
| 527 bytes_used_when_full = BYTES_USED; | |
| 528 #endif | |
| 529 | |
| 530 /* The first time we get here, free the spare memory. */ | |
| 531 if (spare_memory) | |
| 532 { | |
| 533 free (spare_memory); | |
| 534 spare_memory = 0; | |
| 535 } | |
| 536 | |
| 537 /* This used to call error, but if we've run out of memory, we could | |
| 538 get infinite recursion trying to build the string. */ | |
| 539 while (1) | |
| 540 Fsignal (Qnil, Vmemory_signal_data); | |
| 541 } | |
| 542 | |
| 543 DEFUN ("memory-full-p", Fmemory_full_p, Smemory_full_p, 0, 0, 0, | |
| 544 doc: /* t if memory is nearly full, nil otherwise. */) | |
| 545 () | |
| 546 { | |
| 547 return (spare_memory ? Qnil : Qt); | |
| 548 } | |
| 549 | |
| 550 /* If we released our reserve (due to running out of memory), | |
| 551 and we have a fair amount free once again, | |
| 552 try to set aside another reserve in case we run out once more. | |
| 553 | |
| 554 This is called when a relocatable block is freed in ralloc.c. */ | |
| 555 | |
| 556 void | |
| 557 refill_memory_reserve () | |
| 558 { | |
| 559 #ifndef SYSTEM_MALLOC | |
| 560 if (spare_memory == 0) | |
| 561 spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | |
| 562 #endif | |
| 563 } | |
| 564 | 539 |
| 565 /* Called if we can't allocate relocatable space for a buffer. */ | 540 /* Called if we can't allocate relocatable space for a buffer. */ |
| 566 | 541 |
| 567 void | 542 void |
| 568 buffer_memory_full () | 543 buffer_memory_full () |
| 575 malloc. */ | 550 malloc. */ |
| 576 | 551 |
| 577 #ifndef REL_ALLOC | 552 #ifndef REL_ALLOC |
| 578 memory_full (); | 553 memory_full (); |
| 579 #endif | 554 #endif |
| 580 | |
| 581 Vmemory_full = Qt; | |
| 582 | 555 |
| 583 /* This used to call error, but if we've run out of memory, we could | 556 /* This used to call error, but if we've run out of memory, we could |
| 584 get infinite recursion trying to build the string. */ | 557 get infinite recursion trying to build the string. */ |
| 585 while (1) | 558 while (1) |
| 586 Fsignal (Qnil, Vmemory_signal_data); | 559 Fsignal (Qnil, Vmemory_signal_data); |
| 803 POINTER_TYPE *block; | 776 POINTER_TYPE *block; |
| 804 { | 777 { |
| 805 BLOCK_INPUT; | 778 BLOCK_INPUT; |
| 806 free (block); | 779 free (block); |
| 807 UNBLOCK_INPUT; | 780 UNBLOCK_INPUT; |
| 781 /* We don't call refill_memory_reserve here | |
| 782 because that duplicates doing so in emacs_blocked_free | |
| 783 and the criterion should go there. */ | |
| 808 } | 784 } |
| 809 | 785 |
| 810 | 786 |
| 811 /* Like strdup, but uses xmalloc. */ | 787 /* Like strdup, but uses xmalloc. */ |
| 812 | 788 |
| 1176 static void | 1152 static void |
| 1177 emacs_blocked_free (ptr, ptr2) | 1153 emacs_blocked_free (ptr, ptr2) |
| 1178 void *ptr; | 1154 void *ptr; |
| 1179 const void *ptr2; | 1155 const void *ptr2; |
| 1180 { | 1156 { |
| 1157 EMACS_INT bytes_used_now; | |
| 1158 | |
| 1181 BLOCK_INPUT_ALLOC; | 1159 BLOCK_INPUT_ALLOC; |
| 1182 | 1160 |
| 1183 #ifdef GC_MALLOC_CHECK | 1161 #ifdef GC_MALLOC_CHECK |
| 1184 if (ptr) | 1162 if (ptr) |
| 1185 { | 1163 { |
| 1204 free (ptr); | 1182 free (ptr); |
| 1205 | 1183 |
| 1206 /* If we released our reserve (due to running out of memory), | 1184 /* If we released our reserve (due to running out of memory), |
| 1207 and we have a fair amount free once again, | 1185 and we have a fair amount free once again, |
| 1208 try to set aside another reserve in case we run out once more. */ | 1186 try to set aside another reserve in case we run out once more. */ |
| 1209 if (spare_memory == 0 | 1187 if (! NILP (Vmemory_full) |
| 1210 /* Verify there is enough space that even with the malloc | 1188 /* Verify there is enough space that even with the malloc |
| 1211 hysteresis this call won't run out again. | 1189 hysteresis this call won't run out again. |
| 1212 The code here is correct as long as SPARE_MEMORY | 1190 The code here is correct as long as SPARE_MEMORY |
| 1213 is substantially larger than the block size malloc uses. */ | 1191 is substantially larger than the block size malloc uses. */ |
| 1214 && (bytes_used_when_full | 1192 && (bytes_used_when_full |
| 1215 > BYTES_USED + max (malloc_hysteresis, 4) * SPARE_MEMORY)) | 1193 > ((bytes_used_when_reconsidered = BYTES_USED) |
| 1216 spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | 1194 + max (malloc_hysteresis, 4) * SPARE_MEMORY))) |
| 1195 refill_memory_reserve (); | |
| 1217 | 1196 |
| 1218 __free_hook = emacs_blocked_free; | 1197 __free_hook = emacs_blocked_free; |
| 1219 UNBLOCK_INPUT_ALLOC; | 1198 UNBLOCK_INPUT_ALLOC; |
| 1220 } | 1199 } |
| 1221 | 1200 |
| 2558 | 2537 |
| 2559 void | 2538 void |
| 2560 free_float (ptr) | 2539 free_float (ptr) |
| 2561 struct Lisp_Float *ptr; | 2540 struct Lisp_Float *ptr; |
| 2562 { | 2541 { |
| 2563 *(struct Lisp_Float **)&ptr->data = float_free_list; | 2542 ptr->u.chain = float_free_list; |
| 2564 float_free_list = ptr; | 2543 float_free_list = ptr; |
| 2565 } | 2544 } |
| 2566 | 2545 |
| 2567 | 2546 |
| 2568 /* Return a new float object with value FLOAT_VALUE. */ | 2547 /* Return a new float object with value FLOAT_VALUE. */ |
| 2576 if (float_free_list) | 2555 if (float_free_list) |
| 2577 { | 2556 { |
| 2578 /* We use the data field for chaining the free list | 2557 /* We use the data field for chaining the free list |
| 2579 so that we won't use the same field that has the mark bit. */ | 2558 so that we won't use the same field that has the mark bit. */ |
| 2580 XSETFLOAT (val, float_free_list); | 2559 XSETFLOAT (val, float_free_list); |
| 2581 float_free_list = *(struct Lisp_Float **)&float_free_list->data; | 2560 float_free_list = float_free_list->u.chain; |
| 2582 } | 2561 } |
| 2583 else | 2562 else |
| 2584 { | 2563 { |
| 2585 if (float_block_index == FLOAT_BLOCK_SIZE) | 2564 if (float_block_index == FLOAT_BLOCK_SIZE) |
| 2586 { | 2565 { |
| 2676 | 2655 |
| 2677 void | 2656 void |
| 2678 free_cons (ptr) | 2657 free_cons (ptr) |
| 2679 struct Lisp_Cons *ptr; | 2658 struct Lisp_Cons *ptr; |
| 2680 { | 2659 { |
| 2681 *(struct Lisp_Cons **)&ptr->cdr = cons_free_list; | 2660 ptr->u.chain = cons_free_list; |
| 2682 #if GC_MARK_STACK | 2661 #if GC_MARK_STACK |
| 2683 ptr->car = Vdead; | 2662 ptr->car = Vdead; |
| 2684 #endif | 2663 #endif |
| 2685 cons_free_list = ptr; | 2664 cons_free_list = ptr; |
| 2686 } | 2665 } |
| 2695 if (cons_free_list) | 2674 if (cons_free_list) |
| 2696 { | 2675 { |
| 2697 /* We use the cdr for chaining the free list | 2676 /* We use the cdr for chaining the free list |
| 2698 so that we won't use the same field that has the mark bit. */ | 2677 so that we won't use the same field that has the mark bit. */ |
| 2699 XSETCONS (val, cons_free_list); | 2678 XSETCONS (val, cons_free_list); |
| 2700 cons_free_list = *(struct Lisp_Cons **)&cons_free_list->cdr; | 2679 cons_free_list = cons_free_list->u.chain; |
| 2701 } | 2680 } |
| 2702 else | 2681 else |
| 2703 { | 2682 { |
| 2704 if (cons_block_index == CONS_BLOCK_SIZE) | 2683 if (cons_block_index == CONS_BLOCK_SIZE) |
| 2705 { | 2684 { |
| 2730 { | 2709 { |
| 2731 #ifdef GC_CHECK_CONS_LIST | 2710 #ifdef GC_CHECK_CONS_LIST |
| 2732 struct Lisp_Cons *tail = cons_free_list; | 2711 struct Lisp_Cons *tail = cons_free_list; |
| 2733 | 2712 |
| 2734 while (tail) | 2713 while (tail) |
| 2735 tail = *(struct Lisp_Cons **)&tail->cdr; | 2714 tail = tail->u.chain; |
| 2736 #endif | 2715 #endif |
| 2737 } | 2716 } |
| 2738 | 2717 |
| 2739 /* Make a list of 2, 3, 4 or 5 specified objects. */ | 2718 /* Make a list of 2, 3, 4 or 5 specified objects. */ |
| 2740 | 2719 |
| 3124 CHECK_STRING (name); | 3103 CHECK_STRING (name); |
| 3125 | 3104 |
| 3126 if (symbol_free_list) | 3105 if (symbol_free_list) |
| 3127 { | 3106 { |
| 3128 XSETSYMBOL (val, symbol_free_list); | 3107 XSETSYMBOL (val, symbol_free_list); |
| 3129 symbol_free_list = *(struct Lisp_Symbol **)&symbol_free_list->value; | 3108 symbol_free_list = symbol_free_list->next; |
| 3130 } | 3109 } |
| 3131 else | 3110 else |
| 3132 { | 3111 { |
| 3133 if (symbol_block_index == SYMBOL_BLOCK_SIZE) | 3112 if (symbol_block_index == SYMBOL_BLOCK_SIZE) |
| 3134 { | 3113 { |
| 3333 return result; | 3312 return result; |
| 3334 } | 3313 } |
| 3335 } | 3314 } |
| 3336 | 3315 |
| 3337 | 3316 |
| 3317 | |
| 3318 /************************************************************************ | |
| 3319 Memory Full Handling | |
| 3320 ************************************************************************/ | |
| 3321 | |
| 3322 | |
| 3323 /* Called if malloc returns zero. */ | |
| 3324 | |
| 3325 void | |
| 3326 memory_full () | |
| 3327 { | |
| 3328 int i; | |
| 3329 | |
| 3330 Vmemory_full = Qt; | |
| 3331 | |
| 3332 memory_full_cons_threshold = sizeof (struct cons_block); | |
| 3333 | |
| 3334 /* The first time we get here, free the spare memory. */ | |
| 3335 for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) | |
| 3336 if (spare_memory[i]) | |
| 3337 { | |
| 3338 if (i == 0) | |
| 3339 free (spare_memory[i]); | |
| 3340 else if (i >= 1 && i <= 4) | |
| 3341 lisp_align_free (spare_memory[i]); | |
| 3342 else | |
| 3343 lisp_free (spare_memory[i]); | |
| 3344 spare_memory[i] = 0; | |
| 3345 } | |
| 3346 | |
| 3347 /* Record the space now used. When it decreases substantially, | |
| 3348 we can refill the memory reserve. */ | |
| 3349 #ifndef SYSTEM_MALLOC | |
| 3350 bytes_used_when_full = BYTES_USED; | |
| 3351 #endif | |
| 3352 | |
| 3353 /* This used to call error, but if we've run out of memory, we could | |
| 3354 get infinite recursion trying to build the string. */ | |
| 3355 while (1) | |
| 3356 Fsignal (Qnil, Vmemory_signal_data); | |
| 3357 } | |
| 3358 | |
| 3359 /* If we released our reserve (due to running out of memory), | |
| 3360 and we have a fair amount free once again, | |
| 3361 try to set aside another reserve in case we run out once more. | |
| 3362 | |
| 3363 This is called when a relocatable block is freed in ralloc.c, | |
| 3364 and also directly from this file, in case we're not using ralloc.c. */ | |
| 3365 | |
| 3366 void | |
| 3367 refill_memory_reserve () | |
| 3368 { | |
| 3369 #ifndef SYSTEM_MALLOC | |
| 3370 if (spare_memory[0] == 0) | |
| 3371 spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY); | |
| 3372 if (spare_memory[1] == 0) | |
| 3373 spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block), | |
| 3374 MEM_TYPE_CONS); | |
| 3375 if (spare_memory[2] == 0) | |
| 3376 spare_memory[2] = (char *) lisp_align_malloc (sizeof (struct cons_block), | |
| 3377 MEM_TYPE_CONS); | |
| 3378 if (spare_memory[3] == 0) | |
| 3379 spare_memory[3] = (char *) lisp_align_malloc (sizeof (struct cons_block), | |
| 3380 MEM_TYPE_CONS); | |
| 3381 if (spare_memory[4] == 0) | |
| 3382 spare_memory[4] = (char *) lisp_align_malloc (sizeof (struct cons_block), | |
| 3383 MEM_TYPE_CONS); | |
| 3384 if (spare_memory[5] == 0) | |
| 3385 spare_memory[5] = (char *) lisp_malloc (sizeof (struct string_block), | |
| 3386 MEM_TYPE_STRING); | |
| 3387 if (spare_memory[6] == 0) | |
| 3388 spare_memory[6] = (char *) lisp_malloc (sizeof (struct string_block), | |
| 3389 MEM_TYPE_STRING); | |
| 3390 if (spare_memory[0] && spare_memory[1] && spare_memory[5]) | |
| 3391 Vmemory_full = Qnil; | |
| 3392 #endif | |
| 3393 } | |
| 3338 | 3394 |
| 3339 /************************************************************************ | 3395 /************************************************************************ |
| 3340 C Stack Marking | 3396 C Stack Marking |
| 3341 ************************************************************************/ | 3397 ************************************************************************/ |
| 3342 | 3398 |
| 4391 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 4447 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
| 4392 check_gcpros (); | 4448 check_gcpros (); |
| 4393 #endif | 4449 #endif |
| 4394 } | 4450 } |
| 4395 | 4451 |
| 4396 | |
| 4397 #endif /* GC_MARK_STACK != 0 */ | 4452 #endif /* GC_MARK_STACK != 0 */ |
| 4453 | |
| 4454 | |
| 4455 | |
| 4456 /* Return 1 if OBJ is a valid lisp object. | |
| 4457 Return 0 if OBJ is NOT a valid lisp object. | |
| 4458 Return -1 if we cannot validate OBJ. | |
| 4459 This function can be quite slow, | |
| 4460 so it should only be used in code for manual debugging. */ | |
| 4461 | |
| 4462 int | |
| 4463 valid_lisp_object_p (obj) | |
| 4464 Lisp_Object obj; | |
| 4465 { | |
| 4466 void *p; | |
| 4467 #if !GC_MARK_STACK | |
| 4468 int fd; | |
| 4469 #else | |
| 4470 struct mem_node *m; | |
| 4471 #endif | |
| 4472 | |
| 4473 if (INTEGERP (obj)) | |
| 4474 return 1; | |
| 4475 | |
| 4476 p = (void *) XPNTR (obj); | |
| 4477 if (PURE_POINTER_P (p)) | |
| 4478 return 1; | |
| 4479 | |
| 4480 #if !GC_MARK_STACK | |
| 4481 /* We need to determine whether it is safe to access memory at | |
| 4482 address P. Obviously, we cannot just access it (we would SEGV | |
| 4483 trying), so we trick the o/s to tell us whether p is a valid | |
| 4484 pointer. Unfortunately, we cannot use NULL_DEVICE here, as | |
| 4485 emacs_write may not validate p in that case. */ | |
| 4486 if ((fd = emacs_open ("__Valid__Lisp__Object__", O_CREAT | O_WRONLY | O_TRUNC, 0666)) >= 0) | |
| 4487 { | |
| 4488 int valid = (emacs_write (fd, (char *)p, 16) == 16); | |
| 4489 emacs_close (fd); | |
| 4490 unlink ("__Valid__Lisp__Object__"); | |
| 4491 return valid; | |
| 4492 } | |
| 4493 | |
| 4494 return -1; | |
| 4495 #else | |
| 4496 | |
| 4497 m = mem_find (p); | |
| 4498 | |
| 4499 if (m == MEM_NIL) | |
| 4500 return 0; | |
| 4501 | |
| 4502 switch (m->type) | |
| 4503 { | |
| 4504 case MEM_TYPE_NON_LISP: | |
| 4505 return 0; | |
| 4506 | |
| 4507 case MEM_TYPE_BUFFER: | |
| 4508 return live_buffer_p (m, p); | |
| 4509 | |
| 4510 case MEM_TYPE_CONS: | |
| 4511 return live_cons_p (m, p); | |
| 4512 | |
| 4513 case MEM_TYPE_STRING: | |
| 4514 return live_string_p (m, p); | |
| 4515 | |
| 4516 case MEM_TYPE_MISC: | |
| 4517 return live_misc_p (m, p); | |
| 4518 | |
| 4519 case MEM_TYPE_SYMBOL: | |
| 4520 return live_symbol_p (m, p); | |
| 4521 | |
| 4522 case MEM_TYPE_FLOAT: | |
| 4523 return live_float_p (m, p); | |
| 4524 | |
| 4525 case MEM_TYPE_VECTOR: | |
| 4526 case MEM_TYPE_PROCESS: | |
| 4527 case MEM_TYPE_HASH_TABLE: | |
| 4528 case MEM_TYPE_FRAME: | |
| 4529 case MEM_TYPE_WINDOW: | |
| 4530 return live_vector_p (m, p); | |
| 4531 | |
| 4532 default: | |
| 4533 break; | |
| 4534 } | |
| 4535 | |
| 4536 return 0; | |
| 4537 #endif | |
| 4538 } | |
| 4539 | |
| 4398 | 4540 |
| 4399 | 4541 |
| 4400 | 4542 |
| 4401 /*********************************************************************** | 4543 /*********************************************************************** |
| 4402 Pure Storage Management | 4544 Pure Storage Management |
| 4874 total += total_string_size; | 5016 total += total_string_size; |
| 4875 total += total_vector_size * sizeof (Lisp_Object); | 5017 total += total_vector_size * sizeof (Lisp_Object); |
| 4876 total += total_floats * sizeof (struct Lisp_Float); | 5018 total += total_floats * sizeof (struct Lisp_Float); |
| 4877 total += total_intervals * sizeof (struct interval); | 5019 total += total_intervals * sizeof (struct interval); |
| 4878 total += total_strings * sizeof (struct Lisp_String); | 5020 total += total_strings * sizeof (struct Lisp_String); |
| 4879 | 5021 |
| 4880 gc_relative_threshold = total * XFLOAT_DATA (Vgc_cons_percentage); | 5022 gc_relative_threshold = total * XFLOAT_DATA (Vgc_cons_percentage); |
| 4881 } | 5023 } |
| 4882 else | 5024 else |
| 4883 gc_relative_threshold = 0; | 5025 gc_relative_threshold = 0; |
| 4884 | 5026 |
| 5401 register struct Lisp_Cons *ptr = XCONS (obj); | 5543 register struct Lisp_Cons *ptr = XCONS (obj); |
| 5402 if (CONS_MARKED_P (ptr)) break; | 5544 if (CONS_MARKED_P (ptr)) break; |
| 5403 CHECK_ALLOCATED_AND_LIVE (live_cons_p); | 5545 CHECK_ALLOCATED_AND_LIVE (live_cons_p); |
| 5404 CONS_MARK (ptr); | 5546 CONS_MARK (ptr); |
| 5405 /* If the cdr is nil, avoid recursion for the car. */ | 5547 /* If the cdr is nil, avoid recursion for the car. */ |
| 5406 if (EQ (ptr->cdr, Qnil)) | 5548 if (EQ (ptr->u.cdr, Qnil)) |
| 5407 { | 5549 { |
| 5408 obj = ptr->car; | 5550 obj = ptr->car; |
| 5409 cdr_count = 0; | 5551 cdr_count = 0; |
| 5410 goto loop; | 5552 goto loop; |
| 5411 } | 5553 } |
| 5412 mark_object (ptr->car); | 5554 mark_object (ptr->car); |
| 5413 obj = ptr->cdr; | 5555 obj = ptr->u.cdr; |
| 5414 cdr_count++; | 5556 cdr_count++; |
| 5415 if (cdr_count == mark_object_loop_halt) | 5557 if (cdr_count == mark_object_loop_halt) |
| 5416 abort (); | 5558 abort (); |
| 5417 goto loop; | 5559 goto loop; |
| 5418 } | 5560 } |
| 5555 int this_free = 0; | 5697 int this_free = 0; |
| 5556 for (i = 0; i < lim; i++) | 5698 for (i = 0; i < lim; i++) |
| 5557 if (!CONS_MARKED_P (&cblk->conses[i])) | 5699 if (!CONS_MARKED_P (&cblk->conses[i])) |
| 5558 { | 5700 { |
| 5559 this_free++; | 5701 this_free++; |
| 5560 *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list; | 5702 cblk->conses[i].u.chain = cons_free_list; |
| 5561 cons_free_list = &cblk->conses[i]; | 5703 cons_free_list = &cblk->conses[i]; |
| 5562 #if GC_MARK_STACK | 5704 #if GC_MARK_STACK |
| 5563 cons_free_list->car = Vdead; | 5705 cons_free_list->car = Vdead; |
| 5564 #endif | 5706 #endif |
| 5565 } | 5707 } |
| 5574 this block. */ | 5716 this block. */ |
| 5575 if (this_free == CONS_BLOCK_SIZE && num_free > CONS_BLOCK_SIZE) | 5717 if (this_free == CONS_BLOCK_SIZE && num_free > CONS_BLOCK_SIZE) |
| 5576 { | 5718 { |
| 5577 *cprev = cblk->next; | 5719 *cprev = cblk->next; |
| 5578 /* Unhook from the free list. */ | 5720 /* Unhook from the free list. */ |
| 5579 cons_free_list = *(struct Lisp_Cons **) &cblk->conses[0].cdr; | 5721 cons_free_list = cblk->conses[0].u.chain; |
| 5580 lisp_align_free (cblk); | 5722 lisp_align_free (cblk); |
| 5581 n_cons_blocks--; | 5723 n_cons_blocks--; |
| 5582 } | 5724 } |
| 5583 else | 5725 else |
| 5584 { | 5726 { |
| 5605 int this_free = 0; | 5747 int this_free = 0; |
| 5606 for (i = 0; i < lim; i++) | 5748 for (i = 0; i < lim; i++) |
| 5607 if (!FLOAT_MARKED_P (&fblk->floats[i])) | 5749 if (!FLOAT_MARKED_P (&fblk->floats[i])) |
| 5608 { | 5750 { |
| 5609 this_free++; | 5751 this_free++; |
| 5610 *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list; | 5752 fblk->floats[i].u.chain = float_free_list; |
| 5611 float_free_list = &fblk->floats[i]; | 5753 float_free_list = &fblk->floats[i]; |
| 5612 } | 5754 } |
| 5613 else | 5755 else |
| 5614 { | 5756 { |
| 5615 num_used++; | 5757 num_used++; |
| 5621 this block. */ | 5763 this block. */ |
| 5622 if (this_free == FLOAT_BLOCK_SIZE && num_free > FLOAT_BLOCK_SIZE) | 5764 if (this_free == FLOAT_BLOCK_SIZE && num_free > FLOAT_BLOCK_SIZE) |
| 5623 { | 5765 { |
| 5624 *fprev = fblk->next; | 5766 *fprev = fblk->next; |
| 5625 /* Unhook from the free list. */ | 5767 /* Unhook from the free list. */ |
| 5626 float_free_list = *(struct Lisp_Float **) &fblk->floats[0].data; | 5768 float_free_list = fblk->floats[0].u.chain; |
| 5627 lisp_align_free (fblk); | 5769 lisp_align_free (fblk); |
| 5628 n_float_blocks--; | 5770 n_float_blocks--; |
| 5629 } | 5771 } |
| 5630 else | 5772 else |
| 5631 { | 5773 { |
| 5709 so we conservatively assume that it is live. */ | 5851 so we conservatively assume that it is live. */ |
| 5710 int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); | 5852 int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); |
| 5711 | 5853 |
| 5712 if (!sym->gcmarkbit && !pure_p) | 5854 if (!sym->gcmarkbit && !pure_p) |
| 5713 { | 5855 { |
| 5714 *(struct Lisp_Symbol **) &sym->value = symbol_free_list; | 5856 sym->next = symbol_free_list; |
| 5715 symbol_free_list = sym; | 5857 symbol_free_list = sym; |
| 5716 #if GC_MARK_STACK | 5858 #if GC_MARK_STACK |
| 5717 symbol_free_list->function = Vdead; | 5859 symbol_free_list->function = Vdead; |
| 5718 #endif | 5860 #endif |
| 5719 ++this_free; | 5861 ++this_free; |
| 5733 this block. */ | 5875 this block. */ |
| 5734 if (this_free == SYMBOL_BLOCK_SIZE && num_free > SYMBOL_BLOCK_SIZE) | 5876 if (this_free == SYMBOL_BLOCK_SIZE && num_free > SYMBOL_BLOCK_SIZE) |
| 5735 { | 5877 { |
| 5736 *sprev = sblk->next; | 5878 *sprev = sblk->next; |
| 5737 /* Unhook from the free list. */ | 5879 /* Unhook from the free list. */ |
| 5738 symbol_free_list = *(struct Lisp_Symbol **)&sblk->symbols[0].value; | 5880 symbol_free_list = sblk->symbols[0].next; |
| 5739 lisp_free (sblk); | 5881 lisp_free (sblk); |
| 5740 n_symbol_blocks--; | 5882 n_symbol_blocks--; |
| 5741 } | 5883 } |
| 5742 else | 5884 else |
| 5743 { | 5885 { |
| 5961 malloc_hysteresis = 32; | 6103 malloc_hysteresis = 32; |
| 5962 #else | 6104 #else |
| 5963 malloc_hysteresis = 0; | 6105 malloc_hysteresis = 0; |
| 5964 #endif | 6106 #endif |
| 5965 | 6107 |
| 5966 spare_memory = (char *) malloc (SPARE_MEMORY); | 6108 refill_memory_reserve (); |
| 5967 | 6109 |
| 5968 ignore_warnings = 0; | 6110 ignore_warnings = 0; |
| 5969 gcprolist = 0; | 6111 gcprolist = 0; |
| 5970 byte_stack_list = 0; | 6112 byte_stack_list = 0; |
| 5971 staticidx = 0; | 6113 staticidx = 0; |
| 6062 Vmemory_signal_data | 6204 Vmemory_signal_data |
| 6063 = list2 (Qerror, | 6205 = list2 (Qerror, |
| 6064 build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); | 6206 build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); |
| 6065 | 6207 |
| 6066 DEFVAR_LISP ("memory-full", &Vmemory_full, | 6208 DEFVAR_LISP ("memory-full", &Vmemory_full, |
| 6067 doc: /* Non-nil means we are handling a memory-full error. */); | 6209 doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); |
| 6068 Vmemory_full = Qnil; | 6210 Vmemory_full = Qnil; |
| 6069 | 6211 |
| 6070 staticpro (&Qgc_cons_threshold); | 6212 staticpro (&Qgc_cons_threshold); |
| 6071 Qgc_cons_threshold = intern ("gc-cons-threshold"); | 6213 Qgc_cons_threshold = intern ("gc-cons-threshold"); |
| 6072 | 6214 |
| 6077 doc: /* Accumulated time elapsed in garbage collections. | 6219 doc: /* Accumulated time elapsed in garbage collections. |
| 6078 The time is in seconds as a floating point value. */); | 6220 The time is in seconds as a floating point value. */); |
| 6079 DEFVAR_INT ("gcs-done", &gcs_done, | 6221 DEFVAR_INT ("gcs-done", &gcs_done, |
| 6080 doc: /* Accumulated number of garbage collections done. */); | 6222 doc: /* Accumulated number of garbage collections done. */); |
| 6081 | 6223 |
| 6082 defsubr (&Smemory_full_p); | |
| 6083 defsubr (&Scons); | 6224 defsubr (&Scons); |
| 6084 defsubr (&Slist); | 6225 defsubr (&Slist); |
| 6085 defsubr (&Svector); | 6226 defsubr (&Svector); |
| 6086 defsubr (&Smake_byte_code); | 6227 defsubr (&Smake_byte_code); |
| 6087 defsubr (&Smake_list); | 6228 defsubr (&Smake_list); |
