emacs-devel
[Top][All Lists]
Advanced

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

Re: Building Emacs overflowed pure space


From: Stefan Monnier
Subject: Re: Building Emacs overflowed pure space
Date: Wed, 19 Jul 2006 11:05:39 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

>> Dumped with dolist in subr.el: 1209808 bytes used
>> dolist in cl.el:  >1211000 bytes used (overflow)
>> dolist in cl.el with the modification
>> '--cl-dolist-temp-- -> '--dolist-temp-- :
>> 1209832 bytes used

Interesting.  I'm wondering why you say "multiple of 8", since the pointer
to the data part of a string is not a Lisp_Object but a plain pointer
without any special alignment constraint AFAIK.

Also `make-symbol' allocates a fixed amount of memory AFAIK, independent
from the symbol name's length (it keeps a ref to the string argument,
instead, so that (eq X (symbol-name (make-symbol X))) is always true), and
the "--cl-dolist-temp--" string should only be allocated once (when reading
the macro definition).  So the only explanation that I can find is that the
uninterned symbol names get copied to purespace at some point (don't know
when or why), at which point the single shared string "--cl-dolist-temp--"
gets copied N times.

> (defmacro dolist (spec &rest body)
>   "Loop over a list.
> Evaluate BODY with VAR bound to each car from LIST, in turn.
> Then evaluate RESULT to get return value, default nil.

> \(fn (VAR LIST [RESULT]) BODY...)"
>   (declare (indent 1) (debug ((symbolp form &optional form) body)))
>   (let ((temp (make-symbol "--dolist-temp--")))
>     `(let ((,temp ,(nth 1 spec))
>          ,(car spec))
>        (while ,temp
>        (setq ,(car spec) (car ,temp))
>        (setq ,temp (cdr ,temp))
>        ,@body)
>        ,@(if (cdr (cdr spec))
>            `((setq ,(car spec) nil) ,@(cdr (cdr spec)))))))

> In the above definition, `(setq ,temp (cdr ,temp))' is not placed at
> the end of the loop body, so it disables the following optimization in
> byte-opt.el:

>             ;; X: varref-Y    ...     varset-Y goto-X  -->
>             ;; X: varref-Y Z: ... dup varset-Y goto-Z
>             ;; (varset-X goto-BACK, BACK: varref-X --> copy the varref down.)
>             ;; (This is so usual for while loops that it is worth handling).

> Is it OK to place `(setq ...)' after `,@body' as in the CL-version?

The setq can be placed after, but the cdr can't, in case the `body' does
a setcdr on it.  So maybe

   (defmacro dolist (spec &rest body)
     "Loop over a list.
   Evaluate BODY with VAR bound to each car from LIST, in turn.
   Then evaluate RESULT to get return value, default nil.
   
   \(fn (VAR LIST [RESULT]) BODY...)"
     (declare (indent 1) (debug ((symbolp form &optional form) body)))
     (let ((temp (make-symbol "--dolist-temp--")))
       `(let ((,temp ,(nth 1 spec))
              ,(car spec))
          (while ,temp
            (setq ,(car spec) (car ,temp))
            (setq ,temp (prog1 (cdr ,temp) ,@body)))
          ,@(if (cdr (cdr spec))
                `((setq ,(car spec) nil) ,@(cdr (cdr spec)))))))

will do the trick?


        Stefan




reply via email to

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