123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
- ; This was a fun hack, but I didn't get much useful information out of
- ; it -- a profiler that only samples at points allowed by the VM's
- ; interrupt mechanism doesn't tell you what you want to know. The
- ; only information available at that point is the continuation; what
- ; we really want to know is where the PC has been. In particular, the
- ; only procedures that show up in the table at all are those that call
- ; other procedures. JAR 12/92
- '
- (define-structure profiler (export profile)
- (open scheme-level-2 handle vm-exception ;interrupts
- architecture continuation simple-signals condition template
- table structure-refs debug-data sort
- clock) ;schedule-interrupt
- (files (misc profile)))
- (define (profile thunk frequency)
- (let ((table (make-table template-uid))
- (dt (round (/ (expt 10 6) frequency))))
- (primitive-catch
- (lambda (k0)
- (let ((foo (continuation-template k0)))
- (with-handler
- (lambda (c punt)
- (if (and (interrupt-condition? c)
- (eqv? (interrupt-source c) interrupt/alarm))
- (primitive-catch
- (lambda (k)
- (record-profile-information! k foo table)
- (schedule-interrupt dt)))
- (punt)))
- (lambda ()
- (dynamic-wind (lambda () (schedule-interrupt dt -6))
- thunk
- (lambda () (schedule-interrupt 0 1))))))))
- table))
- (define (record-profile-information! k k0-template table)
- (let ((k1 (continuation-cont (continuation-cont k))))
- (let ((z (get-counts table k1)))
- (set-car! z (+ (car z) 1))
- (set-cdr! z (+ (cdr z) 1)))
- (do ((k (continuation-cont k1) (continuation-cont k)))
- ((or (not (continuation? k))
- (eq? (continuation-template k) k0-template)))
- (let ((z (get-counts table k)))
- (set-cdr! z (+ (cdr z) 1))))))
- (define (get-counts table k)
- (let ((info (template-info (continuation-template k))))
- (or (table-ref table info)
- (let ((z (cons 0 0)))
- (table-set! table info z)
- z))))
- (define (template-uid info)
- (cond ((integer? info)
- info)
- ((debug-data? info)
- (debug-data-uid info))
- (else 0))) ;??
- (define interrupt-type cadr)
- (define interrupt/alarm (enum interrupt alarm))
- (define (dump t)
- (let ((l '()))
- (table-walk (lambda (key count)
- (let ((dd (if (integer? key)
- (table-ref debug-data-table key)
- key)))
- (set! l (cons (cons count
- (if (debug-data? dd)
- (debug-data-names dd)
- `(? ,key)))
- l))))
- t)
- (do ((l (sort-list l more-interesting?)
- (cdr l))
- (i 0 (+ i 1)))
- ((or (null? l) (> i *prefix*)))
- (let* ((counts+names (car l))
- (leaf-count (caar counts+names))
- (total-count (cdar counts+names))
- (names (cdr counts+names)))
- (display (pad-left total-count 6)) (display #\space)
- (display (pad-left leaf-count 6)) (display #\space)
- (write names)
- (newline)))))
- (define (more-interesting? x y)
- (let ((c1 (cdar x))
- (c2 (cdar y)))
- (or (> c1 c2)
- (and (= c1 c2)
- (> (caar x) (caar y))))))
- (define *prefix* 60)
- (define (pad-left s n)
- (let ((s (cond ((number? s) (number->string s))
- ((symbol? s) (symbol->string s))
- (else s))))
- (string-append (make-string (- n (string-length s)) #\space)
- s)))
|