[squeak-dev] Incomplete deoptimization of #ifNotNil: and #ifNotNil:ifNil:

Levente Uzonyi leves at elte.hu
Tue Feb 3 20:20:12 UTC 2015


Hi All,

There's a bug in the compiler which should be easy to fix for someone 
familiar with the code.
The following expression returns #(nil nil true true) instead of #(nil 
nil nil nil):

{
nil
 	ifNil: [ 1 ] ifNotNil: [ 2 ];
 	yourself.
nil
 	ifNil: [ 1 ];
 	yourself.
nil
 	ifNotNil: [ 2 ];
 	yourself.
nil
 	ifNotNil: [ 2 ] ifNil: [ 1 ];
 	yourself.
}

The cause of the problem is that in case of #ifNotNil: and 
#ifNotNil:ifNil: the deoptimization doesn't clear all previously 
generated optimized bytecodes.
E.g. in case of #ifNotNil: instead of

<73> pushConstant: nil
<88> dup
<8F 00 00 02> closureNumCopied: 0 numArgs: 0 bytes 33 to 34
     <76> pushConstant: 1
     <7D> blockReturn
<E0> send: ifNotNil:
<87> pop
<D1> send: yourself

we get

<73> pushConstant: nil
<73> pushConstant: nil
<C6> send: ==
<88> dup
<8F 00 00 02> closureNumCopied: 0 numArgs: 0 bytes 33 to 34
     <76> pushConstant: 1
     <7D> blockReturn
<E0> send: ifNotNil:
<87> pop
<D1> send: yourself

It would be great to write some tests which cover all such cases 
(including other methods), but I'm not sure what form is the best for 
this. Simple tests which just verify some values? Or something that 
checks the generated bytecodes?

Levente


More information about the Squeak-dev mailing list