On Mar 25, 2010, at 5:50 PM, Mariano Martinez Peck wrote:

> Hi folks. I want to intercept (and do something) for all objects. I know few 
> approaches, for example:
> 
> 1) using method wrappers (implementing  run: aSelector with: arguments in: 
> aReceiver) I can wrap all compiled methods of all classes  and there I have 
> the receiver.
> 
> 2) become all objects to some kind of hacky object that stores the original 
> object and that redefines the doesNotUnderstand: 
> 
> But in 1) I need to change all CompiledMehtod of all classes. 
> in 2) I have to become all the objects to another object
> 
> Then my question is, is there an easier way to intercept all messages send to 
> all objects from the image side (not going to vm) and with a lower cost ?

No.

So the MOP (meta object protocol), the "reflective API" of Smalltalk does not 
allow for "reifying" message receive. 

Historically, after Reflection was discovered and people started to generalize 
it, of cource they added that. For example, there is CODA:

        
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.108.6885&rep=rep1&type=pdf

which made the whole "message send" explicit and interceptable.

This means it is decomposed into Send, Receive, Lookup, Apply. Very nice. Very 
general. One can override Lookup when one wants to do 
e.g. Multiple inheritance. Or Apply, when the language of the method is not 
smalltalk. Or Receive, if you want to hook into "does an object get
a message?". Futures, non-blocking messages. All easy to be done.

But: it's slow. Dog slow. So people started to think about: how to speed up? 
Sadly the idea of optimizing at runtime (partially evaluating the MOP)
has seen not much work. What was done is "partial reflection": only reifiy 
those opereation at exactly those spots that one is interested in.
This was done in MetaClassTalk (it checks if the MetaClass overrides message 
sending, else it uses normal bytecodes) and to the extreme in Reflex.

Now if you want to change reflective behavior *per object* the other important 
thing is that you need to be able to define changed behavior at
the level of Objects vs. Classes. CLOS style MOPS like MetaClassTalk allow 
*only* for a per-Class-change. 

Enter Eric Tanter's Relex. Reflex generalized the MOP idea to not be bound to 
classes/metaclasses but you can select *per instruction* what to reify.
And that reification is only done when needed, keeping the code you are not 
interested in fast.
(Reflex is what happens when you bring the lessons of AOP back into MOPs. That 
is, the good parts of AOP).

                http://portal.acm.org/citation.cfm?id=949309

Of course, message receive is not easy to achive other than reifying 
method-execute on all methods+doesNotUnderstand. 
This can be made a bit more efficient for all the objects of the class you are 
not interested in by using Object-specific Behavior
(the anonymous subclass trick). Phillippe did that in TreeNurse...
But all in all, this is more of a hack.

Now for message receive, one could imagine a partial reification scheme: a tag 
bit on the object header, if it is there, the VM calls a receive
method instead of the method that would originally be called. So you would pay, 
in all casses, one bit-check on message send *and* you need
space to put this flag. Would anyone want to pay that?

In general, I would like to experiment with a MOP that can reify message 
receive in a meaningful *and efficient* way. But the current VM can't do it.
In addition, there is always the problem that reflection leads to loops (your 
code will use the code it will used on).

        http://scg.unibe.ch/archive/papers/Denk08bMetaContextLNBIP.pdf

Wich needs to be solved, too, if you ever want to be able to use reflection on 
everything (even the things you implement reflectively).

Alternatively, one could use a proxy. Now if you don't use a subclass of 
ProtoObject, but something with VM support int the Style of Adrian Lienhard's
Aliases:

                
http://scg.unibe.ch/archive/papers/Lien08bBackInTimeDebugging.pdf

or the Handle (we need a better word!!!) stuff that JB is working on, maybe 
this would not be too bad. The Alias is *hidden*, you can put it (eventually,
after all engineering done) on any object (even Integers)... and than, after 
you swap out something, you need a proxy anyway for the "outpointer". 

> And if going to vm, how ?

The OOPSLA paper of 2008 on tolerating memory leaks has scheme where they use 
the GC of Jikes. So compared to LOOM, they have a modern
GC without an object table, and it seems much simpler.

        Marcus

--
Marcus Denker  -- http://www.marcusdenker.de
INRIA Lille -- Nord Europe. Team RMoD.


_______________________________________________
Pharo-project mailing list
Pharo-project@lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to