profile-instr.scm 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; This optimizer does the instrumentation for the exact call profiler,
  3. ; by calling the profiler before executing the real function code.
  4. ; It therefore needs a reference to the profile-count procedure,
  5. ; which is exported by the profiler structure.
  6. (set-optimizer! 'profiler-instrumentation
  7. (lambda (forms package)
  8. (get-pcount-name!)
  9. (map (lambda (form)
  10. (instrument-form (force-node form)))
  11. forms)))
  12. ;;; returns a bound name-node for "name" out of "env"
  13. (define (expand-name name env)
  14. (let ((binding (generic-lookup env name)))
  15. (if (node? binding)
  16. binding
  17. (let ((node (make-node operator/name name)))
  18. (node-set! node 'binding (or binding 'unbound))
  19. node))))
  20. ;;; caches the reference to the profile-count function
  21. (define *pcount-name* #f)
  22. (define (get-pcount-name!)
  23. (let* ((p (environment-ref (config-package) 'profiler))
  24. (name (expand-name 'profile-count p)))
  25. (set! *pcount-name* name)))
  26. (define (instrument-form node)
  27. (let ((out (current-noise-port))
  28. (form (node-form node)))
  29. (if (define-node? node)
  30. (begin
  31. (make-similar-node node
  32. `(define ,(cadr form)
  33. ,(instrument-node (caddr form)))))
  34. node)))
  35. (define (instrument-node node)
  36. (cond
  37. ((node? node)
  38. ((operator-table-ref instrumentors (node-operator-id node)) node))
  39. ((list? node)
  40. (instrument-list node))
  41. (else
  42. node)))
  43. (define (instrument-list nodes)
  44. (if (list? nodes)
  45. (map (lambda (node)
  46. (instrument-node node))
  47. nodes)
  48. nodes))
  49. (define (no-instrumentation node)
  50. (let ((form (node-form node)))
  51. (make-similar-node node (instrument-list form))))
  52. (define instrumentors
  53. (make-operator-table no-instrumentation))
  54. (define (define-instrumentor name proc)
  55. (operator-define! instrumentors name #f proc))
  56. (define-instrumentor 'literal no-instrumentation)
  57. (define-instrumentor 'quote no-instrumentation)
  58. (define-instrumentor 'primitive-procedure no-instrumentation)
  59. (define-instrumentor 'call no-instrumentation)
  60. (define-instrumentor 'name no-instrumentation)
  61. (define-instrumentor 'set! no-instrumentation)
  62. (define-instrumentor 'loophole no-instrumentation)
  63. (define-instrumentor 'letrec no-instrumentation)
  64. (define-instrumentor 'pure-letrec no-instrumentation)
  65. (define-instrumentor 'lambda
  66. (lambda (node)
  67. (let* ((form (node-form node))
  68. (param (cadr form))
  69. (body (cddr form)))
  70. (make-similar-node node
  71. `(lambda ,param
  72. ,(make-node operator/begin
  73. `(begin
  74. ,(make-node operator/call
  75. (list *pcount-name*))
  76. ,@(instrument-list body))))))))