Lisp HUG Maillist Archive

Disassembling a method

Is there an easy way that I'm missing to disassemble a specific
method?  I can go from the generic function to the specific method and
its associated functional object via the MOP and/or the inspector and
disassemble it (see below), but I'm looking for a direct invocation.
"Disassemble Definition" in the IDE seem to work only for plain
functions and I wouldn't know what to hand over to the CL:DISASSEMBLE
function to do this in one step.  Any ideas?

Thanks,
Edi.


  CL-USER 1 > (defmethod foo ((a integer))
                (1+ a))
  #<STANDARD-METHOD FOO NIL (INTEGER) 221AFAC7>

  CL-USER 2 > (disassemble (method-function (first (generic-function-methods #'foo))))
  221713EA:
         0:      55               push  ebp
         1:      89E5             move  ebp, esp
         3:      A803             testb al, 3
         5:      750C             jne   L1
         7:      89C7             move  edi, eax
         9:      83C704           add   edi, 4
        12:      7005             jo    L1
        14:      FD               std   
        15:      89F8             move  eax, edi
        17:      C9               leave 
        18:      C3               ret   
  L1:   19:      C9               leave 
        20:      E977ECF9FD       jmp   2011007A         ; #<Function SYSTEM::*%1+$ANY-STUB 2011007A>
        25:      90               nop   
  NIL


Re: Disassembling a method

On Sun, May 18, 2008 at 01:18:56PM +0200, Edi Weitz wrote:
> Is there an easy way that I'm missing to disassemble a specific
> method?  I can go from the generic function to the specific method
> and its associated functional object via the MOP and/or the
> inspector and disassemble it (see below), but I'm looking for a
> direct invocation.  "Disassemble Definition" in the IDE seem to work
> only for plain functions and I wouldn't know what to hand over to
> the CL:DISASSEMBLE function to do this in one step.  Any ideas?
> 
[snip]
> 
>   CL-USER 1 > (defmethod foo ((a integer))
>                 (1+ a))
>   #<STANDARD-METHOD FOO NIL (INTEGER) 221AFAC7>
> 
>   CL-USER 2 > (disassemble (method-function (first (generic-function-methods #'foo))))
[output snipped]

Frankly I'm not sure what you're looking for but I'll take my best
shot.  :)

Poking at the listener and the inspector came up with this:

  CL-USER 35 > (defmethod foo ((a integer)) (1+ a))
  #<STANDARD-METHOD FOO NIL (INTEGER) 22535AF3>

  CL-USER 36 > (disassemble (slot-value * 'function))
  225464C2:
	 0:      55               push  ebp
  [ ... etc ... ]

Or maybe you want this?

  (disassemble 
    (slot-value (find-method #'foo '() (list (find-class 'integer)))
		'function))

Or something else?  IOW what's your ideal call sequence to get what
you want?

(This use of slot-value may be LW-specific, but the find-method came
right out of the CLHS.)

-- L


Re: Disassembling a method

On Sun, 18 May 2008 08:26:31 -0400, Larry Clapp <larry@theclapp.org> wrote:

> Frankly I'm not sure what you're looking for

A /convenient/ way to see the disassembly of the method.  If you've
identified a specific function FOO as a bottleneck and you want to
optimize it, then it sometimes makes sense to look at its disassembly.
The usual cycle for me might be to change the function's definition in
the source file, then "Compile Defun", then to disassemble it either
with "Disassemble Definition" or with typing

  (disassemble 'foo)

into the listener (and maybe repeat this with M-p after
recompilation).  With methods, the first variant ("Disassemble
Definition") doesn't work.  For the second variant, I'm looking for
something I can type into the REPL which is short and unambiguous.

> CL-USER 36 > (disassemble (slot-value * 'function))

This'll only help if you define your methods in the listener which I
usually don't do.

>   (disassemble 
>     (slot-value (find-method #'foo '() (list (find-class 'integer)))
> 		'function))

That's more like it albeit a bit bulky.  I had hoped that I could
maybe use the DSPEC stuff to identify the specific method.

> (This use of slot-value may be LW-specific, but the find-method came
> right out of the CLHS.)

Yeah, I'm aware that any such solution will be LW-specific.  That's
fine.

Thanks,
Edi.


Re: Disassembling a method

On Sun, 18 May 2008 11:09:09 -0400, Larry Clapp <larry@theclapp.org> wrote:

> How about
>
>   (defadvice (disassemble do-methods :around) (function)
>     (if (consp function)
>       (call-next-advice (slot-value
> 			 (find-method (symbol-function (car function))
> 				      '()
> 				      (mapcar #'find-class (cdr function)))
> 			 'function))
>       (call-next-advice function)))
>
>   CL-USER 98 > (disassemble '(foo integer))
>   200A8D62:
> 	 0:      55               push  ebp
>   [ ... etc ... ]
>
> This even works with "Disassemble Definition" -- tell it "(foo
> integer)" instead of just "foo".

That's very helpful, thanks!

Edi.


Re: Disassembling a method

On Mon, 19 May 2008 09:53:48 +0200, "John Thingstad" <jpthing@online.no> wrote:

> As a side note: fdefinition is a generalization of symbol-function
> that is made to work with method setf expanders. (Use as a
> replacement for symbol-function)

Would something change for the better if one replaced symbol-function
with fdefinition in Larry's code?


Updated at: 2020-12-10 08:43 UTC