summaryrefslogtreecommitdiff
path: root/src/emacs.c
diff options
context:
space:
mode:
authorDaniel Colascione <dancol@dancol.org>2019-01-15 17:36:54 -0500
committerDaniel Colascione <dancol@dancol.org>2019-01-15 17:37:36 -0500
commitd12e5d003d503025c1c9b0335d6518a6c3bdfae1 (patch)
tree41829446caca2d488e723843046c4f5b8931d8f8 /src/emacs.c
parent2a3bd6798e9670828f0402079fcc116d6d6b042d (diff)
downloademacs-d12e5d003d503025c1c9b0335d6518a6c3bdfae1.tar.gz
Add portable dumper
Add a new portable dumper as an alternative to unexec. Use it by default. * src/dmpstruct.awk: New file. * src/doc.c (get_doc_string): use will_dump_p(). * src/editfns.c (styled_format): silence compiler warning with UNINIT. * src/emacs-module.c (syms_of_module): staticpro ltv_mark. * src/emacs.c (gflags): new variable. (init_cmdargs): unwrap (string_starts_with_p, find_argument, dump_error_to_string) (load_pdump): new functions. (main): detect pdumper and --temacs invocation; actually load portable dump when detected; set gflags as appropriate; changes to init functions throughout to avoid passing explicit 'initialized' argument. * src/eval.c (inhibit_lisp_code): remove unused variable. (init_eval_once_for_pdumper): new function. (init_eval_once): call it. * src/filelock.c: CANNOT_DUMP -> will_dump_p() * src/fingerprint-dummy.c: new file * src/fingerprint.h: new file * src/fns.c: CANNOT_DUMP -> will_dump_p(), etc. (weak_hash_tables): remove (hashfn_equal, hashfn_eql): un-staticify (make_hash_table): set new 'next_weak' hash table field; drop global weak_hash_tables logic. (copy_hash_table): drop global weak_hash_tables logic. (hash_table_rehash): new function. (hash_lookup, hash_put, hash_remove_from_table, hash_clear): rehash if needed. (sweep_weak_table): un-staticify; explain logic; bool-ify. (sweep_weak_hash_tables): remove function. * src/font.c (syms_of_font): remember pdumper stuff. * src/fontset.c (syms_of_fontset): remember pdumper stuff. * src/frame.c (make_initial_frame): don't reset Vframe_list. (init_frame_once_for_pdumper, init_frame_once): new functions. (syms_of_frame): remove redundant staticpro. * src/fringe.c (init_fringe_once_for_pdumper): new functin. (init_fringe_once): call it. * src/ftcrfont.c (syms_of_ftcrfont_for_pdumper): new function. (syms_of_ftcrfont): call it. * src/ftfont.c (syms_of_ftfont_for_pdumper): new function. (syms_of_ftfont): call it. * src/ftxont.c (syms_of_ftxfont_for_pdumper): new function. (syms_of_ftxfont): call it. * src/gmalloc.c: adjust for pdumper througout (DUMPED): remove weird custom dumped indicator. * src/gnutls.c (syms_of_gnutls): pdumper note for gnutls_global_initialized. * src/image.c (syms_of_image): add pdumper comment, initializer note. * src/insdel.c (prepare_to_modify_buffer_1): account for buffer contents possibly being in dump image. * src/keyboard.c (syms_of_keyboard_for_pdumper): new function. (syms_of_keyboard): staticpro more; call pdumper syms function. * src/lisp.h: add comments throughout (gflags): declare. (will_dump_p, will_bootstrap_p, will_dump_with_pdumper_p) (dumped_with_pdumper_p, will_dump_with_unexec_p) (dumped_with_unexec_p, definitely_will_not_unexec_p): new functions. (POWER_OF_2, ROUNDUP): move macros. (PSEUDOVECTOR_TYPE, PSEUDOVECTOR_TYPEP): take vectorlike header pointer instead of vector; constify. (Lisp_Hash_Table): add comment about need to rehash on access; add comment for next_weak. (HASH_KEY, HASH_VALUE, HASH_HASH, HASH_TABLE_SIZE): const-ify. (hash_table_rehash): declare. (hash_rehash_needed_p, hash_rehash_if_needed): new functions. (finalizers, doomed_finalizers): declare extern. (SUBR_SECTION_ATTRIBUTE): new macro. (staticvec, staticidx): un-static-ify. (sweep_weak_hash_tables): remove declaration. (sweep_weak_table): declare. (hashfn_eql, hashfn_equal): declare. (number_finalizers_run): new variable. (Vdead): externify when ENABLE_CHECKING. (gc_root_type): new enumeration. (gc_root_visitor): new struct. (visit_static_gc_roots): declare. (vectorlike_nbytes): declare. (vector_nbytes): define as trivial inline function wrapper for vectorlike_nbytes. (init_obarray_once): change signature. (primary_thread): extern-ify. (init_buffer): change signature. (init_frame_once): declare. * src/lread.c (readevalloop): adjust for new dumped predicates. (init_obarray_once): new function. (ndefsubr): new variable. (defsubr): increment it. (load_path_check): adjust for pdumper. (load_path_default): use pdumper functions; adjust for dump search. * src/macfont.m (macfont_init_font_change_handler): avoid shadowing global. (syms_of_macfont_for_pdumper): new function. (syms_of_macfont): call it. * src/menu.c (syms_of_menu): staticpro more stuff. * src/minibuf.c (Ftry_completion): rehash if needed. (init_minibuf_once_for_pdumper): new function. (init_minibuf_once): call it. * src/nsfont.m (syms_of_nsfns): staticpro more. * src/nsfont.m (syms_of_nsfont_for_pdumper): new function. (syms_of_nsfont): call it. * src/nsterm.m (syms_of_nsfont): remember pdumper stuff. * src/pdumper.c: new file. * src/pdumper.h: new file. * src/process.c (init_process_emacs): use new pdumper functions instead of CANNOT_DUMP. * src/profiler.c (syms_of_profiler_for_pdumper): new function. (syms_of_profiler_for_pdumper): call it. * src/search.c (syms_of_search_for_pdumper): new function. (syms_of_search_for_pdumper): call it. * src/sheap.c (bss_sbrk_did_unexec): remove. * src/sheap.h (bss_sbrk_did_unexec): remove. * src/syntax.c (syms_of_syntax): don't redundantly staticpro re_match_object. * src/sysdep.c: use will_dump_with_unexec_p() instead of bss hack thing. * src/syssignals.h (init_sigsegv): declare. * src/systime.h (init_timefns): remove bool from signature. * src/textprop.c (syms_of_textprop): move staticpro. * src/thread.c (main_thread_p): constify. * src/thread.h (main_thread_p): constify. * src/timefns.c (init_timefns): remove bool from signature. (syms_of_timefns_for_pdumper): new function. (syms_of_timefns): call it. * src/w32.c: rearrange code. * src/w32.h (w32_relocate): declare. * src/w32fns.c (syms_of_w32fns): add pdumper note. * src/w32font.c (syms_of_w32font_for_pdumper): new function. (syms_of_w32font): call it. * src/w32heap.c (using_dynamic_heap): new variable. (init_heap): use it. * src/w32menu.c (syms_of_w32menu): add pdumper note. * src/w32proc.c (ctrl_c_handler, mainCRTStartup, _start, open_input_file) (rva_to_section, close_file_data): move here. * src/w32uniscribe.c (syms_of_w32uniscribe_for_pdumper): new function. (syms_of_w32uniscribe): call it. * src/window.c (init_window_once_for_pdumper): new function. (init_window_once): call it; staticpro more stuff. * src/xfont.c (syms_of_xfont_for_pdumper): new function. (syms_of_xfont): call it. * src/xftfont.c (syms_of_xftfont_for_pdumper): new function. (syms_of_xftfont): call it. * src/xmenu.c (syms_of_xmenu_for_pdumper): new function. (syms_of_xmenu): call it. * src/xselect.c (syms_of_xselect_for_pdumper): new function. (syms_of_xselect): call it. * src/xsettings.c (syms_of_xsettings): add more pdumper notes. * src/term.c (syms_of_xterm): add pdumper note. * src/dispnew.c (init_faces_initial): new function. (init_display_interactive): rename from init_display; use will_dump_p instead of !initialized. Initialize faces early for pdumper if needed. (init_display): new function. (syms_of_display_for_pdumper): new function. (syms_of_display): call it. * src/dbusbind.c (syms_of_dbusbind): Add TODO for bus reset on pdumper load. * src/data.c (Fdefalias): Use will_dump_p instead of Vpurify_flag. (Fmake_variable_buffer_local): silence compiler warning with -Og by making valcontents UNINIT. (arith_driver): silence compiler warning with UNINIT. * src/conf_post.h (ATTRIBUTE_SECTION): new macro. * src/composite.c (composition_gstring_put_cache): rehash hash table if needed. * src/coding.c (init_coding_once, syms_of_coding): remember pdumper stuff. * src/charset.h (charset_table_size, charset_table_user): declare. * src/charset.c (charset_table_used, charset_table_size): un-static. (init_charset_oncem, syms_of_charset): remember pdumper stuff. * src/category.c (category_table_version): remove obsolete variable. * src/callint.c (syms_of_callint): staticpro 'preserved_fns' (init_callproc): use will_dump_p instead of !CANNOT_DUMP. * src/bytecode.c (exec_byte_code): rehash table tables if needed * src/buffer.c (alloc_buffer_text, free_buffer_text): account for pdumper (init_buffer_once): add TODO; remember stuff for pdumper. (init_buffer): don't take initialized argument; adjust for pdumper. * src/atimer.c (init_atimer): initialize subr only if !initialized. * src/alloc.c: (vector_marked_p, set_vector_marked) (vectorlike_marked_p, set_vectorlike_marked, cons_marked_p) (set_cons_marked, string_marked_p, set_string_marked) (symbol_marked_p, set_symbol_marked, interval_marked_p) (set_interval_marked): new accessor routines. Use them instead of raw GC access throughout. (Vdead): make non-static when ENABLE_CHECKING. (vectorlike_nbytes): rename of 'vector_nbytes'; take a vectorlike header as input instead of a vector. (number_finalizers_run): new internal C variable. (mark_maybe_object): check for pdumper objects. (valid_pointer_p): don't be gratuitously inefficient under rr(1). (make_pure_c_string): add support for size_byte = -2 mode indicating that string data points into Emacs image rodata. (visit_vectorlike_root): visits GC roots embedded in vectorlike objects. (visit_buffer_root): visits GC roots embedded in our totally-not-a-buffer buffer global objects. (visit_static_gc_roots): visit GC roots in the Emacs data section. (mark_object_root_visitor): root callback used for conventional GC marking (weak_hash_tables): new internal variable for tracking found weak hash tables during GC. (mark_and_sweep_weak_table_contents): new weak hash table marking. (garbage_collect_1): use new GC root visitor machinery. (mark_vectorlike): accept a vectorlike_header instead of a Lisp_Vector. (mark_frame, mark_window, mark_hash_table): new functions. (mark_object): initialize 'm'; check for pdumper objects and use new mark-bit accessors throughout. Remove some object-specific marking code and move to helper functions above. (survives_gc_p): check for pdumper objects. (gc-sweep): clear pdumper mark bits. (init_alloc_once_for_pdumper): new helper function for early init called both during normal init and pdumper load. (init_alloc_once): pdumper integration. * src/Makefile.in: Rewrite dumping for pdumper; add pdumper.o; invoke temacs with --temacs command line option; build dmpstruct.h from dmpstruct.awk; stop relying on CANNOT_DUMP; clean up pdumper intermediate files during build. * nextstep/Makefile.in: build emacs.pdmp into NS packages * lisp/startup.el: account for new '--temacs' and '--dump-file' command line option. * lisp/loadup.el: rewrite early init to account for pdumper; use injected 'dump-mode' variable (set via the new '--temacs' option) instead of parsing command line. * lisp/cus-start.el: Check 'dump-mode' instead of 'purify-flag', since the new 'dump-mode' * lib-src/make-fingerprint.c: new program * lib-src/Makefile.in: built make-fingerprint utility program * configure.ac: Add --with-pdumper toggle to control pdumper support; add --with-unexec toggle to control unexec support. Add --with-dumping option to control which dumping strategy we use by default. Adjust for pdumper throughout. Check for posix_madvise. * Makefile.in: Add @DUMPING@ substitution; add pdumper mode. * .gitignore: Add make-fingerprint, temacs.in, fingerprint.c, dmpstruct.h, and pdumper dump files.
Diffstat (limited to 'src/emacs.c')
-rw-r--r--src/emacs.c304
1 files changed, 252 insertions, 52 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 221b074afc9..9c88b6e3f17 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -118,6 +118,9 @@ extern char etext;
#include <sys/resource.h>
#endif
+#include "pdumper.h"
+#include "epaths.h"
+
static const char emacs_version[] = PACKAGE_VERSION;
static const char emacs_copyright[] = COPYRIGHT;
static const char emacs_bugreport[] = PACKAGE_BUGREPORT;
@@ -130,19 +133,9 @@ Lisp_Object empty_unibyte_string, empty_multibyte_string;
Lisp_Object Vlibrary_cache;
#endif
-/* Set after Emacs has started up the first time.
- Prevents reinitialization of the Lisp world and keymaps
- on subsequent starts. */
+struct gflags gflags;
bool initialized;
-#ifndef CANNOT_DUMP
-/* Set to true if this instance of Emacs might dump. */
-# ifndef DOUG_LEA_MALLOC
-static
-# endif
-bool might_dump;
-#endif
-
/* If true, Emacs should not attempt to use a window-specific code,
but instead should use the virtual terminal under which it was started. */
bool inhibit_window_system;
@@ -519,8 +512,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
etc_exists = Ffile_exists_p (tem);
if (!NILP (etc_exists))
{
- Vinstallation_directory
- = Ffile_name_as_directory (dir);
+ Vinstallation_directory = Ffile_name_as_directory (dir);
break;
}
}
@@ -545,8 +537,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
if (!NILP (etc_exists))
{
tem = Fexpand_file_name (build_string (".."), dir);
- Vinstallation_directory
- = Ffile_name_as_directory (tem);
+ Vinstallation_directory = Ffile_name_as_directory (tem);
break;
}
}
@@ -659,6 +650,43 @@ argmatch (char **argv, int argc, const char *sstr, const char *lstr,
}
}
+static bool
+string_starts_with_p (const char* string, const char* prefix)
+{
+ return strncmp (string, prefix, strlen (prefix)) == 0;
+}
+
+/* Return the value of GNU-style long argument ARGUMENT if given on
+ command line. ARGUMENT must begin with "-". If ARGUMENT is not
+ given, return NULL. */
+static char *
+find_argument (const char *argument, int argc, char **argv)
+{
+ char *found = NULL;
+ int i;
+
+ eassert (argument[0] == '-');
+
+ for (i = 1; i < argc; ++i)
+ if (string_starts_with_p (argv[i], argument) &&
+ ((argv[i] + strlen (argument))[0] == '=' ||
+ (argv[i] + strlen (argument))[0] == '\0'))
+ {
+ int j = i;
+ found = argv[j++] + strlen (argument);
+ if (*found == '=')
+ ++found;
+ else if (i < argc)
+ found = argv[j++];
+ else
+ fatal ("no argument given for %s", argument);
+ break;
+ }
+ else if (strcmp (argv[i], "--") == 0)
+ break;
+ return found;
+}
+
/* Close standard output and standard error, reporting any write
errors as best we can. This is intended for use with atexit. */
static void
@@ -677,6 +705,114 @@ close_output_streams (void)
_exit (EXIT_FAILURE);
}
+#ifdef HAVE_PDUMPER
+
+static const char *
+dump_error_to_string (enum pdumper_load_result result)
+{
+ switch (result)
+ {
+ case PDUMPER_LOAD_SUCCESS:
+ return "success";
+ case PDUMPER_LOAD_OOM:
+ return "out of memory";
+ case PDUMPER_NOT_LOADED:
+ return "not loaded";
+ case PDUMPER_LOAD_FILE_NOT_FOUND:
+ return "could not open file";
+ case PDUMPER_LOAD_BAD_FILE_TYPE:
+ return "not a dump file";
+ case PDUMPER_LOAD_FAILED_DUMP:
+ return "dump file is result of failed dump attempt";
+ case PDUMPER_LOAD_VERSION_MISMATCH:
+ return "not built for this Emacs executable";
+ default:
+ return "generic error";
+ }
+}
+
+#define PDUMP_FILE_ARG "--dump-file"
+
+static enum pdumper_load_result
+load_pdump (int argc, char **argv)
+{
+ const char *const suffix = ".pdmp";
+ const char *const argv0_base = "emacs";
+ enum pdumper_load_result result;
+#ifdef WINDOWSNT
+ size_t argv0_len;
+#endif
+
+ /* TODO: maybe more thoroughly scrub process environment in order to
+ make this use case (loading a pdumper image in an unexeced emacs)
+ possible? Right now, we assume that things we don't touch are
+ zero-initialized, and in an unexeced Emacs, this assumption
+ doesn't hold. */
+ if (initialized)
+ fatal ("cannot load pdumper image in unexeced Emacs");
+
+ /* Look for an explicitly-specified dump file. */
+ const char *path_exec = PATH_EXEC;
+ char *dump_file = find_argument (PDUMP_FILE_ARG, argc, argv);
+
+ result = PDUMPER_NOT_LOADED;
+ if (dump_file)
+ result = pdumper_load (dump_file);
+
+ if (dump_file && result != PDUMPER_LOAD_SUCCESS)
+ fatal ("could not load dump file \"%s\": %s",
+ dump_file, dump_error_to_string (result));
+
+ if (result == PDUMPER_LOAD_SUCCESS)
+ goto out;
+
+ /* Look for a dump file in the same directory as the executable; it
+ should have the same basename. */
+
+ dump_file = alloca (strlen (argv[0]) + strlen (suffix) + 1);
+#ifdef WINDOWSNT
+ /* Remove the .exe extension if present. */
+ argv0_len = strlen (argv[0]);
+ if (argv0_len >= 4 && c_strcasecmp (argv[0] + argv0_len - 4, ".exe") == 0)
+ sprintf (dump_file, "%.*s%s", argv0_len - 4, argv[0], suffix);
+ else
+#endif
+ sprintf (dump_file, "%s%s", argv[0], suffix);
+
+ result = pdumper_load (dump_file);
+ if (result == PDUMPER_LOAD_SUCCESS)
+ goto out;
+
+ if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
+ fatal ("could not load dump file \"%s\": %s",
+ dump_file, dump_error_to_string (result));
+
+ /* Finally, look for "emacs.pdmp" in PATH_EXEC. We hardcode
+ "emacs" in "emacs.pdmp" so that the Emacs binary still works
+ if the user copies and renames it.
+
+ FIXME: this doesn't work with emacs-XX.YY.ZZ.pdmp versioned files. */
+#ifdef WINDOWSNT
+ /* On MS-Windows, PATH_EXEC normally starts with a literal
+ "%emacs_dir%", so it will never work without some tweaking. */
+ path_exec = w32_relocate (path_exec);
+#endif
+ dump_file = alloca (strlen (path_exec)
+ + 1
+ + strlen (argv0_base)
+ + strlen (suffix)
+ + 1);
+ sprintf (dump_file, "%s%c%s%s",
+ path_exec, DIRECTORY_SEP, argv0_base, suffix);
+ result = pdumper_load (dump_file);
+ if (result != PDUMPER_LOAD_SUCCESS)
+ dump_file = NULL;
+
+ out:
+ return result;
+}
+#endif /* HAVE_PDUMPER */
+
/* ARGSUSED */
int
main (int argc, char **argv)
@@ -686,7 +822,6 @@ main (int argc, char **argv)
void *stack_bottom_variable;
bool do_initial_setlocale;
- bool dumping;
int skip_args = 0;
bool no_loadup = false;
char *junk = 0;
@@ -702,25 +837,62 @@ main (int argc, char **argv)
/* Record (approximately) where the stack begins. */
stack_bottom = (char *) &stack_bottom_variable;
-#ifndef CANNOT_DUMP
- dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0
- || strcmp (argv[argc - 1], "bootstrap") == 0);
-#else
- dumping = false;
+ const char *dump_mode = NULL;
+ const char *temacs = find_argument ("--temacs", argc, argv);
+#ifdef HAVE_PDUMPER
+ bool attempt_load_pdump = false;
#endif
- argc = maybe_disable_address_randomization (dumping, argc, argv);
-
+ /* Look for this argument first, before any heap allocation, so we
+ can set heap flags properly if we're going to unexec. */
+ if (!initialized && temacs)
+ {
#ifndef CANNOT_DUMP
- might_dump = !initialized;
-
-# ifdef GNU_LINUX
- if (!initialized)
+ if (strcmp (temacs, "dump") == 0 ||
+ strcmp (temacs, "bootstrap") == 0)
+ gflags.will_dump_with_unexec_ = true;
+#endif
+#ifdef HAVE_PDUMPER
+ if (strcmp (temacs, "pdump") == 0 ||
+ strcmp (temacs, "pbootstrap") == 0)
+ gflags.will_dump_with_pdumper_ = true;
+#endif
+#if defined (HAVE_PDUMPER) || !defined (CANNOT_DUMP)
+ if (strcmp (temacs, "bootstrap") == 0 ||
+ strcmp (temacs, "pbootstrap") == 0)
+ gflags.will_bootstrap_ = true;
+ gflags.will_dump_ =
+ will_dump_with_pdumper_p () ||
+ will_dump_with_unexec_p ();
+ if (will_dump_p ())
+ dump_mode = temacs;
+#endif
+ if (!dump_mode)
+ fatal ("Invalid temacs mode '%s'", temacs);
+ }
+ else if (temacs)
{
- char *heap_start = my_heap_start ();
- heap_bss_diff = heap_start - max (my_endbss, my_endbss_static);
+ fatal ("--temacs not supported for unexeced emacs");
}
-# endif
+ else if (initialized)
+ {
+#ifdef HAVE_PDUMPER
+ if (find_argument (PDUMP_FILE_ARG, argc, argv))
+ fatal ("%s not supported in unexeced emacs", PDUMP_FILE_ARG);
+#endif
+ }
+ else
+ {
+ eassert (!initialized);
+ eassert (!temacs);
+#ifdef PDUMP_FILE_ARG
+ attempt_load_pdump = true;
+#endif
+ }
+
+#ifndef CANNOT_DUMP
+ if (!will_dump_with_unexec_p ())
+ gflags.will_not_unexec_ = true;
#endif
#if defined WINDOWSNT || defined HAVE_NTGUI
@@ -742,6 +914,22 @@ main (int argc, char **argv)
w32_init_main_thread ();
#endif
+#ifdef HAVE_PDUMPER
+ if (attempt_load_pdump)
+ load_pdump (argc, argv);
+#endif
+
+ argc = maybe_disable_address_randomization (
+ will_dump_with_unexec_p (), argc, argv);
+
+#if defined (GNU_LINUX) && !defined (CANNOT_DUMP)
+ if (!initialized)
+ {
+ char *heap_start = my_heap_start ();
+ heap_bss_diff = heap_start - max (my_endbss, my_endbss_static);
+ }
+#endif
+
#ifdef RUN_TIME_REMAP
if (initialized)
run_time_remap (argv[0]);
@@ -850,10 +1038,7 @@ main (int argc, char **argv)
frames. */
int extra = (30 * 1000) * 50;
- bool try_to_grow_stack = true;
-#ifndef CANNOT_DUMP
- try_to_grow_stack = !noninteractive || initialized;
-#endif
+ bool try_to_grow_stack = !noninteractive || initialized;
if (try_to_grow_stack)
{
@@ -1184,17 +1369,15 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
&& !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
-# ifndef CANNOT_DUMP
/* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
that causes an infinite recursive loop with FreeBSD. See
Bug#14569. The part of this bug involving Cygwin is no longer
relevant, now that Cygwin defines HYBRID_MALLOC. */
- if (!noninteractive || initialized)
-# endif
+ if (!noninteractive || !will_dump_p ())
malloc_enable_thread ();
#endif
- init_signals (dumping);
+ init_signals ();
noninteractive1 = noninteractive;
@@ -1204,7 +1387,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
{
init_alloc_once ();
init_threads_once ();
- init_obarray ();
+ init_obarray_once ();
init_eval_once ();
init_charset_once ();
init_coding_once ();
@@ -1242,7 +1425,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
/* Before init_window_once, because it sets up the
Vcoding_system_hash_table. */
syms_of_coding (); /* This should be after syms_of_fileio. */
-
+ init_frame_once (); /* Before init_window_once. */
init_window_once (); /* Init the window system. */
#ifdef HAVE_WINDOW_SYSTEM
init_fringe_once (); /* Swap bitmaps if necessary. */
@@ -1282,7 +1465,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
bool module_assertions
= argmatch (argv, argc, "-module-assertions", "--module-assertions", 15,
NULL, &skip_args);
- if (dumping && module_assertions)
+ if (will_dump_p () && module_assertions)
{
fputs ("Module assertions are not supported during dumping\n", stderr);
exit (1);
@@ -1419,7 +1602,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
/* egetenv is a pretty low-level facility, which may get called in
many circumstances; it seems flimsy to put off initializing it
until calling init_callproc. Do not do it when dumping. */
- if (! dumping)
+ if (!will_dump_p ())
set_initial_environment ();
#ifdef WINDOWSNT
@@ -1433,7 +1616,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
variables from the parent process without modifications from
Emacs. */
init_environment (argv);
- init_ntproc (dumping); /* must precede init_editfns. */
+ init_ntproc (will_dump_p ()); /* must precede init_editfns. */
#endif
/* AIX crashes are reported in system versions 3.2.3 and 3.2.4
@@ -1445,7 +1628,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#endif
/* Init buffer storage and default directory of main buffer. */
- init_buffer (initialized);
+ init_buffer ();
init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
@@ -1620,6 +1803,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_threads ();
syms_of_profiler ();
+ syms_of_pdumper ();
#ifdef HAVE_JSON
syms_of_json ();
@@ -1650,7 +1834,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_charset ();
/* This calls putenv and so must precede init_process_emacs. */
- init_timefns (dumping);
+ init_timefns ();
/* This sets Voperating_system_release, which init_process_emacs uses. */
init_editfns ();
@@ -1669,10 +1853,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_process_emacs (sockfd);
init_keyboard (); /* This too must precede init_sys_modes. */
- if (!noninteractive)
- init_display (); /* Determine terminal type. Calls init_sys_modes. */
+ init_display (); /* Determine terminal type. Calls init_sys_modes. */
#if HAVE_W32NOTIFY
- else
+ if (noninteractive)
init_crit (); /* w32notify.c needs this in batch mode. */
#endif /* HAVE_W32NOTIFY */
init_xdisp ();
@@ -1716,7 +1899,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
moncontrol (0);
#endif
- initialized = 1;
+ initialized = true;
+
+ if (dump_mode)
+ Vdump_mode = build_string (dump_mode);
/* Enter editor command loop. This never returns. */
Frecursive_edit ();
@@ -2166,8 +2352,11 @@ You must run Emacs in batch mode in order to dump it. */)
if (! noninteractive)
error ("Dumping Emacs works only in batch mode");
- if (!might_dump)
- error ("Emacs can be dumped only once");
+ if (dumped_with_unexec_p ())
+ error ("Emacs can be dumped using unexec only once");
+
+ if (definitely_will_not_unexec_p ())
+ error ("This Emacs instance was not started in temacs mode");
#if defined GNU_LINUX && !defined CANNOT_DUMP
@@ -2231,12 +2420,19 @@ You must run Emacs in batch mode in order to dump it. */)
#endif /* not WINDOWSNT */
#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
+ struct gflags old_gflags = gflags;
+ gflags.will_dump_ = false;
+ gflags.will_dump_with_unexec_ = false;
+ gflags.dumped_with_unexec_ = true;
+
alloc_unexec_pre ();
unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0);
alloc_unexec_post ();
+ gflags = old_gflags;
+
#ifdef WINDOWSNT
Vlibrary_cache = Qnil;
#endif
@@ -2250,6 +2446,7 @@ You must run Emacs in batch mode in order to dump it. */)
}
#endif /* not CANNOT_DUMP */
+
#if HAVE_SETLOCALE
/* Recover from setlocale (LC_ALL, ""). */
@@ -2585,7 +2782,7 @@ Don't rely on it for testing whether a feature you want to use is available. */
Vsystem_configuration_features = build_string (EMACS_CONFIG_FEATURES);
DEFVAR_BOOL ("noninteractive", noninteractive1,
- doc: /* Non-nil means Emacs is running without interactive terminal. */);
+ doc: /* Non-nil means Emacs is running without interactive terminal. */);
DEFVAR_LISP ("kill-emacs-hook", Vkill_emacs_hook,
doc: /* Hook run when `kill-emacs' is called.
@@ -2670,6 +2867,9 @@ component .BUILD is present. This is now stored separately in
doc: /* Address of mailing list for GNU Emacs bugs. */);
Vreport_emacs_bug_address = build_string (emacs_bugreport);
+ DEFVAR_LISP ("dump-mode", Vdump_mode,
+ doc: /* Non-nil when Emacs is dumping itself. */);
+
DEFVAR_LISP ("dynamic-library-alist", Vdynamic_library_alist,
doc: /* Alist of dynamic libraries vs external files implementing them.
Each element is a list (LIBRARY FILE...), where the car is a symbol