;;; -*- Mode:LISP; Package:MICRO; Base:8; Readtable:ZL -*- (define-micro-function increment (a) "Increment a." ((m-t) pdl-pop) (popj-after-next popj-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-fix))) ((m-t) m+a+1 m-t a-zero) ) (define-micro-function foo (x) (locality d-mem) (start-dispatch 1 0) d-foobar (foo1 n-bit) (foo2 n-bit) (end-dispatch) (locality i-mem) (dispatch pdl-pop (byte-field 1 0) d-foobar) foo1 ((m-t) a-v-true) (popj) foo2 ((m-t) a-v-nil) (popj) ) (define-micro-function add-1-if-even (num) ((m-t) pdl-pop) (popj-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-fix))) (popj-if-bit-set (byte 1 0) m-t) ((m-t) add m-t (a-constant 1)) (popj) ) (define-micro-function car-if-list (l) ((m-t) pdl-pop) (popj-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-list))) ((vma-start-read) m-t) (check-page-read) (dispatch transport md) ((m-t) md) (popj)) (define-micro-function stat-counter () ((m-1) stat-counter) (jump return-m-1-unsigned)) (define-micro-function reset-and-enable-stat-counters (main-clock main-count aux-clock aux-count) ((a-processor-switches) dpb m-zero (lisp-byte lam:%%processor-switch-use-stat2-for-usec-clock) a-processor-switches) ;;stop counters ((rg-mode) andca rg-mode (a-constant (eval (+ (dpb -1 (byte 3 0) 0) ;aux count (dpb -1 (byte 1 4) 0) ;aux clock (dpb -1 (byte 3 20.) 0) ;main count (dpb -1 (byte 1 24.) 0) ;main clock )))) ((m-1) rg-mode) ((m-1) dpb pdl-pop (byte 3 0) a-1) ;aux count ((m-1) dpb pdl-pop (byte 1 4) a-1) ;aux clock ((m-1) dpb pdl-pop (byte 3 20.) a-1) ;main count ((m-1) dpb pdl-pop (byte 1 24.) a-1) ((stat-counter) setz) ((stat-counter-aux) setz) (popj-after-next (m-t) a-v-nil) ((rg-mode) m-1) ) (define-micro-function stop-and-read-stat-counters () ((a-processor-switches) dpb m-zero (lisp-byte lam:%%processor-switch-use-stat2-for-usec-clock) a-processor-switches) ;;stop counters ((rg-mode) andca rg-mode (a-constant (eval (+ (dpb -1 (byte 3 0) 0) ;aux count (dpb -1 (byte 1 4) 0) ;aux clock (dpb -1 (byte 3 20.) 0) ;main count (dpb -1 (byte 1 24.) 0) ;main clock )))) ((m-1) stat-counter) (call return-m-1-unsigned) ((pdl-push) m-t) ((m-1) stat-counter-aux) (call return-m-1-unsigned) ((pdl-push) m-t) (call xcons) (popj)) (define-micro-function write-new-car (list new-car) ((md) pdl-pop) (call-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-list)) trap) ((vma-start-write) pdl-pop) (check-page-write) (gc-write-test) ((m-t) a-v-nil) (popj)) (define-micro-function xor-nil-and-t (x) ((m-a) q-typed-pointer pdl-pop) (jump-equal m-a a-v-nil foo) ((m-t) a-v-nil) (popj) foo ((m-t) a-v-true) (popj)) (define-micro-function check-noop-insert () ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ((m-t) a-v-nil) ;the assembler inserts a no-op here (jump-xct-next bar) ((m-t) a-v-true) ((m-t) (a-constant (byte-value q-data-type dtp-fix))) (popj) bar (popj)) (define-micro-function test-trap () (call trap) (error-table illegal-instruction)) (define-micro-function return-t-fast () (declare (:call-as-misc-instruction t)) ((m-t) a-v-true) (popj)) (defun foo () (return-t-fast)) (define-micro-function test-mmcall-ucode (func) ((m-a) pdl-pop) (call-data-type-not-equal m-a (a-constant (byte-value q-data-type dtp-fef-pointer)) trap) ;(error-table ...) (call p3zero) ((pdl-push) m-a) ((pdl-push) a-v-true) ((arg-call mmcall) (i-arg 1)) (call-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-fix)) trap) ;(error-table...) ((m-t) add m-t (a-constant 1)) (popj)) (defun test-mmcall () (test-mmcall-ucode #'(lambda (arg) (format t "~&The arg is ~s" arg) 5))) ; M-A (and M-FEF and C-PDL at M-AP) HAS PNTR TO FEF TO CALL ; m-ap has already been updated ; m-s has previous m-ap (for frame leaving) ; M-R HAS NUMBER OF ARGUMENTS, (%%lp-ens-num-args-supplied already stored) ; M-T debugging info ; M-B the atom 'si:stat-stuff (define-micro-patch qlentr () (declare (:support-vector (i-arg-stat-data 'si:stat-data))) ((arg-call ref-support-vector) i-arg-stat-data) ((vma-start-read) add md (a-constant 1)) (check-page-read) ;no transport - it might be unbound, and we only care about T ((md) q-typed-pointer md) (jump-not-equal md a-v-true return) ((vma-start-read) m-fef) (check-page-read) (dispatch transport md) ((m-1) (lisp-byte si:%%fefh-pc-in-words) md) ((m-1) sub m-1 (a-constant 1)) ((vma-start-read) add m-1 a-fef) (check-page-read) (dispatch transport md) ((m-t) md) ;;now have debugging info (jump-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-list)) return) ((arg-call ref-support-vector) i-arg-stat-data) ((m-b) q-typed-pointer md) again (call carcdr-no-sb) ;get car in M-A, cdr in M-T (jump-data-type-not-equal m-a (a-constant (byte-value q-data-type dtp-list)) return) ;;do another car ((vma-start-read) m-a) (check-page-read) (dispatch transport md) ((md) q-typed-pointer md) (jump-equal md a-b found-it) ((m-t) q-typed-pointer m-t) (jump-not-equal m-t a-v-nil again) (jump return) found-it ((m-t) m-a) (call qcdr) (jump-data-type-not-equal m-t (a-constant (byte-value q-data-type dtp-list)) return) ((vma-start-read) m-t) (check-page-read) (dispatch transport md) (jump-data-type-not-equal md (a-constant (byte-value q-data-type dtp-fix)) return) ((m-1) md) ((md) q-pointer md) ((md) add md (a-constant 1)) ((md-start-write) ldb md q-pointer a-1) (check-page-write) (gc-write-test) (jump return) return ((m-a vma-start-read) m-fef) (check-page-read) (popj) ) (defun add-stat-data-slot (function &aux (si:%inhibit-read-only t)) (when (symbolp function) (setq function (symbol-function function))) (etypecase function (compiled-function (let ((debug-info (%p-contents-offset function (1- (%structure-boxed-size function)))) (debug-info-present (%p-ldb-offset si:%%fefhi-ms-debug-info-present function si:%fefhi-misc))) (cond ((null debug-info) (%p-dpb-offset 1 si:%%fefhi-ms-debug-info-present function si:%fefhi-misc)) ((consp (car debug-info)) (when (zerop debug-info-present) (format t "~&Function ~s has debug-info ~s, but says no debug-info present" function debug-info) (%p-dpb-offset 1 si:%%fefhi-ms-debug-info-present function si:%fefhi-misc))) (t (format t "~&Function ~s has debug-info ~s and debug-info-present ~s" function debug-info debug-info-present) (when (y-or-n-p "~&Set to NIL ?") (setq debug-info nil)) (%p-dpb-offset 1 si:%%fefhi-ms-debug-info-present function si:%fefhi-misc))) (when (null (assq 'si:stat-data debug-info)) (setf (si:fef-debugging-info function) (cons (list 'si:stat-data 0) debug-info))))))) (defun add-stat-data-slot-to-all-functions () (mapcar 'add-stat-data-slot si:*fef-list*) nil) (defun reset-all-stat-data () (mapcar #'(lambda (function) (let ((sdata (assq 'si:stat-data (debugging-info function)))) (when (null sdata) (ferror nil "no stat data for function ~s" function)) (setf (cadr sdata) 0))) si:*fef-list*) nil) (defvar *stat-data-array* (make-array 2000. :leader-list '(0))) (defun collect-stat-data () (array-initialize *stat-data-array* nil) (setf (fill-pointer *stat-data-array*) 0) (mapcar #'(lambda (function) (let ((sdata (assq 'si:stat-data (debugging-info function)))) (when (and sdata (not (zerop (cadr sdata)))) (array-push-extend *stat-data-array* (list (cadr sdata) function))))) si:*fef-list*) nil) (defun sort-it () (time '(sort *stat-data-array* #'(lambda (x y) (< (car x) (car y)))))) (define-micro-function sort-it-fast-lessp (x y) (call-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-list)) trap) ((vma-start-read) pdl-pop) (check-page-read) (call-data-type-not-equal md (a-constant (byte-value q-data-type dtp-fix)) trap) ((m-b) q-pointer md) (call-data-type-not-equal pdl-top (a-constant (byte-value q-data-type dtp-list)) trap) ((vma-start-read) pdl-pop) (check-page-read) (call-data-type-not-equal md (a-constant (byte-value q-data-type dtp-fix)) trap) ((m-a) q-pointer md) ((m-t) a-v-true) (popj-after-next popj-less-than m-a a-b) ((m-t) a-v-nil)) (defun sort-it-fast () (time '(sort *stat-data-array* #'sort-it-fast-lessp))) (defun print-it () (do ((i (1- (fill-pointer *stat-data-array*)) (1- i))) ((<= i 0)) (print (aref *stat-data-array* i)))) (defvar test-start-time) (defvar test-end-time) (defvar si:stat-data nil) (defun start-test () (when (null (get 'qlentr 'i-mem-block)) (ferror nil "must have qlentr patch ready")) (setq si:stat-data nil) (reset-all-stat-data) (setq test-start-time (time:get-universal-time)) t) (defun finish-test () (setq si:stat-data nil) (setq test-end-time (time:get-universal-time)) (collect-stat-data) (sort-it-fast) t) (defun run-test () (start-test) (let ((si:stat-data t)) (print-herald)) (finish-test)) (defun run-whole-machine-test () (start-test) (dolist (process si:all-processes) (dolist (reason (send process :run-reasons)) (when (instancep reason) (typecase reason ((or tv:lisp-listener zwei:zmacs-frame) (make-process-bind-stat-data process t))))))) (defun find-processes-with-stat-data-on () (loop for process in si:all-processes when (and (not (send process :simple-p)) (eq (symeval-in-stack-group 'si:stat-data (send process :initial-stack-group)) t)) collect process)) (defun get-whole-machine-running-results () (collect-stat-data) (setq test-end-time (time:get-universal-time)) (sort-it-fast) nil) (defun print-stats () (format t "~&From ~\time\ to ~\time\ -- ~\time-interval\" test-start-time test-end-time (- test-end-time test-start-time)) (let ((sum 0)) (dotimes (i (array-active-length *stat-data-array*)) (incf sum (car (aref *stat-data-array* i)))) (format t "~&~:d function calls total" sum) (do ((i (1- (array-active-length *stat-data-array*)) (1- i))) ((< i 0)) (format t "~&~10:d ~2d% ~s" (car (aref *stat-data-array* i)) (round (* 100. (// (float (car (aref *stat-data-array* i))) sum))) (function-name (cadr (aref *stat-data-array* i))))))) (defun new-fef (f) (if (symbolp f) (setq f (symbol-function f))) (etypecase f (compiled-function (add-stat-data-slot f) (push f si:*fef-list*))) nil) (defun make-process-bind-stat-data (process val) (check-type process si:process) (when (eq process current-process) (process-run-function "bind hack" #'make-process-bind-stat-data process val) (return-from make-process-bind-stat-data nil)) (let ((sg (send process :initial-stack-group))) (let ((rp (si:sg-regular-pdl sg)) (sp (si:sg-special-pdl sg))) (when (not (= (si:sg-initial-function-index sg) 3)) (ferror nil "initial function index not 3")) (when (not (> (si:sg-regular-pdl-pointer sg) 3)) (ferror nil "regular pdl too short")) (when (not (or (eq (aref rp 3) #'si:process-top-level) (eq (aref rp 3) #'si:lisp-top-level))) (ferror nil "inital function is not PROCESS-TOP-LEVEL or LISP-TOP-LEVEL")) (do ((index 0 (+ index 2)) slot) ((>= index (si:sg-special-pdl-pointer sg)) (ferror nil "ran out of special pdl")) (without-interrupts (when (or (not (locativep (aref sp (1+ index)))) (and (not (zerop index)) (not (zerop (%p-ldb si:%%SPECPDL-BLOCK-START-FLAG (locf (aref sp index))))))) ;;didn't find a binding already there, so bash ////// (%p-store-contents (locf (aref sp (1+ slot))) (locf (symbol-value 'si:stat-data))) (%p-store-contents (locf (aref sp slot)) val) (return nil)) (when (eq (aref sp (1+ index)) (locf (symbol-value 'si:stat-data))) (%p-store-contents (locf (aref sp index)) val) (return nil)) (when (eq (aref sp (1+ index)) (locf (symbol-value '//////))) (setq slot index)))))) (let* ((closure (symeval-in-instance process 'si:closure)) (bindings (closure-bindings closure))) (cond ((null bindings) (setf (closure-bindings closure) (list (locf (symbol-value 'si:stat-data)) (%make-pointer dtp-locative (ncons val))))) (t (do ((rest bindings (cddr rest))) ((null rest) (setf (closure-bindings closure) (list* (locf (symbol-value 'si:stat-data)) (%make-pointer dtp-locative (ncons val)) (closure-bindings closure)))) (when (eq (car rest) (locf (symbol-value 'si:stat-data))) (%p-store-contents (cadr rest) val) (return nil)))))) ) (defvar total-min-args (make-array 100. :initial-element 0)) (defvar total-max-args (make-array 100. :initial-element 0)) (defvar total-locals (make-array 100. :initial-element 0)) (defvar total-calls 0) (defun find-average-number-of-locals () (setq total-calls 0) (array-initialize total-min-args 0) (array-initialize total-max-args 0) (array-initialize total-locals 0) (dotimes (i (array-active-length *stat-data-array*)) (let ((f (cadr (aref *stat-data-array* i))) (ncalls (car (aref *stat-data-array* i)))) (incf total-calls ncalls) (when (not (= (%data-type f) dtp-fef-pointer)) (ferror nil "not a fef pointer")) (let ((misc (%p-ldb-offset %%q-pointer f si:%fefhi-misc)) (args-info (args-info f))) (incf (aref total-min-args (ldb %%arg-desc-min-args args-info)) ncalls) (incf (aref total-max-args (ldb %%arg-desc-max-args args-info)) ncalls) (incf (aref total-locals (ldb si:%%FEFHI-MS-LOCAL-BLOCK-LENGTH misc)) ncalls)))) ) (defun print-average-number-of-locals () (format t "~&~20tMIN~35tMAX~50tLOCALS") (dotimes (i (array-length total-min-args)) (when (or (not (zerop (aref total-min-args i))) (not (zerop (aref total-max-args i))) (not (zerop (aref total-locals i)))) (format t "~&~5d: " i)) (when (not (zerop (aref total-min-args i))) (format t "~20t~8d" (aref total-min-args i))) (when (not (zerop (aref total-max-args i))) (format t "~35t~8d" (aref total-max-args i))) (when (not (zerop (aref total-locals i))) (format t "~50t~8d" (aref total-locals i)))))