Tracing special messages [WAS] Re: [Vm-dev] Re: normalSend, specialObjectsArray and VM

Mariano Martinez Peck marianopeck at gmail.com
Tue Oct 5 19:13:46 UTC 2010


On Tue, Oct 5, 2010 at 9:04 PM, Eliot Miranda <eliot.miranda at gmail.com>wrote:

>
>
>
> On Tue, Oct 5, 2010 at 12:00 PM, Mariano Martinez Peck <
> marianopeck at gmail.com> wrote:
>
>>
>>
>>
>> On Tue, Oct 5, 2010 at 8:48 PM, Eliot Miranda <eliot.miranda at gmail.com>wrote:
>>
>>>
>>>
>>>
>>> On Tue, Oct 5, 2010 at 11:20 AM, Mariano Martinez Peck <
>>> marianopeck at gmail.com> wrote:
>>>
>>>>
>>>>
>>>>
>>>> On Tue, Oct 5, 2010 at 7:50 PM, Eliot Miranda <eliot.miranda at gmail.com>wrote:
>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Tue, Oct 5, 2010 at 9:23 AM, Mariano Martinez Peck <
>>>>> marianopeck at gmail.com> wrote:
>>>>>
>>>>>>
>>>>>> Hi. So....if I want to intercept ALL message sends....going to
>>>>>> #normalSend is not enough since I have #class, #==, Float>>#+   etc that are
>>>>>> executed directly like bytecodes. So...my questions are now:
>>>>>>
>>>>>> 1) Those special selectors are those that are in "Smalltalk
>>>>>> specialSelectors" ?  are there more?  all from there are special?
>>>>>>
>>>>>> 2) All those "Smalltalk specialSelectors"  have their associated
>>>>>> bytecode primitive in Interpreter??  If true, then I should modify all
>>>>>> bytecodePrim*  in Interpreter. I am right?   If I do that, that's all ? I am
>>>>>> intercepting everything?
>>>>>>
>>>>>
>>>>> Right.  Just modify all of them to eliminate the optimized code and to
>>>>> revert to normalSend.
>>>>>
>>>>
>>>> Thanks Eliot. I didn't understand. What is the optimized code?   I
>>>> checked all bytecodePrim* and the ones that DO NOT send "self normalSend" at
>>>> the end, are very few. The problem is that some return before returning
>>>> "self normalSend". So...I should modify all those who DO NOT call "self
>>>> normalSend" at the end and those which return before.
>>>>
>>>
>>> Change them all so they do a normalSend and nothing else, e.g.
>>>
>>> bytecodePrimAdd
>>> messageSelector := self specialSelector: 0.
>>>  argumentCount := 1.
>>> self normalSend
>>>
>>>
>> Ok, but suppose I DON'T want to slow down the system.... what if I change
>> to this for example
>>
>> bytecodePrimAdd
>>     | rcvr arg result |
>>     rcvr := self internalStackValue: 1.
>>     arg := self internalStackValue: 0.
>>     (self areIntegers: rcvr and: arg)
>>         ifTrue: [result := (self integerValueOf: rcvr) + (self
>> integerValueOf: arg).
>>                 (self isIntegerValue: result) ifTrue:
>>                     [self internalPop: 2 thenPush: (self integerObjectOf:
>> result).
>>                     self markObjectUsage: rcvr.
>>                     ^ self fetchNextBytecode "success"]]
>>         ifFalse: [successFlag := true.
>>                 self externalizeIPandSP.
>>                 self primitiveFloatAdd: rcvr toArg: arg.
>>                 self internalizeIPandSP.
>>                 successFlag ifTrue: [self markObjectUsage: rcvr. ^ self
>> fetchNextBytecode "success"]].
>>
>>     messageSelector := self specialSelector: 0.
>>     argumentCount := 1.
>>     self normalSend
>>
>> Ok...I have to manually check each method, but I don't have problem.
>>
>> Should that work and be almost as fast as normally?
>>
>
> But it doesn't mark the method right?
>


hehe you guessed my following question (it was going to be in another
thread, but since you ask).
Yes, (maybe) I would like to mark, for EACH normal message sent:
1) the obejct that receives the message
2) its class
3) the method dictionary
4) the compiled method.

