runtime compiled method optimizations

Mathieu Suen mathk.sue at gmail.com
Fri Oct 19 23:02:56 UTC 2007


But you can do somethings like:


exp isLocalReference ifTrue:[exp perform: #ifTrue:ifFalse: with: ...  
with: ....] ifFalse: [...]


	Mth



On Oct 19, 2007, at 9:32 PM, Rob Withers wrote:

> That's it, the backward jumps use jumpFalse: and jumpTrue:.  It  
> rings a bell.
>
> I am trying to transform these jumps to equivalent msg sends, only  
> when the receiver is not the expected type.  This way, the normal  
> fast transform works most of the time and when it is the wrong  
> receiver we get a msg send in the image that I can intercept.  The  
> best of both worlds.  Unfortunately it more than doubles the  
> bytecodes for these composite constructs, so I'd love to figure out  
> the most compact forms.
>
> Perhaps the way to go is to define bytecodes for all combinations like
>    jumpFalseForIfTrue:
>    jumpFalseForIfFalse:
>    jumpFalseForIfTrueIfFalse:
>    jumpFalseForWhileFalse:
>    jumpTrueForWhileTrue:
>    jumpFalseForToDo:
> and so on.  Then I would need to figure out how to capture the blocks.
>
> Rob
>
> ----- Original Message ----- From: "nicolas cellier"  
> <ncellier at ifrance.com>
> To: <squeak-dev at lists.squeakfoundation.org>
> Sent: Friday, October 19, 2007 12:17 PM
> Subject: Re: runtime compiled method optimizations
>
>
>> You will also have backward jumps generated by loops (to:do:  
>> whileTrue: whileFalse:)...
>>
>> Though you might be able to transform all these jumps in  
>> equivalent message send (See Decompiler), that's might be  
>> impracticle to do that at interpreter level.
>>
>>
>> Rob Withers a écrit :
>>>
>>> ----- Original Message ----- From: "Igor Stasenko"  
>>> <siguctua at gmail.com>
>>> To: "The general-purpose Squeak developers list" <squeak- 
>>> dev at lists.squeakfoundation.org>
>>> Sent: Thursday, October 18, 2007 11:58 PM
>>> Subject: Re: runtime compiled method optimizations
>>>
>>>
>>>> On 19/10/2007, Rob Withers <reefedjib at yahoo.com> wrote:
>>>>> Igor, I'm afraid you've lost me.  What would the bytecodes look  
>>>>> like in your
>>>>> proposal?  From what you've said, wouldn't the #jumpFalse need  
>>>>> to know what
>>>>> the literal to send is?  I also don't understand how it would  
>>>>> extract the
>>>>> block contents.
>>>>
>>>> You don't need to change bytecode. Just by analysing that jump
>>>> bytecode jumps over a block. Then you can assume that bytes between
>>>> jump bytecode and byte where it points to is the block body.
>>>> So, you can do the trick by changing implementation of #jumpFalse.
>>>> By sending #IfTrue: message to receiver and checking the result.
>>>
>>> I'm still not getting it.  I am all about getting this  
>>> functionality in the most compact form.  Are you saying that I  
>>> should stick to the following bytecodes?
>>>
>>> 17 <10> pushTemp: 0
>>> 18 <9B> jumpFalse: 23
>>> 19 <10> pushTemp: 0
>>> 20 <20> pushConstant: 4
>>> 21 <B0> send: +
>>> 22 <7C> returnTop
>>> 23 <78> returnSelf
>>>
>>> Then if I am reading you right, the block is defined as
>>>    PC start of block := the PC of the jumpFalse: + 1
>>>    PC end of block := the PC of the arg to the jumpBlock - 1
>>> but I don't see where you setup and send the #blockCopy:
>>>
>>> I believe, but I am not sure, the #jumpFalse: is not only used  
>>> for #ifTrue:, ifFalse:. ifTrue:ifFalse: and #ifFalse:ifTrue:,  
>>> plus I want to be able to distinguish between these 4 methods.   
>>> Unless they all get transformed to #ifTrue:ifFalse: with  
>>> appropriate nil blocks...
>>>
>>> Still, I am having a hard time understanding how #jumpFalse:  
>>> suddenly knows to test for boolean (better than the  
>>> testLocalReference), then if it is not boolean, instead of  
>>> sending mustBeBoolean, do a couple of block copies and send  
>>> #ifTrue:ifFalse:.  Can it do all that?  Can we have it scan the  
>>> bytecodes of the current method to make decisions about the  
>>> boundaries of the block copies?  Are we sure it should always  
>>> send #ifTrue:ifFalse:?  You raise some interesting questions.
>>>
>>> Rob
>>>
>>>>
>>>>>
>>>>> thanks,
>>>>> Rob
>>>>>
>>>>>
>>>>> ----- Original Message -----
>>>>> From: "Igor Stasenko" <siguctua at gmail.com>
>>>>> To: "The general-purpose Squeak developers list"
>>>>> <squeak-dev at lists.squeakfoundation.org>
>>>>> Sent: Thursday, October 18, 2007 3:06 PM
>>>>> Subject: Re: runtime compiled method optimizations
>>>>>
>>>>>
>>>>> > No, i think you'd better change the implementation of #jumpFalse
>>>>> > bytecode.
>>>>> > If you see that receiver is non-local , then simply do  
>>>>> message send.
>>>>> > And, i think you can safely use info from jump bytecode to  
>>>>> extract
>>>>> > block contents
>>>>> > (bytes 19 - 22 is the block body).
>>>>> >
>>>>> > On 19/10/2007, Robert Withers <reefedjib at yahoo.com> wrote:
>>>>> >> Hi all,
>>>>> >>
>>>>> >> I have a simple method containing an ifTrue: message.  I have
>>>>> >> compiled it normally, which uses macro transformations:
>>>>> >>
>>>>> >> 17 <10> pushTemp: 0
>>>>> >> 18 <9B> jumpFalse: 23
>>>>> >> 19 <10> pushTemp: 0
>>>>> >> 20 <20> pushConstant: 4
>>>>> >> 21 <B0> send: +
>>>>> >> 22 <7C> returnTop
>>>>> >> 23 <78> returnSelf
>>>>> >>
>>>>> >> and I have compiled it using Klaus Witzel's nifty compiler  
>>>>> changes >> to
>>>>> >> remove macro transformations and the result is an explicit  
>>>>> message
>>>>> >> send of #ifTrue:
>>>>> >>
>>>>> >> 21 <10> pushTemp: 0
>>>>> >> 22 <89> pushThisContext:
>>>>> >> 23 <75> pushConstant: 0
>>>>> >> 24 <C8> send: blockCopy:
>>>>> >> 25 <A4 04> jumpTo: 31
>>>>> >> 27 <10> pushTemp: 0
>>>>> >> 28 <21> pushConstant: 4
>>>>> >> 29 <B0> send: +
>>>>> >> 30 <7C> returnTop
>>>>> >> 31 <E0> send: ifTrue:
>>>>> >> 32 <87> pop
>>>>> >> 33 <78> returnSelf
>>>>> >>
>>>>> >> I would like to check the receiver of the ifTrue:, the 1st  
>>>>> method >> arg
>>>>> >> in this case (Temp: 0), to see if a certain situation exists  
>>>>> (is it >> a
>>>>> >> local reference to an object?).  If it is true, I would like  
>>>>> to run
>>>>> >> the optimal code from the first example, instead of the  
>>>>> longer >> second
>>>>> >> example.   How could we do that?  Something like this?   
>>>>> Could it be
>>>>> >> done entirely by the compiler, given the existence of the  
>>>>> bytecode
>>>>> >> routine for #testLocalReference?
>>>>> >>
>>>>> >> 21 <10> pushTemp: 0
>>>>> >> 22 <??> testLocalReference
>>>>> >> 23 <??> jumpFalse: 30
>>>>> >> 24 <10> pushTemp: 0
>>>>> >> 25 <??> jumpFalse: 40
>>>>> >> 26 <10> pushTemp: 0
>>>>> >> 27 <20> pushConstant: 4
>>>>> >> 28 <B0> send: +
>>>>> >> 29 <7C> returnTop
>>>>> >> 30 <89> pushThisContext:
>>>>> >> 31 <75> pushConstant: 0
>>>>> >> 32 <C8> send: blockCopy:
>>>>> >> 33 <?? ??> jumpTo: 38
>>>>> >> 34 <10> pushTemp: 0
>>>>> >> 35 <21> pushConstant: 4
>>>>> >> 36 <B0> send: +
>>>>> >> 37 <7C> returnTop
>>>>> >> 38 <E0> send: ifTrue:
>>>>> >> 39 <87> pop
>>>>> >> 40 <78> returnSelf
>>>>> >>
>>>>> >>
>>>>> >> Thanks!
>>>>> >> Rob
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >
>>>>> >
>>>>> > --
>>>>> > Best regards,
>>>>> > Igor Stasenko AKA sig.
>>>>> >
>>>>> >
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> -- 
>>>> Best regards,
>>>> Igor Stasenko AKA sig.
>>>>
>>>>
>>>
>>>
>>>
>>
>>
>
>




More information about the Squeak-dev mailing list