view lisp/update-elc-2.el @ 5170:5ddbab03b0e6

various fixes to memory-usage stats -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-03-25 Ben Wing <ben@xemacs.org> * diagnose.el (show-memory-usage): * diagnose.el (show-object-memory-usage-stats): Further changes to correspond with changes in the C code; add an additional column in show-object-memory-usage-stats showing the ancillary Lisp overhead used with each type; shrink columns for windows in show-memory-usage to get it to fit in 79 chars. src/ChangeLog addition: 2010-03-25 Ben Wing <ben@xemacs.org> * alloc.c: * alloc.c (struct): * alloc.c (finish_object_memory_usage_stats): * alloc.c (object_memory_usage_stats): * alloc.c (Fobject_memory_usage): * alloc.c (lisp_object_memory_usage_full): * alloc.c (compute_memusage_stats_length): * lrecord.h: * lrecord.h (struct lrecord_implementation): Add fields to the `lrecord_implementation' structure to list an offset into the array of extra statistics in a `struct generic_usage_stats' and a length, listing the first slice of ancillary Lisp-object memory. Compute automatically in compute_memusage_stats_length(). Use to add an entry `FOO-lisp-ancillary-storage' for object type FOO. Don't crash when an int or char is given to object-memory-usage, signal an error instead. Add functions lisp_object_memory_usage_full() and lisp_object_memory_usage() to compute the total memory usage of an object (sum of object, non-Lisp attached, and Lisp ancillary memory). * array.c: * array.c (gap_array_memory_usage): * array.h: Add function to return memory usage of a gap array. * buffer.c (struct buffer_stats): * buffer.c (compute_buffer_usage): * buffer.c (vars_of_buffer): * extents.c (compute_buffer_extent_usage): * marker.c: * marker.c (compute_buffer_marker_usage): * extents.h: * lisp.h: Remove `struct usage_stats' arg from compute_buffer_marker_usage() and compute_buffer_extent_usage() -- these are ancillary Lisp objects and don't get accumulated into `struct usage_stats'; change the value of `memusage_stats_list' so that `markers' and `extents' memory is in Lisp-ancillary, where it belongs. In compute_buffer_marker_usage(), use lisp_object_memory_usage() rather than lisp_object_storage_size(). * casetab.c: * casetab.c (case_table_memory_usage): * casetab.c (vars_of_casetab): * emacs.c (main_1): Add memory usage stats for case tables. * lisp.h: Add comment explaining the `struct generic_usage_stats' more, as well as the new fields in lrecord_implementation. * console-impl.h: * console-impl.h (struct console_methods): * scrollbar-gtk.c: * scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): * scrollbar-msw.c: * scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage): * scrollbar-x.c: * scrollbar-x.c (x_compute_scrollbar_instance_usage): * scrollbar.c: * scrollbar.c (struct scrollbar_instance_stats): * scrollbar.c (compute_all_scrollbar_instance_usage): * scrollbar.c (scrollbar_instance_memory_usage): * scrollbar.c (scrollbar_objects_create): * scrollbar.c (vars_of_scrollbar): * scrollbar.h: * symsinit.h: * window.c: * window.c (find_window_mirror_maybe): * window.c (struct window_mirror_stats): * window.c (compute_window_mirror_usage): * window.c (window_mirror_memory_usage): * window.c (compute_window_usage): * window.c (window_objects_create): * window.c (syms_of_window): * window.c (vars_of_window): Redo memory-usage associated with windows, window mirrors, and scrollbar instances. Should fix crash in find_window_mirror, among other things. Properly assign memo ry to object memory, non-Lisp extra memory, and Lisp ancillary memory. For example, redisplay structures are non-Lisp memory hanging off a window mirror, not a window; make it an ancillary Lisp-object field. Window mirrors and scrollbar instances have their own statistics, among other things.
author Ben Wing <ben@xemacs.org>
date Thu, 25 Mar 2010 06:07:25 -0500
parents 9fec7fedbf1b
children 308d34e9f07d
line wrap: on
line source

;;; update-elc-2.el --- Recompile remaining .el files, post-dumping

;; Copyright (C) 1997 by Free Software Foundation, Inc.
;; Copyright (C) 2000, 2003 Ben Wing.

;; Author: Ben Wing <ben@xemacs.org>, based on cleantree.el by
;;         Steven L Baur <steve@xemacs.org>
;; Maintainer: XEmacs Development Team
;; Keywords: internal

;; This file is part of XEmacs.

;; XEmacs 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 2, or (at your option)
;; any later version.

;; XEmacs 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 XEmacs; see the file COPYING.  If not, write to the Free
;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
;; 02111-1307, USA.

;;; Synched up with: Not in FSF

;;; Commentary:

;; This file should be used after XEmacs has been dumped, to recompile
;; all remaining out-of-date .els and clean up orphaned .elcs.  It should
;; be called as
;;
;;   xemacs -batch -vanilla -l update-elc-2.el -f batch-update-elc-2 ${dirname}
;;
;; where ${dirname} is the directory tree to recompile, usually `lisp'.
;;
;; Note that this is very different from update-elc.el, which is called
;; BEFORE dumping, handles only the files needed to dump, and is called
;; from temacs instead of xemacs.
;;
;; The original cleantree.el had the comment: This code is derived
;; from Gnus based on a suggestion by David Moore <dmoore@ucsd.edu>