If I first think about normal messages, then:

- 1) and 2) can be done in #normalSend:

normalSend
    "Send a message, starting lookup with the receiver's class."
    "Assume: messageSelector and argumentCount have been set, and that
    the receiver and arguments have been pushed onto the stack,"
    "Note: This method is inlined into the interpreter dispatch loop."
    | rcvr |
    self inline: true.
    self sharedCodeNamed: 'normalSend' inCase: 131.
    rcvr := self internalStackValue: argumentCount.
    self traceObjectUsage: rcvr.
    lkupClass := self fetchClassOf: rcvr.
    receiverClass := lkupClass.
self traceObjectUsage: receiverClass.
    self commonSend.




3) I have no idea.

4) I am not sure. I wanted to ask you :)  Maybe  #internalActivateNewMethod
is a good place?   Maybe adding a "self markObjectUsage: newMethod"   ?



 It only marks the objects.  However if you analyse the bytecodePrimFoo
> implementations you should be able to work out which methods are used,
> SmallInteger>>#+, Float>>#+ et al.
>
>
I didn't understand this last sentence.

Thanks Eliot!!




>
>
>>  Or change the part of the bytecode table that specifies the special
>>> selector primitives to read
>>>  (176 207 sendSpecialSelectorBytecode)
>>>
>>> sendSpecialSelectorBytecode
>>> | selectorIndex specialSelectors |
>>>  selectorIndex := (currentBytecode - 176) * 2.
>>> specialSelectors := self splObj: SpecialSelectors.
>>>  messageSelector := self fetchPointer: selectorIndex
>>> ofObject: specialSelectors.
>>>  argumentCount := self fetchInteger: selectorIndex + 1
>>> ofObject: specialSelectors.
>>>  self normalSend
>>>
>>> But most of all try and slow down and understand what is going on; then
>>> you will be able to answer your own questions.  Reading the blue book<http://www.mirandabanda.org/bluebook/bluebook_imp_toc.html>will help.
>>>
>>>
>>
>> hehehehehe what an idea :) I didn't know I could do that. Thanks for the
>> blue book. I read the vm chapters but several months ago. I should read it
>> again since the first time I didn't understand very much hehehehe.
>>
>>
>>>
>>>>
>>>>
>>>>> Providing you also look at the perform and method evaluation primitives
>>>>> I think you'll get all sends.
>>>>>
>>>>>
>>>> #primitivePerform*   and #primitiveExecuteMethod*    ???
>>>>
>>>>
>>>>> There is another way.  Modify the Smalltalk compiler to to use the
>>>>> special selector sends.
>>>>>
>>>>>
>>>> Thanks Eliot for the idea. Can you explain me a little more (sorry,
>>>> newbie here!). You mean that with the Compiler I can do that all method
>>>> sends use the normal send instead of special bytecodes or primitives?
>>>>
>>>
>>> Yes.  If you modify the compiler not to use the StdSelectors then the
>>> compiler will emit normal sends for all the special selectors.   Again I
>>> think if you slowed down and started playing ore you would discover this for
>>> yourself and in the end be more productive.  I know its hard and frustrating
>>> initially.  But my own competence comes directly from having played around
>>> in this way.
>>>
>>>
>> Thanks Eliot. I will consider this alternative also.
>>
>> Best regards.
>>
>> Mariano
>>
>>
>>> best,
>>> Eliot
>>>
>>>
>>>> Thank you very much.
>>>>
>>>> Mariano
>>>>
>>>>
>>>>>
>>>>>> Thanks a lot in advance,
>>>>>>
>>>>>> Mariano
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sun, Oct 3, 2010 at 11:09 PM, Craig Latta <craig at netjam.org>wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> > Craig Latta has done all this work, talk to him.
>>>>>>>
>>>>>>>     Sure, I'd be happy to discuss it.
>>>>>>>
>>>>>>>
>>>>>>> -C
>>>>>>>
>>>>>>> --
>>>>>>> Craig Latta
>>>>>>> www.netjam.org
>>>>>>> + 31 020 894 6247
>>>>>>> +  1 415 287 3547
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20101005/e54ef578/attachment-0001.htm


More information about the Vm-dev mailing list