Commit 037e65b4 authored by Paul Eggert's avatar Paul Eggert
Browse files

Merge: memory_full, gnutls improvements

parents b3e945d3 57f53182
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):
......
......@@ -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. */
......
......@@ -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;
......
......@@ -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++)
......
......@@ -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
{
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment