diff options
Diffstat (limited to 'src/alloc.c')
-rw-r--r-- | src/alloc.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/src/alloc.c b/src/alloc.c index fe55cde49c9..03dacc77c6e 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,6 +1,6 @@ /* Storage allocation and gc for GNU Emacs Lisp interpreter. -Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2015 Free Software +Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2016 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -2119,8 +2119,11 @@ INIT must be an integer that represents a character. */) { nbytes = XINT (length); val = make_uninit_string (nbytes); - memset (SDATA (val), c, nbytes); - SDATA (val)[nbytes] = 0; + if (nbytes) + { + memset (SDATA (val), c, nbytes); + SDATA (val)[nbytes] = 0; + } } else { @@ -2145,7 +2148,8 @@ INIT must be an integer that represents a character. */) memcpy (p, beg, len); } } - *p = 0; + if (nbytes) + *p = 0; } return val; @@ -3188,7 +3192,8 @@ allocate_vector (EMACS_INT len) if (min ((nbytes_max - header_size) / word_size, MOST_POSITIVE_FIXNUM) < len) memory_full (SIZE_MAX); v = allocate_vectorlike (len); - v->header.size = len; + if (len) + v->header.size = len; return v; } @@ -3727,7 +3732,7 @@ make_event_array (ptrdiff_t nargs, Lisp_Object *args) #ifdef HAVE_MODULES /* Create a new module user ptr object. */ Lisp_Object -make_user_ptr (void (*finalizer) (void*), void *p) +make_user_ptr (void (*finalizer) (void *), void *p) { Lisp_Object obj; struct Lisp_User_Ptr *uptr; @@ -4589,6 +4594,10 @@ maybe_lisp_pointer (void *p) return (uintptr_t) p % GCALIGNMENT == 0; } +#ifndef HAVE_MODULES +enum { HAVE_MODULES = false }; +#endif + /* If P points to Lisp data, mark that as live if it isn't already marked. */ @@ -4602,8 +4611,17 @@ mark_maybe_pointer (void *p) VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); #endif - if (!maybe_lisp_pointer (p)) - return; + if (sizeof (Lisp_Object) == sizeof (void *) || !HAVE_MODULES) + { + if (!maybe_lisp_pointer (p)) + return; + } + else + { + /* For the wide-int case, also mark emacs_value tagged pointers, + which can be generated by emacs-module.c's value_to_lisp. */ + p = (void *) ((uintptr_t) p & ~(GCALIGNMENT - 1)); + } m = mem_find (p); if (m != MEM_NIL) @@ -4680,8 +4698,7 @@ mark_maybe_pointer (void *p) static void ATTRIBUTE_NO_SANITIZE_ADDRESS mark_memory (void *start, void *end) { - void **pp; - int i; + char *pp; /* Make START the pointer to the start of the memory region, if it isn't already. */ @@ -4692,6 +4709,8 @@ mark_memory (void *start, void *end) end = tem; } + eassert (((uintptr_t) start) % GC_POINTER_ALIGNMENT == 0); + /* Mark Lisp data pointed to. This is necessary because, in some situations, the C compiler optimizes Lisp objects away, so that only a pointer to them remains. Example: @@ -4710,13 +4729,11 @@ mark_memory (void *start, void *end) away. The only reference to the life string is through the pointer `s'. */ - for (pp = start; (void *) pp < end; pp++) - for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT) - { - void *p = *(void **) ((char *) pp + i); - mark_maybe_pointer (p); - mark_maybe_object (XIL ((intptr_t) p)); - } + for (pp = start; (void *) pp < end; pp += GC_POINTER_ALIGNMENT) + { + mark_maybe_pointer (*(void **) pp); + mark_maybe_object (*(Lisp_Object *) pp); + } } #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS @@ -5508,9 +5525,16 @@ garbage_collect_1 (void *end) don't let that cause a recursive GC. */ consing_since_gc = 0; - /* Save what's currently displayed in the echo area. */ - message_p = push_message (); - record_unwind_protect_void (pop_message_unwind); + /* Save what's currently displayed in the echo area. Don't do that + if we are GC'ing because we've run out of memory, since + push_message will cons, and we might have no memory for that. */ + if (NILP (Vmemory_full)) + { + message_p = push_message (); + record_unwind_protect_void (pop_message_unwind); + } + else + message_p = false; /* Save a copy of the contents of the stack, for debugging. */ #if MAX_SAVE_STACK > 0 @@ -5641,7 +5665,7 @@ garbage_collect_1 (void *end) } } - if (garbage_collection_messages) + if (garbage_collection_messages && NILP (Vmemory_full)) { if (message_p || minibuf_level > 0) restore_message (); |