Hello,

specific messages (control flow oriented messages) are inlined and you
cannot override them (same problem in the old and the new compiler). In
Opal we introduced some kind of settings to force the compiler not to
inline messages when it is not needed. This can be done at method level
with a pragma for example:

MyClass>>#foo
<compilerOptions: #(- optInlineIf)>
^ #myNonBooleanObject ifTrue: [ 1 ] ifFalse: [ 0 ]

Or at class level, however at class level there are issue with monticello
(therefore you would need to recompile your code after loading it).

InstructionStream class>>#compiler
^ super compiler options: #(+ optLongIvarAccessBytecodes)

See the list of options here: OpalCompiler class>>#defaultOptions


You cannot in the current Pharo/Squeak disable the inlining of all the
control flow messages or it crashes the image. It crashes for example due
to the whileTrue: implementation (no stop condition without inlining) or
the allObjectsDo: one (then you create a context per iteration).

Usually, the compiler is not too aggressive when inlining loops
(whileTrue:, to:do:, ...) so you should be able to override it in most
cases, however it is very aggressive for condition (ifTrue:ifFalse:,
ifNil:ifNotNil:, ...), so you cannot override those methods, except if you
manually add compiler options as explained before. Making the compiler less
aggressive for conditions drastically decrease Pharo overall performance.

In addition, the compilers inline specific messages defined here:
IRBytecodeGenerator
class>>specialSelectorsArray.
In Squeak they inline in addition of these messages the message #class. We
decided not to do it in Pharo because it does not decrease performance nor
increase the memory size by a noticeable value.

There is no setting currently for these specific selectors. So you have to
run the code specified by Carlo:

In Opal to remove the usage of #==, I removed it from the special selector
array in the method:
IRBytecodeGenerator class>>specialSelectorsArray
 ^ #(#+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1
#bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0
#nextPut: 1 #atEnd 0 #== 1 nil 0 #blockCopy: 1 #value 0 #value: 1 #do: 1
#new 0 #new: 1 #x 0 #y 0)

Then I ran:
IRBytecodeGenerator initialize.
OpalCompiler recompileAll.

That's all the ideas I had Sean :-)



2014/1/23 Otto Behrens <o...@finworks.biz>

> >     MyNullClass>>#ifNil: nilBlock ifNotNil: notNilBlock
> >         nilBlock value.
> >
> > Any ideas?
>
> I've got a slightly different understanding of the null object
> pattern, perhaps. I would use it this way:
>
> MyClass is an abstract class that defines an interface that users
> would expect, with a subclass MyNullClass and MyConcreteClass.
>
> Where ever I send messages to the "MyClass", it could either be an
> instance of MyNullClass or MyConcreteClass. MyNullClass would
> implement the protocol of MyClass, but would behave differently. This
> is so that the users /senders of MyClass do not have to do if's to
> determine if it's talking to a null object or not.
>
> And this is where I wonder if I will try to implement the ifNil
> behviour on MyNullClass at all, because the senders have to know about
> the kind of thing it is talking to.
>
> But perhaps this is a different context.
>
> Otto
>
>

Reply via email to