>From 62de6240b57bc148eccfe0c6a723a7dc2e67a526 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 30 Jan 2016 00:47:25 -0800 Subject: [PATCH 07/12] Pacify --enable-gcc-warnings when HYBRID_MALLOC * src/buffer.c (init_buffer): * src/emacs.c (main): * src/xsmfns.c (smc_save_yourself_CB, x_session_initialize): Use emacs_get_current_dir_name, not get_current_dir_name. * src/conf_post.h (aligned_alloc) [HYBRID_MALLOC && emacs]: New macro. (HYBRID_GET_CURRENT_DIR_NAME, get_current_dir_name): Remove. * src/emacs.c: Include "sheap.h". (report_sheap_usage): Remove decl. (Fdump_emacs) [HYBRID_MALLOC]: Report usage directly. Don't assume ptrdiff_t can be printed as int. * src/gmalloc.c [HYBRID_MALLOC]: Include "sheap.h" rather than declaring its contents by hand. (get_current_dir_name, gget_current_dir_name) (hybrid_get_current_dir_name): Remove. (emacs_abort): Remove duplicate decl. (aligned_alloc): Undef, like malloc etc. (ALLOCATED_BEFORE_DUMPING): Now a static function, not a macro. Make it a bit more efficient. (malloc_find_object_address): Remove unused decl. (enum mcheck_status, mcheck, mprobe, mtrace, muntrace, struct mstats) (mstats, memory_warnings): Declare only if GC_MCHECK. * src/lisp.h (emacs_get_current_dir_name): New decl, replacing get_current_dir_name. * src/sheap.c: Include sheap.h first. (STATIC_HEAP_SIZE): Remove; now in sheap.h. (debug_sheap): Now static. (bss_sbrk_buffer_end): Remove; no longer used. (bss_sbrk_ptr): Now static and private. (bss_sbrk_did_unexec): Now bool. (BLOCKSIZE): Remove, to avoid GCC warning about its not being used. (bss_sbrk): Don't treat request_size 0 as special, since the code works without this being a special case. Avoid overflow if request size exceeds INT_MAX. (report_sheap_usage): Remove; now done in emacs.c. * src/sheap.h: New file. * src/sysdep.c (get_current_dir_name): Remove macro. Include "sheap.h". (emacs_get_current_dir_name): Rename function from get_current_dir_name. Handle HYBRID_MALLOC here; this is simpler. (Bug#22086) --- src/buffer.c | 2 +- src/conf_post.h | 5 +--- src/emacs.c | 13 ++++++--- src/gmalloc.c | 51 +++++++++-------------------------- src/lisp.h | 4 +-- src/sheap.c | 83 ++++++++++++++++++++------------------------------------- src/sheap.h | 31 +++++++++++++++++++++ src/sysdep.c | 29 ++++++++++---------- src/xsmfns.c | 4 +-- 9 files changed, 102 insertions(+), 120 deletions(-) create mode 100644 src/sheap.h diff --git a/src/buffer.c b/src/buffer.c index 74b6fb6..bd5425d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5277,7 +5277,7 @@ init_buffer (int initialized) if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) Fset_buffer_multibyte (Qnil); - pwd = get_current_dir_name (); + pwd = emacs_get_current_dir_name (); if (!pwd) { diff --git a/src/conf_post.h b/src/conf_post.h index 5c332a0..9f4becd 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -100,11 +100,8 @@ typedef bool bool_bf; #define malloc hybrid_malloc #define realloc hybrid_realloc #define calloc hybrid_calloc +#define aligned_alloc hybrid_aligned_alloc #define free hybrid_free -#if defined HAVE_GET_CURRENT_DIR_NAME && !defined BROKEN_GET_CURRENT_DIR_NAME -#define HYBRID_GET_CURRENT_DIR_NAME 1 -#define get_current_dir_name hybrid_get_current_dir_name -#endif #endif #endif /* HYBRID_MALLOC */ diff --git a/src/emacs.c b/src/emacs.c index 40075b4..d31ba5a 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -79,6 +79,7 @@ along with GNU Emacs. If not, see . */ #include "composite.h" #include "dispextern.h" #include "regex.h" +#include "sheap.h" #include "syntax.h" #include "sysselect.h" #include "systime.h" @@ -134,7 +135,6 @@ extern void unexec_init_emacs_zone (void); #endif extern void malloc_enable_thread (void); -extern void report_sheap_usage (int); /* If true, Emacs should not attempt to use a window-specific code, but instead should use the virtual terminal under which it was started. */ @@ -772,7 +772,7 @@ main (int argc, char **argv) filename_from_ansi (ch_to_dir, newdir); ch_to_dir = newdir; #endif - original_pwd = get_current_dir_name (); + original_pwd = emacs_get_current_dir_name (); if (chdir (ch_to_dir) != 0) { fprintf (stderr, "%s: Can't chdir to %s: %s\n", @@ -2072,7 +2072,14 @@ You must run Emacs in batch mode in order to dump it. */) Vpurify_flag = Qnil; #ifdef HYBRID_MALLOC - report_sheap_usage (1); + { + static char const fmt[] = "%d of %d static heap bytes used"; + char buf[sizeof fmt + 2 * (INT_STRLEN_BOUND (int) - 2)]; + int max_usage = max_bss_sbrk_ptr - bss_sbrk_buffer; + sprintf (buf, fmt, max_usage, STATIC_HEAP_SIZE); + /* Don't log messages, because at this point buffers cannot be created. */ + message1_nolog (buf); + } #endif fflush (stdout); diff --git a/src/gmalloc.c b/src/gmalloc.c index 30e0131..4fd3246 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c @@ -28,11 +28,6 @@ License along with this library. If not, see . #include #include #include - -#ifdef HYBRID_GET_CURRENT_DIR_NAME -#undef get_current_dir_name -#endif - #include #ifdef USE_PTHREAD @@ -43,10 +38,6 @@ License along with this library. If not, see . #include /* for sbrk */ #endif -#ifdef emacs -extern void emacs_abort (void); -#endif - /* If HYBRID_MALLOC is defined, then temacs will use malloc, realloc... as defined in this file (and renamed gmalloc, grealloc... via the macros that follow). The dumped emacs, @@ -63,6 +54,7 @@ extern void emacs_abort (void); #undef malloc #undef realloc #undef calloc +#undef aligned_alloc #undef free #define malloc gmalloc #define realloc grealloc @@ -71,13 +63,13 @@ extern void emacs_abort (void); #define free gfree #ifdef HYBRID_MALLOC -extern void *bss_sbrk (ptrdiff_t size); -extern int bss_sbrk_did_unexec; -extern char bss_sbrk_buffer[]; -extern void *bss_sbrk_buffer_end; -#define DUMPED bss_sbrk_did_unexec -#define ALLOCATED_BEFORE_DUMPING(P) \ - ((P) < bss_sbrk_buffer_end && (P) >= (void *) bss_sbrk_buffer) +# include "sheap.h" +# define DUMPED bss_sbrk_did_unexec +static bool +ALLOCATED_BEFORE_DUMPING (char *p) +{ + return bss_sbrk_buffer <= p && p < bss_sbrk_buffer + STATIC_HEAP_SIZE; +} #endif #ifdef __cplusplus @@ -87,10 +79,6 @@ extern "C" #include -#ifdef emacs -extern void emacs_abort (void); -#endif - /* Underlying allocation function; successive calls should return contiguous pieces of memory. */ extern void *(*__morecore) (ptrdiff_t size); @@ -255,10 +243,6 @@ extern int _malloc_thread_enabled_p; #define UNLOCK_ALIGNED_BLOCKS() #endif -/* Given an address in the middle of a malloc'd object, - return the address of the beginning of the object. */ -extern void *malloc_find_object_address (void *ptr); - /* If not NULL, this function is called after each time `__morecore' is called to increase the data size. */ extern void (*__after_morecore_hook) (void); @@ -279,6 +263,8 @@ extern void *(*__malloc_hook) (size_t size); extern void *(*__realloc_hook) (void *ptr, size_t size); extern void *(*__memalign_hook) (size_t size, size_t alignment); +#ifdef GC_MCHECK + /* Return values for `mprobe': these are the kinds of inconsistencies that `mcheck' enables detection of. */ enum mcheck_status @@ -321,6 +307,8 @@ extern struct mstats mstats (void); /* Call WARNFUN with a warning message when memory usage is high. */ extern void memory_warnings (void *start, void (*warnfun) (const char *)); +#endif + #undef extern #ifdef __cplusplus @@ -1797,7 +1785,7 @@ hybrid_aligned_alloc (size_t alignment, size_t size) #endif } #endif - + void * hybrid_realloc (void *ptr, size_t size) { @@ -1825,19 +1813,6 @@ hybrid_realloc (void *ptr, size_t size) return result; } -#ifdef HYBRID_GET_CURRENT_DIR_NAME -/* Defined in sysdep.c. */ -char *gget_current_dir_name (void); - -char * -hybrid_get_current_dir_name (void) -{ - if (DUMPED) - return get_current_dir_name (); - return gget_current_dir_name (); -} -#endif - #else /* ! HYBRID_MALLOC */ void * diff --git a/src/lisp.h b/src/lisp.h index 82cbca8..53f123d 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4254,9 +4254,7 @@ struct tty_display_info; struct terminal; /* Defined in sysdep.c. */ -#ifndef HAVE_GET_CURRENT_DIR_NAME -extern char *get_current_dir_name (void); -#endif +extern char *emacs_get_current_dir_name (void); extern void stuff_char (char c); extern void init_foreground_group (void); extern void sys_subshell (void); diff --git a/src/sheap.c b/src/sheap.c index 1451eca..fe905ca 100644 --- a/src/sheap.c +++ b/src/sheap.c @@ -19,87 +19,62 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ #include + +#include "sheap.h" + #include #include "lisp.h" #include #include /* for exit */ -#ifdef ENABLE_CHECKING -#define STATIC_HEAP_SIZE (28 * 1024 * 1024) -#else -#define STATIC_HEAP_SIZE (19 * 1024 * 1024) -#endif - -int debug_sheap = 0; - -#define BLOCKSIZE 4096 +static int debug_sheap; char bss_sbrk_buffer[STATIC_HEAP_SIZE]; -/* The following is needed in gmalloc.c */ -void *bss_sbrk_buffer_end = bss_sbrk_buffer + STATIC_HEAP_SIZE; -char *bss_sbrk_ptr; char *max_bss_sbrk_ptr; -int bss_sbrk_did_unexec; +bool bss_sbrk_did_unexec; void * bss_sbrk (ptrdiff_t request_size) { + static char *bss_sbrk_ptr; + if (!bss_sbrk_ptr) { max_bss_sbrk_ptr = bss_sbrk_ptr = bss_sbrk_buffer; #ifdef CYGWIN - sbrk (BLOCKSIZE); /* force space for fork to work */ + /* Force space for fork to work. */ + sbrk (4096); #endif } - if (!(int) request_size) - { - return (bss_sbrk_ptr); - } - else if (bss_sbrk_ptr + (int) request_size < bss_sbrk_buffer) + int used = bss_sbrk_ptr - bss_sbrk_buffer; + + if (request_size < -used) { - printf - ("attempt to free too much: avail %d used %d failed request %d\n", - STATIC_HEAP_SIZE, bss_sbrk_ptr - bss_sbrk_buffer, - (int) request_size); + printf (("attempt to free too much: " + "avail %d used %d failed request %"pD"d\n"), + STATIC_HEAP_SIZE, used, request_size); exit (-1); return 0; } - else if (bss_sbrk_ptr + (int) request_size > - bss_sbrk_buffer + STATIC_HEAP_SIZE) + else if (STATIC_HEAP_SIZE - used < request_size) { - printf ("static heap exhausted: avail %d used %d failed request %d\n", - STATIC_HEAP_SIZE, - bss_sbrk_ptr - bss_sbrk_buffer, (int) request_size); + printf ("static heap exhausted: avail %d used %d failed request %"pD"d\n", + STATIC_HEAP_SIZE, used, request_size); exit (-1); return 0; } - else if ((int) request_size < 0) - { - bss_sbrk_ptr += (int) request_size; - if (debug_sheap) - printf ("freed size %d\n", request_size); - return bss_sbrk_ptr; - } - else + + void *ret = bss_sbrk_ptr; + bss_sbrk_ptr += request_size; + if (max_bss_sbrk_ptr < bss_sbrk_ptr) + max_bss_sbrk_ptr = bss_sbrk_ptr; + if (debug_sheap) { - char *ret = bss_sbrk_ptr; - if (debug_sheap) - printf ("allocated 0x%08x size %d\n", ret, request_size); - bss_sbrk_ptr += (int) request_size; - if (bss_sbrk_ptr > max_bss_sbrk_ptr) - max_bss_sbrk_ptr = bss_sbrk_ptr; - return ret; + if (request_size < 0) + printf ("freed size %"pD"d\n", request_size); + else + printf ("allocated %p size %"pD"d\n", ret, request_size); } -} - -void -report_sheap_usage (int die_if_pure_storage_exceeded) -{ - char buf[200]; - sprintf (buf, "Maximum static heap usage: %d of %d bytes", - max_bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); - /* Don't log messages, cause at this point, we're not allowed to create - buffers. */ - message1_nolog (buf); + return ret; } diff --git a/src/sheap.h b/src/sheap.h new file mode 100644 index 0000000..4af3cf4 --- /dev/null +++ b/src/sheap.h @@ -0,0 +1,31 @@ +/* Static heap allocation for GNU Emacs. + +Copyright 2016 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see . */ + +#include + +#ifdef ENABLE_CHECKING +# define STATIC_HEAP_SIZE (28 * 1024 * 1024) +#else +# define STATIC_HEAP_SIZE (19 * 1024 * 1024) +#endif + +extern char bss_sbrk_buffer[STATIC_HEAP_SIZE]; +extern char *max_bss_sbrk_ptr; +extern bool bss_sbrk_did_unexec; +extern void *bss_sbrk (ptrdiff_t); diff --git a/src/sysdep.c b/src/sysdep.c index 3c3da0d..c224143 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -19,14 +19,6 @@ along with GNU Emacs. If not, see . */ #include -/* If HYBRID_GET_CURRENT_DIR_NAME is defined in conf_post.h, then we - need the following before including unistd.h, in order to pick up - the right prototype for gget_current_dir_name. */ -#ifdef HYBRID_GET_CURRENT_DIR_NAME -#undef get_current_dir_name -#define get_current_dir_name gget_current_dir_name -#endif - #include #include "sysstdio.h" #ifdef HAVE_PWD_H @@ -40,6 +32,7 @@ along with GNU Emacs. If not, see . */ #include #include "lisp.h" +#include "sheap.h" #include "sysselect.h" #include "blockinput.h" @@ -137,14 +130,21 @@ static const int baud_convert[] = 1800, 2400, 4800, 9600, 19200, 38400 }; -#if !defined HAVE_GET_CURRENT_DIR_NAME || defined BROKEN_GET_CURRENT_DIR_NAME \ - || (defined HYBRID_GET_CURRENT_DIR_NAME) -/* Return the current working directory. Returns NULL on errors. - Any other returned value must be freed with free. This is used - only when get_current_dir_name is not defined on the system. */ +/* Return the current working directory. The result should be freed + with 'free'. Return NULL on errors. */ char * -get_current_dir_name (void) +emacs_get_current_dir_name (void) { +# if HAVE_GET_CURRENT_DIR_NAME && !BROKEN_GET_CURRENT_DIR_NAME +# ifdef HYBRID_MALLOC + bool use_libc = bss_sbrk_did_unexec; +# else + bool use_libc = true; +# endif + if (use_libc) + return get_current_dir_name (); +# endif + char *buf; char *pwd = getenv ("PWD"); struct stat dotstat, pwdstat; @@ -192,7 +192,6 @@ get_current_dir_name (void) } return buf; } -#endif /* Discard pending input on all input descriptors. */ diff --git a/src/xsmfns.c b/src/xsmfns.c index 7641449..df5c46b 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c @@ -204,7 +204,7 @@ smc_save_yourself_CB (SmcConn smcConn, props[props_idx]->vals[0].value = SDATA (user_login_name); ++props_idx; - char *cwd = get_current_dir_name (); + char *cwd = emacs_get_current_dir_name (); if (cwd) { props[props_idx] = &prop_ptr[props_idx]; @@ -401,7 +401,7 @@ x_session_initialize (struct x_display_info *dpyinfo) ptrdiff_t name_len = 0; /* libSM seems to crash if pwd is missing - see bug#18851. */ - if (! get_current_dir_name ()) + if (! emacs_get_current_dir_name ()) { fprintf (stderr, "Disabling session management due to pwd error: %s\n", emacs_strerror (errno)); -- 2.5.0