[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Skipping unexec via a big .elc file (was: When should ralloc.c be used?)

From: Stefan Monnier
Subject: Skipping unexec via a big .elc file (was: When should ralloc.c be used?)
Date: Sun, 23 Oct 2016 12:44:33 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux)

>> If someone wants to do that, great. I'd rather spend my own limited
>> cycles on fixing the main problem, which is unexec.
> I thought we agreed to get rid of unexec by loading a single .elc file
> at startup of Emacs, and remove the distinction between temacs and
> Emacs altogether.  Is that what you'd like to work on?

FWIW, I just did a quick experiment with the patch below which dumps the
state of Emacs's obarray after loadup.el into a big "dumped.elc" file.
Not sure if such an approach could work, but in any case I expect that
a working .elc file should likely be of comparable size.

The result is a .elc file of 3.3MB which seems reasonable.
When I try to load it, tho, I get:

    % time src/emacs -Q --batch -l dumped.elc -f kill-emacs
    src/emacs -Q --batch -l dumped.elc -f kill-emacs  3.50s user 0.00s system 
99% cpu 3.506 total

And that's with a warm cache on "i3-4170 CPU @ 3.70GHz" (my first, and
still only, CPU that goes beyond 3GHz).

So even if there might be ways to speed this up, it doesn't look
too promising.


diff --git a/lisp/loadup.el b/lisp/loadup.el
index 5c16464..dddd71f 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -474,6 +474,65 @@
                              (expand-file-name name invocation-directory)
+      (message "Dumping into dumped.elc...preparing...")
+      ;; Dump the current state into a file so we can reload it!
+      (with-current-buffer (generate-new-buffer "dumped.elc")
+        (message "Dumping into dumped.elc...generating...")
+        (insert ";address@hidden@address@hidden;;; Compiled\n;;; in Emacs 
version " emacs-version "\n")
+        (let ((cmds '()))
+          (setcdr global-buffers-menu-map nil) ;; Get rid of buffer objects!
+          (mapatoms
+           (lambda (s)
+             (when (and (fboundp s)
+                        (not (subrp (symbol-function s)))
+                        ;; FIXME: We need these, but they contain
+                        ;; unprintable objects.
+                        (not (memq s '(rename-buffer))))
+               (push `(fset ',s ,(macroexp-quote (symbol-function s))) cmds))
+             (when (and (boundp s) (not (keywordp s))
+                        (not (memq s '(nil t
+                                       ;; I think we don't need these!
+                                       terminal-frame
+                                       ;; FIXME: We need these, but they 
+                                       ;; unprintable objects.
+                                       advertised-signature-table
+                                       undo-auto--undoably-changed-buffers))))
+               ;; FIXME: Don't record in the load-history!
+               ;; FIXME: Handle varaliases!
+               (let ((v (symbol-value s)))
+                 (push `(defvar ,s
+                          ,(cond
+                            ((subrp v)
+                             `(symbol-function ',(intern (subr-name v))))
+                            ((and (markerp v) (null (marker-buffer v)))
+                             '(make-marker))
+                            ((and (overlayp v) (null (overlay-buffer v)))
+                             '(let ((ol (make-overlay (point-min) 
+                                (delete-overlay ol)
+                                ol))
+                            (v (macroexp-quote v))))
+                       cmds)))
+             (when (symbol-plist s)
+               (push `(setplist ',s ',(symbol-plist s)) cmds))))
+          (message "Dumping into dumped.elc...printing...")
+          (let ((print-circle t)
+                (print-gensym t)
+                (print-quoted t)
+                (print-level nil)
+                (print-length nil)
+                (print-escape-newlines t))
+            (print `(progn . ,cmds) (current-buffer)))
+          (goto-char (point-min))
+          (while (re-search-forward " (\\(defvar\\|setplist\\|fset\\) " nil t)
+            (goto-char (match-beginning 0))
+            (delete-char 1) (insert "\n"))
+          (message "Dumping into dumped.elc...saving...")
+          (let ((coding-system-for-write 'emacs-internal))
+            (write-region (point-min) (point-max) (buffer-name)))
+          (message "Dumping into dumped.elc...done")
+          ))
 ;; For machines with CANNOT_DUMP defined in config.h,

reply via email to

[Prev in Thread] Current Thread [Next in Thread]