Gathering statistics on messages sent to an object

If you subscribe to pharo-dev you will have seen that I’ve been looking
at the primitives used in DiskStore.

As part of that investigation I wanted to get an idea of which messages
are typically sent to DiskStore and how often.

Denis Kudriashov provided a neat package that implements a “halt on
next object call”.  I’ve been wanting to play with the package for a
while and decided this was a good opportunity.

I’ve extended that package to keep count of how many times messages are
sent to a target object, e.g.:

| point trace |

point := 2@3.
trace := ExternalSendStats logStatsFor: point.
trace stats.
“a Dictionary(
#y->1 )”

The package is probably too simplistic, and there’s bound to be other
ways to do this, but it met my immediate needs and gave me a chance to
try out the Ghost package.  I’ll extend it if and when I need to.

Many thanks to Denis for making the Ghost package available, and
hopefully this is useful for someone, or at least triggers some new

Denis’ original article is at:

The extensions can be installed with:

Metacello new
baseline: ‘AkgGhost’;
repository: ‘github://akgrant43/akg-ghost:master/mc’;



Hi Alistair.

Do you know that you are able to count any message send? (not only external).
For this you need prevent meta recursion. Now inside message processing you do:
aMessage sendTo: anObject

which produces another intercepting message #perform:withArguments which repeats original message send.

Fortunately Ghost handles such kind of meta recursion and there is no infinite loop here: any self-sends are ignored in such cases.
If you want intercept any message try following code:
ExternalSendTrace>>send: aMessage to: anObject
| method |
announcer announce: (ExternalSendAnnouncement message: aMessage trace: self).
method := anObject class lookupSelector: aMessage selector.
^GHMetaMessages executeWith: anObject andArguments: aMessage arguments method: method
In that case we lookup and execute method by using mirror primitive which not sends any message to object.
For example:
rect := 10@30 corner: 100@300.
trace := ExternalSendStats logStatsFor: rect.
rect area.
trace stats.
 “a Dictionary(#area->1 #height->1 #width->1 )”
Best regards,

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: