profile-instr.scm 2.7 KB

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