Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 rivejä
7.5 KiB

5 vuotta sitten
  1. (require 'slime)
  2. (require 'cl-lib)
  3. (eval-when-compile (require 'cl)) ; lexical-let*
  4. (define-slime-contrib slime-sprof
  5. "Integration with SBCL's sb-sprof."
  6. (:authors "Juho Snellman"
  7. "Stas Boukarev")
  8. (:license "MIT")
  9. (:swank-dependencies swank-sprof)
  10. (:on-load
  11. (let ((C '(and (slime-connected-p)
  12. (equal (slime-lisp-implementation-type) "SBCL"))))
  13. (setf (cdr (last (assoc "Profiling" slime-easy-menu)))
  14. `("--"
  15. [ "Start sb-sprof" slime-sprof-start ,C ]
  16. [ "Stop sb-sprof" slime-sprof-stop ,C ]
  17. [ "Report sb-sprof" slime-sprof-report ,C ])))))
  18. (defvar slime-sprof-exclude-swank nil
  19. "*Display swank functions in the report.")
  20. (define-derived-mode slime-sprof-browser-mode fundamental-mode
  21. "slprof"
  22. "Mode for browsing profiler data\
  23. \\<slime-sprof-browser-mode-map>\
  24. \\{slime-sprof-browser-mode-map}"
  25. :syntax-table lisp-mode-syntax-table
  26. (setq buffer-read-only t))
  27. (set-keymap-parent slime-sprof-browser-mode-map slime-parent-map)
  28. (slime-define-keys slime-sprof-browser-mode-map
  29. ("h" 'describe-mode)
  30. ("d" 'slime-sprof-browser-disassemble-function)
  31. ("g" 'slime-sprof-browser-go-to)
  32. ("v" 'slime-sprof-browser-view-source)
  33. ("s" 'slime-sprof-toggle-swank-exclusion)
  34. ((kbd "RET") 'slime-sprof-browser-toggle))
  35. ;; Start / stop profiling
  36. (cl-defun slime-sprof-start (&optional (mode :cpu))
  37. (interactive)
  38. (slime-eval `(swank:swank-sprof-start :mode ,mode)))
  39. (defun slime-sprof-start-alloc ()
  40. (interactive)
  41. (slime-sprof-start :alloc))
  42. (defun slime-sprof-start-time ()
  43. (interactive)
  44. (slime-sprof-start :time))
  45. (defun slime-sprof-stop ()
  46. (interactive)
  47. (slime-eval `(swank:swank-sprof-stop)))
  48. ;; Reporting
  49. (defun slime-sprof-format (graph)
  50. (with-current-buffer (slime-buffer-name :sprof)
  51. (let ((inhibit-read-only t))
  52. (erase-buffer)
  53. (insert (format "%4s %-54s %6s %6s %6s\n"
  54. "Rank"
  55. "Name"
  56. "Self%"
  57. "Cumul%"
  58. "Total%"))
  59. (dolist (data graph)
  60. (slime-sprof-browser-insert-line data 54))))
  61. (forward-line 2))
  62. (cl-defun slime-sprof-update (&optional (exclude-swank slime-sprof-exclude-swank))
  63. (slime-eval-async `(swank:swank-sprof-get-call-graph
  64. :exclude-swank ,exclude-swank)
  65. 'slime-sprof-format))
  66. (defalias 'slime-sprof-browser 'slime-sprof-report)
  67. (defun slime-sprof-report ()
  68. (interactive)
  69. (slime-with-popup-buffer ((slime-buffer-name :sprof)
  70. :connection t
  71. :select t
  72. :mode 'slime-sprof-browser-mode)
  73. (slime-sprof-update)))
  74. (defun slime-sprof-toggle-swank-exclusion ()
  75. (interactive)
  76. (setq slime-sprof-exclude-swank
  77. (not slime-sprof-exclude-swank))
  78. (slime-sprof-update))
  79. (defun slime-sprof-browser-insert-line (data name-length)
  80. (cl-destructuring-bind (index name self cumul total)
  81. data
  82. (if index
  83. (insert (format "%-4d " index))
  84. (insert " "))
  85. (slime-insert-propertized
  86. (slime-sprof-browser-name-properties)
  87. (format (format "%%-%ds " name-length)
  88. (slime-sprof-abbreviate-name name name-length)))
  89. (insert (format "%6.2f " self))
  90. (when cumul
  91. (insert (format "%6.2f " cumul))
  92. (when total
  93. (insert (format "%6.2f" total))))
  94. (when index
  95. (slime-sprof-browser-add-line-text-properties
  96. `(profile-index ,index expanded nil)))
  97. (insert "\n")))
  98. (defun slime-sprof-abbreviate-name (name max-length)
  99. (cl-subseq name 0 (min (length name) max-length)))
  100. ;; Expanding / collapsing
  101. (defun slime-sprof-browser-toggle ()
  102. (interactive)
  103. (let ((index (get-text-property (point) 'profile-index)))
  104. (when index
  105. (save-excursion
  106. (if (slime-sprof-browser-line-expanded-p)
  107. (slime-sprof-browser-collapse)
  108. (slime-sprof-browser-expand))))))
  109. (defun slime-sprof-browser-collapse ()
  110. (let ((inhibit-read-only t))
  111. (slime-sprof-browser-add-line-text-properties '(expanded nil))
  112. (forward-line)
  113. (cl-loop until (or (eobp)
  114. (get-text-property (point) 'profile-index))
  115. do
  116. (delete-region (point-at-bol) (point-at-eol))
  117. (unless (eobp)
  118. (delete-char 1)))))
  119. (defun slime-sprof-browser-expand ()
  120. (lexical-let* ((buffer (current-buffer))
  121. (point (point))
  122. (index (get-text-property point 'profile-index)))
  123. (slime-eval-async `(swank:swank-sprof-expand-node ,index)
  124. (lambda (data)
  125. (with-current-buffer buffer
  126. (save-excursion
  127. (destructuring-bind (&key callers calls)
  128. data
  129. (slime-sprof-browser-add-expansion callers
  130. "Callers"
  131. 0)
  132. (slime-sprof-browser-add-expansion calls
  133. "Calls"
  134. 0))))))))
  135. (defun slime-sprof-browser-add-expansion (data type nesting)
  136. (when data
  137. (let ((inhibit-read-only t))
  138. (slime-sprof-browser-add-line-text-properties '(expanded t))
  139. (end-of-line)
  140. (insert (format "\n %s" type))
  141. (dolist (node data)
  142. (cl-destructuring-bind (index name cumul) node
  143. (insert (format (format "\n%%%ds" (+ 7 (* 2 nesting))) ""))
  144. (slime-insert-propertized
  145. (slime-sprof-browser-name-properties)
  146. (let ((len (- 59 (* 2 nesting))))
  147. (format (format "%%-%ds " len)
  148. (slime-sprof-abbreviate-name name len))))
  149. (slime-sprof-browser-add-line-text-properties
  150. `(profile-sub-index ,index))
  151. (insert (format "%6.2f" cumul)))))))
  152. (defun slime-sprof-browser-line-expanded-p ()
  153. (get-text-property (point) 'expanded))
  154. (defun slime-sprof-browser-add-line-text-properties (properties)
  155. (add-text-properties (point-at-bol)
  156. (point-at-eol)
  157. properties))
  158. (defun slime-sprof-browser-name-properties ()
  159. '(face sldb-restart-number-face))
  160. ;; "Go to function"
  161. (defun slime-sprof-browser-go-to ()
  162. (interactive)
  163. (let ((sub-index (get-text-property (point) 'profile-sub-index)))
  164. (when sub-index
  165. (let ((pos (text-property-any
  166. (point-min) (point-max) 'profile-index sub-index)))
  167. (when pos (goto-char pos))))))
  168. ;; Disassembly
  169. (defun slime-sprof-browser-disassemble-function ()
  170. (interactive)
  171. (let ((index (or (get-text-property (point) 'profile-index)
  172. (get-text-property (point) 'profile-sub-index))))
  173. (when index
  174. (slime-eval-describe `(swank:swank-sprof-disassemble
  175. ,index)))))
  176. ;; View source
  177. (defun slime-sprof-browser-view-source ()
  178. (interactive)
  179. (let ((index (or (get-text-property (point) 'profile-index)
  180. (get-text-property (point) 'profile-sub-index))))
  181. (when index
  182. (slime-eval-async
  183. `(swank:swank-sprof-source-location ,index)
  184. (lambda (source-location)
  185. (slime-dcase source-location
  186. ((:error message)
  187. (message "%s" message)
  188. (ding))
  189. (t
  190. (slime-show-source-location source-location))))))))
  191. (provide 'slime-sprof)