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)
{
#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 */
#include "composite.h"
#include "dispextern.h"
#include "regex.h"
+#include "sheap.h"
#include "syntax.h"
#include "sysselect.h"
#include "systime.h"
#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. */
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",
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);
#include <string.h>
#include <limits.h>
#include <stdint.h>
-
-#ifdef HYBRID_GET_CURRENT_DIR_NAME
-#undef get_current_dir_name
-#endif
-
#include <unistd.h>
#ifdef USE_PTHREAD
#include <w32heap.h> /* 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,
#undef malloc
#undef realloc
#undef calloc
+#undef aligned_alloc
#undef free
#define malloc gmalloc
#define realloc grealloc
#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
#include <stddef.h>
-#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);
#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);
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
/* 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
#endif
}
#endif
-
+
void *
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 *
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);
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
+
+#include "sheap.h"
+
#include <stdio.h>
#include "lisp.h"
#include <unistd.h>
#include <stdlib.h> /* 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;
}
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+
+#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);
#include <config.h>
-/* 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 <execinfo.h>
#include "sysstdio.h"
#ifdef HAVE_PWD_H
#include <utimens.h>
#include "lisp.h"
+#include "sheap.h"
#include "sysselect.h"
#include "blockinput.h"
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;
}
return buf;
}
-#endif
\f
/* Discard pending input on all input descriptors. */
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];
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));