diff options
| author | Richard M. Stallman | 2005-10-29 19:39:50 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2005-10-29 19:39:50 +0000 |
| commit | 24d8a105d8ee6a59fe5535d5d6117d0c1002aa71 (patch) | |
| tree | 94a1d013a0a82d9e1513e87a2f8cebf30fe09aa8 /src/alloc.c | |
| parent | b0820d6af046e736d6b94ef7c9e2386afdcf449d (diff) | |
| download | emacs-24d8a105d8ee6a59fe5535d5d6117d0c1002aa71.tar.gz emacs-24d8a105d8ee6a59fe5535d5d6117d0c1002aa71.zip | |
(syms_of_alloc) <memory-full>: Doc fix.
(Fmemory_full_p): Function deleted.
(syms_of_alloc): Don't defsubr it.
(memory_full_cons_threshold): New variable.
(spare_memory): Now a vector of 7 elts.
(buffer_memory_full): Don't set Vmemory_full here.
(xfree): Don't try to refill here.
(emacs_blocked_free): Record BYTES_USED in local var.
(memory_full): Now free all the slots in spare_memory.
(refill_memory_reserve): Allocate each slot in spare_memory.
(init_alloc_once): Call refill_memory_reserve.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 166 |
1 files changed, 102 insertions, 64 deletions
diff --git a/src/alloc.c b/src/alloc.c index b8744b3f09a..b18e313fc87 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -182,6 +182,11 @@ EMACS_INT gc_relative_threshold; | |||
| 182 | 182 | ||
| 183 | static Lisp_Object Vgc_cons_percentage; | 183 | static Lisp_Object Vgc_cons_percentage; |
| 184 | 184 | ||
| 185 | /* Minimum number of bytes of consing since GC before next GC, | ||
| 186 | when memory is full. */ | ||
| 187 | |||
| 188 | EMACS_INT memory_full_cons_threshold; | ||
| 189 | |||
| 185 | /* Nonzero during GC. */ | 190 | /* Nonzero during GC. */ |
| 186 | 191 | ||
| 187 | int gc_in_progress; | 192 | int gc_in_progress; |
| @@ -213,11 +218,12 @@ static int total_free_conses, total_free_markers, total_free_symbols; | |||
| 213 | static int total_free_floats, total_floats; | 218 | static int total_free_floats, total_floats; |
| 214 | 219 | ||
| 215 | /* Points to memory space allocated as "spare", to be freed if we run | 220 | /* Points to memory space allocated as "spare", to be freed if we run |
| 216 | out of memory. */ | 221 | out of memory. We keep one large block, four cons-blocks, and |
| 222 | two string blocks. */ | ||
| 217 | 223 | ||
| 218 | char *spare_memory; | 224 | char *spare_memory[7]; |
| 219 | 225 | ||
| 220 | /* Amount of spare memory to keep in reserve. */ | 226 | /* Amount of spare memory to keep in large reserve block. */ |
| 221 | 227 | ||
| 222 | #define SPARE_MEMORY (1 << 14) | 228 | #define SPARE_MEMORY (1 << 14) |
| 223 | 229 | ||
| @@ -350,6 +356,9 @@ enum mem_type | |||
| 350 | MEM_TYPE_WINDOW | 356 | MEM_TYPE_WINDOW |
| 351 | }; | 357 | }; |
| 352 | 358 | ||
| 359 | static POINTER_TYPE *lisp_align_malloc P_ ((size_t, enum mem_type)); | ||
| 360 | static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); | ||
| 361 | |||
| 353 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 362 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 354 | 363 | ||
| 355 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 364 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| @@ -449,6 +458,8 @@ static void mem_rotate_right P_ ((struct mem_node *)); | |||
| 449 | static void mem_delete P_ ((struct mem_node *)); | 458 | static void mem_delete P_ ((struct mem_node *)); |
| 450 | static void mem_delete_fixup P_ ((struct mem_node *)); | 459 | static void mem_delete_fixup P_ ((struct mem_node *)); |
| 451 | static INLINE struct mem_node *mem_find P_ ((void *)); | 460 | static INLINE struct mem_node *mem_find P_ ((void *)); |
| 461 | void refill_memory_reserve (); | ||
| 462 | |||
| 452 | 463 | ||
| 453 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 464 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
| 454 | static void check_gcpros P_ ((void)); | 465 | static void check_gcpros P_ ((void)); |
| @@ -514,53 +525,6 @@ display_malloc_warning () | |||
| 514 | #else | 525 | #else |
| 515 | # define BYTES_USED _bytes_used | 526 | # define BYTES_USED _bytes_used |
| 516 | #endif | 527 | #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 | 528 | ||
| 565 | /* Called if we can't allocate relocatable space for a buffer. */ | 529 | /* Called if we can't allocate relocatable space for a buffer. */ |
| 566 | 530 | ||
| @@ -578,8 +542,6 @@ buffer_memory_full () | |||
| 578 | memory_full (); | 542 | memory_full (); |
| 579 | #endif | 543 | #endif |
| 580 | 544 | ||
| 581 | Vmemory_full = Qt; | ||
| 582 | |||
| 583 | /* This used to call error, but if we've run out of memory, we could | 545 | /* This used to call error, but if we've run out of memory, we could |
| 584 | get infinite recursion trying to build the string. */ | 546 | get infinite recursion trying to build the string. */ |
| 585 | while (1) | 547 | while (1) |
| @@ -805,12 +767,9 @@ xfree (block) | |||
| 805 | BLOCK_INPUT; | 767 | BLOCK_INPUT; |
| 806 | free (block); | 768 | free (block); |
| 807 | UNBLOCK_INPUT; | 769 | UNBLOCK_INPUT; |
| 808 | 770 | /* We don't call refill_memory_reserve here | |
| 809 | #ifndef SYSTEM_MALLOC | 771 | because that duplicates doing so in emacs_blocked_free |
| 810 | /* Refill the spare memory if we can. */ | 772 | and the criterion should go there. */ |
| 811 | if (spare_memory == 0) | ||
| 812 | refill_memory_reserve (); | ||
| 813 | #endif | ||
| 814 | } | 773 | } |
| 815 | 774 | ||
| 816 | 775 | ||
| @@ -1184,6 +1143,8 @@ emacs_blocked_free (ptr, ptr2) | |||
| 1184 | void *ptr; | 1143 | void *ptr; |
| 1185 | const void *ptr2; | 1144 | const void *ptr2; |
| 1186 | { | 1145 | { |
| 1146 | EMACS_INT bytes_used_now; | ||
| 1147 | |||
| 1187 | BLOCK_INPUT_ALLOC; | 1148 | BLOCK_INPUT_ALLOC; |
| 1188 | 1149 | ||
| 1189 | #ifdef GC_MALLOC_CHECK | 1150 | #ifdef GC_MALLOC_CHECK |
| @@ -1212,14 +1173,15 @@ emacs_blocked_free (ptr, ptr2) | |||
| 1212 | /* If we released our reserve (due to running out of memory), | 1173 | /* If we released our reserve (due to running out of memory), |
| 1213 | and we have a fair amount free once again, | 1174 | and we have a fair amount free once again, |
| 1214 | try to set aside another reserve in case we run out once more. */ | 1175 | try to set aside another reserve in case we run out once more. */ |
| 1215 | if (spare_memory == 0 | 1176 | if (! NILP (Vmemory_full) |
| 1216 | /* Verify there is enough space that even with the malloc | 1177 | /* Verify there is enough space that even with the malloc |
| 1217 | hysteresis this call won't run out again. | 1178 | hysteresis this call won't run out again. |
| 1218 | The code here is correct as long as SPARE_MEMORY | 1179 | The code here is correct as long as SPARE_MEMORY |
| 1219 | is substantially larger than the block size malloc uses. */ | 1180 | is substantially larger than the block size malloc uses. */ |
| 1220 | && (bytes_used_when_full | 1181 | && (bytes_used_when_full |
| 1221 | > BYTES_USED + max (malloc_hysteresis, 4) * SPARE_MEMORY)) | 1182 | > ((bytes_used_now = BYTES_USED) |
| 1222 | spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | 1183 | + max (malloc_hysteresis, 4) * SPARE_MEMORY)) |
| 1184 | refill_memory_reserve (); | ||
| 1223 | 1185 | ||
| 1224 | __free_hook = emacs_blocked_free; | 1186 | __free_hook = emacs_blocked_free; |
| 1225 | UNBLOCK_INPUT_ALLOC; | 1187 | UNBLOCK_INPUT_ALLOC; |
| @@ -3386,6 +3348,83 @@ make_event_array (nargs, args) | |||
| 3386 | 3348 | ||
| 3387 | 3349 | ||
| 3388 | /************************************************************************ | 3350 | /************************************************************************ |
| 3351 | Memory Full Handling | ||
| 3352 | ************************************************************************/ | ||
| 3353 | |||
| 3354 | |||
| 3355 | /* Called if malloc returns zero. */ | ||
| 3356 | |||
| 3357 | void | ||
| 3358 | memory_full () | ||
| 3359 | { | ||
| 3360 | int i; | ||
| 3361 | |||
| 3362 | Vmemory_full = Qt; | ||
| 3363 | |||
| 3364 | memory_full_cons_threshold = sizeof (struct cons_block); | ||
| 3365 | |||
| 3366 | /* The first time we get here, free the spare memory. */ | ||
| 3367 | for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) | ||
| 3368 | if (spare_memory[i]) | ||
| 3369 | { | ||
| 3370 | if (i == 0) | ||
| 3371 | free (spare_memory[i]); | ||
| 3372 | else if (i >= 1 && i <= 4) | ||
| 3373 | lisp_align_free (spare_memory[i]); | ||
| 3374 | else | ||
| 3375 | lisp_free (spare_memory[i]); | ||
| 3376 | spare_memory[i] = 0; | ||
| 3377 | } | ||
| 3378 | |||
| 3379 | /* Record the space now used. When it decreases substantially, | ||
| 3380 | we can refill the memory reserve. */ | ||
| 3381 | #ifndef SYSTEM_MALLOC | ||
| 3382 | bytes_used_when_full = BYTES_USED; | ||
| 3383 | #endif | ||
| 3384 | |||
| 3385 | /* This used to call error, but if we've run out of memory, we could | ||
| 3386 | get infinite recursion trying to build the string. */ | ||
| 3387 | while (1) | ||
| 3388 | Fsignal (Qnil, Vmemory_signal_data); | ||
| 3389 | } | ||
| 3390 | |||
| 3391 | /* If we released our reserve (due to running out of memory), | ||
| 3392 | and we have a fair amount free once again, | ||
| 3393 | try to set aside another reserve in case we run out once more. | ||
| 3394 | |||
| 3395 | This is called when a relocatable block is freed in ralloc.c, | ||
| 3396 | and also directly from this file, in case we're not using ralloc.c. */ | ||
| 3397 | |||
| 3398 | void | ||
| 3399 | refill_memory_reserve () | ||
| 3400 | { | ||
| 3401 | #ifndef SYSTEM_MALLOC | ||
| 3402 | if (spare_memory[0] == 0) | ||
| 3403 | spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY); | ||
| 3404 | if (spare_memory[1] == 0) | ||
| 3405 | spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3406 | MEM_TYPE_CONS); | ||
| 3407 | if (spare_memory[2] == 0) | ||
| 3408 | spare_memory[2] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3409 | MEM_TYPE_CONS); | ||
| 3410 | if (spare_memory[3] == 0) | ||
| 3411 | spare_memory[3] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3412 | MEM_TYPE_CONS); | ||
| 3413 | if (spare_memory[4] == 0) | ||
| 3414 | spare_memory[4] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3415 | MEM_TYPE_CONS); | ||
| 3416 | if (spare_memory[5] == 0) | ||
| 3417 | spare_memory[5] = (char *) lisp_malloc (sizeof (struct string_block), | ||
| 3418 | MEM_TYPE_STRING); | ||
| 3419 | if (spare_memory[6] == 0) | ||
| 3420 | spare_memory[6] = (char *) lisp_malloc (sizeof (struct string_block), | ||
| 3421 | MEM_TYPE_STRING); | ||
| 3422 | if (spare_memory[0] && spare_memory[1] && spare_memory[5]) | ||
| 3423 | Vmemory_full = Qnil; | ||
| 3424 | #endif | ||
| 3425 | } | ||
| 3426 | |||
| 3427 | /************************************************************************ | ||
| 3389 | C Stack Marking | 3428 | C Stack Marking |
| 3390 | ************************************************************************/ | 3429 | ************************************************************************/ |
| 3391 | 3430 | ||
| @@ -6012,7 +6051,7 @@ init_alloc_once () | |||
| 6012 | malloc_hysteresis = 0; | 6051 | malloc_hysteresis = 0; |
| 6013 | #endif | 6052 | #endif |
| 6014 | 6053 | ||
| 6015 | spare_memory = (char *) malloc (SPARE_MEMORY); | 6054 | refill_memory_reserve (); |
| 6016 | 6055 | ||
| 6017 | ignore_warnings = 0; | 6056 | ignore_warnings = 0; |
| 6018 | gcprolist = 0; | 6057 | gcprolist = 0; |
| @@ -6113,7 +6152,7 @@ This means that certain objects should be allocated in shared (pure) space. */) | |||
| 6113 | build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); | 6152 | build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); |
| 6114 | 6153 | ||
| 6115 | DEFVAR_LISP ("memory-full", &Vmemory_full, | 6154 | DEFVAR_LISP ("memory-full", &Vmemory_full, |
| 6116 | doc: /* Non-nil means we are handling a memory-full error. */); | 6155 | doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); |
| 6117 | Vmemory_full = Qnil; | 6156 | Vmemory_full = Qnil; |
| 6118 | 6157 | ||
| 6119 | staticpro (&Qgc_cons_threshold); | 6158 | staticpro (&Qgc_cons_threshold); |
| @@ -6128,7 +6167,6 @@ The time is in seconds as a floating point value. */); | |||
| 6128 | DEFVAR_INT ("gcs-done", &gcs_done, | 6167 | DEFVAR_INT ("gcs-done", &gcs_done, |
| 6129 | doc: /* Accumulated number of garbage collections done. */); | 6168 | doc: /* Accumulated number of garbage collections done. */); |
| 6130 | 6169 | ||
| 6131 | defsubr (&Smemory_full_p); | ||
| 6132 | defsubr (&Scons); | 6170 | defsubr (&Scons); |
| 6133 | defsubr (&Slist); | 6171 | defsubr (&Slist); |
| 6134 | defsubr (&Svector); | 6172 | defsubr (&Svector); |