diff options
| author | Chong Yidong | 2009-08-29 22:15:12 +0000 |
|---|---|---|
| committer | Chong Yidong | 2009-08-29 22:15:12 +0000 |
| commit | aec7ab2d27060295a8422ca9295ac8b3b4fcb7d1 (patch) | |
| tree | 4035328eb48ef28167dbad4e0f5c1e63b55eefe1 | |
| parent | 7daf6b549d70507ebf26fac08c332c73cbe9256c (diff) | |
| download | emacs-aec7ab2d27060295a8422ca9295ac8b3b4fcb7d1.tar.gz emacs-aec7ab2d27060295a8422ca9295ac8b3b4fcb7d1.zip | |
cedet/semantic/elp.el: New file.
| -rw-r--r-- | lisp/cedet/semantic/elp.el | 772 |
1 files changed, 772 insertions, 0 deletions
diff --git a/lisp/cedet/semantic/elp.el b/lisp/cedet/semantic/elp.el new file mode 100644 index 00000000000..a60692ca3de --- /dev/null +++ b/lisp/cedet/semantic/elp.el | |||
| @@ -0,0 +1,772 @@ | |||
| 1 | ;;; semantic-elp.el --- Bind ELP to measure Semantic | ||
| 2 | |||
| 3 | ;; Copyright (C) 2008, 2009 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Eric M. Ludlam <eric@siege-engine.com> | ||
| 6 | ;; X-RCS: $Id: semantic-elp.el,v 1.16 2009/04/02 01:18:33 zappo Exp $ | ||
| 7 | |||
| 8 | ;; This file is part of GNU Emacs. | ||
| 9 | |||
| 10 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 11 | ;; it under the terms of the GNU General Public License as published by | ||
| 12 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 13 | ;; (at your option) any later version. | ||
| 14 | |||
| 15 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | ;; GNU General Public License for more details. | ||
| 19 | |||
| 20 | ;; You should have received a copy of the GNU General Public License | ||
| 21 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 22 | |||
| 23 | ;;; Commentary: | ||
| 24 | ;; | ||
| 25 | ;; Provide fast ways to profile various (often slow) Semantic processes. | ||
| 26 | |||
| 27 | (require 'elp) | ||
| 28 | (require 'data-debug) | ||
| 29 | (require 'semantic/adebug) | ||
| 30 | (require 'semantic/tag-ls) | ||
| 31 | (require 'semantic/tag-file) | ||
| 32 | (require 'semantic/db) | ||
| 33 | (require 'semantic/db-find) | ||
| 34 | (require 'semantic/db-typecache) | ||
| 35 | (require 'semantic/scope) | ||
| 36 | (require 'semantic/analyze/fcn) | ||
| 37 | (require 'semantic/analyze) | ||
| 38 | (require 'semantic/analyze/complete) | ||
| 39 | |||
| 40 | ;;; Code: | ||
| 41 | (defvar semantic-elp-emacs-core-list | ||
| 42 | '( | ||
| 43 | append | ||
| 44 | copy-sequence | ||
| 45 | expand-file-name | ||
| 46 | file-exists-p | ||
| 47 | file-name-directory | ||
| 48 | file-name-nondirectory | ||
| 49 | file-attributes | ||
| 50 | file-truename | ||
| 51 | find-buffer-visiting | ||
| 52 | length | ||
| 53 | locate-file | ||
| 54 | nconc | ||
| 55 | nreverse | ||
| 56 | sort | ||
| 57 | string< | ||
| 58 | string= | ||
| 59 | ) | ||
| 60 | "List of Emacs functions for profiling.") | ||
| 61 | |||
| 62 | (defvar semantic-elp-eieio-core-list | ||
| 63 | '( | ||
| 64 | eieio-generic-call | ||
| 65 | eieio-generic-call-primary-only | ||
| 66 | eieiomt-method-list | ||
| 67 | eieio-generic-form | ||
| 68 | eieio-oref | ||
| 69 | eieio-oset | ||
| 70 | obj-of-class-p | ||
| 71 | ) | ||
| 72 | "List of EIEIO functions for profiling.") | ||
| 73 | |||
| 74 | (defvar semantic-elp-ede-core-list | ||
| 75 | '( | ||
| 76 | ede-current-project | ||
| 77 | ede-directory-get-open-project | ||
| 78 | ede-expand-filename | ||
| 79 | ede-expand-filename-impl | ||
| 80 | ede-locate-file-in-project | ||
| 81 | ede-locate-file-in-project-impl | ||
| 82 | ede-system-include-path | ||
| 83 | ede-toplevel | ||
| 84 | ede-toplevel-project | ||
| 85 | ede-directory-project-p | ||
| 86 | ) | ||
| 87 | "List of EDE functions to watch out for.") | ||
| 88 | |||
| 89 | (defvar semantic-elp-semantic-core-list | ||
| 90 | '( | ||
| 91 | semantic-ctxt-current-argument | ||
| 92 | semantic-ctxt-current-assignment | ||
| 93 | semantic-ctxt-current-class-list | ||
| 94 | semantic-ctxt-current-function | ||
| 95 | semantic-ctxt-current-symbol-and-bounds | ||
| 96 | semantic-current-tag | ||
| 97 | semantic-dependency-tag-file | ||
| 98 | semantic-equivalent-tag-p | ||
| 99 | semantic-fetch-tags | ||
| 100 | semantic-fetch-tags-fast | ||
| 101 | semantic-find-tag-by-overlay | ||
| 102 | semantic-sort-tags-by-name-decreasing | ||
| 103 | semantic-sort-tags-by-name-increasing | ||
| 104 | semantic-sort-tags-by-name-then-type-increasing | ||
| 105 | semantic-sort-tags-by-type-decreasing | ||
| 106 | semantic-sort-tags-by-type-increasing | ||
| 107 | semantic-tag-clone | ||
| 108 | semantic-tag-components | ||
| 109 | semantic-tag-copy | ||
| 110 | semantic-tag-external-member-children | ||
| 111 | semantic-tag-file-name | ||
| 112 | semantic-tag-function-arguments | ||
| 113 | semantic-tag-function-parent | ||
| 114 | semantic-tag-get-attribute | ||
| 115 | semantic-tag-in-buffer-p | ||
| 116 | semantic-tag-include-filename | ||
| 117 | ;;semantic-tag-lessp-name-then-type | ||
| 118 | semantic-tag-name | ||
| 119 | semantic-tag-new-type | ||
| 120 | semantic-tag-of-class-p | ||
| 121 | semantic-tag-of-type-p | ||
| 122 | semantic-tag-of-type-p | ||
| 123 | semantic-tag-p | ||
| 124 | semantic-tag-prototype-p | ||
| 125 | semantic-tag-set-faux | ||
| 126 | semantic-tag-type | ||
| 127 | semantic-tag-type-members | ||
| 128 | semantic-tag-type-superclasses | ||
| 129 | semantic-tag-with-position-p | ||
| 130 | ) | ||
| 131 | "List of core Semantic functions for profiling.") | ||
| 132 | (defvar semantic-elp-semantic-find-core-list | ||
| 133 | '( | ||
| 134 | semantic-find-tags-by-class | ||
| 135 | semantic-find-tags-by-name | ||
| 136 | semantic-find-tags-by-name-regexp | ||
| 137 | semantic-find-tags-by-scope-protection | ||
| 138 | semantic-find-tags-by-type | ||
| 139 | semantic-find-tags-for-completion | ||
| 140 | semantic-find-tags-included | ||
| 141 | semantic-find-tags-of-compound-type | ||
| 142 | ) | ||
| 143 | "List of semantic-find routines for profiling.") | ||
| 144 | |||
| 145 | (defvar semantic-elp-semanticdb-core-list | ||
| 146 | '( | ||
| 147 | semanticdb-cache-get | ||
| 148 | semanticdb-current-database-list | ||
| 149 | semanticdb-file-table | ||
| 150 | semanticdb-file-table-object | ||
| 151 | semanticdb-full-filename | ||
| 152 | semanticdb-get-buffer | ||
| 153 | semanticdb-get-table-index | ||
| 154 | semanticdb-refresh-references | ||
| 155 | semanticdb-refresh-table | ||
| 156 | semanticdb-needs-refresh-p | ||
| 157 | semanticdb-directory-loaded-p | ||
| 158 | semanticdb-full-filename | ||
| 159 | semanticdb-create-table-for-file | ||
| 160 | ) | ||
| 161 | "List of core Semanticdb functions for profiling.") | ||
| 162 | |||
| 163 | (defvar semantic-elp-include-path-list | ||
| 164 | '( | ||
| 165 | semanticdb-find-incomplete-cache-entries-p | ||
| 166 | semanticdb-find-load-unloaded | ||
| 167 | semanticdb-find-table-for-include | ||
| 168 | semanticdb-find-throttle-active-p | ||
| 169 | semanticdb-find-translate-path-default | ||
| 170 | semanticdb-find-translate-path-brutish-default | ||
| 171 | semanticdb-find-translate-path-includes--internal | ||
| 172 | semanticdb-find-translate-path-includes-default | ||
| 173 | ) | ||
| 174 | "List of include path calculation functions for profiling.") | ||
| 175 | |||
| 176 | (defvar semantic-elp-semanticdb-find-list | ||
| 177 | '( | ||
| 178 | semanticdb-fast-strip-find-results | ||
| 179 | semanticdb-find-results-p | ||
| 180 | semanticdb-find-tags-by-class | ||
| 181 | semanticdb-find-tags-by-name | ||
| 182 | semanticdb-find-tags-by-name-regexp | ||
| 183 | semanticdb-find-tags-collector | ||
| 184 | semanticdb-find-tags-external-children-of-type | ||
| 185 | semanticdb-find-tags-for-completion | ||
| 186 | semanticdb-strip-find-results | ||
| 187 | ) | ||
| 188 | "List of semanticdb find functions to profile. | ||
| 189 | You may also need `semantic-elp-include-path-list'.") | ||
| 190 | |||
| 191 | (defun semantic-elp-core-enable () | ||
| 192 | "Do an ELP reset, and enable profiling of the core system." | ||
| 193 | (elp-reset-all) | ||
| 194 | (elp-instrument-list semantic-elp-emacs-core-list) | ||
| 195 | (elp-instrument-list semantic-elp-eieio-core-list) | ||
| 196 | (elp-instrument-list semantic-elp-ede-core-list) | ||
| 197 | (elp-instrument-list semantic-elp-semantic-core-list) | ||
| 198 | (elp-instrument-list semantic-elp-semanticdb-core-list) | ||
| 199 | (elp-instrument-list semantic-elp-semanticdb-find-list) | ||
| 200 | (elp-instrument-list semantic-elp-include-path-list) | ||
| 201 | ) | ||
| 202 | |||
| 203 | |||
| 204 | (defun semantic-elp-include-path-enable () | ||
| 205 | "Enable profiling for `semanticdb-find-translate-path'." | ||
| 206 | (semantic-elp-core-enable) | ||
| 207 | (elp-set-master 'semanticdb-find-translate-path-default) | ||
| 208 | ) | ||
| 209 | |||
| 210 | (defvar semantic-elp-typecache-list | ||
| 211 | '( | ||
| 212 | semantic-analyze-split-name | ||
| 213 | semanticdb-get-typecache | ||
| 214 | semanticdb-typecache-merge-streams | ||
| 215 | semanticdb-typecache-safe-tag-members | ||
| 216 | semanticdb-typecache-apply-filename | ||
| 217 | semanticdb-typecache-file-tags | ||
| 218 | semanticdb-typecache-include-tags | ||
| 219 | ) | ||
| 220 | "List of typecaching functions for profiling.") | ||
| 221 | |||
| 222 | (defun semantic-elp-profile-typecache (tab) | ||
| 223 | "Profile the typecache. Start with table TAB." | ||
| 224 | (let ((tc (semanticdb-get-typecache tab))) | ||
| 225 | (semanticdb-typecache-file-tags tab) | ||
| 226 | (semanticdb-typecache-include-tags tab) | ||
| 227 | tc)) | ||
| 228 | |||
| 229 | (defun semantic-elp-typecache-enable () | ||
| 230 | "Enable profiling for `semanticdb-get-typecache'." | ||
| 231 | (semantic-elp-include-path-enable) | ||
| 232 | (elp-instrument-list semantic-elp-typecache-list) | ||
| 233 | (elp-set-master 'semantic-elp-profile-typecache) | ||
| 234 | ) | ||
| 235 | |||
| 236 | (defvar semantic-elp-scope-list | ||
| 237 | '( | ||
| 238 | semantic-analyze-find-tag | ||
| 239 | semantic-analyze-scope-nested-tags | ||
| 240 | semantic-analyze-scoped-types | ||
| 241 | semantic-analyze-scoped-types | ||
| 242 | semantic-analyze-tag-prototype-p | ||
| 243 | semantic-analyze-scoped-type-parts | ||
| 244 | semantic-calculate-scope | ||
| 245 | semantic-ctxt-scoped-types | ||
| 246 | semantic-get-all-local-variables | ||
| 247 | semantic-scope-find | ||
| 248 | semanticdb-typecache-find | ||
| 249 | semanticdb-typecache-merge-streams | ||
| 250 | ) | ||
| 251 | "List of scope calculation functions for profiling.") | ||
| 252 | |||
| 253 | (defun semantic-elp-scope-enable () | ||
| 254 | "Enable profiling for `semanticdb-calculate-scope'." | ||
| 255 | (semantic-elp-core-enable) | ||
| 256 | (elp-instrument-list semantic-elp-typecache-list) | ||
| 257 | (elp-instrument-list semantic-elp-scope-list) | ||
| 258 | (elp-set-master 'semantic-calculate-scope) | ||
| 259 | ) | ||
| 260 | |||
| 261 | (defvar semantic-elp-analyze-list | ||
| 262 | '( | ||
| 263 | semantic-analyze-current-symbol | ||
| 264 | semantic-analyze-current-context | ||
| 265 | semantic-analyze-dereference-metatype | ||
| 266 | semantic-analyze-find-tag-sequence | ||
| 267 | semantic-analyze-interesting-tag | ||
| 268 | semantic-analyze-pop-to-context | ||
| 269 | semantic-analyze-select-best-tag | ||
| 270 | semantic-analyze-tag-type | ||
| 271 | semantic-analyze-type-to-name | ||
| 272 | semantic-analyze-type-constraint | ||
| 273 | semantic-analyze-scoped-type-parts | ||
| 274 | semantic-cache-data-to-buffer | ||
| 275 | ) | ||
| 276 | "List of analyzer calculation functions for profiling.") | ||
| 277 | |||
| 278 | (defun semantic-elp-analyze-enable () | ||
| 279 | "Enable profiling for `semanticdb-analyze-current-context'." | ||
| 280 | (semantic-elp-scope-enable) | ||
| 281 | (elp-instrument-list semantic-elp-analyze-list) | ||
| 282 | (elp-set-master 'semantic-analyze-current-context) | ||
| 283 | ) | ||
| 284 | |||
| 285 | (defvar semantic-elp-symref-list | ||
| 286 | '( | ||
| 287 | semantic-symref-hits-in-region | ||
| 288 | semantic-symref-test-count-hits-in-tag | ||
| 289 | ) | ||
| 290 | "List of symref functions for profiling.") | ||
| 291 | |||
| 292 | (defun semantic-elp-analyze-symref-hits () | ||
| 293 | "Enable profiling for `semanticdb-analyze-current-context'." | ||
| 294 | (semantic-elp-analyze-enable) | ||
| 295 | (elp-instrument-list semantic-elp-symref-list) | ||
| 296 | (elp-set-master 'semantic-symref-test-count-hits-in-tag) | ||
| 297 | ) | ||
| 298 | |||
| 299 | (defvar semantic-elp-complete-list | ||
| 300 | '( | ||
| 301 | semantic-analyze-possible-completions | ||
| 302 | semantic-analyze-possible-completions-default | ||
| 303 | semantic-analyze-tags-of-class-list | ||
| 304 | semantic-analyze-type-constants | ||
| 305 | semantic-unique-tag-table-by-name | ||
| 306 | ) | ||
| 307 | "List of smart completion functions for profiling.") | ||
| 308 | |||
| 309 | (defun semantic-elp-complete-enable () | ||
| 310 | "Enable profiling for `semanticdb-analyze-current-context'." | ||
| 311 | (semantic-elp-analyze-enable) | ||
| 312 | (elp-instrument-list semantic-elp-complete-list) | ||
| 313 | (elp-set-master 'semantic-analyze-possible-completions) | ||
| 314 | ) | ||
| 315 | |||
| 316 | ;;; Storage Classes | ||
| 317 | ;; | ||
| 318 | ;; | ||
| 319 | (defclass semantic-elp-data () | ||
| 320 | ((raw :initarg :raw | ||
| 321 | :type list | ||
| 322 | :documentation | ||
| 323 | "The raw ELP data.") | ||
| 324 | (sort :initform time | ||
| 325 | :documentation | ||
| 326 | "Which column do we sort our data by during various dumps.") | ||
| 327 | (sorted :initform nil | ||
| 328 | :documentation | ||
| 329 | "The sorted and filtered version of this data.") | ||
| 330 | (total :initarg :total | ||
| 331 | :initform nil | ||
| 332 | :documentation | ||
| 333 | "The total time spent in the operation. | ||
| 334 | Recorded outside of ELP.") | ||
| 335 | ) | ||
| 336 | "Class for managing ELP data.") | ||
| 337 | |||
| 338 | (defmethod semantic-elp-change-sort ((data semantic-elp-data) &optional newsort) | ||
| 339 | "Change the sort in DATA object to NEWSORT." | ||
| 340 | (cond ((eq newsort 'rotate) | ||
| 341 | (let* ((arot '((time . avg) | ||
| 342 | (avg . calls) | ||
| 343 | (calls . name) | ||
| 344 | (name . time))) | ||
| 345 | (next (cdr (assoc (oref data sort) arot))) | ||
| 346 | ) | ||
| 347 | (oset data sort next))) | ||
| 348 | ((null newsort) | ||
| 349 | nil) | ||
| 350 | (t | ||
| 351 | (oset data sort newsort))) | ||
| 352 | (let ((r (copy-sequence (oref data raw))) | ||
| 353 | (s (oref data sort))) | ||
| 354 | (cond ((eq s 'time) | ||
| 355 | (oset data sorted (sort r (lambda (a b) | ||
| 356 | (> (aref a 1) (aref b 1)) | ||
| 357 | ))) | ||
| 358 | ) | ||
| 359 | ((eq s 'avg) | ||
| 360 | (oset data sorted (sort r (lambda (a b) | ||
| 361 | (> (aref a 2) (aref b 2)) | ||
| 362 | ))) | ||
| 363 | ) | ||
| 364 | ((eq s 'calls) | ||
| 365 | (oset data sorted (sort r (lambda (a b) | ||
| 366 | (> (aref a 0) (aref b 0)) | ||
| 367 | ))) | ||
| 368 | ) | ||
| 369 | ((eq s 'name) | ||
| 370 | (oset data sorted (sort r (lambda (a b) | ||
| 371 | (string< (aref a 3) (aref b 3)) | ||
| 372 | ))) | ||
| 373 | ) | ||
| 374 | (t (message "Don't know how to resort with %s" s) | ||
| 375 | )))) | ||
| 376 | |||
| 377 | (defun semantic-elp-goto-function (point) | ||
| 378 | "Goto the function from the ELP data. | ||
| 379 | Argument POINT is where to get the data from." | ||
| 380 | (let* ((data (get-text-property point 'ddebug)) | ||
| 381 | ) | ||
| 382 | (find-function (intern-soft (aref data 3))) | ||
| 383 | )) | ||
| 384 | |||
| 385 | (defmethod semantic-elp-dump-table ((data semantic-elp-data) | ||
| 386 | prefix) | ||
| 387 | "dump out the current DATA table using PREFIX before each line." | ||
| 388 | (let* ((elpd (oref data sorted)) | ||
| 389 | (spaces (make-string (- (length prefix) 2) ? )) | ||
| 390 | ) | ||
| 391 | (data-debug-insert-simple-thing | ||
| 392 | "Calls\t Total Time\t Avg Time/Call\tName" | ||
| 393 | spaces " " 'underline) | ||
| 394 | (dolist (d elpd) | ||
| 395 | (when (> (aref d 0) 0) ;; We had some calls | ||
| 396 | (let ((start (point)) | ||
| 397 | (end nil)) | ||
| 398 | (data-debug-insert-simple-thing | ||
| 399 | (format " % 4d\t% 2.7f\t% 2.7f\t%s" | ||
| 400 | (aref d 0) (aref d 1) (aref d 2) (aref d 3)) | ||
| 401 | spaces " " nil) | ||
| 402 | (setq end (1- (point))) | ||
| 403 | (put-text-property start end 'ddebug d) | ||
| 404 | (put-text-property start end 'ddebug-noexpand t) | ||
| 405 | (put-text-property start end 'ddebug-function | ||
| 406 | 'semantic-elp-goto-function) | ||
| 407 | ) | ||
| 408 | )) | ||
| 409 | ) | ||
| 410 | ) | ||
| 411 | |||
| 412 | (defmethod data-debug/eieio-insert-slots ((data semantic-elp-data) | ||
| 413 | prefix) | ||
| 414 | "Show the fields of ELP data in an adebug buffer. | ||
| 415 | Ignore the usual, and format a nice table." | ||
| 416 | (data-debug-insert-thing (object-name-string data) | ||
| 417 | prefix | ||
| 418 | "Name: ") | ||
| 419 | (let* ((cl (object-class data)) | ||
| 420 | (cv (class-v cl))) | ||
| 421 | (data-debug-insert-thing (class-constructor cl) | ||
| 422 | prefix | ||
| 423 | "Class: ") | ||
| 424 | ) | ||
| 425 | |||
| 426 | (data-debug-insert-thing (oref data :total) | ||
| 427 | prefix | ||
| 428 | "Total Time Spent: ") | ||
| 429 | |||
| 430 | (let ((s (oref data sort)) | ||
| 431 | ) | ||
| 432 | ;; Show how it's sorted: | ||
| 433 | (let ((start (point)) | ||
| 434 | (end nil) | ||
| 435 | ) | ||
| 436 | (insert prefix "Sort Method: " (symbol-name s)) | ||
| 437 | (setq end (point)) | ||
| 438 | ;; (data-debug-insert-thing s prefix "Sort Method: ") | ||
| 439 | (put-text-property start end 'ddebug data) | ||
| 440 | (put-text-property start end 'ddebug-noexpand t) | ||
| 441 | (put-text-property start end 'ddebug-indent(length prefix)) | ||
| 442 | (put-text-property start end 'ddebug-prefix prefix) | ||
| 443 | (put-text-property start end 'ddebug-function | ||
| 444 | 'semantic-elp-change-sort-adebug) | ||
| 445 | (put-text-property start end 'help-echo | ||
| 446 | "Change the Sort by selecting twice.") | ||
| 447 | (insert "\n")) | ||
| 448 | |||
| 449 | ;; How to sort the raw data | ||
| 450 | (semantic-elp-change-sort data) | ||
| 451 | ) | ||
| 452 | ;; Display | ||
| 453 | (semantic-elp-dump-table data prefix) | ||
| 454 | ) | ||
| 455 | |||
| 456 | (defun semantic-elp-change-sort-adebug (point) | ||
| 457 | "Change the sort function here. Redisplay. | ||
| 458 | Argument POINT is where the text is." | ||
| 459 | (let* ((data (get-text-property point 'ddebug)) | ||
| 460 | (prefix (get-text-property point 'ddebug-prefix)) | ||
| 461 | ) | ||
| 462 | ;; Get rid of the old table. | ||
| 463 | (data-debug-contract-current-line) | ||
| 464 | ;; Change it | ||
| 465 | (semantic-elp-change-sort data 'rotate) | ||
| 466 | (end-of-line) | ||
| 467 | (forward-word -1) | ||
| 468 | (delete-region (point) (point-at-eol)) | ||
| 469 | (insert (symbol-name (oref data sort))) | ||
| 470 | ;; Redraw it. | ||
| 471 | (save-excursion | ||
| 472 | (end-of-line) | ||
| 473 | (forward-char 1) | ||
| 474 | (semantic-elp-dump-table data prefix)) | ||
| 475 | )) | ||
| 476 | |||
| 477 | (defclass semantic-elp-object-base (eieio-persistent) | ||
| 478 | ((file-header-line :initform ";; SEMANTIC ELP Profiling Save File") | ||
| 479 | (total :initarg :total | ||
| 480 | :type number | ||
| 481 | :documentation | ||
| 482 | "Amount of time spent during the entire collection.") | ||
| 483 | ) | ||
| 484 | "Base elp object.") | ||
| 485 | |||
| 486 | (defclass semantic-elp-object (semantic-elp-object-base) | ||
| 487 | ((time :initarg :time | ||
| 488 | :type semantic-elp-data | ||
| 489 | :documentation | ||
| 490 | "Times for calculating something.") | ||
| 491 | (answer :initarg :answer | ||
| 492 | :documentation | ||
| 493 | "Any answer that might be useful.")) | ||
| 494 | "Simple elp object for remembering one analysis run.") | ||
| 495 | |||
| 496 | (defclass semantic-elp-object-analyze (semantic-elp-object-base) | ||
| 497 | ((pathtime :initarg :pathtime | ||
| 498 | :type semantic-elp-data | ||
| 499 | :documentation | ||
| 500 | "Times for calculating the include path.") | ||
| 501 | (typecachetime :initarg :typecachetime | ||
| 502 | :type semantic-elp-data | ||
| 503 | :documentation | ||
| 504 | "Times for calculating the typecache.") | ||
| 505 | (scopetime :initarg :scopetime | ||
| 506 | :type semantic-elp-data | ||
| 507 | :documentation | ||
| 508 | "Times for calculating the typecache") | ||
| 509 | (ctxttime :initarg :ctxttime | ||
| 510 | :type semantic-elp-data | ||
| 511 | :documentation | ||
| 512 | "Times for calculating the context.") | ||
| 513 | (completiontime :initarg :completiontime | ||
| 514 | :type semantic-elp-data | ||
| 515 | :documentation | ||
| 516 | "Times for calculating the completions.") | ||
| 517 | ) | ||
| 518 | "Results from a profile run.") | ||
| 519 | |||
| 520 | ;;; ELP hackery. | ||
| 521 | ;; | ||
| 522 | |||
| 523 | (defvar semantic-elp-last-results nil | ||
| 524 | "Save the last results from an ELP run for more post processing.") | ||
| 525 | |||
| 526 | (defun semantic-elp-results (name) | ||
| 527 | "Fetch results from the last run, and display. | ||
| 528 | Copied out of elp.el and modified only slightly. | ||
| 529 | Argument NAME is the name to give the ELP data object." | ||
| 530 | (let ((resvec | ||
| 531 | (mapcar | ||
| 532 | (function | ||
| 533 | (lambda (funsym) | ||
| 534 | (let* ((info (get funsym elp-timer-info-property)) | ||
| 535 | (symname (format "%s" funsym)) | ||
| 536 | (cc (aref info 0)) | ||
| 537 | (tt (aref info 1))) | ||
| 538 | (if (not info) | ||
| 539 | (insert "No profiling information found for: " | ||
| 540 | symname) | ||
| 541 | ;;(setq longest (max longest (length symname))) | ||
| 542 | (vector cc tt (if (zerop cc) | ||
| 543 | 0.0 ;avoid arithmetic div-by-zero errors | ||
| 544 | (/ (float tt) (float cc))) | ||
| 545 | symname))))) | ||
| 546 | elp-all-instrumented-list)) | ||
| 547 | ) ; end let | ||
| 548 | (setq semantic-elp-last-results (semantic-elp-data name :raw resvec)) | ||
| 549 | (elp-reset-all)) | ||
| 550 | ) | ||
| 551 | |||
| 552 | ;;; The big analyze and timer function! | ||
| 553 | ;; | ||
| 554 | ;; | ||
| 555 | |||
| 556 | (defvar semantic-elp-last-run nil | ||
| 557 | "The results from the last elp run.") | ||
| 558 | |||
| 559 | (defun semantic-elp-analyze () | ||
| 560 | "Run the analyzer, using ELP to measure performance." | ||
| 561 | (interactive) | ||
| 562 | (let ((elp-recycle-buffers-p nil) | ||
| 563 | (totalstart (current-time)) | ||
| 564 | (totalstop nil) | ||
| 565 | start stop | ||
| 566 | path pathtime | ||
| 567 | typecache typecachetime | ||
| 568 | scope scopetime | ||
| 569 | ctxt ctxttime | ||
| 570 | completion completiontime) | ||
| 571 | ;; Force tag table to be up to date. | ||
| 572 | (semantic-clear-toplevel-cache) | ||
| 573 | (semantic-fetch-tags) | ||
| 574 | ;; Path translation | ||
| 575 | (semantic-elp-include-path-enable) | ||
| 576 | (progn | ||
| 577 | (setq start (current-time)) | ||
| 578 | (setq path (semanticdb-find-translate-path nil nil)) | ||
| 579 | (setq stop (current-time))) | ||
| 580 | (semantic-elp-results "translate-path") | ||
| 581 | (setq pathtime semantic-elp-last-results) | ||
| 582 | (oset pathtime :total (semantic-elapsed-time start stop)) | ||
| 583 | ;; typecache | ||
| 584 | (let* ((tab semanticdb-current-table) | ||
| 585 | (idx (semanticdb-get-table-index tab)) | ||
| 586 | (tc nil) | ||
| 587 | ) | ||
| 588 | (semantic-elp-typecache-enable) | ||
| 589 | (progn | ||
| 590 | (setq start (current-time)) | ||
| 591 | (setq tc (semantic-elp-profile-typecache tab)) | ||
| 592 | (setq stop (current-time))) | ||
| 593 | (setq typecache tc)) | ||
| 594 | (semantic-elp-results "typecache") | ||
| 595 | (setq typecachetime semantic-elp-last-results) | ||
| 596 | (oset typecachetime :total (semantic-elapsed-time start stop)) | ||
| 597 | ;; Scope | ||
| 598 | (semantic-elp-scope-enable) | ||
| 599 | (progn | ||
| 600 | (setq start (current-time)) | ||
| 601 | (setq scope (semantic-calculate-scope)) | ||
| 602 | (setq stop (current-time))) | ||
| 603 | (semantic-elp-results "scope") | ||
| 604 | (setq scopetime semantic-elp-last-results) | ||
| 605 | (oset scopetime :total (semantic-elapsed-time start stop)) | ||
| 606 | ;; Analyze! | ||
| 607 | (semantic-elp-analyze-enable) | ||
| 608 | (progn | ||
| 609 | (setq start (current-time)) | ||
| 610 | (setq ctxt (semantic-analyze-current-context)) ; skip caching | ||
| 611 | (setq stop (current-time))) | ||
| 612 | (semantic-elp-results "analyze") | ||
| 613 | (setq ctxttime semantic-elp-last-results) | ||
| 614 | (oset ctxttime :total (semantic-elapsed-time start stop)) | ||
| 615 | ;; Complete! | ||
| 616 | (semantic-elp-complete-enable) | ||
| 617 | (progn | ||
| 618 | (setq start (current-time)) | ||
| 619 | (setq completion (semantic-analyze-possible-completions ctxt)) | ||
| 620 | (setq stop (current-time))) | ||
| 621 | (semantic-elp-results "complete") | ||
| 622 | (setq completiontime semantic-elp-last-results) | ||
| 623 | (oset completiontime :total (semantic-elapsed-time start stop)) | ||
| 624 | ;; Finish it | ||
| 625 | (setq totalstop (current-time)) | ||
| 626 | ;; build it | ||
| 627 | (let ((elpobj (semantic-elp-object-analyze | ||
| 628 | "ELP" | ||
| 629 | :total (semantic-elapsed-time totalstart totalstop) | ||
| 630 | :pathtime pathtime | ||
| 631 | :typecachetime typecachetime | ||
| 632 | :scopetime scopetime | ||
| 633 | :ctxttime ctxttime | ||
| 634 | :completiontime completiontime | ||
| 635 | ))) | ||
| 636 | (data-debug-show elpobj) | ||
| 637 | (setq semantic-elp-last-run elpobj) | ||
| 638 | (let ((saveas (read-file-name "Save Profile to: " (expand-file-name "~/") | ||
| 639 | "semantic.elp" nil "semantic.elp"))) | ||
| 640 | (oset elpobj :file saveas) | ||
| 641 | (eieio-persistent-save elpobj) | ||
| 642 | ) | ||
| 643 | ))) | ||
| 644 | |||
| 645 | (defun semantic-elp-idle-work () | ||
| 646 | "Run the idle work scheduler, using ELP to measure performance." | ||
| 647 | (interactive) | ||
| 648 | (let ((elp-recycle-buffers-p nil) | ||
| 649 | (totalstart nil) | ||
| 650 | (totalstop nil) | ||
| 651 | ans time | ||
| 652 | ) | ||
| 653 | ;; Path translation | ||
| 654 | (semantic-elp-core-enable) | ||
| 655 | (setq totalstart (current-time)) | ||
| 656 | (semantic-idle-scheduler-work-parse-neighboring-files) | ||
| 657 | (setq totalstop (current-time)) | ||
| 658 | (semantic-elp-results "") | ||
| 659 | (setq time semantic-elp-last-results) | ||
| 660 | (oset time :total (semantic-elapsed-time totalstart totalstop)) | ||
| 661 | ;; build it | ||
| 662 | (let ((elpobj (semantic-elp-object | ||
| 663 | "ELP" | ||
| 664 | :total (semantic-elapsed-time totalstart totalstop) | ||
| 665 | :time time))) | ||
| 666 | (data-debug-show elpobj) | ||
| 667 | (setq semantic-elp-last-run elpobj) | ||
| 668 | (let ((saveas (read-file-name "Save Profile to: " (expand-file-name "~/") | ||
| 669 | "semantic.elp" nil "semantic.elp"))) | ||
| 670 | (oset elpobj :file saveas) | ||
| 671 | (eieio-persistent-save elpobj) | ||
| 672 | ) | ||
| 673 | ))) | ||
| 674 | |||
| 675 | (defun semantic-elp-searchdb () | ||
| 676 | "Run a semanticdb search routine with the profiler. | ||
| 677 | The expectation is that you will edit this fcn with different | ||
| 678 | `semanticdb-find-' routines." | ||
| 679 | (interactive) | ||
| 680 | (let ((elp-recycle-buffers-p nil) | ||
| 681 | (totalstart nil) | ||
| 682 | (totalstop nil) | ||
| 683 | ans time | ||
| 684 | ) | ||
| 685 | ;; reset | ||
| 686 | (semantic-clear-toplevel-cache) | ||
| 687 | (semantic-fetch-tags) | ||
| 688 | |||
| 689 | ;; Path translation | ||
| 690 | (semantic-elp-include-path-enable) | ||
| 691 | (setq totalstart (current-time)) | ||
| 692 | |||
| 693 | (setq ans (semanticdb-find-tags-by-name-regexp "task" nil)) | ||
| 694 | |||
| 695 | (setq totalstop (current-time)) | ||
| 696 | (semantic-elp-results "") | ||
| 697 | (setq time semantic-elp-last-results) | ||
| 698 | (oset time :total (semantic-elapsed-time totalstart totalstop)) | ||
| 699 | ;; build it | ||
| 700 | (let ((elpobj (semantic-elp-object | ||
| 701 | "ELP" | ||
| 702 | :total (semantic-elapsed-time totalstart totalstop) | ||
| 703 | :time time | ||
| 704 | :answer ans))) | ||
| 705 | (data-debug-show elpobj) | ||
| 706 | (setq semantic-elp-last-run elpobj) | ||
| 707 | (let ((saveas (read-file-name "Save Profile to: " (expand-file-name "~/") | ||
| 708 | "semantic.elp" nil "semantic.elp"))) | ||
| 709 | (oset elpobj :file saveas) | ||
| 710 | (eieio-persistent-save elpobj) | ||
| 711 | ) | ||
| 712 | ))) | ||
| 713 | |||
| 714 | (defun semantic-elp-symref-hit-count () | ||
| 715 | "Run a `semantic-symref-test-count-hits-in-tag' with elp on." | ||
| 716 | (interactive) | ||
| 717 | (let ((elp-recycle-buffers-p nil) | ||
| 718 | (totalstart nil) | ||
| 719 | (totalstop nil) | ||
| 720 | ans time | ||
| 721 | ) | ||
| 722 | ;; reset | ||
| 723 | (semantic-clear-toplevel-cache) | ||
| 724 | (semantic-fetch-tags) | ||
| 725 | |||
| 726 | ;; Build up caches so we get user use timings. | ||
| 727 | (semantic-analyze-current-context) | ||
| 728 | |||
| 729 | ;; Enable everything for analysis. | ||
| 730 | (semantic-elp-analyze-symref-hits) | ||
| 731 | |||
| 732 | ;; Do the analysis | ||
| 733 | (setq totalstart (current-time)) | ||
| 734 | |||
| 735 | (setq ans (semantic-symref-test-count-hits-in-tag)) | ||
| 736 | |||
| 737 | (setq totalstop (current-time)) | ||
| 738 | |||
| 739 | (semantic-elp-results "") | ||
| 740 | (setq time semantic-elp-last-results) | ||
| 741 | (oset time :total (semantic-elapsed-time totalstart totalstop)) | ||
| 742 | ;; build it | ||
| 743 | (let ((elpobj (semantic-elp-object | ||
| 744 | "ELP" | ||
| 745 | :total (semantic-elapsed-time totalstart totalstop) | ||
| 746 | :time time | ||
| 747 | :answer ans))) | ||
| 748 | (data-debug-show elpobj) | ||
| 749 | (setq semantic-elp-last-run elpobj) | ||
| 750 | ;;(let ((saveas (read-file-name "Save Profile to: " (expand-file-name "~/") | ||
| 751 | ;; "semantic.elp" nil "semantic.elp"))) | ||
| 752 | ;; (oset elpobj :file saveas) | ||
| 753 | ;; (eieio-persistent-save elpobj) | ||
| 754 | ;; ) | ||
| 755 | ))) | ||
| 756 | |||
| 757 | (defun semantic-elp-show-last-run () | ||
| 758 | "Show the last elp run." | ||
| 759 | (interactive) | ||
| 760 | (when (not semantic-elp-last-run) | ||
| 761 | (error "No last run to show")) | ||
| 762 | (data-debug-show semantic-elp-last-run)) | ||
| 763 | |||
| 764 | (defun semantic-elp-load-old-run (file) | ||
| 765 | "Load an old run from FILE, and show it." | ||
| 766 | (interactive "fLast Run File: ") | ||
| 767 | (setq semantic-elp-last-run | ||
| 768 | (eieio-persistent-read file)) | ||
| 769 | (data-debug-show semantic-elp-last-run)) | ||
| 770 | |||
| 771 | (provide 'semantic/elp) | ||
| 772 | ;;; semantic-elp.el ends here | ||