profiling generic functions

Bug #309086 reported by Nikodemus Siivola on 2008-12-17
Affects Status Importance Assigned to Milestone

Bug Description

(from tonyms on #lisp IRC 2003-02-25)

In sbcl-, typing
    (defclass foo () ((bar :accessor foo-bar)))
    (profile foo-bar)
    (unintern 'foo-bar)
    (defclass foo () ((bar :accessor foo-bar)))
gives the error message
    "#:FOO-BAR already names an ordinary function or a macro."

Problem: when a generic function is profiled, it appears as an ordinary
function to PCL. (Remembering the uninterned accessor is OK, as the
redefinition must be able to remove old accessors from their generic

Update: in 1.0.23 the above problem does not occur, but if the UNINTERN
call is left out, we get the error message
  FOO-BAR already names an ordinary function or a macro.

description: updated
Changed in sbcl:
importance: Undecided → Medium
status: New → Confirmed
David Vázquez (davazp) wrote :

This does not occur for TRACE. So, I have a trivial patch for this bug which uses fdefinition encapsulation, I think.

David Vázquez (davazp) wrote :

Forget above! I am ashamed, I did not test it! It misses the hook functions, so it is not so trivial. Let me give a try.

Changed in sbcl:
assignee: nobody → David Vázquez (davazp)
David Vázquez (davazp) wrote :

Well, a patch as the following works, but I guess it results in an unacceptable performance penalty.
I think encapsulation is the right place to do this, however. Therefore I think we could improve the
encapsulate machinery. What do you think?

diff --git a/src/code/profile.lisp b/src/code/profile.lisp
index c4d2750..b4c6ad0 100644
--- a/src/code/profile.lisp
+++ b/src/code/profile.lisp
@@ -257,6 +257,11 @@
                         (funcall function setf-name)))))))))

+;;; This function is called by the profile encapsulation.
+(defun profile-call (func)
+ (declare (special basic-definition arg-list))
+ (apply func arg-list))
 ;;; Profile the named function, which should exist and not be profiled
 ;;; already.
 (defun profile-1-unprofiled-fun (name)
@@ -264,8 +269,7 @@
     (multiple-value-bind (encapsulation-fun read-stats-fun clear-stats-fun)
         (profile-encapsulation-lambdas encapsulated-fun)
- (setf (fdefinition name)
- encapsulation-fun))
+ (encapsulate name 'profile `(profile-call ,encapsulation-fun)))
       (setf (gethash name *profiled-fun-name->info*)
             (make-profile-info :name name
                                :encapsulated-fun encapsulated-fun
@@ -292,7 +296,7 @@
            (remhash name *profiled-fun-name->info*)
            (if (eq (fdefinition name) (profile-info-encapsulation-fun pinfo))
- (setf (fdefinition name) (profile-info-encapsulated-fun pinfo)))
+ (unencapsulate name 'profile))
                (warn "preserving current definition of redefined function ~S"

David Vázquez (davazp) on 2013-04-10
Changed in sbcl:
assignee: David Vázquez (davazp) → nobody
Stas Boukarev (stassats) wrote :

In 1d97281c2848293be067267f21065b451d9e070c

Changed in sbcl:
status: Confirmed → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers