diff options
| -rw-r--r-- | src/ChangeLog | 16 | ||||
| -rw-r--r-- | src/alloc.c | 80 | ||||
| -rw-r--r-- | src/buffer.c | 6 | ||||
| -rw-r--r-- | src/editfns.c | 2 | ||||
| -rw-r--r-- | src/gnutls.c | 18 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/menu.c | 2 | ||||
| -rw-r--r-- | src/minibuf.c | 2 | ||||
| -rw-r--r-- | src/xterm.c | 2 |
9 files changed, 90 insertions, 42 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 703976e4700..45d8e38738a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,21 @@ 2011-06-02 Paul Eggert <eggert@cs.ucla.edu> + 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. (Bug#8762) + + * gnutls.c: Use Emacs's memory allocators. + Without this change, the gnutls library would invoke malloc etc. + directly, which causes problems on non-SYNC_INPUT hosts, and which + runs afoul of improving memory_full behavior. (Bug#8761) + (fn_gnutls_global_set_mem_functions): New macro or function pointer. + (emacs_gnutls_global_init): Use it to specify xmalloc, xrealloc, + xfree instead of the default malloc, realloc, free. + (Fgnutls_boot): No need to check for memory allocation failure, + since xmalloc does that for us. + Remove arbitrary limit of 2**31 entries in hash tables. (Bug#8771) * category.c (hash_get_category_set): * ccl.c (ccl_driver): diff --git a/src/alloc.c b/src/alloc.c index 8fcc6f91df9..0c18fca1755 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -467,7 +467,7 @@ display_malloc_warning (void) /* Called if we can't allocate relocatable space for a buffer. */ void -buffer_memory_full (void) +buffer_memory_full (EMACS_INT nbytes) { /* If buffers use the relocating allocator, no need to free spare_memory, because we may have plenty of malloc space left @@ -477,7 +477,7 @@ buffer_memory_full (void) malloc. */ #ifndef REL_ALLOC - memory_full (); + memory_full (nbytes); #endif /* This used to call error, but if we've run out of memory, we could @@ -673,7 +673,7 @@ xmalloc (size_t size) MALLOC_UNBLOCK_INPUT; if (!val && size) - memory_full (); + memory_full (size); return val; } @@ -694,7 +694,8 @@ xrealloc (POINTER_TYPE *block, size_t size) val = (POINTER_TYPE *) realloc (block, size); MALLOC_UNBLOCK_INPUT; - if (!val && size) memory_full (); + if (!val && size) + memory_full (size); return val; } @@ -787,7 +788,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) MALLOC_UNBLOCK_INPUT; if (!val && nbytes) - memory_full (); + memory_full (nbytes); return val; } @@ -934,7 +935,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) if (base == 0) { MALLOC_UNBLOCK_INPUT; - memory_full (); + memory_full (ABLOCKS_BYTES); } aligned = (base == abase); @@ -960,7 +961,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) lisp_malloc_loser = base; free (base); MALLOC_UNBLOCK_INPUT; - memory_full (); + memory_full (SIZE_MAX); } } #endif @@ -2792,7 +2793,7 @@ allocate_vectorlike (EMACS_INT len) int word_size = sizeof p->contents[0]; if ((SIZE_MAX - header_size) / word_size < len) - memory_full (); + memory_full (SIZE_MAX); MALLOC_BLOCK_INPUT; @@ -3270,35 +3271,58 @@ make_event_array (register int nargs, Lisp_Object *args) ************************************************************************/ -/* Called if malloc returns zero. */ +/* Called if malloc (NBYTES) returns zero. If NBYTES == SIZE_MAX, + there may have been size_t overflow so that malloc was never + called, or perhaps malloc was invoked successfully but the + resulting pointer had problems fitting into a tagged EMACS_INT. In + either case this counts as memory being full even though malloc did + not fail. */ void -memory_full (void) +memory_full (size_t nbytes) { - int i; + /* Do not go into hysterics merely because a large request failed. */ + int enough_free_memory = 0; + if (SPARE_MEMORY < nbytes) + { + void *p = malloc (SPARE_MEMORY); + if (p) + { + if (spare_memory[0]) + free (p); + else + spare_memory[0] = p; + enough_free_memory = 1; + } + } - Vmemory_full = Qt; + if (! enough_free_memory) + { + int i; - memory_full_cons_threshold = sizeof (struct cons_block); + Vmemory_full = Qt; - /* The first time we get here, free the spare memory. */ - for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) - if (spare_memory[i]) - { - if (i == 0) - free (spare_memory[i]); - else if (i >= 1 && i <= 4) - lisp_align_free (spare_memory[i]); - else - lisp_free (spare_memory[i]); - spare_memory[i] = 0; - } + memory_full_cons_threshold = sizeof (struct cons_block); + + /* The first time we get here, free the spare memory. */ + for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) + if (spare_memory[i]) + { + if (i == 0) + free (spare_memory[i]); + else if (i >= 1 && i <= 4) + lisp_align_free (spare_memory[i]); + else + lisp_free (spare_memory[i]); + spare_memory[i] = 0; + } - /* Record the space now used. When it decreases substantially, - we can refill the memory reserve. */ + /* Record the space now used. When it decreases substantially, + we can refill the memory reserve. */ #if !defined SYSTEM_MALLOC && !defined SYNC_INPUT - bytes_used_when_full = BYTES_USED; + bytes_used_when_full = BYTES_USED; #endif + } /* This used to call error, but if we've run out of memory, we could get infinite recursion trying to build the string. */ diff --git a/src/buffer.c b/src/buffer.c index 05bd129976f..e9ff8f492ba 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -328,7 +328,7 @@ even if it is dead. The return value is never nil. */) alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1); UNBLOCK_INPUT; if (! BUF_BEG_ADDR (b)) - buffer_memory_full (); + buffer_memory_full (BUF_GAP_SIZE (b) + 1); b->pt = BEG; b->begv = BEG; @@ -4892,7 +4892,7 @@ alloc_buffer_text (struct buffer *b, size_t nbytes) if (p == NULL) { UNBLOCK_INPUT; - memory_full (); + memory_full (nbytes); } b->text->beg = (unsigned char *) p; @@ -4920,7 +4920,7 @@ enlarge_buffer_text (struct buffer *b, EMACS_INT delta) if (p == NULL) { UNBLOCK_INPUT; - memory_full (); + memory_full (nbytes); } BUF_BEG_ADDR (b) = (unsigned char *) p; diff --git a/src/editfns.c b/src/editfns.c index 8b48355fbfa..0e40fde9ca4 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3636,7 +3636,7 @@ usage: (format STRING &rest OBJECTS) */) { EMACS_INT i; if ((SIZE_MAX - formatlen) / sizeof (struct info) <= nargs) - memory_full (); + memory_full (SIZE_MAX); SAFE_ALLOCA (info, struct info *, (nargs + 1) * sizeof *info + formatlen); discarded = (char *) &info[nargs + 1]; for (i = 0; i < nargs + 1; i++) diff --git a/src/gnutls.c b/src/gnutls.c index 5558fb9ee0b..9342ce7912e 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -110,6 +110,10 @@ DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int)); DEF_GNUTLS_FN (int, gnutls_global_init, (void)); DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func)); DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int)); +DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions, + (gnutls_alloc_function, gnutls_alloc_function, + gnutls_is_secure_function, gnutls_realloc_function, + gnutls_free_function)); DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t)); DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t)); DEF_GNUTLS_FN (int, gnutls_priority_set_direct, @@ -168,6 +172,7 @@ init_gnutls_functions (Lisp_Object libraries) LOAD_GNUTLS_FN (library, gnutls_global_init); LOAD_GNUTLS_FN (library, gnutls_global_set_log_function); LOAD_GNUTLS_FN (library, gnutls_global_set_log_level); + LOAD_GNUTLS_FN (library, gnutls_global_set_mem_functions); LOAD_GNUTLS_FN (library, gnutls_handshake); LOAD_GNUTLS_FN (library, gnutls_init); LOAD_GNUTLS_FN (library, gnutls_priority_set_direct); @@ -213,6 +218,7 @@ init_gnutls_functions (Lisp_Object libraries) #define fn_gnutls_global_init gnutls_global_init #define fn_gnutls_global_set_log_function gnutls_global_set_log_function #define fn_gnutls_global_set_log_level gnutls_global_set_log_level +#define fn_gnutls_global_set_mem_functions gnutls_global_set_mem_functions #define fn_gnutls_handshake gnutls_handshake #define fn_gnutls_init gnutls_init #define fn_gnutls_priority_set_direct gnutls_priority_set_direct @@ -582,7 +588,11 @@ emacs_gnutls_global_init (void) int ret = GNUTLS_E_SUCCESS; if (!gnutls_global_initialized) - ret = fn_gnutls_global_init (); + { + fn_gnutls_global_set_mem_functions (xmalloc, xmalloc, NULL, + xrealloc, xfree); + ret = fn_gnutls_global_init (); + } gnutls_global_initialized = 1; return gnutls_make_error (ret); @@ -768,8 +778,7 @@ one trustfile (usually a CA bundle). */) { GNUTLS_LOG (2, max_log_level, "allocating x509 credentials"); x509_cred = XPROCESS (proc)->gnutls_x509_cred; - if (fn_gnutls_certificate_allocate_credentials (&x509_cred) < 0) - memory_full (); + fn_gnutls_certificate_allocate_credentials (&x509_cred); if (NUMBERP (verify_flags)) { @@ -792,8 +801,7 @@ one trustfile (usually a CA bundle). */) { GNUTLS_LOG (2, max_log_level, "allocating anon credentials"); anon_cred = XPROCESS (proc)->gnutls_anon_cred; - if (fn_gnutls_anon_allocate_client_credentials (&anon_cred) < 0) - memory_full (); + fn_gnutls_anon_allocate_client_credentials (&anon_cred); } else { diff --git a/src/lisp.h b/src/lisp.h index 6e61d0b8bd3..a9e7354f9fc 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2684,8 +2684,8 @@ extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); extern void reset_malloc_hooks (void); extern void uninterrupt_malloc (void); extern void malloc_warning (const char *); -extern void memory_full (void) NO_RETURN; -extern void buffer_memory_full (void) NO_RETURN; +extern void memory_full (size_t) NO_RETURN; +extern void buffer_memory_full (EMACS_INT) NO_RETURN; extern int survives_gc_p (Lisp_Object); extern void mark_object (Lisp_Object); #if defined REL_ALLOC && !defined SYSTEM_MALLOC diff --git a/src/menu.c b/src/menu.c index e4338f349f6..7eda4c6ebb5 100644 --- a/src/menu.c +++ b/src/menu.c @@ -178,7 +178,7 @@ static void grow_menu_items (void) { if ((INT_MAX - MENU_ITEMS_PANE_LENGTH) / 2 < menu_items_allocated) - memory_full (); + memory_full (SIZE_MAX); menu_items_allocated *= 2; menu_items = larger_vector (menu_items, menu_items_allocated, Qnil); } diff --git a/src/minibuf.c b/src/minibuf.c index b3f157ba69a..ba8729bdff2 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -245,7 +245,7 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial, len == size - 1 && line[len - 1] != '\n')) { if ((size_t) -1 / 2 < size) - memory_full (); + memory_full (SIZE_MAX); size *= 2; line = (char *) xrealloc (line, size); } diff --git a/src/xterm.c b/src/xterm.c index 0923bbb717a..d6d6457f522 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -4225,7 +4225,7 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; if ((size_t) -1 / sizeof *scroll_bar_windows < new_size) - memory_full (); + memory_full (SIZE_MAX); scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, nbytes); memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); |
