diff options
| author | Paul Eggert | 2011-05-30 09:47:35 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-05-30 09:47:35 -0700 |
| commit | 531b01656f89e093b9fa35959fa41e534b025320 (patch) | |
| tree | 190b5a279e0e8e0130b6ba070fa217ce1282e2f3 /src/alloc.c | |
| parent | de677ace77fa48962be80b668662a7009498e5d6 (diff) | |
| download | emacs-531b01656f89e093b9fa35959fa41e534b025320.tar.gz emacs-531b01656f89e093b9fa35959fa41e534b025320.zip | |
[ChangeLog]
Malloc failure behavior now depends on size of allocation.
* lib/allocator.h (struct allocator.die): New size arg.
* lib/careadlinkat.c (careadlinkat): Pass size to 'die' function.
If the actual problem is an ssize_t limitation, not a size_t or
malloc failure, fail with errno == ENAMETOOLONG instead of calling 'die'.
[src/ChangeLog]
Malloc failure behavior now depends on size of allocation.
* alloc.c (buffer_memory_full, memory_full): New arg NBYTES.
* lisp.h: Change signatures accordingly.
* alloc.c, buffer.c, editfns.c, menu.c, minibuf.c, xterm.c:
All callers changed.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 78 |
1 files changed, 51 insertions, 27 deletions
diff --git a/src/alloc.c b/src/alloc.c index 8215cc53cd3..be045be2ab4 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -471,7 +471,7 @@ display_malloc_warning (void) | |||
| 471 | /* Called if we can't allocate relocatable space for a buffer. */ | 471 | /* Called if we can't allocate relocatable space for a buffer. */ |
| 472 | 472 | ||
| 473 | void | 473 | void |
| 474 | buffer_memory_full (void) | 474 | buffer_memory_full (EMACS_INT nbytes) |
| 475 | { | 475 | { |
| 476 | /* If buffers use the relocating allocator, no need to free | 476 | /* If buffers use the relocating allocator, no need to free |
| 477 | spare_memory, because we may have plenty of malloc space left | 477 | spare_memory, because we may have plenty of malloc space left |
| @@ -481,7 +481,7 @@ buffer_memory_full (void) | |||
| 481 | malloc. */ | 481 | malloc. */ |
| 482 | 482 | ||
| 483 | #ifndef REL_ALLOC | 483 | #ifndef REL_ALLOC |
| 484 | memory_full (); | 484 | memory_full (nbytes); |
| 485 | #endif | 485 | #endif |
| 486 | 486 | ||
| 487 | /* This used to call error, but if we've run out of memory, we could | 487 | /* This used to call error, but if we've run out of memory, we could |
| @@ -677,7 +677,7 @@ xmalloc (size_t size) | |||
| 677 | MALLOC_UNBLOCK_INPUT; | 677 | MALLOC_UNBLOCK_INPUT; |
| 678 | 678 | ||
| 679 | if (!val && size) | 679 | if (!val && size) |
| 680 | memory_full (); | 680 | memory_full (size); |
| 681 | return val; | 681 | return val; |
| 682 | } | 682 | } |
| 683 | 683 | ||
| @@ -698,7 +698,8 @@ xrealloc (POINTER_TYPE *block, size_t size) | |||
| 698 | val = (POINTER_TYPE *) realloc (block, size); | 698 | val = (POINTER_TYPE *) realloc (block, size); |
| 699 | MALLOC_UNBLOCK_INPUT; | 699 | MALLOC_UNBLOCK_INPUT; |
| 700 | 700 | ||
| 701 | if (!val && size) memory_full (); | 701 | if (!val && size) |
| 702 | memory_full (size); | ||
| 702 | return val; | 703 | return val; |
| 703 | } | 704 | } |
| 704 | 705 | ||
| @@ -791,7 +792,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 791 | 792 | ||
| 792 | MALLOC_UNBLOCK_INPUT; | 793 | MALLOC_UNBLOCK_INPUT; |
| 793 | if (!val && nbytes) | 794 | if (!val && nbytes) |
| 794 | memory_full (); | 795 | memory_full (nbytes); |
| 795 | return val; | 796 | return val; |
| 796 | } | 797 | } |
| 797 | 798 | ||
| @@ -938,7 +939,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 938 | if (base == 0) | 939 | if (base == 0) |
| 939 | { | 940 | { |
| 940 | MALLOC_UNBLOCK_INPUT; | 941 | MALLOC_UNBLOCK_INPUT; |
| 941 | memory_full (); | 942 | memory_full (ABLOCKS_BYTES); |
| 942 | } | 943 | } |
| 943 | 944 | ||
| 944 | aligned = (base == abase); | 945 | aligned = (base == abase); |
| @@ -964,7 +965,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 964 | lisp_malloc_loser = base; | 965 | lisp_malloc_loser = base; |
| 965 | free (base); | 966 | free (base); |
| 966 | MALLOC_UNBLOCK_INPUT; | 967 | MALLOC_UNBLOCK_INPUT; |
| 967 | memory_full (); | 968 | memory_full (SIZE_MAX); |
| 968 | } | 969 | } |
| 969 | } | 970 | } |
| 970 | #endif | 971 | #endif |
| @@ -3270,35 +3271,58 @@ make_event_array (register int nargs, Lisp_Object *args) | |||
| 3270 | ************************************************************************/ | 3271 | ************************************************************************/ |
| 3271 | 3272 | ||
| 3272 | 3273 | ||
| 3273 | /* Called if malloc returns zero. */ | 3274 | /* Called if malloc (NBYTES) returns zero. If NBYTES == SIZE_MAX, |
| 3275 | there may have been size_t overflow so that malloc was never | ||
| 3276 | called, or perhaps malloc was invoked successfully but the | ||
| 3277 | resulting pointer had problems fitting into a tagged EMACS_INT. In | ||
| 3278 | either case this counts as memory being full even though malloc did | ||
| 3279 | not fail. */ | ||
| 3274 | 3280 | ||
| 3275 | void | 3281 | void |
| 3276 | memory_full (void) | 3282 | memory_full (size_t nbytes) |
| 3277 | { | 3283 | { |
| 3278 | int i; | 3284 | /* Do not go into hysterics merely because a large request failed. */ |
| 3285 | int enough_free_memory = 0; | ||
| 3286 | if (SPARE_MEMORY < nbytes) | ||
| 3287 | { | ||
| 3288 | void *p = malloc (SPARE_MEMORY); | ||
| 3289 | if (p) | ||
| 3290 | { | ||
| 3291 | if (spare_memory[0]) | ||
| 3292 | free (p); | ||
| 3293 | else | ||
| 3294 | spare_memory[0] = p; | ||
| 3295 | enough_free_memory = 1; | ||
| 3296 | } | ||
| 3297 | } | ||
| 3279 | 3298 | ||
| 3280 | Vmemory_full = Qt; | 3299 | if (! enough_free_memory) |
| 3300 | { | ||
| 3301 | int i; | ||
| 3281 | 3302 | ||
| 3282 | memory_full_cons_threshold = sizeof (struct cons_block); | 3303 | Vmemory_full = Qt; |
| 3283 | 3304 | ||
| 3284 | /* The first time we get here, free the spare memory. */ | 3305 | memory_full_cons_threshold = sizeof (struct cons_block); |
| 3285 | for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) | 3306 | |
| 3286 | if (spare_memory[i]) | 3307 | /* The first time we get here, free the spare memory. */ |
| 3287 | { | 3308 | for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) |
| 3288 | if (i == 0) | 3309 | if (spare_memory[i]) |
| 3289 | free (spare_memory[i]); | 3310 | { |
| 3290 | else if (i >= 1 && i <= 4) | 3311 | if (i == 0) |
| 3291 | lisp_align_free (spare_memory[i]); | 3312 | free (spare_memory[i]); |
| 3292 | else | 3313 | else if (i >= 1 && i <= 4) |
| 3293 | lisp_free (spare_memory[i]); | 3314 | lisp_align_free (spare_memory[i]); |
| 3294 | spare_memory[i] = 0; | 3315 | else |
| 3295 | } | 3316 | lisp_free (spare_memory[i]); |
| 3317 | spare_memory[i] = 0; | ||
| 3318 | } | ||
| 3296 | 3319 | ||
| 3297 | /* Record the space now used. When it decreases substantially, | 3320 | /* Record the space now used. When it decreases substantially, |
| 3298 | we can refill the memory reserve. */ | 3321 | we can refill the memory reserve. */ |
| 3299 | #if !defined SYSTEM_MALLOC && !defined SYNC_INPUT | 3322 | #if !defined SYSTEM_MALLOC && !defined SYNC_INPUT |
| 3300 | bytes_used_when_full = BYTES_USED; | 3323 | bytes_used_when_full = BYTES_USED; |
| 3301 | #endif | 3324 | #endif |
| 3325 | } | ||
| 3302 | 3326 | ||
| 3303 | /* This used to call error, but if we've run out of memory, we could | 3327 | /* This used to call error, but if we've run out of memory, we could |
| 3304 | get infinite recursion trying to build the string. */ | 3328 | get infinite recursion trying to build the string. */ |