emacs-devel
[Top][All Lists]
Advanced

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

Re: debug performance problem


From: Richard Stallman
Subject: Re: debug performance problem
Date: Sat, 15 Dec 2001 23:21:11 -0700 (MST)

    But I think it is still too slow to do step by step execution.  The
    old debugger responded quasi instantly to each 'd' or 'j' request.

I agree, that delay is unacceptable.

I have one other idea for speeding it up, though.  It could be
possible to save the backtrace text from the previous debugger
invocation, and that way only the part that has changed needs to be
rescanned.

Does this make it adequately fast?



(defvar debugger-previous-backtrace nil
  "The contents of the previous backtrace (including text properties).
This is to optimize `debugger-make-xrefs'.")

(defun debugger-make-xrefs (&optional buffer)
  "Attach cross-references to symbol names in the `*Backtrace*' buffer."
  (interactive "b")
  (save-excursion
    (set-buffer (or buffer (current-buffer)))
    (setq buffer (current-buffer))
    (let ((buffer-read-only nil)
          (old-end 1) (new-end 1))
      ;; If we saved an old backtrace, find the common part
      ;; between the new and the old.
      ;; Compare line by line, starting from the end,
      ;; because that's the part that is likely to be unchanged.
      (if debugger-previous-backtrace
          (let (old-start new-start (all-match t))
            (goto-char (point-max))
            (with-temp-buffer
              (insert debugger-previous-backtrace)
              (while (and all-match (not (bobp)))
                (setq old-end (point))
                (forward-line -1)
                (setq old-start (point))
                (with-current-buffer buffer
                  (setq new-end (point))
                  (forward-line -1)
                  (setq new-start (point)))
                (if (not (zerop
                          (compare-buffer-substrings
                           (current-buffer) old-start old-end
                           buffer new-start new-end)))
                    (setq all-match nil))))
            ;; Now new-end is the position of the start of the
            ;; unchanged part in the current buffer, and old-end is
            ;; the position of that same text in the saved old
            ;; backtrace.  But we must subtract 1 since strings are
            ;; indexed in origin 0.

            ;; Replace the unchanged part of the backtrace
            ;; with the text from debugger-previous-backtrace,
            ;; since that already has the proper xrefs.
            ;; With this optimization, we only need to scan
            ;; the changed part of the backtrace.
            (delete-region new-end (point-max))
            (goto-char (point-max))
            (insert (substring debugger-previous-backtrace (1- old-end)))
            ;; Make the unchanged part of the backtrace inaccessible
            ;; so it won't be scanned.
            (narrow-to-region (point-min) new-end)))
            
      ;; Scan the new part of the backtrace, inserting xrefs.
      (goto-char (point-min))
      (while (progn
               (skip-syntax-forward "^w_")
               (not (eobp)))
        (let* ((beg (point))
               (end (progn (skip-syntax-forward "w_") (point)))
               (sym (intern-soft (buffer-substring-no-properties
                                  beg end)))
               (file (and sym (symbol-file sym))))
          (message "sym %s, file %s" sym file)
          (recursive-edit)
          (when file
            (goto-char beg)
            ;; help-xref-button needs to operate on something matched
            ;; by a regexp, so set that up for it.
            (re-search-forward "\\(\\(\\sw\\|\\s_\\)+\\)")
            (help-xref-button 1 'help-function-def sym file))))
      (widen))
    (setq debugger-previous-backtrace (buffer-string))))




reply via email to

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