;;; Code:

;; Help debug problems.
(setq stack-trace-on-error t
      load-always-display-messages t)

(defvar update-elc-ignored-dirs
  `("." ".." "CVS" "SCCS" "RCS" ,@(unless (featurep 'mule) '("mule"))))

(defvar update-elc-ignored-files
  ;; note: entries here are regexps
  '("^," ;; #### huh?
    "^paths\\.el$"
    "^loadup\\.el$"
    "^loadup-el\\.el$"
    "^update-elc\\.el$"
    "^update-elc-2\\.el$"
    "^dumped-lisp\\.el$"
    "^make-docfile\\.el$"
    "^site-start\\.el$"
    "^site-load\\.el$"
    "^site-init\\.el$"))

(defvar dirfiles-table (make-hash-table :test 'equal))

;; SEEN accumulates the list of already-handled dirs.
(defun do-update-elc-2 (dir compile-stage-p seen)
  (setq dir (file-name-as-directory dir))
  ;; Only scan this sub-tree if we haven't been here yet.
  (unless (member (file-truename dir) seen)
    (push (file-truename dir) seen)

    (let ((files (or (gethash dir dirfiles-table)
		     (directory-files dir t nil t))))

      ;; Do this directory.
      (if compile-stage-p
	  ;; Stage 2: Recompile necessary .els
	  (dolist (file files)
	    (when (string-match "\\.el$" file)
	      (let ((file-c (concat file "c")))
		(when (and (not (member file-c files))
			   ;; no need to check for out-of-date-ness because
			   ;; that was already done, and .elc removed.
			   (let (ignore)
			     (mapcar
			      #'(lambda (regexp)
				  (if (string-match
				       regexp
				       (file-name-nondirectory file))
				      (setq ignore t)))
			      update-elc-ignored-files)
			     (not ignore)))
		  (byte-compile-file file)))))

	;; Stage 1.
	;; Remove out-of-date elcs
	(let (deleted)
	  (dolist (file files)
	    (when (string-match "\\.el$" file)
	      (let ((file-c (concat file "c")))
		(when (and (member file-c files)
			   (file-newer-than-file-p file file-c))
		  (message "Removing out-of-date %s" file-c)
		  (delete-file file-c)
		  (push file-c deleted)))))

	;; Remove elcs without corresponding el
	(dolist (file-c files)
	  (when (string-match "\\.elc$" file-c)
	    (let ((file (replace-in-string file-c "c$" "")))
	      (when (not (member file files))
		(message "Removing %s; no corresponding .el" file-c)
		(delete-file file-c)
		(push file-c deleted)))))

	(setq files (set-difference files deleted :test 'equal))))

      (puthash dir files dirfiles-table)

      ;; We descend recursively.  On my Windows machine, it is much faster
      ;; to call directory-files again to recompute than to call
      ;; file-directory-p on each member of the files list.
      (dolist (dir (directory-files dir t nil t 'dir))
	(when (not (member (file-name-nondirectory dir)
			   update-elc-ignored-dirs))
	  (do-update-elc-2 dir compile-stage-p seen))))))

(defun batch-update-elc-2 ()
  (defvar command-line-args-left)
  (unless noninteractive
    (error "`batch-update-elc-2' is to be used only with -batch"))
  (let ((dir (car command-line-args-left)))
    ;; don't depend on being able to autoload `update-autoload-files'!
    (load "autoload")
    (load "bytecomp")
    (load "byte-optimize")
    ;; #### the API used here is deprecated, convert to one with explicit
    ;; arguments when it is available
    ;; update-elc.el signals us to rebuild the autoloads when necessary.
    ;; in some cases it will rebuild the autoloads itself, but doing it this
    ;; way is slow, so we avoid it when possible.
    (when (file-exists-p (expand-file-name "REBUILD_AUTOLOADS"
					   invocation-directory))
      ;; if we were instructed to rebuild the autoloads, force the file
      ;; to be touched even w/o changes; otherwise, we won't ever stop
      ;; being told to rebuild them.
      (update-autoload-files dir "auto" nil t)
      (byte-recompile-file (expand-file-name "auto-autoloads.el" dir) 0)
      (when (featurep 'mule)
	(let ((muledir (expand-file-name "../lisp/mule" (file-truename dir))))
	  ;; force here just like above.
	  (update-autoload-files muledir "mule" nil t)
	  (byte-recompile-file (expand-file-name "auto-autoloads.el" dir) 0))))
    (when (featurep 'modules)
      (let* ((moddir (expand-file-name "../modules" (file-truename dir)))
	     (autofile (expand-file-name "auto-autoloads.el" moddir)))
	(update-autoload-files 
	 (delete (concat (file-name-as-directory moddir) ".")
		 (delete (concat (file-name-as-directory moddir) "..")
			 (directory-files moddir t nil nil 0)))
	 "modules" autofile)
	(byte-recompile-file autofile 0)))
    ;; now load the (perhaps newly rebuilt) autoloads; we were called with
    ;; -no-autoloads so they're not already loaded.
    (load (expand-file-name "auto-autoloads" lisp-directory))
    (when (featurep 'mule)
      (load (expand-file-name "mule/auto-autoloads" lisp-directory)))
    ;; We remove all the bad .elcs before any byte-compilation, because
    ;; there may be dependencies between one .el and another (even across
    ;; directories), and we don't want to load an out-of-date .elc while
    ;; byte-compiling a file.
    (message "Removing old or spurious .elcs in directory tree `%s'..." dir)
    (do-update-elc-2 dir nil nil)
    (message "Removing old or spurious .elcs in directory tree `%s'...done"
	     dir)
    (message "Recompiling updated .els in directory tree `%s'..." dir)
    (do-update-elc-2 dir t nil)
    (message "Recompiling updated .els in directory tree `%s'...done" dir)
    ;; likewise here.
    (load "cus-dep")
    (Custom-make-dependencies dir)
    (byte-recompile-file (expand-file-name "custom-load.el" dir) 0)
    (when (featurep 'mule)
      (Custom-make-dependencies (expand-file-name "mule" dir))
      (byte-recompile-file (expand-file-name "mule/custom-load.el" dir) 0)
      ;; See the eval-when-compile in the definition of
      ;; Installation-file-coding-system; if the file name sniffing or the
      ;; available coding systems have changed, version.elc should be
      ;; rebuilt.
      (byte-recompile-file (expand-file-name "version.el" dir) 0)))
  (setq command-line-args-left nil))

;;; update-elc-2.el ends here