diff options
| author | Karoly Lorentey | 2005-11-07 14:56:19 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2005-11-07 14:56:19 +0000 |
| commit | 79c3172f78d56cf88c927fb0ff5c3b30fd676686 (patch) | |
| tree | 20932caaa9695f3bb29b543f46107319a687308d /src/alloc.c | |
| parent | 9684e4c92f12f7c31f5e6fda7742960b403395f6 (diff) | |
| parent | fab0d3087eb5215a5d08379ac765af27abc28842 (diff) | |
| download | emacs-79c3172f78d56cf88c927fb0ff5c3b30fd676686.tar.gz emacs-79c3172f78d56cf88c927fb0ff5c3b30fd676686.zip | |
Merged from miles@gnu.org--gnu-2005 (patch 149-151, 629-641)
Patches applied:
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-629
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-630
Merge from gnus--rel--5.10
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-631
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-632
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-633
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-634
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-635
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-636
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-637
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-638
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-639
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-640
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-641
Update from CVS
* miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-149
Merge from emacs--cvs-trunk--0
* miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-150
Update from CVS
* miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-151
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-437
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 165 |
1 files changed, 106 insertions, 59 deletions
diff --git a/src/alloc.c b/src/alloc.c index ff0c3d46d44..1e95447549b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -138,6 +138,8 @@ static pthread_mutex_t alloc_mutex; | |||
| 138 | 138 | ||
| 139 | static __malloc_size_t bytes_used_when_full; | 139 | static __malloc_size_t bytes_used_when_full; |
| 140 | 140 | ||
| 141 | static __malloc_size_t bytes_used_when_reconsidered; | ||
| 142 | |||
| 141 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer | 143 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer |
| 142 | to a struct Lisp_String. */ | 144 | to a struct Lisp_String. */ |
| 143 | 145 | ||
| @@ -182,6 +184,11 @@ EMACS_INT gc_relative_threshold; | |||
| 182 | 184 | ||
| 183 | static Lisp_Object Vgc_cons_percentage; | 185 | static Lisp_Object Vgc_cons_percentage; |
| 184 | 186 | ||
| 187 | /* Minimum number of bytes of consing since GC before next GC, | ||
| 188 | when memory is full. */ | ||
| 189 | |||
| 190 | EMACS_INT memory_full_cons_threshold; | ||
| 191 | |||
| 185 | /* Nonzero during GC. */ | 192 | /* Nonzero during GC. */ |
| 186 | 193 | ||
| 187 | int gc_in_progress; | 194 | int gc_in_progress; |
| @@ -213,11 +220,12 @@ static int total_free_conses, total_free_markers, total_free_symbols; | |||
| 213 | static int total_free_floats, total_floats; | 220 | static int total_free_floats, total_floats; |
| 214 | 221 | ||
| 215 | /* Points to memory space allocated as "spare", to be freed if we run | 222 | /* Points to memory space allocated as "spare", to be freed if we run |
| 216 | out of memory. */ | 223 | out of memory. We keep one large block, four cons-blocks, and |
| 224 | two string blocks. */ | ||
| 217 | 225 | ||
| 218 | static char *spare_memory; | 226 | char *spare_memory[7]; |
| 219 | 227 | ||
| 220 | /* Amount of spare memory to keep in reserve. */ | 228 | /* Amount of spare memory to keep in large reserve block. */ |
| 221 | 229 | ||
| 222 | #define SPARE_MEMORY (1 << 14) | 230 | #define SPARE_MEMORY (1 << 14) |
| 223 | 231 | ||
| @@ -351,6 +359,11 @@ enum mem_type | |||
| 351 | MEM_TYPE_WINDOW | 359 | MEM_TYPE_WINDOW |
| 352 | }; | 360 | }; |
| 353 | 361 | ||
| 362 | static POINTER_TYPE *lisp_align_malloc P_ ((size_t, enum mem_type)); | ||
| 363 | static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); | ||
| 364 | void refill_memory_reserve (); | ||
| 365 | |||
| 366 | |||
| 354 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 367 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 355 | 368 | ||
| 356 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 369 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| @@ -451,6 +464,7 @@ static void mem_delete P_ ((struct mem_node *)); | |||
| 451 | static void mem_delete_fixup P_ ((struct mem_node *)); | 464 | static void mem_delete_fixup P_ ((struct mem_node *)); |
| 452 | static INLINE struct mem_node *mem_find P_ ((void *)); | 465 | static INLINE struct mem_node *mem_find P_ ((void *)); |
| 453 | 466 | ||
| 467 | |||
| 454 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 468 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
| 455 | static void check_gcpros P_ ((void)); | 469 | static void check_gcpros P_ ((void)); |
| 456 | #endif | 470 | #endif |
| @@ -511,57 +525,10 @@ display_malloc_warning () | |||
| 511 | 525 | ||
| 512 | 526 | ||
| 513 | #ifdef DOUG_LEA_MALLOC | 527 | #ifdef DOUG_LEA_MALLOC |
| 514 | # define BYTES_USED (mallinfo ().arena) | 528 | # define BYTES_USED (mallinfo ().uordblks) |
| 515 | #else | 529 | #else |
| 516 | # define BYTES_USED _bytes_used | 530 | # define BYTES_USED _bytes_used |
| 517 | #endif | 531 | #endif |
| 518 | |||
| 519 | |||
| 520 | /* Called if malloc returns zero. */ | ||
| 521 | |||
| 522 | void | ||
| 523 | memory_full () | ||
| 524 | { | ||
| 525 | Vmemory_full = Qt; | ||
| 526 | |||
| 527 | #ifndef SYSTEM_MALLOC | ||
| 528 | bytes_used_when_full = BYTES_USED; | ||
| 529 | #endif | ||
| 530 | |||
| 531 | /* The first time we get here, free the spare memory. */ | ||
| 532 | if (spare_memory) | ||
| 533 | { | ||
| 534 | free (spare_memory); | ||
| 535 | spare_memory = 0; | ||
| 536 | } | ||
| 537 | |||
| 538 | /* This used to call error, but if we've run out of memory, we could | ||
| 539 | get infinite recursion trying to build the string. */ | ||
| 540 | while (1) | ||
| 541 | Fsignal (Qnil, Vmemory_signal_data); | ||
| 542 | } | ||
| 543 | |||
| 544 | DEFUN ("memory-full-p", Fmemory_full_p, Smemory_full_p, 0, 0, 0, | ||
| 545 | doc: /* t if memory is nearly full, nil otherwise. */) | ||
| 546 | () | ||
| 547 | { | ||
| 548 | return (spare_memory ? Qnil : Qt); | ||
| 549 | } | ||
| 550 | |||
| 551 | /* If we released our reserve (due to running out of memory), | ||
| 552 | and we have a fair amount free once again, | ||
| 553 | try to set aside another reserve in case we run out once more. | ||
| 554 | |||
| 555 | This is called when a relocatable block is freed in ralloc.c. */ | ||
| 556 | |||
| 557 | void | ||
| 558 | refill_memory_reserve () | ||
| 559 | { | ||
| 560 | #ifndef SYSTEM_MALLOC | ||
| 561 | if (spare_memory == 0) | ||
| 562 | spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | ||
| 563 | #endif | ||
| 564 | } | ||
| 565 | 532 | ||
| 566 | /* Called if we can't allocate relocatable space for a buffer. */ | 533 | /* Called if we can't allocate relocatable space for a buffer. */ |
| 567 | 534 | ||
| @@ -579,8 +546,6 @@ buffer_memory_full () | |||
| 579 | memory_full (); | 546 | memory_full (); |
| 580 | #endif | 547 | #endif |
| 581 | 548 | ||
| 582 | Vmemory_full = Qt; | ||
| 583 | |||
| 584 | /* This used to call error, but if we've run out of memory, we could | 549 | /* This used to call error, but if we've run out of memory, we could |
| 585 | get infinite recursion trying to build the string. */ | 550 | get infinite recursion trying to build the string. */ |
| 586 | while (1) | 551 | while (1) |
| @@ -806,6 +771,9 @@ xfree (block) | |||
| 806 | BLOCK_INPUT; | 771 | BLOCK_INPUT; |
| 807 | free (block); | 772 | free (block); |
| 808 | UNBLOCK_INPUT; | 773 | UNBLOCK_INPUT; |
| 774 | /* We don't call refill_memory_reserve here | ||
| 775 | because that duplicates doing so in emacs_blocked_free | ||
| 776 | and the criterion should go there. */ | ||
| 809 | } | 777 | } |
| 810 | 778 | ||
| 811 | 779 | ||
| @@ -1179,6 +1147,8 @@ emacs_blocked_free (ptr, ptr2) | |||
| 1179 | void *ptr; | 1147 | void *ptr; |
| 1180 | const void *ptr2; | 1148 | const void *ptr2; |
| 1181 | { | 1149 | { |
| 1150 | EMACS_INT bytes_used_now; | ||
| 1151 | |||
| 1182 | BLOCK_INPUT_ALLOC; | 1152 | BLOCK_INPUT_ALLOC; |
| 1183 | 1153 | ||
| 1184 | #ifdef GC_MALLOC_CHECK | 1154 | #ifdef GC_MALLOC_CHECK |
| @@ -1207,14 +1177,15 @@ emacs_blocked_free (ptr, ptr2) | |||
| 1207 | /* If we released our reserve (due to running out of memory), | 1177 | /* If we released our reserve (due to running out of memory), |
| 1208 | and we have a fair amount free once again, | 1178 | and we have a fair amount free once again, |
| 1209 | try to set aside another reserve in case we run out once more. */ | 1179 | try to set aside another reserve in case we run out once more. */ |
| 1210 | if (spare_memory == 0 | 1180 | if (! NILP (Vmemory_full) |
| 1211 | /* Verify there is enough space that even with the malloc | 1181 | /* Verify there is enough space that even with the malloc |
| 1212 | hysteresis this call won't run out again. | 1182 | hysteresis this call won't run out again. |
| 1213 | The code here is correct as long as SPARE_MEMORY | 1183 | The code here is correct as long as SPARE_MEMORY |
| 1214 | is substantially larger than the block size malloc uses. */ | 1184 | is substantially larger than the block size malloc uses. */ |
| 1215 | && (bytes_used_when_full | 1185 | && (bytes_used_when_full |
| 1216 | > BYTES_USED + max (malloc_hysteresis, 4) * SPARE_MEMORY)) | 1186 | > ((bytes_used_when_reconsidered = BYTES_USED) |
| 1217 | spare_memory = (char *) malloc ((size_t) SPARE_MEMORY); | 1187 | + max (malloc_hysteresis, 4) * SPARE_MEMORY))) |
| 1188 | refill_memory_reserve (); | ||
| 1218 | 1189 | ||
| 1219 | __free_hook = emacs_blocked_free; | 1190 | __free_hook = emacs_blocked_free; |
| 1220 | UNBLOCK_INPUT_ALLOC; | 1191 | UNBLOCK_INPUT_ALLOC; |
| @@ -3381,6 +3352,83 @@ make_event_array (nargs, args) | |||
| 3381 | 3352 | ||
| 3382 | 3353 | ||
| 3383 | /************************************************************************ | 3354 | /************************************************************************ |
| 3355 | Memory Full Handling | ||
| 3356 | ************************************************************************/ | ||
| 3357 | |||
| 3358 | |||
| 3359 | /* Called if malloc returns zero. */ | ||
| 3360 | |||
| 3361 | void | ||
| 3362 | memory_full () | ||
| 3363 | { | ||
| 3364 | int i; | ||
| 3365 | |||
| 3366 | Vmemory_full = Qt; | ||
| 3367 | |||
| 3368 | memory_full_cons_threshold = sizeof (struct cons_block); | ||
| 3369 | |||
| 3370 | /* The first time we get here, free the spare memory. */ | ||
| 3371 | for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) | ||
| 3372 | if (spare_memory[i]) | ||
| 3373 | { | ||
| 3374 | if (i == 0) | ||
| 3375 | free (spare_memory[i]); | ||
| 3376 | else if (i >= 1 && i <= 4) | ||
| 3377 | lisp_align_free (spare_memory[i]); | ||
| 3378 | else | ||
| 3379 | lisp_free (spare_memory[i]); | ||
| 3380 | spare_memory[i] = 0; | ||
| 3381 | } | ||
| 3382 | |||
| 3383 | /* Record the space now used. When it decreases substantially, | ||
| 3384 | we can refill the memory reserve. */ | ||
| 3385 | #ifndef SYSTEM_MALLOC | ||
| 3386 | bytes_used_when_full = BYTES_USED; | ||
| 3387 | #endif | ||
| 3388 | |||
| 3389 | /* This used to call error, but if we've run out of memory, we could | ||
| 3390 | get infinite recursion trying to build the string. */ | ||
| 3391 | while (1) | ||
| 3392 | Fsignal (Qnil, Vmemory_signal_data); | ||
| 3393 | } | ||
| 3394 | |||
| 3395 | /* If we released our reserve (due to running out of memory), | ||
| 3396 | and we have a fair amount free once again, | ||
| 3397 | try to set aside another reserve in case we run out once more. | ||
| 3398 | |||
| 3399 | This is called when a relocatable block is freed in ralloc.c, | ||
| 3400 | and also directly from this file, in case we're not using ralloc.c. */ | ||
| 3401 | |||
| 3402 | void | ||
| 3403 | refill_memory_reserve () | ||
| 3404 | { | ||
| 3405 | #ifndef SYSTEM_MALLOC | ||
| 3406 | if (spare_memory[0] == 0) | ||
| 3407 | spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY); | ||
| 3408 | if (spare_memory[1] == 0) | ||
| 3409 | spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3410 | MEM_TYPE_CONS); | ||
| 3411 | if (spare_memory[2] == 0) | ||
| 3412 | spare_memory[2] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3413 | MEM_TYPE_CONS); | ||
| 3414 | if (spare_memory[3] == 0) | ||
| 3415 | spare_memory[3] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3416 | MEM_TYPE_CONS); | ||
| 3417 | if (spare_memory[4] == 0) | ||
| 3418 | spare_memory[4] = (char *) lisp_align_malloc (sizeof (struct cons_block), | ||
| 3419 | MEM_TYPE_CONS); | ||
| 3420 | if (spare_memory[5] == 0) | ||
| 3421 | spare_memory[5] = (char *) lisp_malloc (sizeof (struct string_block), | ||
| 3422 | MEM_TYPE_STRING); | ||
| 3423 | if (spare_memory[6] == 0) | ||
| 3424 | spare_memory[6] = (char *) lisp_malloc (sizeof (struct string_block), | ||
| 3425 | MEM_TYPE_STRING); | ||
| 3426 | if (spare_memory[0] && spare_memory[1] && spare_memory[5]) | ||
| 3427 | Vmemory_full = Qnil; | ||
| 3428 | #endif | ||
| 3429 | } | ||
| 3430 | |||
| 3431 | /************************************************************************ | ||
| 3384 | C Stack Marking | 3432 | C Stack Marking |
| 3385 | ************************************************************************/ | 3433 | ************************************************************************/ |
| 3386 | 3434 | ||
| @@ -6008,7 +6056,7 @@ init_alloc_once () | |||
| 6008 | malloc_hysteresis = 0; | 6056 | malloc_hysteresis = 0; |
| 6009 | #endif | 6057 | #endif |
| 6010 | 6058 | ||
| 6011 | spare_memory = (char *) malloc (SPARE_MEMORY); | 6059 | refill_memory_reserve (); |
| 6012 | 6060 | ||
| 6013 | ignore_warnings = 0; | 6061 | ignore_warnings = 0; |
| 6014 | gcprolist = 0; | 6062 | gcprolist = 0; |
| @@ -6109,7 +6157,7 @@ This means that certain objects should be allocated in shared (pure) space. */) | |||
| 6109 | build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); | 6157 | build_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); |
| 6110 | 6158 | ||
| 6111 | DEFVAR_LISP ("memory-full", &Vmemory_full, | 6159 | DEFVAR_LISP ("memory-full", &Vmemory_full, |
| 6112 | doc: /* Non-nil means we are handling a memory-full error. */); | 6160 | doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); |
| 6113 | Vmemory_full = Qnil; | 6161 | Vmemory_full = Qnil; |
| 6114 | 6162 | ||
| 6115 | staticpro (&Qgc_cons_threshold); | 6163 | staticpro (&Qgc_cons_threshold); |
| @@ -6124,7 +6172,6 @@ The time is in seconds as a floating point value. */); | |||
| 6124 | DEFVAR_INT ("gcs-done", &gcs_done, | 6172 | DEFVAR_INT ("gcs-done", &gcs_done, |
| 6125 | doc: /* Accumulated number of garbage collections done. */); | 6173 | doc: /* Accumulated number of garbage collections done. */); |
| 6126 | 6174 | ||
| 6127 | defsubr (&Smemory_full_p); | ||
| 6128 | defsubr (&Scons); | 6175 | defsubr (&Scons); |
| 6129 | defsubr (&Slist); | 6176 | defsubr (&Slist); |
| 6130 | defsubr (&Svector); | 6177 | defsubr (&Svector); |