runtime compiled method optimizations

nicolas cellier ncellier at ifrance.com
Fri Oct 19 19:17:42 UTC 2007


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