[squeak-dev] Boolean over-optimization #ifTrue:/#ifFalse:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Boolean over-optimization #ifTrue:/#ifFalse:

Igor Stasenko
Hello,

i currently tried to implement a proxy (subclass of ProtoObject) with
own IfTrue:/ifFalse: methods.
What i can't understand, is why VM throws me with #mustBeBoolean
message instead of doing real send if optimized pattern fails (when
receiver of #IfTrue: is a non-boolean)?

Is there any way, without modifying compiler, how to force it to do real send?



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Paolo Bonzini-2
Igor Stasenko wrote:
> Hello,
>
> i currently tried to implement a proxy (subclass of ProtoObject) with
> own IfTrue:/ifFalse: methods.
> What i can't understand, is why VM throws me with #mustBeBoolean
> message instead of doing real send if optimized pattern fails (when
> receiver of #IfTrue: is a non-boolean)?

Because you cannot distinguish #ifTrue:#ifFalse: sends from #whileTrue:
for example, and because there are no BlockC{ontext,losure} objects for
the argument blocks.

Paolo

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Igor Stasenko
On 05/03/2008, Paolo Bonzini <[hidden email]> wrote:

> Igor Stasenko wrote:
>  > Hello,
>  >
>  > i currently tried to implement a proxy (subclass of ProtoObject) with
>  > own IfTrue:/ifFalse: methods.
>  > What i can't understand, is why VM throws me with #mustBeBoolean
>  > message instead of doing real send if optimized pattern fails (when
>  > receiver of #IfTrue: is a non-boolean)?
>
>
> Because you cannot distinguish #ifTrue:#ifFalse: sends from #whileTrue:
>  for example, and because there are no BlockC{ontext,losure} objects for
>  the argument blocks.
>

So, the only way is to compile method without optimization of #ifTrue #ifFalse:,
to make sure they do real sends?

If yes, i'd like to see optimizations optional, so people can do like:

Compiler turnOffOptimizations.
MyClass compileAll.
Compiler turnOnOptimizations.

>
>  Paolo
>
>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Lukas Renggli
> So, the only way is to compile method without optimization of #ifTrue #ifFalse:,
>  to make sure they do real sends?

Just today in my blog-reader:

http://www.cincomsmalltalk.com/userblogs/mls/blogView?showComments=true&printTitle=Boolean_Objects&entry=3382109971

This should also work in Squeak.

>  If yes, i'd like to see optimizations optional, so people can do like:
>
>  Compiler turnOffOptimizations.

That will not only kill your performance ...

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Igor Stasenko
On 05/03/2008, Lukas Renggli <[hidden email]> wrote:
> > So, the only way is to compile method without optimization of #ifTrue #ifFalse:,
>  >  to make sure they do real sends?
>
>
> Just today in my blog-reader:
>
>  http://www.cincomsmalltalk.com/userblogs/mls/blogView?showComments=true&printTitle=Boolean_Objects&entry=3382109971

Oh, this one is useful. I can test in #mustBeBoolean if my proxy
simulating true or false and return true or false to continue
evaluation.
Thanks for advice.

>
>  This should also work in Squeak.
>
>
>  >  If yes, i'd like to see optimizations optional, so people can do like:
>  >
>  >  Compiler turnOffOptimizations.
>
>
> That will not only kill your performance ...
>
I run methods with proxies to simulate evaluation of method over
different object memory.
In this case, a correct message sending semantics is much more
important than speed.

>  Lukas
>
>
>  --
>  Lukas Renggli
>  http://www.lukas-renggli.ch
>
>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Joshua Gargus-2
In reply to this post by Igor Stasenko
The #compilerClass method allows you to specify the compiler to be  
used for a class (and its subclasses).  So, one approach would be to  
implement a subclass of Compiler (say, "ProxyCompiler") that disables  
optimization of #ifTrue:ifFalse: etc.

I'm not sure about a clean way to disable optimizations in a subclass  
of Compiler.  Here's a moderately horrible way to disable them  
globally...
        - give Compiler a boolean class variable "DisableSpecialSelectors"
        - hack MethodNode>>noteSpecialSelector: thusly...

noteSpecialSelector: selectorSymbol
        " special > 0 denotes specially treated messages. "

        DisableSpecialSelectors ifTrue: [special := 0. ^self].

        "Deconvert initial keywords from SQ2K"
        special := #(:Test:Yes: :Test:No: :Test:Yes:No: :Test:No:Yes:
                                and: or:
                                :Until:do: :While:do: whileFalse whileTrue
                                :Repeat:to:do: :Repeat:to:by:do:
                                ) indexOf: selectorSymbol.
        special > 0 ifTrue: [^ self].

        special := MacroSelectors indexOf: selectorSymbol.


Then, you could override #translate:noPattern:ifFail: in  
ProxyCompiler, as follows...

translate: aStream noPattern: noPattern ifFail: failBlock
        [ DisableSpecialSelectors := true.
                ^super translate: aStream noPattern: noPattern ifFail: failBlock
        ] ensure: [DisableSpecialSelectors := false].


Finally, implement #compilerClass on the class-side of your Proxy  
class, and answer ProxyCompiler.

Heh, that was sorta fun!
Josh




On Mar 4, 2008, at 10:39 PM, Igor Stasenko wrote:

> On 05/03/2008, Paolo Bonzini <[hidden email]> wrote:
>> Igor Stasenko wrote:
>>> Hello,
>>>
>>> i currently tried to implement a proxy (subclass of ProtoObject)  
>>> with
>>> own IfTrue:/ifFalse: methods.
>>> What i can't understand, is why VM throws me with #mustBeBoolean
>>> message instead of doing real send if optimized pattern fails (when
>>> receiver of #IfTrue: is a non-boolean)?
>>
>>
>> Because you cannot distinguish #ifTrue:#ifFalse: sends from  
>> #whileTrue:
>> for example, and because there are no BlockC{ontext,losure} objects  
>> for
>> the argument blocks.
>>
>
> So, the only way is to compile method without optimization of  
> #ifTrue #ifFalse:,
> to make sure they do real sends?
>
> If yes, i'd like to see optimizations optional, so people can do like:
>
> Compiler turnOffOptimizations.
> MyClass compileAll.
> Compiler turnOnOptimizations.
>
>>
>> Paolo
>>
>>
>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Compiling with macro inliner switch [was: Boolean over-optimization #ifTrue:/#ifFalse:]

Klaus D. Witzel
In reply to this post by Igor Stasenko
On Wed, 05 Mar 2008 07:39:33 +0100, Igor Stasenko wrote:

> On 05/03/2008, Paolo Bonzini wrote:
>> Igor Stasenko wrote:
>>  > Hello,
>>  >
>>  > i currently tried to implement a proxy (subclass of ProtoObject) with
>>  > own IfTrue:/ifFalse: methods.
>>  > What i can't understand, is why VM throws me with #mustBeBoolean
>>  > message instead of doing real send if optimized pattern fails (when
>>  > receiver of #IfTrue: is a non-boolean)?
>>
>> Because you cannot distinguish #ifTrue:#ifFalse: sends from #whileTrue:
>>  for example, and because there are no BlockC{ontext,losure} objects for
>>  the argument blocks.
>>
>
> So, the only way is to compile method without optimization of #ifTrue  
> #ifFalse:, to make sure they do real sends?
>
> If yes, i'd like to see optimizations optional,

For Rob Wither's project I've made a small patch  
NoMacroCompiler-kwl.1dot5.cs which allows to specify per method (in a  
pragma) or system-wide that macros are inlined or result in a full send.  
Could be adapted to select what kind of macro not/to optimize. I've also  
identified which Squeak .image methods *must* be compiled *with* macro  
inlineing so that the .image does not crash/get stuck. And out of  
meta-programming/memory reasons, the implementation of #whileTrue*,  
#whileFalse* must be compiled *with* inlineing ;-)

Let me know if that's interesting to you.

/Klaus

> so people can do like:
>
> Compiler turnOffOptimizations.
> MyClass compileAll.
> Compiler turnOnOptimizations.
>
>>
>>  Paolo
>>
>>
>
>



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Compiling with macro inliner switch [was: Boolean over-optimization #ifTrue:/#ifFalse:]

Igor Stasenko
On 05/03/2008, Klaus D. Witzel <[hidden email]> wrote:

> On Wed, 05 Mar 2008 07:39:33 +0100, Igor Stasenko wrote:
>
>  > On 05/03/2008, Paolo Bonzini wrote:
>  >> Igor Stasenko wrote:
>  >>  > Hello,
>  >>  >
>  >>  > i currently tried to implement a proxy (subclass of ProtoObject) with
>  >>  > own IfTrue:/ifFalse: methods.
>  >>  > What i can't understand, is why VM throws me with #mustBeBoolean
>  >>  > message instead of doing real send if optimized pattern fails (when
>  >>  > receiver of #IfTrue: is a non-boolean)?
>  >>
>  >> Because you cannot distinguish #ifTrue:#ifFalse: sends from #whileTrue:
>  >>  for example, and because there are no BlockC{ontext,losure} objects for
>  >>  the argument blocks.
>  >>
>  >
>  > So, the only way is to compile method without optimization of #ifTrue
>  > #ifFalse:, to make sure they do real sends?
>  >
>  > If yes, i'd like to see optimizations optional,
>
>  For Rob Wither's project I've made a small patch
>  NoMacroCompiler-kwl.1dot5.cs which allows to specify per method (in a
>  pragma) or system-wide that macros are inlined or result in a full send.
>  Could be adapted to select what kind of macro not/to optimize. I've also
>  identified which Squeak .image methods *must* be compiled *with* macro
>  inlineing so that the .image does not crash/get stuck. And out of
>  meta-programming/memory reasons, the implementation of #whileTrue*,
>  #whileFalse* must be compiled *with* inlineing ;-)
>

The only place, where whileTrue:/whileFalse: should be _always_
compiled optimized its in
BlockContext/BlockClosure whileTrue:/whileFalse: methods.
In rest of the code there is nothing bad in using real sends.

>  Let me know if that's interesting to you.
>

Yes, let me take a look at it.
i'm already using pragma <metacode> to switch between different
simulation modes (but it's in my own domain, not related to optimized
booleans).

I'm currently doing some research, by implementing own object memory
with a small set of classes. To make things done fast, i decided to
not create parsers/bytecode interpreter, but instead, use squeak as
backend for evaluating a code using proxies.

My intent is to create a kind of self-hosted VM, which after some
bootstrap can start working without the need of implementing things
externally, like primitives/bytecode interpreter.
A 'primitives' in this system will be replaced by a special methods,
marked with <metacode> pragma, which should follow special rules and
handled differently by compiler.
But what is good, that these methods are 'live' - you can change their
implementation at any time, in same way as any other method in
smalltalk.
As a first 'showcase' i like to make complete implementation of
classes which can create objects and do smallint math without the need
of primitives (means, all behavior implementation resides in object
memory).

To complete a full circle, the VM should be capable to compile methods
to bare metal (CPU instructions) and can execute them without any
external help.

>  /Klaus

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Compiling with macro inliner switch [was: Boolean over-optimization #ifTrue:/#ifFalse:]

stephane ducasse
Sounds really interesting idea.

Stef

>> Yes, let me take a look at it.
> i'm already using pragma <metacode> to switch between different
> simulation modes (but it's in my own domain, not related to optimized
> booleans).
>
> I'm currently doing some research, by implementing own object memory
> with a small set of classes. To make things done fast, i decided to
> not create parsers/bytecode interpreter, but instead, use squeak as
> backend for evaluating a code using proxies.
>
> My intent is to create a kind of self-hosted VM, which after some
> bootstrap can start working without the need of implementing things
> externally, like primitives/bytecode interpreter.
> A 'primitives' in this system will be replaced by a special methods,
> marked with <metacode> pragma, which should follow special rules and
> handled differently by compiler.
> But what is good, that these methods are 'live' - you can change their
> implementation at any time, in same way as any other method in
> smalltalk.
> As a first 'showcase' i like to make complete implementation of
> classes which can create objects and do smallint math without the need
> of primitives (means, all behavior implementation resides in object
> memory).
>
> To complete a full circle, the VM should be capable to compile methods
> to bare metal (CPU instructions) and can execute them without any
> external help.
>
>> /Klaus
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>
>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Compiling with macro inliner switch [was: Boolean over-optimization #ifTrue:/#ifFalse:]

Klaus D. Witzel
In reply to this post by Igor Stasenko
On Wed, 05 Mar 2008 10:09:53 +0100, Igor Stasenko wrote:

> On 05/03/2008, Klaus D. Witzel wrote:
>> On Wed, 05 Mar 2008 07:39:33 +0100, Igor Stasenko wrote:
>>  > On 05/03/2008, Paolo Bonzini wrote:
>>  >> Igor Stasenko wrote:
>>  >>  > Hello,
>>  >>  >
>>  >>  > i currently tried to implement a proxy (subclass of ProtoObject)  
>>  >>  > with own IfTrue:/ifFalse: methods.
>>  >>  > What i can't understand, is why VM throws me with #mustBeBoolean
>>  >>  > message instead of doing real send if optimized pattern fails  
>>  >>  > (when receiver of #IfTrue: is a non-boolean)?
>>  >>
>>  >> Because you cannot distinguish #ifTrue:#ifFalse: sends from  
>> #whileTrue:
>>  >>  for example, and because there are no BlockC{ontext,losure}  
>> objects for
>>  >>  the argument blocks.
>>  >
>>  > So, the only way is to compile method without optimization of #ifTrue
>>  > #ifFalse:, to make sure they do real sends?
>>  >
>>  > If yes, i'd like to see optimizations optional,
>>
>>  For Rob Wither's project I've made a small patch
>>  NoMacroCompiler-kwl.1dot5.cs which allows to specify per method (in a
>>  pragma) or system-wide that macros are inlined or result in a full  
>> send.
>>  Could be adapted to select what kind of macro not/to optimize. I've  
>> also
>>  identified which Squeak .image methods *must* be compiled *with* macro
>>  inlineing so that the .image does not crash/get stuck. And out of
>>  meta-programming/memory reasons, the implementation of #whileTrue*,
>>  #whileFalse* must be compiled *with* inlineing ;-)
>>
>
> The only place, where whileTrue:/whileFalse: should be _always_
> compiled optimized its in
> BlockContext/BlockClosure whileTrue:/whileFalse: methods.
> In rest of the code there is nothing bad in using real sends.
Yes. And that's magically recognized by the attached.

>
>>  Let me know if that's interesting to you.
>
> Yes, let me take a look at it.

Attached. Beware of

CommandHistory class forgetAllGrabCommandsFrom:
ContextPart handleSignal:
ContextPart restart
ContextPart resume:
Exception outer
ImageSegment allObjectsDo:
ImageSegment comeFullyUpOnReload:
ImageSegment rehashSets
ImageSegment restoreEndianness
ImageSegment copyFromRoots:sizeHint:areUnique:
ImageSegment install
ImageSegment readFromFile
PointerFinder class pointersTo:except:
Process debug:title:full:
Process debugWithTitle:
Process terminate
ProjectLoading class openName:stream:fromDirectory:withProjectView:
SystemNavigation allObjectsDo:
SystemProgressMorph nextSlotFor:
Utilities class pointersTo:except:

you *have* been warned. Besides that list, I found that the Squeak .image  
can be run at the full message send level.

> i'm already using pragma <metacode> to switch between different
> simulation modes (but it's in my own domain, not related to optimized
> booleans).
>
> I'm currently doing some research, by implementing own object memory
> with a small set of classes. To make things done fast, i decided to
> not create parsers/bytecode interpreter, but instead, use squeak as
> backend for evaluating a code using proxies.

So I don't have to develop that? Great, send me a copy please.

/Klaus


NoMacroCompiler-kwl.1dot5dot1.cs (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Compiling with macro inliner switch [was: Boolean over-optimization #ifTrue:/#ifFalse:]

Igor Stasenko
On 05/03/2008, Klaus D. Witzel <[hidden email]> wrote:

> On Wed, 05 Mar 2008 10:09:53 +0100, Igor Stasenko wrote:
>
>
>  > On 05/03/2008, Klaus D. Witzel wrote:
>  >> On Wed, 05 Mar 2008 07:39:33 +0100, Igor Stasenko wrote:
>  >>  > On 05/03/2008, Paolo Bonzini wrote:
>  >>  >> Igor Stasenko wrote:
>  >>  >>  > Hello,
>  >>  >>  >
>  >>  >>  > i currently tried to implement a proxy (subclass of ProtoObject)
>  >>  >>  > with own IfTrue:/ifFalse: methods.
>  >>  >>  > What i can't understand, is why VM throws me with #mustBeBoolean
>  >>  >>  > message instead of doing real send if optimized pattern fails
>  >>  >>  > (when receiver of #IfTrue: is a non-boolean)?
>  >>  >>
>  >>  >> Because you cannot distinguish #ifTrue:#ifFalse: sends from
>  >> #whileTrue:
>  >>  >>  for example, and because there are no BlockC{ontext,losure}
>  >> objects for
>  >>  >>  the argument blocks.
>  >>  >
>  >>  > So, the only way is to compile method without optimization of #ifTrue
>  >>  > #ifFalse:, to make sure they do real sends?
>  >>  >
>  >>  > If yes, i'd like to see optimizations optional,
>  >>
>  >>  For Rob Wither's project I've made a small patch
>  >>  NoMacroCompiler-kwl.1dot5.cs which allows to specify per method (in a
>  >>  pragma) or system-wide that macros are inlined or result in a full
>  >> send.
>  >>  Could be adapted to select what kind of macro not/to optimize. I've
>  >> also
>  >>  identified which Squeak .image methods *must* be compiled *with* macro
>  >>  inlineing so that the .image does not crash/get stuck. And out of
>  >>  meta-programming/memory reasons, the implementation of #whileTrue*,
>  >>  #whileFalse* must be compiled *with* inlineing ;-)
>  >>
>  >
>  > The only place, where whileTrue:/whileFalse: should be _always_
>  > compiled optimized its in
>  > BlockContext/BlockClosure whileTrue:/whileFalse: methods.
>  > In rest of the code there is nothing bad in using real sends.
>
>
> Yes. And that's magically recognized by the attached.
>
>
>  >
>  >>  Let me know if that's interesting to you.
>  >
>  > Yes, let me take a look at it.
>
>
> Attached. Beware of
>
>  CommandHistory class forgetAllGrabCommandsFrom:
>  ContextPart handleSignal:
>  ContextPart restart
>  ContextPart resume:
>  Exception outer
>  ImageSegment allObjectsDo:
>  ImageSegment comeFullyUpOnReload:
>  ImageSegment rehashSets
>  ImageSegment restoreEndianness
>  ImageSegment copyFromRoots:sizeHint:areUnique:
>  ImageSegment install
>  ImageSegment readFromFile
>  PointerFinder class pointersTo:except:
>  Process debug:title:full:
>  Process debugWithTitle:
>  Process terminate
>  ProjectLoading class openName:stream:fromDirectory:withProjectView:
>  SystemNavigation allObjectsDo:
>  SystemProgressMorph nextSlotFor:
>  Utilities class pointersTo:except:
>
>  you *have* been warned. Besides that list, I found that the Squeak .image
>  can be run at the full message send level.
>
I'm never planned to use this outside the scope of my own
classes/methods, where i exactly know what should happen. So there is
no risk at all :)

>
>  > i'm already using pragma <metacode> to switch between different
>  > simulation modes (but it's in my own domain, not related to optimized
>  > booleans).
>  >
>  > I'm currently doing some research, by implementing own object memory
>  > with a small set of classes. To make things done fast, i decided to
>  > not create parsers/bytecode interpreter, but instead, use squeak as
>  > backend for evaluating a code using proxies.
>
>
> So I don't have to develop that? Great, send me a copy please.
>
Sure!

>
>  /Klaus
>

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Objects as Booleans (was Re: Boolean over-optimization #ifTrue:/#ifFalse:)

Bert Freudenberg
In reply to this post by Lukas Renggli
On Mar 5, 2008, at 7:52 , Lukas Renggli wrote:

>> So, the only way is to compile method without optimization of  
>> #ifTrue #ifFalse:,
>>  to make sure they do real sends?
>
> Just today in my blog-reader:
>
> http://www.cincomsmalltalk.com/userblogs/mls/blogView?
> showComments=true&printTitle=Boolean_Objects&entry=3382109971
>
> This should also work in Squeak.
Hehe, very cool. It works a bit differently in Squeak, where the  
image code has to rewind the context before the jump bytecode that  
recognized the non-boolean. Attached is a little changeset that adds  
#asBoolean to various classes and overrides #mustBeBooleanIn: to use  
that, provided objectsAsBooleans has been enabled. File in, then try  
this:

Preferences enable: #objectsAsBooleans.
#(0 1 nil #() #(a b c) 'hi' '') collect: [:each |
        each  -> (each ifTrue: ['yes'] ifFalse: ['no'])]

#(0->'no' 1->'yes' nil->'no' #()->'no' #(#a #b #c)->'yes' 'hi'->'yes'  
''->'no')

Fun indeed :)

- Bert -





oooleans-bf.1.cs.gz (872 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Objects as Booleans (was Re: Boolean over-optimization #ifTrue:/#ifFalse:)

Igor Stasenko
On 05/03/2008, Bert Freudenberg <[hidden email]> wrote:

> On Mar 5, 2008, at 7:52 , Lukas Renggli wrote:
>
>  >> So, the only way is to compile method without optimization of
>  >> #ifTrue #ifFalse:,
>  >>  to make sure they do real sends?
>  >
>  > Just today in my blog-reader:
>  >
>  > http://www.cincomsmalltalk.com/userblogs/mls/blogView?
>  > showComments=true&printTitle=Boolean_Objects&entry=3382109971
>  >
>  > This should also work in Squeak.
>
>  Hehe, very cool. It works a bit differently in Squeak, where the
>  image code has to rewind the context before the jump bytecode that
>  recognized the non-boolean. Attached is a little changeset that adds
>  #asBoolean to various classes and overrides #mustBeBooleanIn: to use
>  that, provided objectsAsBooleans has been enabled. File in, then try
>  this:
>
>  Preferences enable: #objectsAsBooleans.
>  #(0 1 nil #() #(a b c) 'hi' '') collect: [:each |
>         each  -> (each ifTrue: ['yes'] ifFalse: ['no'])]
>
>  #(0->'no' 1->'yes' nil->'no' #()->'no' #(#a #b #c)->'yes' 'hi'->'yes'
>  ''->'no')
>
>  Fun indeed :)
>

Yeah, rewinding a bytecode counter of parent context is a kind of
woodo black magic. But hey! It works!

>
>  - Bert -
>



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Rewinding the pc [was: Objects as Booleans (was Re: Boolean over-optimization #ifTrue:/#ifFalse:)]

Klaus D. Witzel
On Wed, 05 Mar 2008 12:44:31 +0100, Igor Stasenko wrote:

> On 05/03/2008, Bert Freudenberg <[hidden email]> wrote:
>> On Mar 5, 2008, at 7:52 , Lukas Renggli wrote:
>>
>>  >> So, the only way is to compile method without optimization of
>>  >> #ifTrue #ifFalse:,
>>  >>  to make sure they do real sends?
>>  >
>>  > Just today in my blog-reader:
>>  >
>>  > http://www.cincomsmalltalk.com/userblogs/mls/blogView?
>>  > showComments=true&printTitle=Boolean_Objects&entry=3382109971
>>  >
>>  > This should also work in Squeak.
>>
>>  Hehe, very cool. It works a bit differently in Squeak, where the
>>  image code has to rewind the context before the jump bytecode that
>>  recognized the non-boolean. Attached is a little changeset that adds
>>  #asBoolean to various classes and overrides #mustBeBooleanIn: to use
>>  that, provided objectsAsBooleans has been enabled. File in, then try
>>  this:
>>
>>  Preferences enable: #objectsAsBooleans.
>>  #(0 1 nil #() #(a b c) 'hi' '') collect: [:each |
>>         each  -> (each ifTrue: ['yes'] ifFalse: ['no'])]
>>
>>  #(0->'no' 1->'yes' nil->'no' #()->'no' #(#a #b #c)->'yes' 'hi'->'yes'
>>  ''->'no')
>>
>>  Fun indeed :)
>>
>
> Yeah, rewinding a bytecode counter of parent context is a kind of
> woodo black magic. But hey! It works!

I admit I do it every now and then, for example in a subclass of compiler  
who wants another parser class (critique + better hack appreciated, but no  
code duplication :)

!LLk1Compiler methodsFor: 'adaption-Compiler'!
parserClass
        thisContext sender jump: 1! !

/Klaus

>>
>>  - Bert -
>>
>
>
>



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Boolean over-optimization #ifTrue:/#ifFalse:

Michael van der Gulik-2
In reply to this post by Igor Stasenko


On Wed, Mar 5, 2008 at 7:01 PM, Igor Stasenko <[hidden email]> wrote:
Hello,

i currently tried to implement a proxy (subclass of ProtoObject) with
own IfTrue:/ifFalse: methods.
What i can't understand, is why VM throws me with #mustBeBoolean
message instead of doing real send if optimized pattern fails (when
receiver of #IfTrue: is a non-boolean)?


FYI, I have a vested interested in message capture, as does Craig Latta.

My approach is at http://www.squeaksource.com/DPON/MessageCapture-mvdg.13.mcz. It includes special inspecters and print methods that let the debugger work (mostly) as well, although its still as dangerous as programming in C or playing with dynamite.

I can't remember if I also capture the ifTrue:/ifFalse sends; I may have overridden #mustBeBoolean to handle that case.

Craig Latta's approach was to make a special class using VM modifications. I think this is a better approach and I might rip his code off at some stage :-P.

Gulik.

--
http://people.squeakfoundation.org/person/mikevdg
http://gulik.pbwiki.com/

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Boolean over-optimization #ifTrue:/#ifFalse:

Michael van der Gulik-2
In reply to this post by Igor Stasenko


On Wed, Mar 5, 2008 at 7:01 PM, Igor Stasenko <[hidden email]> wrote:
Hello,

i currently tried to implement a proxy (subclass of ProtoObject) with
own IfTrue:/ifFalse: methods.
What i can't understand, is why VM throws me with #mustBeBoolean
message instead of doing real send if optimized pattern fails (when
receiver of #IfTrue: is a non-boolean)?

Is there any way, without modifying compiler, how to force it to do real send?


Oh, you'll also have trouble with >>class and >>==. These two messages are implemented directly in the VM and bypass method lookup. I have no solution to this but there's a patch for the VM here: http://wiki.squeak.org/squeak/2074.

Gulik.

--
http://people.squeakfoundation.org/person/mikevdg
http://gulik.pbwiki.com/

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

ccrraaiigg
In reply to this post by Michael van der Gulik-2

Hi--

 > Craig Latta's approach was to make a special class using VM
 > modifications.

      Yeah, I handled all the special messages. In Spoon, if the
receiver is a proxy, then a real message-send (almost always followed by
a forward) happens at all times. The proxy class can live anywhere in
the hierarchy, too.


-C



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Igor Stasenko
In reply to this post by Joshua Gargus-2
On 05/03/2008, Joshua Gargus <[hidden email]> wrote:

> The #compilerClass method allows you to specify the compiler to be
>  used for a class (and its subclasses).  So, one approach would be to
>  implement a subclass of Compiler (say, "ProxyCompiler") that disables
>  optimization of #ifTrue:ifFalse: etc.
>
>  I'm not sure about a clean way to disable optimizations in a subclass
>  of Compiler.  Here's a moderately horrible way to disable them
>  globally...
>         - give Compiler a boolean class variable "DisableSpecialSelectors"
>         - hack MethodNode>>noteSpecialSelector: thusly...
>
>  noteSpecialSelector: selectorSymbol
>         " special > 0 denotes specially treated messages. "
>
>         DisableSpecialSelectors ifTrue: [special := 0. ^self].
>
>         "Deconvert initial keywords from SQ2K"
>         special := #(:Test:Yes: :Test:No: :Test:Yes:No: :Test:No:Yes:

What are these selectors (:Test:Yes: :Test:No: :Test:Yes:No: :Test:No:Yes:)?
And why they need special handling..
And what SQ2K means?
Ohh.. it seems that its easier to write own parser than using default one.

I'd like to add that a Parser/Compiler are focused on compiling
things, not for examining parse tree, which is bad.
Like, for instance, why MethodNode doesn't have accessor to arguments
ivar and forcing me to use #asTranslationMethodOfClass: only for a
single reason - to have a change to look an argument names of parsed
method.


>                                 and: or:
>                                 :Until:do: :While:do: whileFalse whileTrue
>                                 :Repeat:to:do: :Repeat:to:by:do:
>                                 ) indexOf: selectorSymbol.
>         special > 0 ifTrue: [^ self].
>
>         special := MacroSelectors indexOf: selectorSymbol.
>
>
>  Then, you could override #translate:noPattern:ifFail: in
>  ProxyCompiler, as follows...
>
>  translate: aStream noPattern: noPattern ifFail: failBlock
>         [       DisableSpecialSelectors := true.
>                 ^super translate: aStream noPattern: noPattern ifFail: failBlock
>         ] ensure: [DisableSpecialSelectors := false].
>
>
>  Finally, implement #compilerClass on the class-side of your Proxy
>  class, and answer ProxyCompiler.
>
>  Heh, that was sorta fun!
>  Josh
>
>
>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Dan Ingalls
Igor asked...

>What are these selectors (:Test:Yes: :Test:No: :Test:Yes:No: :Test:No:Yes:)?

These were synonyms for ifTrue/ifFalse in SQ2K

>And why they need special handling..

For the same reason as ifTrue/ifFalse.

>And what SQ2K means?

SQ2K, (named as the year 2000 was approaching) was an "alternate syntax" experiment that you may find in the archives.  At one point it was well enough supported that you could view code in the new syntax, type and compile new code in it, but fileOuts and the changes file continued to work in the old ST80 format.  The project was dropped shortly after everything worked ;-).

        - Dan

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Boolean over-optimization #ifTrue:/#ifFalse:

Paolo Bonzini-2

> SQ2K, (named as the year 2000 was approaching) was an "alternate syntax" experiment

If I parsed this
<http://209.85.129.104/search?q=cache:lh62Jns1EzkJ:coweb.cc.gatech.edu/cs2340/uploads/colonfreesyntax.cs.gz+SQ2K+squeak&hl=en&ct=clnk&cd=1>
correctly it would look something like

a := Array new(5).
a at(1) put('abc').

Paolo